mirror of
https://github.com/lightpanda-io/browser.git
synced 2025-10-30 07:31:47 +00:00
share sessionstate and underlying DOM global with the isolated
This commit is contained in:
@@ -328,7 +328,7 @@ pub fn Env(comptime S: type, comptime types: anytype) type {
|
||||
// when the handle_scope is freed.
|
||||
// We also maintain our own "scope_arena" which allows us to have
|
||||
// all page related memory easily managed.
|
||||
pub fn startScope(self: *Executor, global: anytype, state: State, module_loader: anytype) !*Scope {
|
||||
pub fn startScope(self: *Executor, global: anytype, state: State, module_loader: anytype, enter: bool) !*Scope {
|
||||
std.debug.assert(self.scope == null);
|
||||
|
||||
const ModuleLoader = switch (@typeInfo(@TypeOf(module_loader))) {
|
||||
@@ -345,62 +345,74 @@ pub fn Env(comptime S: type, comptime types: anytype) type {
|
||||
const isolate = env.isolate;
|
||||
const Global = @TypeOf(global.*);
|
||||
|
||||
var handle_scope: v8.HandleScope = undefined;
|
||||
v8.HandleScope.init(&handle_scope, isolate);
|
||||
errdefer handle_scope.deinit();
|
||||
var context: v8.Context = undefined;
|
||||
{
|
||||
var handle_scope: v8.HandleScope = undefined;
|
||||
v8.HandleScope.init(&handle_scope, isolate);
|
||||
defer handle_scope.deinit();
|
||||
|
||||
const js_global = v8.FunctionTemplate.initDefault(isolate);
|
||||
attachClass(Global, isolate, js_global);
|
||||
const js_global = v8.FunctionTemplate.initDefault(isolate);
|
||||
attachClass(Global, isolate, js_global);
|
||||
|
||||
const global_template = js_global.getInstanceTemplate();
|
||||
global_template.setInternalFieldCount(1);
|
||||
const global_template = js_global.getInstanceTemplate();
|
||||
global_template.setInternalFieldCount(1);
|
||||
|
||||
// All the FunctionTemplates that we created and setup in Env.init
|
||||
// are now going to get associated with our global instance.
|
||||
const templates = &self.env.templates;
|
||||
inline for (Types, 0..) |s, i| {
|
||||
const Struct = @field(types, s.name);
|
||||
const class_name = v8.String.initUtf8(isolate, comptime classNameForStruct(Struct));
|
||||
global_template.set(class_name.toName(), templates[i], v8.PropertyAttribute.None);
|
||||
}
|
||||
// All the FunctionTemplates that we created and setup in Env.init
|
||||
// are now going to get associated with our global instance.
|
||||
const templates = &self.env.templates;
|
||||
inline for (Types, 0..) |s, i| {
|
||||
const Struct = @field(types, s.name);
|
||||
const class_name = v8.String.initUtf8(isolate, comptime classNameForStruct(Struct));
|
||||
global_template.set(class_name.toName(), templates[i], v8.PropertyAttribute.None);
|
||||
}
|
||||
|
||||
// The global object (Window) has already been hooked into the v8
|
||||
// engine when the Env was initialized - like every other type.
|
||||
// But the V8 global is its own FunctionTemplate instance so even
|
||||
// though it's also a Window, we need to set the prototype for this
|
||||
// specific instance of the the Window.
|
||||
if (@hasDecl(Global, "prototype")) {
|
||||
const proto_type = Receiver(@typeInfo(Global.prototype).pointer.child);
|
||||
const proto_name = @typeName(proto_type);
|
||||
const proto_index = @field(TYPE_LOOKUP, proto_name).index;
|
||||
js_global.inherit(templates[proto_index]);
|
||||
}
|
||||
|
||||
const context = v8.Context.init(isolate, global_template, null);
|
||||
context.enter();
|
||||
errdefer context.exit();
|
||||
|
||||
// This shouldn't be necessary, but it is:
|
||||
// https://groups.google.com/g/v8-users/c/qAQQBmbi--8
|
||||
// TODO: see if newer V8 engines have a way around this.
|
||||
inline for (Types, 0..) |s, i| {
|
||||
const Struct = @field(types, s.name);
|
||||
|
||||
if (@hasDecl(Struct, "prototype")) {
|
||||
const proto_type = Receiver(@typeInfo(Struct.prototype).pointer.child);
|
||||
// The global object (Window) has already been hooked into the v8
|
||||
// engine when the Env was initialized - like every other type.
|
||||
// But the V8 global is its own FunctionTemplate instance so even
|
||||
// though it's also a Window, we need to set the prototype for this
|
||||
// specific instance of the the Window.
|
||||
if (@hasDecl(Global, "prototype")) {
|
||||
const proto_type = Receiver(@typeInfo(Global.prototype).pointer.child);
|
||||
const proto_name = @typeName(proto_type);
|
||||
if (@hasField(TypeLookup, proto_name) == false) {
|
||||
@compileError("Type '" ++ @typeName(Struct) ++ "' defines an unknown prototype: " ++ proto_name);
|
||||
}
|
||||
|
||||
const proto_index = @field(TYPE_LOOKUP, proto_name).index;
|
||||
const proto_obj = templates[proto_index].getFunction(context).toObject();
|
||||
js_global.inherit(templates[proto_index]);
|
||||
}
|
||||
|
||||
const self_obj = templates[i].getFunction(context).toObject();
|
||||
_ = self_obj.setPrototype(context, proto_obj);
|
||||
const context_local = v8.Context.init(isolate, global_template, null);
|
||||
context = v8.Persistent(v8.Context).init(isolate, context_local).castToContext();
|
||||
context.enter();
|
||||
errdefer if (enter) context.exit();
|
||||
defer if (!enter) context.exit();
|
||||
|
||||
// This shouldn't be necessary, but it is:
|
||||
// https://groups.google.com/g/v8-users/c/qAQQBmbi--8
|
||||
// TODO: see if newer V8 engines have a way around this.
|
||||
inline for (Types, 0..) |s, i| {
|
||||
const Struct = @field(types, s.name);
|
||||
|
||||
if (@hasDecl(Struct, "prototype")) {
|
||||
const proto_type = Receiver(@typeInfo(Struct.prototype).pointer.child);
|
||||
const proto_name = @typeName(proto_type);
|
||||
if (@hasField(TypeLookup, proto_name) == false) {
|
||||
@compileError("Type '" ++ @typeName(Struct) ++ "' defines an unknown prototype: " ++ proto_name);
|
||||
}
|
||||
|
||||
const proto_index = @field(TYPE_LOOKUP, proto_name).index;
|
||||
const proto_obj = templates[proto_index].getFunction(context).toObject();
|
||||
|
||||
const self_obj = templates[i].getFunction(context).toObject();
|
||||
_ = self_obj.setPrototype(context, proto_obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var handle_scope: ?v8.HandleScope = null;
|
||||
if (enter) {
|
||||
handle_scope = @as(v8.HandleScope, undefined);
|
||||
v8.HandleScope.init(&handle_scope.?, isolate);
|
||||
}
|
||||
errdefer if (enter) handle_scope.?.deinit();
|
||||
|
||||
self.scope = Scope{
|
||||
.state = state,
|
||||
.isolate = isolate,
|
||||
@@ -453,8 +465,9 @@ pub fn Env(comptime S: type, comptime types: anytype) type {
|
||||
pub const Scope = struct {
|
||||
state: State,
|
||||
isolate: v8.Isolate,
|
||||
// This context is a persistent object. The persistent needs to be recovered and reset.
|
||||
context: v8.Context,
|
||||
handle_scope: v8.HandleScope,
|
||||
handle_scope: ?v8.HandleScope,
|
||||
|
||||
// references the Env.template array
|
||||
templates: []v8.FunctionTemplate,
|
||||
@@ -506,8 +519,12 @@ pub fn Env(comptime S: type, comptime types: anytype) type {
|
||||
for (self.callbacks.items) |*cb| {
|
||||
cb.deinit();
|
||||
}
|
||||
self.context.exit();
|
||||
self.handle_scope.deinit();
|
||||
if (self.handle_scope) |*scope| {
|
||||
scope.deinit();
|
||||
self.context.exit();
|
||||
}
|
||||
var presistent_context = v8.Persistent(v8.Context).recoverCast(self.context);
|
||||
presistent_context.deinit();
|
||||
}
|
||||
|
||||
fn trackCallback(self: *Scope, pf: PersistentFunction) !void {
|
||||
|
||||
@@ -49,6 +49,7 @@ pub fn Runner(comptime State: type, comptime Global: type, comptime types: anyty
|
||||
if (Global == void) &default_global else global,
|
||||
state,
|
||||
{},
|
||||
true,
|
||||
);
|
||||
return self;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user