Skip to content

Commit 3dd792f

Browse files
Merge pull request #154 from lightpanda-io/array_like
Array like
2 parents d4c1191 + b75e166 commit 3dd792f

File tree

8 files changed

+449
-17
lines changed

8 files changed

+449
-17
lines changed

src/api.zig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ pub const API = Engine.API;
4444
pub const TPL = Engine.TPL;
4545

4646
pub const JSResult = Engine.JSResult;
47+
pub const JSObject = Engine.JSObject;
4748
pub const Callback = Engine.Callback;
4849
pub const CallbackSync = Engine.CallbackSync;
4950
pub const CallbackArg = Engine.CallbackArg;

src/engines/v8/generate.zig

Lines changed: 89 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ const utils = internal.utils;
1010

1111
const public = @import("../../api.zig");
1212
const Loop = public.Loop;
13+
const JSObject = public.JSObject;
1314

1415
const cbk = @import("callback.zig");
1516
const nativeToJS = @import("types_primitives.zig").nativeToJS;
@@ -167,7 +168,6 @@ fn getArg(
167168
isolate: v8.Isolate,
168169
ctx: v8.Context,
169170
) arg.T {
170-
_ = this;
171171
var value: arg.T = undefined;
172172

173173
if (arg.isNative()) {
@@ -192,6 +192,7 @@ fn getArg(
192192
std.mem.Allocator => alloc,
193193
*Loop => utils.loop,
194194
cbk.Func, cbk.FuncSync, cbk.Arg => unreachable,
195+
JSObject => JSObject{ .ctx = ctx, .js_obj = this },
195196
else => jsToNative(
196197
alloc,
197198
arg.T,
@@ -395,7 +396,7 @@ pub fn setNativeObject(
395396
obj: anytype,
396397
js_obj: v8.Object,
397398
isolate: v8.Isolate,
398-
) !void {
399+
) !*T {
399400

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

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

441443
fn setReturnType(
442444
alloc: std.mem.Allocator,
443445
comptime all_T: []refl.Struct,
444446
comptime ret: refl.Type,
447+
comptime func: refl.Func,
445448
res: anytype,
449+
js_res: v8.ReturnValue,
446450
ctx: v8.Context,
447451
isolate: v8.Isolate,
448452
) !v8.Value {
@@ -454,7 +458,7 @@ fn setReturnType(
454458
// if null just return JS null
455459
return isolate.initNull().toValue();
456460
}
457-
return setReturnType(alloc, all_T, ret, res.?, ctx, isolate);
461+
return setReturnType(alloc, all_T, ret, func, res.?, js_res, ctx, isolate);
458462
}
459463

460464
// Union type
@@ -468,7 +472,9 @@ fn setReturnType(
468472
alloc,
469473
all_T,
470474
tt,
475+
func,
471476
@field(res, tt.name.?),
477+
js_res,
472478
ctx,
473479
isolate,
474480
);
@@ -490,7 +496,9 @@ fn setReturnType(
490496
alloc,
491497
all_T,
492498
field,
499+
func,
493500
@field(res, name),
501+
js_res,
494502
ctx,
495503
isolate,
496504
);
@@ -509,14 +517,32 @@ fn setReturnType(
509517
// instantiate a JS object from template
510518
// and bind it to the native object
511519
const js_obj = gen.getTpl(index).tpl.getInstanceTemplate().initInstance(ctx);
512-
_ = try setNativeObject(
520+
const obj_ptr = setNativeObject(
513521
alloc,
514522
all_T[index],
515523
ret.underT(),
516524
res,
517525
js_obj,
518526
isolate,
519-
);
527+
) catch unreachable;
528+
529+
// call postAttach func
530+
const T_refl = all_T[index];
531+
if (comptime try refl.postAttachFunc(T_refl.T)) |piArgsT| {
532+
postAttach(
533+
utils.allocator,
534+
T_refl,
535+
all_T,
536+
func,
537+
piArgsT,
538+
obj_ptr,
539+
js_obj,
540+
js_res,
541+
ctx,
542+
isolate,
543+
);
544+
}
545+
520546
return js_obj.toValue();
521547
}
522548

@@ -530,6 +556,44 @@ fn setReturnType(
530556
return js_val;
531557
}
532558

559+
fn postAttach(
560+
alloc: std.mem.Allocator,
561+
comptime T_refl: refl.Struct,
562+
comptime all_T: []refl.Struct,
563+
comptime func: refl.Func,
564+
comptime argsT: type,
565+
obj_ptr: anytype,
566+
js_obj: v8.Object,
567+
js_res: v8.ReturnValue,
568+
ctx: v8.Context,
569+
isolate: v8.Isolate,
570+
) void {
571+
var args: argsT = undefined;
572+
@field(args, "0") = obj_ptr;
573+
@field(args, "1") = JSObject{ .ctx = ctx, .js_obj = js_obj };
574+
const f = @field(T_refl.T, "postAttach");
575+
const ret = comptime try refl.funcReturnType(@TypeOf(f));
576+
if (comptime refl.isErrorUnion(ret)) {
577+
_ = @call(.auto, f, args) catch |err| {
578+
return throwError(
579+
alloc,
580+
T_refl,
581+
all_T,
582+
func,
583+
err,
584+
js_res,
585+
isolate,
586+
);
587+
};
588+
} else {
589+
_ = @call(
590+
.auto,
591+
f,
592+
args,
593+
);
594+
}
595+
}
596+
533597
fn getNativeObject(
534598
comptime T_refl: refl.Struct,
535599
comptime all_T: []refl.Struct,
@@ -639,22 +703,40 @@ fn callFunc(
639703
if (comptime func_kind == .constructor) {
640704

641705
// bind native object to JS object this
642-
setNativeObject(
706+
_ = setNativeObject(
643707
utils.allocator,
644708
T_refl,
645709
func.return_type.underT(),
646710
res,
647711
cbk_info.getThis(),
648712
isolate,
649713
) catch unreachable; // TODO: internal errors
714+
715+
// call postAttach func
716+
if (comptime try refl.postAttachFunc(T_refl.T)) |piArgsT| {
717+
postAttach(
718+
utils.allocator,
719+
T_refl,
720+
all_T,
721+
func,
722+
piArgsT,
723+
&res,
724+
cbk_info.getThis(),
725+
cbk_info.getReturnValue(),
726+
ctx,
727+
isolate,
728+
);
729+
}
650730
} else {
651731

652732
// return to javascript the result
653733
const js_val = setReturnType(
654734
utils.allocator,
655735
all_T,
656736
func.return_type,
737+
func,
657738
res,
739+
cbk_info.getReturnValue(),
658740
ctx,
659741
isolate,
660742
) catch unreachable; // TODO: internal errors

src/engines/v8/v8.zig

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ pub const CallbackArg = @import("callback.zig").Arg;
1818
pub const LoadFnType = @import("generate.zig").LoadFnType;
1919
pub const loadFn = @import("generate.zig").loadFn;
2020
const setNativeObject = @import("generate.zig").setNativeObject;
21+
const nativeToJS = @import("types_primitives.zig").nativeToJS;
2122
const valueToUtf8 = @import("types_primitives.zig").valueToUtf8;
2223

2324
pub const API = struct {
@@ -387,6 +388,20 @@ fn createJSObject(
387388
);
388389
}
389390

391+
pub const JSObject = struct {
392+
ctx: v8.Context,
393+
js_obj: v8.Object,
394+
395+
pub fn set(self: JSObject, key: []const u8, value: anytype) !void {
396+
const isolate = self.ctx.getIsolate();
397+
const js_value = try nativeToJS(@TypeOf(value), value, isolate);
398+
const js_key = v8.String.initUtf8(isolate, key);
399+
if (!self.js_obj.setValue(self.ctx, js_key, js_value)) {
400+
return error.SetV8Object;
401+
}
402+
}
403+
};
404+
390405
pub const TryCatch = struct {
391406
try_catch: *v8.TryCatch,
392407

0 commit comments

Comments
 (0)