@@ -844,7 +844,7 @@ pub fn Env(comptime State: type, comptime WebApis: type) type {
844844
845845 const entry = ModuleEntry {
846846 .module = PersistentModule .init (self .isolate , m ),
847- .promise = PersistentPromise .init (self .isolate , .{.handle = evaluated .handle }),
847+ .promise = PersistentPromise .init (self .isolate , .{ .handle = evaluated .handle }),
848848 };
849849 if (cacheable ) {
850850 try self .module_cache .putNoClobber (arena , owned_url , entry );
@@ -1036,88 +1036,10 @@ pub fn Env(comptime State: type, comptime WebApis: type) type {
10361036 }
10371037 },
10381038 .slice = > {
1039- var force_u8 = false ;
1040- var array_buffer : ? v8.ArrayBuffer = null ;
1041- if (js_value .isTypedArray ()) {
1042- const buffer_view = js_value .castTo (v8 .ArrayBufferView );
1043- array_buffer = buffer_view .getBuffer ();
1044- } else if (js_value .isArrayBufferView ()) {
1045- force_u8 = true ;
1046- const buffer_view = js_value .castTo (v8 .ArrayBufferView );
1047- array_buffer = buffer_view .getBuffer ();
1048- } else if (js_value .isArrayBuffer ()) {
1049- force_u8 = true ;
1050- array_buffer = js_value .castTo (v8 .ArrayBuffer );
1051- }
1052-
1053- if (array_buffer ) | buffer | {
1054- const backing_store = v8 .BackingStore .sharedPtrGet (& buffer .getBackingStore ());
1055- const data = backing_store .getData ();
1056- const byte_len = backing_store .getByteLength ();
1057-
1058- switch (ptr .child ) {
1059- u8 = > {
1060- // need this sentinel check to keep the compiler happy
1061- if (ptr .sentinel () == null ) {
1062- if (force_u8 or js_value .isUint8Array () or js_value .isUint8ClampedArray ()) {
1063- if (byte_len == 0 ) return &[_ ]u8 {};
1064- const arr_ptr = @as ([* ]u8 , @ptrCast (@alignCast (data )));
1065- return arr_ptr [0.. byte_len ];
1066- }
1067- }
1068- },
1069- i8 = > {
1070- if (js_value .isInt8Array ()) {
1071- if (byte_len == 0 ) return &[_ ]i8 {};
1072- const arr_ptr = @as ([* ]i8 , @ptrCast (@alignCast (data )));
1073- return arr_ptr [0.. byte_len ];
1074- }
1075- },
1076- u16 = > {
1077- if (js_value .isUint16Array ()) {
1078- if (byte_len == 0 ) return &[_ ]u16 {};
1079- const arr_ptr = @as ([* ]u16 , @ptrCast (@alignCast (data )));
1080- return arr_ptr [0 .. byte_len / 2 ];
1081- }
1082- },
1083- i16 = > {
1084- if (js_value .isInt16Array ()) {
1085- if (byte_len == 0 ) return &[_ ]i16 {};
1086- const arr_ptr = @as ([* ]i16 , @ptrCast (@alignCast (data )));
1087- return arr_ptr [0 .. byte_len / 2 ];
1088- }
1089- },
1090- u32 = > {
1091- if (js_value .isUint32Array ()) {
1092- if (byte_len == 0 ) return &[_ ]u32 {};
1093- const arr_ptr = @as ([* ]u32 , @ptrCast (@alignCast (data )));
1094- return arr_ptr [0 .. byte_len / 4 ];
1095- }
1096- },
1097- i32 = > {
1098- if (js_value .isInt32Array ()) {
1099- if (byte_len == 0 ) return &[_ ]i32 {};
1100- const arr_ptr = @as ([* ]i32 , @ptrCast (@alignCast (data )));
1101- return arr_ptr [0 .. byte_len / 4 ];
1102- }
1103- },
1104- u64 = > {
1105- if (js_value .isBigUint64Array ()) {
1106- if (byte_len == 0 ) return &[_ ]u64 {};
1107- const arr_ptr = @as ([* ]u64 , @ptrCast (@alignCast (data )));
1108- return arr_ptr [0 .. byte_len / 8 ];
1109- }
1110- },
1111- i64 = > {
1112- if (js_value .isBigInt64Array ()) {
1113- if (byte_len == 0 ) return &[_ ]i64 {};
1114- const arr_ptr = @as ([* ]i64 , @ptrCast (@alignCast (data )));
1115- return arr_ptr [0 .. byte_len / 8 ];
1116- }
1117- },
1118- else = > {},
1039+ if (ptr .sentinel () == null ) {
1040+ if (try self .jsValueToTypedArray (ptr .child , js_value )) | value | {
1041+ return value ;
11191042 }
1120- return error .InvalidArgument ;
11211043 }
11221044
11231045 if (ptr .child == u8 ) {
@@ -1223,6 +1145,11 @@ pub fn Env(comptime State: type, comptime WebApis: type) type {
12231145 }
12241146 return try self .createFunction (js_value );
12251147 }
1148+ if (@hasDecl (T , "_TYPED_ARRAY_ID_KLUDGE" )) {
1149+ const VT = @typeInfo (std .meta .fieldInfo (T , .values ).type ).pointer .child ;
1150+ const arr = (try self .jsValueToTypedArray (VT , js_value )) orelse return null ;
1151+ return .{ .values = arr };
1152+ }
12261153
12271154 if (T == String ) {
12281155 return .{ .string = try valueToString (self .context_arena , js_value , self .isolate , self .v8_context ) };
@@ -1262,6 +1189,90 @@ pub fn Env(comptime State: type, comptime WebApis: type) type {
12621189 return value ;
12631190 }
12641191
1192+ fn jsValueToTypedArray (_ : * JsContext , comptime T : type , js_value : v8.Value ) ! ? []T {
1193+ var force_u8 = false ;
1194+ var array_buffer : ? v8.ArrayBuffer = null ;
1195+ if (js_value .isTypedArray ()) {
1196+ const buffer_view = js_value .castTo (v8 .ArrayBufferView );
1197+ array_buffer = buffer_view .getBuffer ();
1198+ } else if (js_value .isArrayBufferView ()) {
1199+ force_u8 = true ;
1200+ const buffer_view = js_value .castTo (v8 .ArrayBufferView );
1201+ array_buffer = buffer_view .getBuffer ();
1202+ } else if (js_value .isArrayBuffer ()) {
1203+ force_u8 = true ;
1204+ array_buffer = js_value .castTo (v8 .ArrayBuffer );
1205+ }
1206+
1207+ const buffer = array_buffer orelse return null ;
1208+
1209+ const backing_store = v8 .BackingStore .sharedPtrGet (& buffer .getBackingStore ());
1210+ const data = backing_store .getData ();
1211+ const byte_len = backing_store .getByteLength ();
1212+
1213+ switch (T ) {
1214+ u8 = > {
1215+ // need this sentinel check to keep the compiler happy
1216+ if (force_u8 or js_value .isUint8Array () or js_value .isUint8ClampedArray ()) {
1217+ if (byte_len == 0 ) return &[_ ]u8 {};
1218+ const arr_ptr = @as ([* ]u8 , @ptrCast (@alignCast (data )));
1219+ return arr_ptr [0.. byte_len ];
1220+ }
1221+ },
1222+ i8 = > {
1223+ if (js_value .isInt8Array ()) {
1224+ if (byte_len == 0 ) return &[_ ]i8 {};
1225+ const arr_ptr = @as ([* ]i8 , @ptrCast (@alignCast (data )));
1226+ return arr_ptr [0.. byte_len ];
1227+ }
1228+ },
1229+ u16 = > {
1230+ if (js_value .isUint16Array ()) {
1231+ if (byte_len == 0 ) return &[_ ]u16 {};
1232+ const arr_ptr = @as ([* ]u16 , @ptrCast (@alignCast (data )));
1233+ return arr_ptr [0 .. byte_len / 2 ];
1234+ }
1235+ },
1236+ i16 = > {
1237+ if (js_value .isInt16Array ()) {
1238+ if (byte_len == 0 ) return &[_ ]i16 {};
1239+ const arr_ptr = @as ([* ]i16 , @ptrCast (@alignCast (data )));
1240+ return arr_ptr [0 .. byte_len / 2 ];
1241+ }
1242+ },
1243+ u32 = > {
1244+ if (js_value .isUint32Array ()) {
1245+ if (byte_len == 0 ) return &[_ ]u32 {};
1246+ const arr_ptr = @as ([* ]u32 , @ptrCast (@alignCast (data )));
1247+ return arr_ptr [0 .. byte_len / 4 ];
1248+ }
1249+ },
1250+ i32 = > {
1251+ if (js_value .isInt32Array ()) {
1252+ if (byte_len == 0 ) return &[_ ]i32 {};
1253+ const arr_ptr = @as ([* ]i32 , @ptrCast (@alignCast (data )));
1254+ return arr_ptr [0 .. byte_len / 4 ];
1255+ }
1256+ },
1257+ u64 = > {
1258+ if (js_value .isBigUint64Array ()) {
1259+ if (byte_len == 0 ) return &[_ ]u64 {};
1260+ const arr_ptr = @as ([* ]u64 , @ptrCast (@alignCast (data )));
1261+ return arr_ptr [0 .. byte_len / 8 ];
1262+ }
1263+ },
1264+ i64 = > {
1265+ if (js_value .isBigInt64Array ()) {
1266+ if (byte_len == 0 ) return &[_ ]i64 {};
1267+ const arr_ptr = @as ([* ]i64 , @ptrCast (@alignCast (data )));
1268+ return arr_ptr [0 .. byte_len / 8 ];
1269+ }
1270+ },
1271+ else = > {},
1272+ }
1273+ return error .InvalidArgument ;
1274+ }
1275+
12651276 fn createFunction (self : * JsContext , js_value : v8.Value ) ! Function {
12661277 // caller should have made sure this was a function
12671278 std .debug .assert (js_value .isFunction ());
@@ -1618,12 +1629,12 @@ pub fn Env(comptime State: type, comptime WebApis: type) type {
16181629 const isolate = self .isolate ;
16191630
16201631 const resource = jsStringToZig (self .call_arena , .{ .handle = resource_name .? }, isolate ) catch | err | {
1621- log .err (.app , "OOM" , .{.err = err , .src = "dynamicModuleCallback1" });
1632+ log .err (.app , "OOM" , .{ .err = err , .src = "dynamicModuleCallback1" });
16221633 return @constCast (self .rejectPromise ("Out of memory" ).handle );
16231634 };
16241635
16251636 const specifier = jsStringToZig (self .call_arena , .{ .handle = v8_specifier .? }, isolate ) catch | err | {
1626- log .err (.app , "OOM" , .{.err = err , .src = "dynamicModuleCallback2" });
1637+ log .err (.app , "OOM" , .{ .err = err , .src = "dynamicModuleCallback2" });
16271638 return @constCast (self .rejectPromise ("Out of memory" ).handle );
16281639 };
16291640
@@ -1633,7 +1644,7 @@ pub fn Env(comptime State: type, comptime WebApis: type) type {
16331644 resource ,
16341645 .{ .alloc = .if_needed , .null_terminated = true },
16351646 ) catch | err | {
1636- log .err (.app , "OOM" , .{.err = err , .src = "dynamicModuleCallback3" });
1647+ log .err (.app , "OOM" , .{ .err = err , .src = "dynamicModuleCallback3" });
16371648 return @constCast (self .rejectPromise ("Out of memory" ).handle );
16381649 };
16391650
@@ -2193,6 +2204,10 @@ pub fn Env(comptime State: type, comptime WebApis: type) type {
21932204 const _TYPED_ARRAY_ID_KLUDGE = true ;
21942205
21952206 values : []const T ,
2207+
2208+ pub fn dupe (self : TypedArray (T ), allocator : Allocator ) ! TypedArray (T ) {
2209+ return .{ .values = try allocator .dupe (T , self .values ) };
2210+ }
21962211 };
21972212 }
21982213
0 commit comments