Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add refs to NativeContext and remove it from globals #213

Merged
merged 3 commits into from
Mar 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 12 additions & 8 deletions src/engines/v8/generate.zig
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ fn checkArgsLen(
}

fn getNativeArg(
nat_ctx: *NativeContext,
comptime T_refl: refl.Struct,
comptime arg_T: refl.Type,
js_value: v8.Value,
Expand All @@ -151,7 +152,7 @@ fn getNativeArg(
if (!js_value.isObject()) return JSError.InvalidArgument;

// JS object
const ptr = try getNativeObject(T_refl, js_value.castTo(v8.Object));
const ptr = try getNativeObject(nat_ctx, T_refl, js_value.castTo(v8.Object));
if (arg_T.underPtr() != null) {
value = ptr;
} else {
Expand All @@ -175,7 +176,7 @@ fn getArg(
if (arg.isNative()) {

// native types
value = try getNativeArg(gen.Types[arg.T_refl_index.?], arg, js_val.?);
value = try getNativeArg(nat_ctx, gen.Types[arg.T_refl_index.?], arg, js_val.?);
} else if (arg.nested_index) |index| {

// nested types (ie. JS anonymous objects)
Expand Down Expand Up @@ -401,6 +402,7 @@ const PersistentObject = v8.Persistent(v8.Object);

fn bindObjectNativeToJS(
alloc: std.mem.Allocator,
nat_ctx: *NativeContext,
comptime T_refl: refl.Struct,
nat_obj: anytype,
js_obj: v8.Object,
Expand All @@ -427,15 +429,15 @@ fn bindObjectNativeToJS(
const int_ptr = try alloc.create(usize);
int_ptr.* = @intFromPtr(nat_obj);
ext = v8.External.init(isolate, int_ptr);
try refs.addObject(alloc, int_ptr.*, T_refl.index);
try nat_ctx.nat_objs.put(alloc, int_ptr.*, T_refl.index);
}
js_obj_pers.setInternalField(0, ext);
return js_obj_pers;
}

fn bindObjectJSToNative(
alloc: std.mem.Allocator,
objects: *NativeContext.Objects,
objects: *NativeContext.JSObjects,
nat_obj: anytype,
js_obj: v8.Object,
) !void {
Expand Down Expand Up @@ -463,14 +465,15 @@ fn bindObjectNativeAndJS(
// bind the Native object to the JS object
const js_obj_binded = try bindObjectNativeToJS(
alloc,
nat_ctx,
T_refl,
nat_obj,
js_obj,
isolate,
);

// bind the JS object to the Native object
try bindObjectJSToNative(alloc, nat_ctx.objects, nat_obj, js_obj_binded);
try bindObjectJSToNative(alloc, &nat_ctx.js_objs, nat_obj, js_obj_binded);

// call postAttach func
if (comptime try refl.postAttachFunc(T_refl.T)) |piArgsT| {
Expand Down Expand Up @@ -547,7 +550,7 @@ pub fn setNativeObject(

// JS object is not provided, check the objects map
const nat_obj_ref = @intFromPtr(nat_obj_ptr);
if (nat_ctx.objects.get(nat_obj_ref)) |js_obj_ref| {
if (nat_ctx.js_objs.get(nat_obj_ref)) |js_obj_ref| {

// a JS object is already linked to the current Native object
// return it
Expand Down Expand Up @@ -772,6 +775,7 @@ fn postAttach(
}

fn getNativeObject(
nat_ctx: *NativeContext,
comptime T_refl: refl.Struct,
js_obj: v8.Object,
) !*T_refl.Self() {
Expand Down Expand Up @@ -807,7 +811,7 @@ fn getNativeObject(
}
} else {
// use the refs mechanism to retrieve from high level Type
obj_ptr = try refs.getObject(T, gen.Types, ext);
obj_ptr = try refs.getObject(nat_ctx.nat_objs, T, gen.Types, ext);
}
}
return obj_ptr;
Expand Down Expand Up @@ -870,7 +874,7 @@ fn callFunc(

// retrieve the zig object
if (comptime func_kind != .constructor and !T_refl.isEmpty()) {
const obj_ptr = getNativeObject(T_refl, cbk_info.getThis()) catch unreachable;
const obj_ptr = getNativeObject(nat_ctx, T_refl, cbk_info.getThis()) catch unreachable;
const self_T = @TypeOf(@field(args, "0"));
if (self_T == T_refl.Self()) {
@field(args, "0") = obj_ptr.*;
Expand Down
35 changes: 6 additions & 29 deletions src/engines/v8/v8.zig
Original file line number Diff line number Diff line change
Expand Up @@ -78,24 +78,6 @@ pub const Env = struct {

pub fn init(alloc: std.mem.Allocator, loop: *public.Loop) anyerror!Env {

// globals values
// --------------

// refs
refs.map = refs.Map{};

// native context
// --------------

const objects_ptr = try alloc.create(NativeContext.Objects);
objects_ptr.* = NativeContext.Objects{};
const nat_ctx = try alloc.create(NativeContext);
nat_ctx.* = .{
.alloc = alloc,
.loop = loop,
.objects = objects_ptr,
};

// v8 values
// ---------

Expand All @@ -115,7 +97,7 @@ pub const Env = struct {
const globals = v8.ObjectTemplate.initDefault(isolate);

return Env{
.nat_ctx = nat_ctx,
.nat_ctx = try NativeContext.init(alloc, loop),
.isolate_params = params,
.isolate = isolate,
.hscope = hscope,
Expand All @@ -142,15 +124,7 @@ pub const Env = struct {

// native context
// --------------
self.nat_ctx.objects.deinit(self.nat_ctx.alloc);
self.nat_ctx.alloc.destroy(self.nat_ctx.objects);
self.nat_ctx.alloc.destroy(self.nat_ctx);

// globals values
// --------------

// unset globals
refs.map = undefined;
self.nat_ctx.deinit();

self.* = undefined;
}
Expand Down Expand Up @@ -215,9 +189,12 @@ pub const Env = struct {
return; // no-op
}

// context
// JS context
self.js_ctx.?.exit();
self.js_ctx = undefined;

// Native context
self.nat_ctx.stop();
}
pub fn getGlobal(self: Env) anyerror!Object {
if (self.js_ctx == null) {
Expand Down
30 changes: 28 additions & 2 deletions src/native_context.zig
Original file line number Diff line number Diff line change
@@ -1,18 +1,37 @@
const std = @import("std");

const Loop = @import("api.zig").Loop;
const NatObjects = @import("internal_api.zig").refs.Map;

pub const NativeContext = struct {
alloc: std.mem.Allocator,
loop: *Loop,
objects: *Objects,

js_objs: JSObjects,
nat_objs: NatObjects,

// NOTE: DO NOT ACCESS DIRECTLY js_types
// - use once loadTypes at startup to set them
// - and then getType during execution to access them
js_types: ?[]usize = null,

pub const Objects = std.AutoHashMapUnmanaged(usize, usize);
pub const JSObjects = std.AutoHashMapUnmanaged(usize, usize);

pub fn init(alloc: std.mem.Allocator, loop: *Loop) !*NativeContext {
const self = try alloc.create(NativeContext);
self.* = .{
.alloc = alloc,
.loop = loop,
.js_objs = JSObjects{},
.nat_objs = NatObjects{},
};
return self;
}

pub fn stop(self: *NativeContext) void {
self.js_objs.clearAndFree(self.alloc);
self.nat_objs.clearAndFree(self.alloc);
}

// loadTypes into the NativeContext
// The caller holds the memory of the js_types slice,
Expand All @@ -27,4 +46,11 @@ pub const NativeContext = struct {
const t = self.js_types.?[index];
return @as(*T, @ptrFromInt(t));
}

pub fn deinit(self: *NativeContext) void {
self.stop();
self.js_objs.deinit(self.alloc);
self.nat_objs.deinit(self.alloc);
self.* = undefined;
}
};
7 changes: 1 addition & 6 deletions src/refs.zig
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,8 @@ const refl = internal.refl;
// it will be store on the JS object as an internal field
// - value is the index of API
pub const Map = std.AutoHashMapUnmanaged(usize, usize);
pub var map: Map = undefined;

pub fn addObject(alloc: std.mem.Allocator, key: usize, value: usize) !void {
try map.put(alloc, key, value);
}

pub fn getObject(comptime T: type, comptime types: []refl.Struct, ptr: anytype) !*T {
pub fn getObject(map: Map, comptime T: type, comptime types: []refl.Struct, ptr: anytype) !*T {

// use the object pointer (key) to retrieve the API index (value) in the map
const ptr_aligned: *align(@alignOf(usize)) anyopaque = @alignCast(ptr);
Expand Down
Loading