@@ -47253,6 +47253,18 @@ static JSValue JS_ThrowTypeErrorDetachedArrayBuffer(JSContext *ctx)
47253
47253
return JS_ThrowTypeError(ctx, "ArrayBuffer is detached");
47254
47254
}
47255
47255
47256
+ // #sec-get-arraybuffer.prototype.detached
47257
+ static JSValue js_array_buffer_get_detached(JSContext *ctx,
47258
+ JSValueConst this_val)
47259
+ {
47260
+ JSArrayBuffer *abuf = JS_GetOpaque2(ctx, this_val, JS_CLASS_ARRAY_BUFFER);
47261
+ if (!abuf)
47262
+ return JS_EXCEPTION;
47263
+ if (abuf->shared)
47264
+ return JS_ThrowTypeError(ctx, "detached called on SharedArrayBuffer");
47265
+ return JS_NewBool(ctx, abuf->detached);
47266
+ }
47267
+
47256
47268
static JSValue js_array_buffer_get_byteLength(JSContext *ctx,
47257
47269
JSValueConst this_val,
47258
47270
int class_id)
@@ -47325,6 +47337,52 @@ uint8_t *JS_GetArrayBuffer(JSContext *ctx, size_t *psize, JSValueConst obj)
47325
47337
return NULL;
47326
47338
}
47327
47339
47340
+ // ES #sec-arraybuffer.prototype.transfer
47341
+ static JSValue js_array_buffer_transfer(JSContext *ctx,
47342
+ JSValueConst this_val,
47343
+ int argc, JSValueConst *argv)
47344
+ {
47345
+ JSArrayBuffer *abuf;
47346
+ uint64_t new_len, old_len;
47347
+ uint8_t *bs, *new_bs;
47348
+
47349
+ abuf = JS_GetOpaque2(ctx, this_val, JS_CLASS_ARRAY_BUFFER);
47350
+ if (!abuf)
47351
+ return JS_EXCEPTION;
47352
+ if (abuf->shared)
47353
+ return JS_ThrowTypeError(ctx, "cannot transfer a SharedArrayBuffer");
47354
+ if (argc < 1 || JS_IsUndefined(argv[0]))
47355
+ new_len = abuf->byte_length;
47356
+ else if (JS_ToIndex(ctx, &new_len, argv[0]))
47357
+ return JS_EXCEPTION;
47358
+ if (abuf->detached)
47359
+ return JS_ThrowTypeErrorDetachedArrayBuffer(ctx);
47360
+ /* create an empty AB */
47361
+ if (new_len == 0) {
47362
+ JS_DetachArrayBuffer(ctx, this_val);
47363
+ return js_array_buffer_constructor2(ctx, JS_UNDEFINED, 0, JS_CLASS_ARRAY_BUFFER);
47364
+ }
47365
+ bs = abuf->data;
47366
+ old_len = abuf->byte_length;
47367
+ /* if length mismatch, realloc. Otherwise, use the same backing buffer. */
47368
+ if (new_len != old_len) {
47369
+ new_bs = js_realloc(ctx, bs, new_len);
47370
+ if (!new_bs)
47371
+ return JS_EXCEPTION;
47372
+ bs = new_bs;
47373
+ if (new_len > old_len)
47374
+ memset(bs + old_len, 0, new_len - old_len);
47375
+ }
47376
+ /* neuter the backing buffer */
47377
+ abuf->data = NULL;
47378
+ abuf->byte_length = 0;
47379
+ abuf->detached = TRUE;
47380
+ return js_array_buffer_constructor3(ctx, JS_UNDEFINED, new_len,
47381
+ JS_CLASS_ARRAY_BUFFER,
47382
+ bs, abuf->free_func,
47383
+ NULL, FALSE);
47384
+ }
47385
+
47328
47386
static JSValue js_array_buffer_slice(JSContext *ctx,
47329
47387
JSValueConst this_val,
47330
47388
int argc, JSValueConst *argv, int class_id)
@@ -47393,7 +47451,10 @@ static JSValue js_array_buffer_slice(JSContext *ctx,
47393
47451
47394
47452
static const JSCFunctionListEntry js_array_buffer_proto_funcs[] = {
47395
47453
JS_CGETSET_MAGIC_DEF("byteLength", js_array_buffer_get_byteLength, NULL, JS_CLASS_ARRAY_BUFFER ),
47454
+ JS_CGETSET_DEF("detached", js_array_buffer_get_detached, NULL ),
47396
47455
JS_CFUNC_MAGIC_DEF("slice", 2, js_array_buffer_slice, JS_CLASS_ARRAY_BUFFER ),
47456
+ JS_CFUNC_DEF("transfer", 0, js_array_buffer_transfer ),
47457
+ JS_CFUNC_DEF("transferToFixedLength", 0, js_array_buffer_transfer ),
47397
47458
JS_PROP_STRING_DEF("[Symbol.toStringTag]", "ArrayBuffer", JS_PROP_CONFIGURABLE ),
47398
47459
};
47399
47460
0 commit comments