@@ -1931,7 +1931,7 @@ pub fn Env(comptime State: type, comptime WebApis: type) type {
19311931 }
19321932
19331933 generateIndexer (Struct , template_proto );
1934- generateNamedIndexer (Struct , template_proto );
1934+ generateNamedIndexer (Struct , template . getInstanceTemplate () );
19351935 generateUndetectable (Struct , template .getInstanceTemplate ());
19361936 }
19371937
@@ -2116,7 +2116,8 @@ pub fn Env(comptime State: type, comptime WebApis: type) type {
21162116 }
21172117 return ;
21182118 }
2119- const configuration = v8.NamedPropertyHandlerConfiguration {
2119+
2120+ var configuration = v8.NamedPropertyHandlerConfiguration {
21202121 .getter = struct {
21212122 fn callback (c_name : ? * const v8.C_Name , raw_info : ? * const v8.C_PropertyCallbackInfo ) callconv (.c ) u8 {
21222123 const info = v8 .PropertyCallbackInfo .initFromV8 (raw_info );
@@ -2138,13 +2139,37 @@ pub fn Env(comptime State: type, comptime WebApis: type) type {
21382139 .flags = v8 .PropertyHandlerFlags .OnlyInterceptStrings | v8 .PropertyHandlerFlags .NonMasking ,
21392140 };
21402141
2141- // If you're trying to implement setter, read:
2142- // https://groups.google.com/g/v8-users/c/8tahYBsHpgY/m/IteS7Wn2AAAJ
2143- // The issue I had was
2144- // (a) where to attache it: does it go ont he instance_template
2145- // instead of the prototype?
2146- // (b) defining the getter or query to respond with the
2147- // PropertyAttribute to indicate if the property can be set
2142+ if (@hasDecl (Struct , "named_set" )) {
2143+ configuration .setter = struct {
2144+ fn callback (c_name : ? * const v8.C_Name , c_value : ? * const v8.C_Value , raw_info : ? * const v8.C_PropertyCallbackInfo ) callconv (.c ) u8 {
2145+ const info = v8 .PropertyCallbackInfo .initFromV8 (raw_info );
2146+ var caller = Caller (Self , State ).init (info );
2147+ defer caller .deinit ();
2148+
2149+ const named_function = comptime NamedFunction .init (Struct , "named_set" );
2150+ return caller .setNamedIndex (Struct , named_function , .{ .handle = c_name .? }, .{ .handle = c_value .? }, info ) catch | err | blk : {
2151+ caller .handleError (Struct , named_function , err , info );
2152+ break :blk v8 .Intercepted .No ;
2153+ };
2154+ }
2155+ }.callback ;
2156+ }
2157+
2158+ if (@hasDecl (Struct , "named_delete" )) {
2159+ configuration .deleter = struct {
2160+ fn callback (c_name : ? * const v8.C_Name , raw_info : ? * const v8.C_PropertyCallbackInfo ) callconv (.c ) u8 {
2161+ const info = v8 .PropertyCallbackInfo .initFromV8 (raw_info );
2162+ var caller = Caller (Self , State ).init (info );
2163+ defer caller .deinit ();
2164+
2165+ const named_function = comptime NamedFunction .init (Struct , "named_delete" );
2166+ return caller .deleteNamedIndex (Struct , named_function , .{ .handle = c_name .? }, info ) catch | err | blk : {
2167+ caller .handleError (Struct , named_function , err , info );
2168+ break :blk v8 .Intercepted .No ;
2169+ };
2170+ }
2171+ }.callback ;
2172+ }
21482173 template_proto .setNamedProperty (configuration , null );
21492174 }
21502175
@@ -2646,37 +2671,63 @@ fn Caller(comptime E: type, comptime State: type) type {
26462671 }
26472672
26482673 fn getNamedIndex (self : * Self , comptime Struct : type , comptime named_function : NamedFunction , name : v8.Name , info : v8.PropertyCallbackInfo ) ! u8 {
2649- const js_context = self .js_context ;
26502674 const func = @field (Struct , named_function .name );
2651- const NamedGet = @TypeOf (func );
2652- if (@typeInfo (NamedGet ).@"fn" .return_type == null ) {
2653- @compileError (named_function .full_name ++ " must have a return type" );
2654- }
2675+ comptime assertSelfReceiver (Struct , named_function );
26552676
26562677 var has_value = true ;
2657- var args : ParamterTypes (NamedGet ) = undefined ;
2658- const arg_fields = @typeInfo (@TypeOf (args )).@"struct" .fields ;
2659- switch (arg_fields .len ) {
2660- 0 , 1 , 2 = > @compileError (named_function .full_name ++ " must take at least a u32 and *bool parameter" ),
2661- 3 , 4 = > {
2662- const zig_instance = try E .typeTaggedAnyOpaque (named_function , * Receiver (Struct ), info .getThis ());
2663- comptime assertSelfReceiver (Struct , named_function );
2664- @field (args , "0" ) = zig_instance ;
2665- @field (args , "1" ) = try self .nameToString (name );
2666- @field (args , "2" ) = & has_value ;
2667- if (comptime arg_fields .len == 4 ) {
2668- comptime assertIsStateArg (Struct , named_function , 3 );
2669- @field (args , "3" ) = js_context .state ;
2670- }
2671- },
2672- else = > @compileError (named_function .full_name ++ " has too many parmaters" ),
2678+ var args = try self .getArgs (Struct , named_function , 3 , info );
2679+ const zig_instance = try E .typeTaggedAnyOpaque (named_function , * Receiver (Struct ), info .getThis ());
2680+ @field (args , "0" ) = zig_instance ;
2681+ @field (args , "1" ) = try self .nameToString (name );
2682+ @field (args , "2" ) = & has_value ;
2683+
2684+ const res = @call (.auto , func , args );
2685+ if (has_value == false ) {
2686+ return v8 .Intercepted .No ;
26732687 }
2688+ info .getReturnValue ().set (try self .js_context .zigValueToJs (res ));
2689+ return v8 .Intercepted .Yes ;
2690+ }
2691+
2692+ fn setNamedIndex (self : * Self , comptime Struct : type , comptime named_function : NamedFunction , name : v8.Name , js_value : v8.Value , info : v8.PropertyCallbackInfo ) ! u8 {
2693+ const js_context = self .js_context ;
2694+ const func = @field (Struct , named_function .name );
2695+ comptime assertSelfReceiver (Struct , named_function );
2696+
2697+ var has_value = true ;
2698+ var args = try self .getArgs (Struct , named_function , 4 , info );
2699+ const zig_instance = try E .typeTaggedAnyOpaque (named_function , * Receiver (Struct ), info .getThis ());
2700+ @field (args , "0" ) = zig_instance ;
2701+ @field (args , "1" ) = try self .nameToString (name );
2702+ @field (args , "2" ) = try js_context .jsValueToZig (named_function , @TypeOf (@field (args , "2" )), js_value );
2703+ @field (args , "3" ) = & has_value ;
26742704
26752705 const res = @call (.auto , func , args );
2706+ return namedSetOrDeleteCall (res , has_value );
2707+ }
2708+
2709+ fn deleteNamedIndex (self : * Self , comptime Struct : type , comptime named_function : NamedFunction , name : v8.Name , info : v8.PropertyCallbackInfo ) ! u8 {
2710+ const func = @field (Struct , named_function .name );
2711+ comptime assertSelfReceiver (Struct , named_function );
2712+
2713+ var has_value = true ;
2714+ var args = try self .getArgs (Struct , named_function , 3 , info );
2715+ const zig_instance = try E .typeTaggedAnyOpaque (named_function , * Receiver (Struct ), info .getThis ());
2716+ @field (args , "0" ) = zig_instance ;
2717+ @field (args , "1" ) = try self .nameToString (name );
2718+ @field (args , "2" ) = & has_value ;
2719+
2720+ const res = @call (.auto , func , args );
2721+ return namedSetOrDeleteCall (res , has_value );
2722+ }
2723+
2724+ fn namedSetOrDeleteCall (res : anytype , has_value : bool ) ! u8 {
2725+ if (@typeInfo (@TypeOf (res )) == .error_union ) {
2726+ _ = try res ;
2727+ }
26762728 if (has_value == false ) {
26772729 return v8 .Intercepted .No ;
26782730 }
2679- info .getReturnValue ().set (try js_context .zigValueToJs (res ));
26802731 return v8 .Intercepted .Yes ;
26812732 }
26822733
0 commit comments