@@ -10,6 +10,7 @@ const NativeContext = internal.NativeContext;
10
10
const JSObjectID = @import ("v8.zig" ).JSObjectID ;
11
11
const setNativeType = @import ("generate.zig" ).setNativeType ;
12
12
const CallbackInfo = @import ("generate.zig" ).CallbackInfo ;
13
+ const getV8Object = @import ("generate.zig" ).getV8Object ;
13
14
14
15
// TODO: Make this JS engine agnostic
15
16
// by providing a common interface
@@ -21,17 +22,11 @@ pub const Arg = struct {
21
22
// foo: bool = false,
22
23
};
23
24
24
- // TODO: set the correct "this" on Func object
25
- // see https://developer.mozilla.org/en-US/docs/Web/API/setTimeout#the_this_problem
26
- // should we use:
27
- // - the context globals?
28
- // - null?
29
- // - the calling function (info.getThis)?
30
-
31
25
pub const FuncSync = struct {
32
26
js_func : v8.Function ,
33
27
js_args : []v8.Value ,
34
28
isolate : v8.Isolate ,
29
+ thisArg : ? v8.Object = null ,
35
30
36
31
pub fn init (
37
32
alloc : std.mem.Allocator ,
@@ -86,15 +81,23 @@ pub const FuncSync = struct {
86
81
};
87
82
}
88
83
84
+ pub fn setThisArg (self : * Func , nat_obj_ptr : anytype ) ! void {
85
+ self .thisArg = try getV8Object (
86
+ self .nat_ctx ,
87
+ nat_obj_ptr ,
88
+ ) orelse return error .V8ObjectNotFound ;
89
+ }
90
+
89
91
pub fn call (self : FuncSync , alloc : std.mem.Allocator ) anyerror ! void {
90
92
91
93
// retrieve context
92
94
// NOTE: match the Func.call implementation
93
95
const ctx = self .isolate .getCurrentContext ();
94
96
95
- // retrieve JS this from persistent handle
96
- // TODO: see correct "this" comment above
97
- const this = ctx .getGlobal ();
97
+ // Callbacks are typically called with a this value of undefined.
98
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this#callbacks
99
+ // TODO use undefined this instead of global.
100
+ const this = self .thisArg orelse ctx .getGlobal ();
98
101
99
102
// execute function
100
103
_ = self .js_func .call (ctx , this , self .js_args );
@@ -123,6 +126,8 @@ pub const Func = struct {
123
126
nat_ctx : * NativeContext ,
124
127
isolate : v8.Isolate ,
125
128
129
+ thisArg : ? v8.Object = null ,
130
+
126
131
pub fn init (
127
132
alloc : std.mem.Allocator ,
128
133
nat_ctx : * NativeContext ,
@@ -183,6 +188,13 @@ pub const Func = struct {
183
188
};
184
189
}
185
190
191
+ pub fn setThisArg (self : * Func , nat_obj_ptr : anytype ) ! void {
192
+ self .thisArg = try getV8Object (
193
+ self .nat_ctx ,
194
+ nat_obj_ptr ,
195
+ ) orelse return error .V8ObjectNotFound ;
196
+ }
197
+
186
198
pub fn deinit (self : Func , alloc : std.mem.Allocator ) void {
187
199
188
200
// cleanup persistent references in v8
@@ -256,9 +268,10 @@ pub const Func = struct {
256
268
}
257
269
// else -> no arguments
258
270
259
- // retrieve JS "this" from persistent handle
260
- // TODO: see correct "this" comment above
261
- const this = js_ctx .getGlobal ();
271
+ // Callbacks are typically called with a this value of undefined.
272
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this#callbacks
273
+ // TODO use undefined this instead of global.
274
+ const this = self .thisArg orelse js_ctx .getGlobal ();
262
275
263
276
// execute function
264
277
const result = js_func .call (js_ctx , this , args );
0 commit comments