@@ -1094,88 +1094,10 @@ pub fn Env(comptime State: type, comptime WebApis: type) type {
10941094 }
10951095 },
10961096 .slice = > {
1097- var force_u8 = false ;
1098- var array_buffer : ? v8.ArrayBuffer = null ;
1099- if (js_value .isTypedArray ()) {
1100- const buffer_view = js_value .castTo (v8 .ArrayBufferView );
1101- array_buffer = buffer_view .getBuffer ();
1102- } else if (js_value .isArrayBufferView ()) {
1103- force_u8 = true ;
1104- const buffer_view = js_value .castTo (v8 .ArrayBufferView );
1105- array_buffer = buffer_view .getBuffer ();
1106- } else if (js_value .isArrayBuffer ()) {
1107- force_u8 = true ;
1108- array_buffer = js_value .castTo (v8 .ArrayBuffer );
1109- }
1110-
1111- if (array_buffer ) | buffer | {
1112- const backing_store = v8 .BackingStore .sharedPtrGet (& buffer .getBackingStore ());
1113- const data = backing_store .getData ();
1114- const byte_len = backing_store .getByteLength ();
1115-
1116- switch (ptr .child ) {
1117- u8 = > {
1118- // need this sentinel check to keep the compiler happy
1119- if (ptr .sentinel () == null ) {
1120- if (force_u8 or js_value .isUint8Array () or js_value .isUint8ClampedArray ()) {
1121- if (byte_len == 0 ) return &[_ ]u8 {};
1122- const arr_ptr = @as ([* ]u8 , @ptrCast (@alignCast (data )));
1123- return arr_ptr [0.. byte_len ];
1124- }
1125- }
1126- },
1127- i8 = > {
1128- if (js_value .isInt8Array ()) {
1129- if (byte_len == 0 ) return &[_ ]i8 {};
1130- const arr_ptr = @as ([* ]i8 , @ptrCast (@alignCast (data )));
1131- return arr_ptr [0.. byte_len ];
1132- }
1133- },
1134- u16 = > {
1135- if (js_value .isUint16Array ()) {
1136- if (byte_len == 0 ) return &[_ ]u16 {};
1137- const arr_ptr = @as ([* ]u16 , @ptrCast (@alignCast (data )));
1138- return arr_ptr [0 .. byte_len / 2 ];
1139- }
1140- },
1141- i16 = > {
1142- if (js_value .isInt16Array ()) {
1143- if (byte_len == 0 ) return &[_ ]i16 {};
1144- const arr_ptr = @as ([* ]i16 , @ptrCast (@alignCast (data )));
1145- return arr_ptr [0 .. byte_len / 2 ];
1146- }
1147- },
1148- u32 = > {
1149- if (js_value .isUint32Array ()) {
1150- if (byte_len == 0 ) return &[_ ]u32 {};
1151- const arr_ptr = @as ([* ]u32 , @ptrCast (@alignCast (data )));
1152- return arr_ptr [0 .. byte_len / 4 ];
1153- }
1154- },
1155- i32 = > {
1156- if (js_value .isInt32Array ()) {
1157- if (byte_len == 0 ) return &[_ ]i32 {};
1158- const arr_ptr = @as ([* ]i32 , @ptrCast (@alignCast (data )));
1159- return arr_ptr [0 .. byte_len / 4 ];
1160- }
1161- },
1162- u64 = > {
1163- if (js_value .isBigUint64Array ()) {
1164- if (byte_len == 0 ) return &[_ ]u64 {};
1165- const arr_ptr = @as ([* ]u64 , @ptrCast (@alignCast (data )));
1166- return arr_ptr [0 .. byte_len / 8 ];
1167- }
1168- },
1169- i64 = > {
1170- if (js_value .isBigInt64Array ()) {
1171- if (byte_len == 0 ) return &[_ ]i64 {};
1172- const arr_ptr = @as ([* ]i64 , @ptrCast (@alignCast (data )));
1173- return arr_ptr [0 .. byte_len / 8 ];
1174- }
1175- },
1176- else = > {},
1097+ if (ptr .sentinel () == null ) {
1098+ if (try self .jsValueToTypedArray (ptr .child , js_value )) | value | {
1099+ return value ;
11771100 }
1178- return error .InvalidArgument ;
11791101 }
11801102
11811103 if (ptr .child == u8 ) {
@@ -1282,6 +1204,12 @@ pub fn Env(comptime State: type, comptime WebApis: type) type {
12821204 return try self .createFunction (js_value );
12831205 }
12841206
1207+ if (@hasDecl (T , "_TYPED_ARRAY_ID_KLUDGE" )) {
1208+ const VT = @typeInfo (std .meta .fieldInfo (T , .values ).type ).pointer .child ;
1209+ const arr = (try self .jsValueToTypedArray (VT , js_value )) orelse return null ;
1210+ return .{ .values = arr };
1211+ }
1212+
12851213 if (T == String ) {
12861214 return .{ .string = try valueToString (self .context_arena , js_value , self .isolate , self .v8_context ) };
12871215 }
@@ -1320,6 +1248,90 @@ pub fn Env(comptime State: type, comptime WebApis: type) type {
13201248 return value ;
13211249 }
13221250
1251+ fn jsValueToTypedArray (_ : * JsContext , comptime T : type , js_value : v8.Value ) ! ? []T {
1252+ var force_u8 = false ;
1253+ var array_buffer : ? v8.ArrayBuffer = null ;
1254+ if (js_value .isTypedArray ()) {
1255+ const buffer_view = js_value .castTo (v8 .ArrayBufferView );
1256+ array_buffer = buffer_view .getBuffer ();
1257+ } else if (js_value .isArrayBufferView ()) {
1258+ force_u8 = true ;
1259+ const buffer_view = js_value .castTo (v8 .ArrayBufferView );
1260+ array_buffer = buffer_view .getBuffer ();
1261+ } else if (js_value .isArrayBuffer ()) {
1262+ force_u8 = true ;
1263+ array_buffer = js_value .castTo (v8 .ArrayBuffer );
1264+ }
1265+
1266+ const buffer = array_buffer orelse return null ;
1267+
1268+ const backing_store = v8 .BackingStore .sharedPtrGet (& buffer .getBackingStore ());
1269+ const data = backing_store .getData ();
1270+ const byte_len = backing_store .getByteLength ();
1271+
1272+ switch (T ) {
1273+ u8 = > {
1274+ // need this sentinel check to keep the compiler happy
1275+ if (force_u8 or js_value .isUint8Array () or js_value .isUint8ClampedArray ()) {
1276+ if (byte_len == 0 ) return &[_ ]u8 {};
1277+ const arr_ptr = @as ([* ]u8 , @ptrCast (@alignCast (data )));
1278+ return arr_ptr [0.. byte_len ];
1279+ }
1280+ },
1281+ i8 = > {
1282+ if (js_value .isInt8Array ()) {
1283+ if (byte_len == 0 ) return &[_ ]i8 {};
1284+ const arr_ptr = @as ([* ]i8 , @ptrCast (@alignCast (data )));
1285+ return arr_ptr [0.. byte_len ];
1286+ }
1287+ },
1288+ u16 = > {
1289+ if (js_value .isUint16Array ()) {
1290+ if (byte_len == 0 ) return &[_ ]u16 {};
1291+ const arr_ptr = @as ([* ]u16 , @ptrCast (@alignCast (data )));
1292+ return arr_ptr [0 .. byte_len / 2 ];
1293+ }
1294+ },
1295+ i16 = > {
1296+ if (js_value .isInt16Array ()) {
1297+ if (byte_len == 0 ) return &[_ ]i16 {};
1298+ const arr_ptr = @as ([* ]i16 , @ptrCast (@alignCast (data )));
1299+ return arr_ptr [0 .. byte_len / 2 ];
1300+ }
1301+ },
1302+ u32 = > {
1303+ if (js_value .isUint32Array ()) {
1304+ if (byte_len == 0 ) return &[_ ]u32 {};
1305+ const arr_ptr = @as ([* ]u32 , @ptrCast (@alignCast (data )));
1306+ return arr_ptr [0 .. byte_len / 4 ];
1307+ }
1308+ },
1309+ i32 = > {
1310+ if (js_value .isInt32Array ()) {
1311+ if (byte_len == 0 ) return &[_ ]i32 {};
1312+ const arr_ptr = @as ([* ]i32 , @ptrCast (@alignCast (data )));
1313+ return arr_ptr [0 .. byte_len / 4 ];
1314+ }
1315+ },
1316+ u64 = > {
1317+ if (js_value .isBigUint64Array ()) {
1318+ if (byte_len == 0 ) return &[_ ]u64 {};
1319+ const arr_ptr = @as ([* ]u64 , @ptrCast (@alignCast (data )));
1320+ return arr_ptr [0 .. byte_len / 8 ];
1321+ }
1322+ },
1323+ i64 = > {
1324+ if (js_value .isBigInt64Array ()) {
1325+ if (byte_len == 0 ) return &[_ ]i64 {};
1326+ const arr_ptr = @as ([* ]i64 , @ptrCast (@alignCast (data )));
1327+ return arr_ptr [0 .. byte_len / 8 ];
1328+ }
1329+ },
1330+ else = > {},
1331+ }
1332+ return error .InvalidArgument ;
1333+ }
1334+
13231335 fn createFunction (self : * JsContext , js_value : v8.Value ) ! Function {
13241336 // caller should have made sure this was a function
13251337 std .debug .assert (js_value .isFunction ());
@@ -2387,6 +2399,10 @@ pub fn Env(comptime State: type, comptime WebApis: type) type {
23872399 const _TYPED_ARRAY_ID_KLUDGE = true ;
23882400
23892401 values : []const T ,
2402+
2403+ pub fn dupe (self : TypedArray (T ), allocator : Allocator ) ! TypedArray (T ) {
2404+ return .{ .values = try allocator .dupe (T , self .values ) };
2405+ }
23902406 };
23912407 }
23922408
0 commit comments