diff --git a/quickjs.c b/quickjs.c index b611372..1930c5d 100644 --- a/quickjs.c +++ b/quickjs.c @@ -55344,10 +55344,47 @@ static JSValue js_array_buffer_get_resizable(JSContext *ctx, return JS_NewBool(ctx, array_buffer_is_resizable(abuf)); } +static void js_array_buffer_update_typed_arrays(JSArrayBuffer *abuf) +{ + uint32_t size_log2, size_elem; + struct list_head *el; + JSTypedArray *ta; + JSObject *p; + uint8_t *data; + int64_t len; + + len = abuf->byte_length; + data = abuf->data; + // update lengths of all typed arrays backed by this array buffer + list_for_each(el, &abuf->array_list) { + ta = list_entry(el, JSTypedArray, link); + p = ta->obj; + if (p->class_id == JS_CLASS_DATAVIEW) { + continue; + } else { + p->u.array.count = 0; + p->u.array.u.ptr = NULL; + size_log2 = typed_array_size_log2(p->class_id); + size_elem = 1 << size_log2; + if (ta->track_rab) { + if (len >= (int64_t)ta->offset + size_elem) { + p->u.array.count = (len - ta->offset) >> size_log2; + p->u.array.u.ptr = &data[ta->offset]; + } + } else { + if (len >= (int64_t)ta->offset + ta->length) { + p->u.array.count = ta->length >> size_log2; + p->u.array.u.ptr = &data[ta->offset]; + } + } + } + } + +} + void JS_DetachArrayBuffer(JSContext *ctx, JSValueConst obj) { JSArrayBuffer *abuf = JS_GetOpaque(obj, JS_CLASS_ARRAY_BUFFER); - struct list_head *el; if (!abuf || abuf->detached) return; @@ -55356,19 +55393,7 @@ void JS_DetachArrayBuffer(JSContext *ctx, JSValueConst obj) abuf->data = NULL; abuf->byte_length = 0; abuf->detached = TRUE; - - list_for_each(el, &abuf->array_list) { - JSTypedArray *ta; - JSObject *p; - - ta = list_entry(el, JSTypedArray, link); - p = ta->obj; - /* Note: the typed array length and offset fields are not modified */ - if (p->class_id != JS_CLASS_DATAVIEW) { - p->u.array.count = 0; - p->u.array.u.ptr = NULL; - } - } + js_array_buffer_update_typed_arrays(abuf); } /* get an ArrayBuffer or SharedArrayBuffer */ @@ -55483,6 +55508,7 @@ static JSValue js_array_buffer_transfer(JSContext *ctx, abuf->data = NULL; abuf->byte_length = 0; abuf->detached = TRUE; + js_array_buffer_update_typed_arrays(abuf); return js_array_buffer_constructor3(ctx, JS_UNDEFINED, new_len, pmax_len, JS_CLASS_ARRAY_BUFFER, bs, free_func, @@ -55493,11 +55519,7 @@ static JSValue js_array_buffer_transfer(JSContext *ctx, static JSValue js_array_buffer_resize(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int class_id) { - uint32_t size_log2, size_elem; - struct list_head *el; JSArrayBuffer *abuf; - JSTypedArray *ta; - JSObject *p; uint8_t *data; int64_t len; @@ -55540,29 +55562,7 @@ static JSValue js_array_buffer_resize(JSContext *ctx, JSValueConst this_val, abuf->byte_length = len; abuf->data = data; } - data = abuf->data; - // update lengths of all typed arrays backed by this array buffer - list_for_each(el, &abuf->array_list) { - ta = list_entry(el, JSTypedArray, link); - p = ta->obj; - if (p->class_id == JS_CLASS_DATAVIEW) - continue; - p->u.array.count = 0; - p->u.array.u.ptr = NULL; - size_log2 = typed_array_size_log2(p->class_id); - size_elem = 1 << size_log2; - if (ta->track_rab) { - if (len >= (int64_t)ta->offset + size_elem) { - p->u.array.count = (len - ta->offset) >> size_log2; - p->u.array.u.ptr = &data[ta->offset]; - } - } else { - if (len >= (int64_t)ta->offset + ta->length) { - p->u.array.count = ta->length >> size_log2; - p->u.array.u.ptr = &data[ta->offset]; - } - } - } + js_array_buffer_update_typed_arrays(abuf); return JS_UNDEFINED; } diff --git a/tests/test_builtin.js b/tests/test_builtin.js index a11407e..14bcc06 100644 --- a/tests/test_builtin.js +++ b/tests/test_builtin.js @@ -511,6 +511,14 @@ function test_typed_array() assert(a.toString(), "1,2,3,4"); a.set([10, 11], 2); assert(a.toString(), "1,2,10,11"); + + // https://github.com/quickjs-ng/quickjs/issues/1208 + buffer = new ArrayBuffer(16); + a = new Uint8Array(buffer); + a.fill(42); + assert(a[0], 42); + buffer.transfer(); + assert(a[0], undefined); } /* return [s, line_num, col_num] where line_num and col_num are the