remove unused code, remove references to v8::Persistent

This commit is contained in:
Karl Seguin
2026-01-05 18:33:37 +08:00
parent 4720268426
commit 2322cb9b83
11 changed files with 28 additions and 157 deletions

View File

@@ -117,7 +117,6 @@ pub fn build(b: *Build) !void {
} }
{ {
// ZIGDOM
// browser // browser
const exe = b.addExecutable(.{ const exe = b.addExecutable(.{
.name = "legacy_test", .name = "legacy_test",

View File

@@ -39,10 +39,3 @@ pub fn getInt64(self: BigInt) i64 {
pub fn getUint64(self: BigInt) u64 { pub fn getUint64(self: BigInt) u64 {
return v8.v8__BigInt__Uint64Value(self.handle, null); return v8.v8__BigInt__Uint64Value(self.handle, null);
} }
pub fn toValue(self: BigInt) js.Value {
return .{
.ctx = undefined, // Will be set by caller if needed
.handle = @ptrCast(self.handle),
};
}

View File

@@ -72,7 +72,7 @@ identity_map: std.AutoHashMapUnmanaged(usize, js.Global(js.Object)) = .empty,
// Some web APIs have to manage opaque values. Ideally, they use an // Some web APIs have to manage opaque values. Ideally, they use an
// js.Object, but the js.Object has no lifetime guarantee beyond the // js.Object, but the js.Object has no lifetime guarantee beyond the
// current call. They can call .persist() on their js.Object to get // current call. They can call .persist() on their js.Object to get
// a `*PersistentObject()`. We need to track these to free them. // a `Global(Object)`. We need to track these to free them.
// This used to be a map and acted like identity_map; the key was // This used to be a map and acted like identity_map; the key was
// the @intFromPtr(js_obj.handle). But v8 can re-use address. Without // the @intFromPtr(js_obj.handle). But v8 can re-use address. Without
// a reliable way to know if an object has already been persisted, // a reliable way to know if an object has already been persisted,
@@ -526,15 +526,15 @@ pub fn zigValueToJs(self: *Context, value: anytype, comptime opts: Caller.CallOp
} }
// To turn a Zig instance into a v8 object, we need to do a number of things. // To turn a Zig instance into a v8 object, we need to do a number of things.
// First, if it's a struct, we need to put it on the heap // First, if it's a struct, we need to put it on the heap.
// Second, if we've already returned this instance, we should return // Second, if we've already returned this instance, we should return
// the same object. Hence, our executor maintains a map of Zig objects // the same object. Hence, our executor maintains a map of Zig objects
// to v8.PersistentObject (the "identity_map"). // to v8.Global(js.Object) (the "identity_map").
// Finally, if this is the first time we've seen this instance, we need to: // Finally, if this is the first time we've seen this instance, we need to:
// 1 - get the FunctionTemplate (from our templates slice) // 1 - get the FunctionTemplate (from our templates slice)
// 2 - Create the TaggedAnyOpaque so that, if needed, we can do the reverse // 2 - Create the TaggedAnyOpaque so that, if needed, we can do the reverse
// (i.e. js -> zig) // (i.e. js -> zig)
// 3 - Create a v8.PersistentObject (because Zig owns this object, not v8) // 3 - Create a v8.Global(js.Object) (because Zig owns this object, not v8)
// 4 - Store our TaggedAnyOpaque into the persistent object // 4 - Store our TaggedAnyOpaque into the persistent object
// 5 - Update our identity_map (so that, if we return this same instance again, // 5 - Update our identity_map (so that, if we return this same instance again,
// we can just grab it from the identity_map) // we can just grab it from the identity_map)

View File

@@ -23,6 +23,10 @@ const HandleScope = @This();
handle: v8.HandleScope, handle: v8.HandleScope,
// V8 takes an address of the value that's passed in, so it needs to be stable.
// We can't create the v8.HandleScope here, pass it to v8 and then return the
// value, as v8 will then have taken the address of the function-scopped (and no
// longer valid) local.
pub fn init(self: *HandleScope, isolate: js.Isolate) void { pub fn init(self: *HandleScope, isolate: js.Isolate) void {
v8.v8__HandleScope__CONSTRUCT(&self.handle, isolate.handle); v8.v8__HandleScope__CONSTRUCT(&self.handle, isolate.handle);
} }

View File

@@ -154,7 +154,7 @@ pub fn contextCreated(
// Retrieves the RemoteObject for a given value. // Retrieves the RemoteObject for a given value.
// The value is loaded through the ExecutionWorld's mapZigInstanceToJs function, // The value is loaded through the ExecutionWorld's mapZigInstanceToJs function,
// just like a method return value. Therefore, if we've mapped this // just like a method return value. Therefore, if we've mapped this
// value before, we'll get the existing JS PersistedObject and if not // value before, we'll get the existing js.Global(js.Object) and if not
// we'll create it and track it for cleanup when the context ends. // we'll create it and track it for cleanup when the context ends.
pub fn getRemoteObject( pub fn getRemoteObject(
self: *const Inspector, self: *const Inspector,

View File

@@ -22,10 +22,3 @@ const v8 = js.v8;
const Name = @This(); const Name = @This();
handle: *const v8.Name, handle: *const v8.Name,
pub fn toValue(self: Name) js.Value {
return .{
.ctx = undefined, // Will be set by caller if needed
.handle = @ptrCast(self.handle),
};
}

View File

@@ -23,7 +23,6 @@ const v8 = js.v8;
const IS_DEBUG = @import("builtin").mode == .Debug; const IS_DEBUG = @import("builtin").mode == .Debug;
const Context = @import("Context.zig"); const Context = @import("Context.zig");
const PersistentObject = v8.Persistent(v8.Object);
const Allocator = std.mem.Allocator; const Allocator = std.mem.Allocator;
@@ -71,16 +70,6 @@ pub fn set(self: Object, key: anytype, value: anytype, comptime opts: js.bridge.
return out.has_value; return out.has_value;
} }
pub fn setIndex(self: Object, key: u32, value: anytype, comptime opts: js.bridge.Caller.CallOpts) !bool {
const ctx = self.ctx;
const js_value = try ctx.zigValueToJs(value, opts);
var out: v8.MaybeBool = undefined;
v8.v8__Object__SetAtIndex(self.handle, ctx.handle, key, js_value.handle, &out);
return out.has_value;
}
pub fn defineOwnProperty(self: Object, name: []const u8, value: js.Value, attr: v8.PropertyAttribute) ?bool { pub fn defineOwnProperty(self: Object, name: []const u8, value: js.Value, attr: v8.PropertyAttribute) ?bool {
const ctx = self.ctx; const ctx = self.ctx;
const name_handle = ctx.isolate.initStringHandle(name); const name_handle = ctx.isolate.initStringHandle(name);

View File

@@ -53,7 +53,7 @@ startup_data: v8.StartupData,
external_references: [countExternalReferences()]isize, external_references: [countExternalReferences()]isize,
// Track whether this snapshot owns its data (was created in-process) // Track whether this snapshot owns its data (was created in-process)
// If false, the data points into embedded_snapshot_blob and should not be freed // If false, the data points into embedded_snapshot_blob and will not be freed
owns_data: bool = false, owns_data: bool = false,
pub fn load() !Snapshot { pub fn load() !Snapshot {
@@ -106,7 +106,7 @@ pub fn write(self: Snapshot, writer: *std.Io.Writer) !void {
pub fn fromEmbedded(self: Snapshot) bool { pub fn fromEmbedded(self: Snapshot) bool {
// if the snapshot comes from the embedFile, then it'll be flagged as not // if the snapshot comes from the embedFile, then it'll be flagged as not
// owneing (aka, not needing to free) the data. // owning (aka, not needing to free) the data.
return self.owns_data == false; return self.owns_data == false;
} }

View File

@@ -168,7 +168,7 @@ pub fn toBool(self: Value) bool {
pub fn typeOf(self: Value) js.String { pub fn typeOf(self: Value) js.String {
const str_handle = v8.v8__Value__TypeOf(self.handle, self.ctx.isolate.handle).?; const str_handle = v8.v8__Value__TypeOf(self.handle, self.ctx.isolate.handle).?;
return js.String{ .ctx = @constCast(self.ctx), .handle = str_handle }; return js.String{ .ctx = self.ctx) .handle = str_handle };
} }
pub fn toF32(self: Value) !f32 { pub fn toF32(self: Value) !f32 {
@@ -225,7 +225,7 @@ pub fn toJson(self: Value, allocator: Allocator) ![]u8 {
} }
fn _toString(self: Value, comptime null_terminate: bool, opts: js.String.ToZigOpts) !(if (null_terminate) [:0]u8 else []u8) { fn _toString(self: Value, comptime null_terminate: bool, opts: js.String.ToZigOpts) !(if (null_terminate) [:0]u8 else []u8) {
const ctx: *js.Context = @constCast(self.ctx); const ctx = self.ctx;
if (self.isSymbol()) { if (self.isSymbol()) {
const sym_handle = v8.v8__Symbol__Description(@ptrCast(self.handle), ctx.isolate.handle).?; const sym_handle = v8.v8__Symbol__Description(@ptrCast(self.handle), ctx.isolate.handle).?;
@@ -253,7 +253,7 @@ pub fn (ctx: *js.Context, json: []const u8) !Value {
} }
pub fn persist(self: Value) !Value { pub fn persist(self: Value) !Value {
var ctx: *js.Context = @constCast(self.ctx); var ctx = self.ctx;
const global = js.Global(Value).init(ctx.isolate.handle, self.handle); const global = js.Global(Value).init(ctx.isolate.handle, self.handle);
try ctx.global_values.append(ctx.arena, global); try ctx.global_values.append(ctx.arena, global);
@@ -274,7 +274,7 @@ pub fn toObject(self: Value) js.Object {
} }
return .{ return .{
.ctx = @constCast(self.ctx), .ctx = self.ctx,
.handle = @ptrCast(self.handle), .handle = @ptrCast(self.handle),
}; };
} }
@@ -285,7 +285,7 @@ pub fn toArray(self: Value) js.Array {
} }
return .{ return .{
.ctx = @constCast(self.ctx), .ctx = self.ctx,
.handle = @ptrCast(self.handle), .handle = @ptrCast(self.handle),
}; };
} }
@@ -307,3 +307,15 @@ pub fn format(self: Value, writer: *std.Io.Writer) !void {
const str = self.toString(.{}) catch return error.WriteFailed; const str = self.toString(.{}) catch return error.WriteFailed;
return writer.writeAll(str); return writer.writeAll(str);
} }
pub fn persist(self: Value) !Value {
var ctx = self.ctx;
const global = js.Global(Value).init(ctx.isolate.handle, self.handle);
try ctx.global_values.append(ctx.arena, global);
return .{
.ctx = ctx,
.handle = global.local(),
};
}

View File

@@ -86,84 +86,6 @@ pub const Exception = struct {
} }
}; };
pub fn UndefinedOr(comptime T: type) type {
return union(enum) {
undefined: void,
value: T,
};
}
// An interface for types that want to have their jsScopeEnd function be
// called when the call context ends
const CallScopeEndCallback = struct {
ptr: *anyopaque,
callScopeEndFn: *const fn (ptr: *anyopaque) void,
fn init(ptr: anytype) CallScopeEndCallback {
const T = @TypeOf(ptr);
const ptr_info = @typeInfo(T);
const gen = struct {
pub fn callScopeEnd(pointer: *anyopaque) void {
const self: T = @ptrCast(@alignCast(pointer));
return ptr_info.pointer.child.jsCallScopeEnd(self);
}
};
return .{
.ptr = ptr,
.callScopeEndFn = gen.callScopeEnd,
};
}
pub fn callScopeEnd(self: CallScopeEndCallback) void {
self.callScopeEndFn(self.ptr);
}
};
// Callback called on global's property missing.
// Return true to intercept the execution or false to let the call
// continue the chain.
pub const GlobalMissingCallback = struct {
ptr: *anyopaque,
missingFn: *const fn (ptr: *anyopaque, name: []const u8, ctx: *Context) bool,
pub fn init(ptr: anytype) GlobalMissingCallback {
const T = @TypeOf(ptr);
const ptr_info = @typeInfo(T);
const gen = struct {
pub fn missing(pointer: *anyopaque, name: []const u8, ctx: *Context) bool {
const self: T = @ptrCast(@alignCast(pointer));
return ptr_info.pointer.child.missing(self, name, ctx);
}
};
return .{
.ptr = ptr,
.missingFn = gen.missing,
};
}
pub fn missing(self: GlobalMissingCallback, name: []const u8, ctx: *Context) bool {
return self.missingFn(self.ptr, name, ctx);
}
};
// Attributes that return a primitive type are setup directly on the
// FunctionTemplate when the Env is setup. More complex types need a v8.Context
// and cannot be set directly on the FunctionTemplate.
// We default to saying types are primitives because that's mostly what
// we have. If we add a new complex type that isn't explictly handled here,
// we'll get a compiler error in simpleZigValueToJs, and can then explicitly
// add the type here.
pub fn isComplexAttributeType(ti: std.builtin.Type) bool {
return switch (ti) {
.array => true,
else => false,
};
}
// These are simple types that we can convert to JS with only an isolate. This // These are simple types that we can convert to JS with only an isolate. This
// is separated from the Caller's zigValueToJs to make it available when we // is separated from the Caller's zigValueToJs to make it available when we
// don't have a caller (i.e., when setting static attributes on types) // don't have a caller (i.e., when setting static attributes on types)
@@ -293,17 +215,6 @@ pub fn simpleZigValueToJs(isolate: Isolate, value: anytype, comptime fail: bool,
} }
return null; return null;
} }
pub fn classNameForStruct(comptime Struct: type) []const u8 {
if (@hasDecl(Struct, "js_name")) {
return Struct.js_name;
}
@setEvalBranchQuota(10_000);
const full_name = @typeName(Struct);
const last = std.mem.lastIndexOfScalar(u8, full_name, '.') orelse return full_name;
return full_name[last + 1 ..];
}
// When we return a Zig object to V8, we put it on the heap and pass it into // When we return a Zig object to V8, we put it on the heap and pass it into
// v8 as an *anyopaque (i.e. void *). When V8 gives us back the value, say, as a // v8 as an *anyopaque (i.e. void *). When V8 gives us back the value, say, as a
// function parameter, we know what type it _should_ be. // function parameter, we know what type it _should_ be.

View File

@@ -429,36 +429,6 @@ const TransferAsResponseWriter = struct {
} }
}; };
// @ZIGDOM - do we still need this? just send the full URL?
// const DocumentUrlWriter = struct {
// uri: *std.Uri,
// fn init(uri: *std.Uri) DocumentUrlWriter {
// return .{
// .uri = uri,
// };
// }
// pub fn jsonStringify(self: *const DocumentUrlWriter, jws: anytype) !void {
// self._jsonStringify(jws) catch return error.WriteFailed;
// }
// fn _jsonStringify(self: *const DocumentUrlWriter, jws: anytype) !void {
// const writer = jws.writer;
// try jws.beginWriteRaw();
// try writer.writeByte('\"');
// try self.uri.writeToStream(writer, .{
// .scheme = true,
// .authentication = true,
// .authority = true,
// .path = true,
// .query = true,
// });
// try writer.writeByte('\"');
// jws.endWriteRaw();
// }
// };
fn idFromRequestId(request_id: []const u8) !u64 { fn idFromRequestId(request_id: []const u8) !u64 {
if (!std.mem.startsWith(u8, request_id, "REQ-")) { if (!std.mem.startsWith(u8, request_id, "REQ-")) {
return error.InvalidParams; return error.InvalidParams;