@@ -47253,6 +47253,18 @@ static JSValue JS_ThrowTypeErrorDetachedArrayBuffer(JSContext *ctx)
4725347253 return JS_ThrowTypeError(ctx, "ArrayBuffer is detached");
4725447254}
4725547255
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+
4725647268static JSValue js_array_buffer_get_byteLength(JSContext *ctx,
4725747269 JSValueConst this_val,
4725847270 int class_id)
@@ -47325,6 +47337,52 @@ uint8_t *JS_GetArrayBuffer(JSContext *ctx, size_t *psize, JSValueConst obj)
4732547337 return NULL;
4732647338}
4732747339
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+
4732847386static JSValue js_array_buffer_slice(JSContext *ctx,
4732947387 JSValueConst this_val,
4733047388 int argc, JSValueConst *argv, int class_id)
@@ -47393,7 +47451,10 @@ static JSValue js_array_buffer_slice(JSContext *ctx,
4739347451
4739447452static const JSCFunctionListEntry js_array_buffer_proto_funcs[] = {
4739547453 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 ),
4739647455 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 ),
4739747458 JS_PROP_STRING_DEF("[Symbol.toStringTag]", "ArrayBuffer", JS_PROP_CONFIGURABLE ),
4739847459};
4739947460
0 commit comments