Skip to content

Commit

Permalink
Merge pull request #219 from lightpanda-io/callback-this
Browse files Browse the repository at this point in the history
callback: add a this argument
  • Loading branch information
krichprollsch authored May 2, 2024
2 parents 9c46a62 + 7d80552 commit e8b74e1
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 13 deletions.
39 changes: 26 additions & 13 deletions src/engines/v8/callback.zig
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const NativeContext = internal.NativeContext;
const JSObjectID = @import("v8.zig").JSObjectID;
const setNativeType = @import("generate.zig").setNativeType;
const CallbackInfo = @import("generate.zig").CallbackInfo;
const getV8Object = @import("generate.zig").getV8Object;

// TODO: Make this JS engine agnostic
// by providing a common interface
Expand All @@ -21,17 +22,11 @@ pub const Arg = struct {
// foo: bool = false,
};

// TODO: set the correct "this" on Func object
// see https://developer.mozilla.org/en-US/docs/Web/API/setTimeout#the_this_problem
// should we use:
// - the context globals?
// - null?
// - the calling function (info.getThis)?

pub const FuncSync = struct {
js_func: v8.Function,
js_args: []v8.Value,
isolate: v8.Isolate,
thisArg: ?v8.Object = null,

pub fn init(
alloc: std.mem.Allocator,
Expand Down Expand Up @@ -86,15 +81,23 @@ pub const FuncSync = struct {
};
}

pub fn setThisArg(self: *Func, nat_obj_ptr: anytype) !void {
self.thisArg = try getV8Object(
self.nat_ctx,
nat_obj_ptr,
) orelse return error.V8ObjectNotFound;
}

pub fn call(self: FuncSync, alloc: std.mem.Allocator) anyerror!void {

// retrieve context
// NOTE: match the Func.call implementation
const ctx = self.isolate.getCurrentContext();

// retrieve JS this from persistent handle
// TODO: see correct "this" comment above
const this = ctx.getGlobal();
// Callbacks are typically called with a this value of undefined.
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this#callbacks
// TODO use undefined this instead of global.
const this = self.thisArg orelse ctx.getGlobal();

// execute function
_ = self.js_func.call(ctx, this, self.js_args);
Expand Down Expand Up @@ -123,6 +126,8 @@ pub const Func = struct {
nat_ctx: *NativeContext,
isolate: v8.Isolate,

thisArg: ?v8.Object = null,

pub fn init(
alloc: std.mem.Allocator,
nat_ctx: *NativeContext,
Expand Down Expand Up @@ -183,6 +188,13 @@ pub const Func = struct {
};
}

pub fn setThisArg(self: *Func, nat_obj_ptr: anytype) !void {
self.thisArg = try getV8Object(
self.nat_ctx,
nat_obj_ptr,
) orelse return error.V8ObjectNotFound;
}

pub fn deinit(self: Func, alloc: std.mem.Allocator) void {

// cleanup persistent references in v8
Expand Down Expand Up @@ -256,9 +268,10 @@ pub const Func = struct {
}
// else -> no arguments

// retrieve JS "this" from persistent handle
// TODO: see correct "this" comment above
const this = js_ctx.getGlobal();
// Callbacks are typically called with a this value of undefined.
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this#callbacks
// TODO use undefined this instead of global.
const this = self.thisArg orelse js_ctx.getGlobal();

// execute function
const result = js_func.call(js_ctx, this, args);
Expand Down
12 changes: 12 additions & 0 deletions src/engines/v8/generate.zig
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,18 @@ inline fn initJSObject(
return tpl.getInstanceTemplate().initInstance(js_ctx);
}

// getV8Object returns the existing v8.Object corresponding to the given native
// pointer from the native context.
pub fn getV8Object(nat_ctx: *NativeContext, nat_obj_ptr: anytype) !?v8.Object {
// ensure Native object is a pointer
if (comptime !refl.isPointer(@TypeOf(nat_obj_ptr))) return error.NotAPointer;

const nat_obj_ref = @intFromPtr(nat_obj_ptr);
const js_obj_ref = nat_ctx.js_objs.get(nat_obj_ref) orelse return null;
const js_obj_handle = @as(*v8.C_Object, @ptrFromInt(js_obj_ref));
return v8.Object{ .handle = js_obj_handle };
}

pub fn setNativeObject(
alloc: std.mem.Allocator,
nat_ctx: *NativeContext,
Expand Down

0 comments on commit e8b74e1

Please sign in to comment.