Skip to content
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
1 change: 1 addition & 0 deletions src/api.zig
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ pub const API = Engine.API;
pub const TPL = Engine.TPL;

pub const JSResult = Engine.JSResult;
pub const JSObject = Engine.JSObject;
pub const Callback = Engine.Callback;
pub const CallbackSync = Engine.CallbackSync;
pub const CallbackArg = Engine.CallbackArg;
Expand Down
96 changes: 89 additions & 7 deletions src/engines/v8/generate.zig
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const utils = internal.utils;

const public = @import("../../api.zig");
const Loop = public.Loop;
const JSObject = public.JSObject;

const cbk = @import("callback.zig");
const nativeToJS = @import("types_primitives.zig").nativeToJS;
Expand Down Expand Up @@ -167,7 +168,6 @@ fn getArg(
isolate: v8.Isolate,
ctx: v8.Context,
) arg.T {
_ = this;
var value: arg.T = undefined;

if (arg.isNative()) {
Expand All @@ -192,6 +192,7 @@ fn getArg(
std.mem.Allocator => alloc,
*Loop => utils.loop,
cbk.Func, cbk.FuncSync, cbk.Arg => unreachable,
JSObject => JSObject{ .ctx = ctx, .js_obj = this },
else => jsToNative(
alloc,
arg.T,
Expand Down Expand Up @@ -395,7 +396,7 @@ pub fn setNativeObject(
obj: anytype,
js_obj: v8.Object,
isolate: v8.Isolate,
) !void {
) !*T {

// assign and bind native obj to JS obj
var obj_ptr: *T = undefined;
Expand All @@ -420,7 +421,7 @@ pub fn setNativeObject(
// if the object is an empty struct (ie. a kind of container)
// no need to keep it's reference
if (T_refl.isEmpty()) {
return;
return obj_ptr;
}

// bind the native object pointer to JS obj
Expand All @@ -436,13 +437,16 @@ pub fn setNativeObject(
try refs.addObject(alloc, int_ptr.*, T_refl.index);
}
js_obj.setInternalField(0, ext);
return obj_ptr;
}

fn setReturnType(
alloc: std.mem.Allocator,
comptime all_T: []refl.Struct,
comptime ret: refl.Type,
comptime func: refl.Func,
res: anytype,
js_res: v8.ReturnValue,
ctx: v8.Context,
isolate: v8.Isolate,
) !v8.Value {
Expand All @@ -454,7 +458,7 @@ fn setReturnType(
// if null just return JS null
return isolate.initNull().toValue();
}
return setReturnType(alloc, all_T, ret, res.?, ctx, isolate);
return setReturnType(alloc, all_T, ret, func, res.?, js_res, ctx, isolate);
}

// Union type
Expand All @@ -468,7 +472,9 @@ fn setReturnType(
alloc,
all_T,
tt,
func,
@field(res, tt.name.?),
js_res,
ctx,
isolate,
);
Expand All @@ -490,7 +496,9 @@ fn setReturnType(
alloc,
all_T,
field,
func,
@field(res, name),
js_res,
ctx,
isolate,
);
Expand All @@ -509,14 +517,32 @@ fn setReturnType(
// instantiate a JS object from template
// and bind it to the native object
const js_obj = gen.getTpl(index).tpl.getInstanceTemplate().initInstance(ctx);
_ = try setNativeObject(
const obj_ptr = setNativeObject(
alloc,
all_T[index],
ret.underT(),
res,
js_obj,
isolate,
);
) catch unreachable;

// call postAttach func
const T_refl = all_T[index];
if (comptime try refl.postAttachFunc(T_refl.T)) |piArgsT| {
postAttach(
utils.allocator,
T_refl,
all_T,
func,
piArgsT,
obj_ptr,
js_obj,
js_res,
ctx,
isolate,
);
}

return js_obj.toValue();
}

Expand All @@ -530,6 +556,44 @@ fn setReturnType(
return js_val;
}

fn postAttach(
alloc: std.mem.Allocator,
comptime T_refl: refl.Struct,
comptime all_T: []refl.Struct,
comptime func: refl.Func,
comptime argsT: type,
obj_ptr: anytype,
js_obj: v8.Object,
js_res: v8.ReturnValue,
ctx: v8.Context,
isolate: v8.Isolate,
) void {
var args: argsT = undefined;
@field(args, "0") = obj_ptr;
@field(args, "1") = JSObject{ .ctx = ctx, .js_obj = js_obj };
const f = @field(T_refl.T, "postAttach");
const ret = comptime try refl.funcReturnType(@TypeOf(f));
if (comptime refl.isErrorUnion(ret)) {
_ = @call(.auto, f, args) catch |err| {
return throwError(
alloc,
T_refl,
all_T,
func,
err,
js_res,
isolate,
);
};
} else {
_ = @call(
.auto,
f,
args,
);
}
}

fn getNativeObject(
comptime T_refl: refl.Struct,
comptime all_T: []refl.Struct,
Expand Down Expand Up @@ -639,22 +703,40 @@ fn callFunc(
if (comptime func_kind == .constructor) {

// bind native object to JS object this
setNativeObject(
_ = setNativeObject(
utils.allocator,
T_refl,
func.return_type.underT(),
res,
cbk_info.getThis(),
isolate,
) catch unreachable; // TODO: internal errors

// call postAttach func
if (comptime try refl.postAttachFunc(T_refl.T)) |piArgsT| {
postAttach(
utils.allocator,
T_refl,
all_T,
func,
piArgsT,
&res,
cbk_info.getThis(),
cbk_info.getReturnValue(),
ctx,
isolate,
);
}
} else {

// return to javascript the result
const js_val = setReturnType(
utils.allocator,
all_T,
func.return_type,
func,
res,
cbk_info.getReturnValue(),
ctx,
isolate,
) catch unreachable; // TODO: internal errors
Expand Down
15 changes: 15 additions & 0 deletions src/engines/v8/v8.zig
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ pub const CallbackArg = @import("callback.zig").Arg;
pub const LoadFnType = @import("generate.zig").LoadFnType;
pub const loadFn = @import("generate.zig").loadFn;
const setNativeObject = @import("generate.zig").setNativeObject;
const nativeToJS = @import("types_primitives.zig").nativeToJS;
const valueToUtf8 = @import("types_primitives.zig").valueToUtf8;

pub const API = struct {
Expand Down Expand Up @@ -387,6 +388,20 @@ fn createJSObject(
);
}

pub const JSObject = struct {
ctx: v8.Context,
js_obj: v8.Object,

pub fn set(self: JSObject, key: []const u8, value: anytype) !void {
const isolate = self.ctx.getIsolate();
const js_value = try nativeToJS(@TypeOf(value), value, isolate);
const js_key = v8.String.initUtf8(isolate, key);
if (!self.js_obj.setValue(self.ctx, js_key, js_value)) {
return error.SetV8Object;
}
}
};

pub const TryCatch = struct {
try_catch: *v8.TryCatch,

Expand Down
Loading