Skip to content

Commit 1fcb573

Browse files
authored
Implement ArrayBuffer.prototype.transfer (#101)
1 parent 9e8d278 commit 1fcb573

File tree

2 files changed

+62
-1
lines changed

2 files changed

+62
-1
lines changed

quickjs.c

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
4725647268
static 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+
4732847386
static 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

4739447452
static 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

test262.conf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ Array.prototype.flatten
6565
Array.prototype.includes
6666
Array.prototype.values
6767
ArrayBuffer
68-
arraybuffer-transfer=skip
68+
arraybuffer-transfer
6969
arrow-function
7070
async-functions
7171
async-iteration

0 commit comments

Comments
 (0)