remove global handlescope

This commit is contained in:
Karl Seguin
2026-01-16 16:51:19 +08:00
parent 62aa564df1
commit 5c1b7935e2
5 changed files with 72 additions and 47 deletions

View File

@@ -88,6 +88,10 @@ pub const CallOpts = struct {
};
pub fn constructor(self: *Caller, comptime T: type, func: anytype, handle: *const v8.FunctionCallbackInfo, comptime opts: CallOpts) void {
var hs: js.HandleScope = undefined;
hs.init(self.local.isolate);
defer hs.deinit();
const info = FunctionCallbackInfo{ .handle = handle };
self._constructor(func, info) catch |err| {
self.handleError(T, @TypeOf(func), err, info, opts);
@@ -127,6 +131,10 @@ fn _constructor(self: *Caller, func: anytype, info: FunctionCallbackInfo) !void
}
pub fn method(self: *Caller, comptime T: type, func: anytype, handle: *const v8.FunctionCallbackInfo, comptime opts: CallOpts) void {
var hs: js.HandleScope = undefined;
hs.init(self.local.isolate);
defer hs.deinit();
const info = FunctionCallbackInfo{ .handle = handle };
self._method(T, func, info, opts) catch |err| {
self.handleError(T, @TypeOf(func), err, info, opts);
@@ -146,6 +154,10 @@ fn _method(self: *Caller, comptime T: type, func: anytype, info: FunctionCallbac
}
pub fn function(self: *Caller, comptime T: type, func: anytype, handle: *const v8.FunctionCallbackInfo, comptime opts: CallOpts) void {
var hs: js.HandleScope = undefined;
hs.init(self.local.isolate);
defer hs.deinit();
const info = FunctionCallbackInfo{ .handle = handle };
self._function(func, info, opts) catch |err| {
self.handleError(T, @TypeOf(func), err, info, opts);
@@ -160,6 +172,10 @@ fn _function(self: *Caller, func: anytype, info: FunctionCallbackInfo, comptime
}
pub fn getIndex(self: *Caller, comptime T: type, func: anytype, idx: u32, handle: *const v8.PropertyCallbackInfo, comptime opts: CallOpts) u8 {
var hs: js.HandleScope = undefined;
hs.init(self.local.isolate);
defer hs.deinit();
const info = PropertyCallbackInfo{ .handle = handle };
return self._getIndex(T, func, idx, info, opts) catch |err| {
self.handleError(T, @TypeOf(func), err, info, opts);
@@ -178,6 +194,10 @@ fn _getIndex(self: *Caller, comptime T: type, func: anytype, idx: u32, info: Pro
}
pub fn getNamedIndex(self: *Caller, comptime T: type, func: anytype, name: *const v8.Name, handle: *const v8.PropertyCallbackInfo, comptime opts: CallOpts) u8 {
var hs: js.HandleScope = undefined;
hs.init(self.local.isolate);
defer hs.deinit();
const info = PropertyCallbackInfo{ .handle = handle };
return self._getNamedIndex(T, func, name, info, opts) catch |err| {
self.handleError(T, @TypeOf(func), err, info, opts);
@@ -196,6 +216,10 @@ fn _getNamedIndex(self: *Caller, comptime T: type, func: anytype, name: *const v
}
pub fn setNamedIndex(self: *Caller, comptime T: type, func: anytype, name: *const v8.Name, js_value: *const v8.Value, handle: *const v8.PropertyCallbackInfo, comptime opts: CallOpts) u8 {
var hs: js.HandleScope = undefined;
hs.init(self.local.isolate);
defer hs.deinit();
const info = PropertyCallbackInfo{ .handle = handle };
return self._setNamedIndex(T, func, name, .{ .local = &self.local, .handle = js_value }, info, opts) catch |err| {
self.handleError(T, @TypeOf(func), err, info, opts);
@@ -218,6 +242,10 @@ fn _setNamedIndex(self: *Caller, comptime T: type, func: anytype, name: *const v
}
pub fn deleteNamedIndex(self: *Caller, comptime T: type, func: anytype, name: *const v8.Name, handle: *const v8.PropertyCallbackInfo, comptime opts: CallOpts) u8 {
var hs: js.HandleScope = undefined;
hs.init(self.local.isolate);
defer hs.deinit();
const info = PropertyCallbackInfo{ .handle = handle };
return self._deleteNamedIndex(T, func, name, info, opts) catch |err| {
self.handleError(T, @TypeOf(func), err, info, opts);

View File

@@ -45,10 +45,9 @@ isolate: js.Isolate,
// from this, and we can free it when the context is done.
handle: v8.Global,
// The Context Global (our Window) as a v8::Global.
global_global: v8.Global,
// True if the context is auto-entered,
entered: bool,
handle_scope: ?js.HandleScope,
cpu_profiler: ?*v8.CpuProfiler = null,
// references Env.templates
@@ -67,7 +66,8 @@ call_arena: Allocator,
call_depth: usize = 0,
// When a Caller is active (V8->Zig callback), this points to its Local.
// When null, Zig->V8 calls must create a temporary Local with HandleScope.
// When null, Zig->V8 calls must create a js.Local.Scope and initialize via
// context.localScope
local: ?*const js.Local = null,
// Serves two purposes. Like `global_objects`, this is used to free
@@ -168,20 +168,20 @@ pub fn deinit(self: *Context) void {
v8.v8__Global__Reset(global);
}
if (self.handle_scope) |_| {
if (self.entered) {
var ls: js.Local.Scope = undefined;
self.localScope(&ls);
defer ls.deinit();
v8.v8__Context__Exit(ls.local.handle);
}
// v8.v8__Global__Reset(&self.global_global);
// v8.v8__Global__Reset(&self.handle);
v8.v8__Global__Reset(&self.handle);
}
// Any operation on the context have to be made from a local.
pub fn localScope(self: *Context, ls: *js.Local.Scope) void {
const isolate = self.isolate;
js.HandleScope.init(&ls.handle_scope, isolate);
// TODO: add and init ls.hs for the handlescope
ls.local = .{
.ctx = self,

View File

@@ -76,49 +76,41 @@ pub fn createContext(self: *ExecutionWorld, page: *Page, enter: bool) !*Context
const isolate = env.isolate;
const arena = self.context_arena.allocator();
// our window wrapped in a v8::Global
var global_global: v8.Global = undefined;
var hs: js.HandleScope = undefined;
hs.init(isolate);
defer hs.deinit();
// Getting this into the snapshot is tricky (anything involving the
// global is tricky). Easier to do here
const global_template = @import("Snapshot.zig").createGlobalTemplate(isolate.handle, env.templates);
v8.v8__ObjectTemplate__SetNamedHandler(global_template, &.{
.getter = bridge.unknownPropertyCallback,
.setter = null,
.query = null,
.deleter = null,
.enumerator = null,
.definer = null,
.descriptor = null,
.data = null,
.flags = v8.kOnlyInterceptStrings | v8.kNonMasking,
});
const v8_context = v8.v8__Context__New(isolate.handle, global_template, null).?;
// Create the v8::Context and wrap it in a v8::Global
var context_global: v8.Global = undefined;
const v8_context = blk: {
var temp_scope: js.HandleScope = undefined;
temp_scope.init(isolate);
defer temp_scope.deinit();
v8.v8__Global__New(isolate.handle, v8_context, &context_global);
// Getting this into the snapshot is tricky (anything involving the
// global is tricky). Easier to do here
const global_template = @import("Snapshot.zig").createGlobalTemplate(isolate.handle, env.templates);
v8.v8__ObjectTemplate__SetNamedHandler(global_template, &.{
.getter = bridge.unknownPropertyCallback,
.setter = null,
.query = null,
.deleter = null,
.enumerator = null,
.definer = null,
.descriptor = null,
.data = null,
.flags = v8.kOnlyInterceptStrings | v8.kNonMasking,
});
// our window wrapped in a v8::Global
const global_obj = v8.v8__Context__Global(v8_context).?;
var global_global: v8.Global = undefined;
v8.v8__Global__New(isolate.handle, global_obj, &global_global);
const local_context = v8.v8__Context__New(isolate.handle, global_template, null).?;
v8.v8__Global__New(isolate.handle, local_context, &context_global);
const global_obj = v8.v8__Context__Global(local_context).?;
v8.v8__Global__New(isolate.handle, global_obj, &global_global);
break :blk local_context;
};
var handle_scope: ?js.HandleScope = null;
if (enter) {
handle_scope = @as(js.HandleScope, undefined);
handle_scope.?.init(isolate);
v8.v8__Context__Enter(v8_context);
}
errdefer if (enter) {
v8.v8__Context__Exit(v8_context);
handle_scope.?.deinit();
};
const context_id = env.context_id;
@@ -127,11 +119,10 @@ pub fn createContext(self: *ExecutionWorld, page: *Page, enter: bool) !*Context
self.context = Context{
.page = page,
.id = context_id,
.entered = enter,
.isolate = isolate,
.handle = context_global,
.global_global = global_global,
.templates = env.templates,
.handle_scope = handle_scope,
.script_manager = &page._script_manager,
.call_arena = page.call_arena,
.arena = arena,

View File

@@ -1287,7 +1287,7 @@ pub fn debugContextId(self: *const Local) i32 {
return v8.v8__Context__DebugContextId(self.handle);
}
// Encapsulates a Local and a HandleScope (TODO). When we're going from V8->Zig
// Encapsulates a Local and a HandleScope. When we're going from V8->Zig
// we easily get both a Local and a HandleScope via Caller.init.
// But when we're going from Zig -> V8, things are more complicated.
@@ -1314,9 +1314,10 @@ pub fn debugContextId(self: *const Local) i32 {
// page.js.local.?
pub const Scope = struct {
local: Local,
handle_scope: js.HandleScope,
pub fn deinit(self: *const Scope) void {
_ = self;
pub fn deinit(self: *Scope) void {
self.handle_scope.deinit();
}
pub fn toLocal(self: *Scope, global: anytype) ToLocalReturnType(@TypeOf(global)) {

View File

@@ -372,7 +372,12 @@ pub fn unknownPropertyCallback(c_name: ?*const v8.Name, handle: ?*const v8.Prope
caller.init(v8_isolate);
defer caller.deinit();
const local = caller.local;
const local = &caller.local;
var hs: js.HandleScope = undefined;
hs.init(local.isolate);
defer hs.deinit();
const property: []const u8 = local.valueHandleToString(@ptrCast(c_name.?), .{}) catch {
return 0;
};