mirror of
https://github.com/bellard/quickjs.git
synced 2026-05-27 19:09:36 +00:00
fixed (again) JS atomics in case of typed array resizing - use same function name as quickjs-ng for js_atomics_get_buf() (#508)
This commit is contained in:
parent
d417cafaf0
commit
efda450a21
84
quickjs.c
84
quickjs.c
@ -58998,19 +58998,16 @@ typedef enum AtomicsOpEnum {
|
||||
ATOMICS_OP_LOAD,
|
||||
} AtomicsOpEnum;
|
||||
|
||||
static int js_atomics_get_ptr(JSContext *ctx, void **pptr,
|
||||
JSObject **pobj, uint64_t *pidx,
|
||||
int *psize_log2, JSClassID *pclass_id,
|
||||
JSValueConst obj, JSValueConst idx_val,
|
||||
int is_waitable)
|
||||
static JSObject *js_atomics_get_buf(JSContext *ctx,
|
||||
JSValueConst obj, JSValueConst idx_val,
|
||||
uint64_t *pidx, int is_waitable)
|
||||
{
|
||||
JSObject *p;
|
||||
JSTypedArray *ta;
|
||||
JSArrayBuffer *abuf;
|
||||
void *ptr;
|
||||
uint64_t idx;
|
||||
BOOL err;
|
||||
int size_log2, old_len;
|
||||
int old_len;
|
||||
|
||||
if (JS_VALUE_GET_TAG(obj) != JS_TAG_OBJECT)
|
||||
goto fail;
|
||||
@ -59024,59 +59021,44 @@ static int js_atomics_get_ptr(JSContext *ctx, void **pptr,
|
||||
if (err) {
|
||||
fail:
|
||||
JS_ThrowTypeError(ctx, "integer TypedArray expected");
|
||||
return -1;
|
||||
return NULL;
|
||||
}
|
||||
ta = p->u.typed_array;
|
||||
abuf = ta->buffer->u.array_buffer;
|
||||
if (!abuf->shared) {
|
||||
if (is_waitable == 2) {
|
||||
JS_ThrowTypeError(ctx, "not a SharedArrayBuffer TypedArray");
|
||||
return -1;
|
||||
return NULL;
|
||||
}
|
||||
if (abuf->detached) {
|
||||
JS_ThrowTypeErrorDetachedArrayBuffer(ctx);
|
||||
return -1;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
old_len = p->u.array.count;
|
||||
|
||||
if (JS_ToIndex(ctx, &idx, idx_val)) {
|
||||
return -1;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (idx >= old_len)
|
||||
goto oob;
|
||||
|
||||
if (is_waitable == 1) {
|
||||
/* notify(): just avoid having an invalid pointer if overflow */
|
||||
if (idx >= p->u.array.count)
|
||||
ptr = NULL;
|
||||
} else {
|
||||
if (is_waitable != 1) {
|
||||
/* RevalidateAtomicAccess() */
|
||||
if (typed_array_is_oob(p)) {
|
||||
JS_ThrowTypeErrorArrayBufferOOB(ctx);
|
||||
return -1;
|
||||
return NULL;
|
||||
}
|
||||
if (idx >= p->u.array.count) {
|
||||
oob:
|
||||
JS_ThrowRangeError(ctx, "out-of-bound access");
|
||||
return -1;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
size_log2 = typed_array_size_log2(p->class_id);
|
||||
ptr = p->u.array.u.uint8_ptr + ((uintptr_t)idx << size_log2);
|
||||
|
||||
*pptr = ptr;
|
||||
if (pobj)
|
||||
*pobj = p;
|
||||
if (pidx)
|
||||
*pidx = idx;
|
||||
if (psize_log2)
|
||||
*psize_log2 = size_log2;
|
||||
if (pclass_id)
|
||||
*pclass_id = p->class_id;
|
||||
return 0;
|
||||
*pidx = idx;
|
||||
return p;
|
||||
}
|
||||
|
||||
static JSValue js_atomics_op(JSContext *ctx,
|
||||
@ -59087,12 +59069,12 @@ static JSValue js_atomics_op(JSContext *ctx,
|
||||
uint64_t v, a, rep_val, idx;
|
||||
void *ptr;
|
||||
JSValue ret;
|
||||
JSClassID class_id;
|
||||
JSObject *p;
|
||||
|
||||
if (js_atomics_get_ptr(ctx, &ptr, &p, &idx, &size_log2, &class_id,
|
||||
argv[0], argv[1], 0))
|
||||
p = js_atomics_get_buf(ctx, argv[0], argv[1], &idx, 0);
|
||||
if (!p)
|
||||
return JS_EXCEPTION;
|
||||
size_log2 = typed_array_size_log2(p->class_id);
|
||||
rep_val = 0;
|
||||
if (op == ATOMICS_OP_LOAD) {
|
||||
v = 0;
|
||||
@ -59122,9 +59104,10 @@ static JSValue js_atomics_op(JSContext *ctx,
|
||||
return JS_ThrowTypeErrorDetachedArrayBuffer(ctx);
|
||||
if (idx >= p->u.array.count)
|
||||
return JS_ThrowRangeError(ctx, "out-of-bound access");
|
||||
}
|
||||
|
||||
switch(op | (size_log2 << 3)) {
|
||||
}
|
||||
ptr = p->u.array.u.uint8_ptr + ((uintptr_t)idx << size_log2);
|
||||
|
||||
switch(op | (size_log2 << 3)) {
|
||||
|
||||
#define OP(op_name, func_name) \
|
||||
case ATOMICS_OP_ ## op_name | (0 << 3): \
|
||||
@ -59193,7 +59176,7 @@ static JSValue js_atomics_op(JSContext *ctx,
|
||||
abort();
|
||||
}
|
||||
|
||||
switch(class_id) {
|
||||
switch(p->class_id) {
|
||||
case JS_CLASS_INT8_ARRAY:
|
||||
a = (int8_t)a;
|
||||
goto done;
|
||||
@ -59235,10 +59218,11 @@ static JSValue js_atomics_store(JSContext *ctx,
|
||||
JSObject *p;
|
||||
uint64_t idx;
|
||||
int64_t v;
|
||||
|
||||
if (js_atomics_get_ptr(ctx, &ptr, &p, &idx, &size_log2, NULL,
|
||||
argv[0], argv[1], 0))
|
||||
|
||||
p = js_atomics_get_buf(ctx, argv[0], argv[1], &idx, 0);
|
||||
if (!p)
|
||||
return JS_EXCEPTION;
|
||||
size_log2 = typed_array_size_log2(p->class_id);
|
||||
if (size_log2 == 3) {
|
||||
ret = JS_ToBigIntFree(ctx, JS_DupValue(ctx, argv[2]));
|
||||
if (JS_IsException(ret))
|
||||
@ -59264,6 +59248,8 @@ static JSValue js_atomics_store(JSContext *ctx,
|
||||
if (idx >= p->u.array.count)
|
||||
return JS_ThrowRangeError(ctx, "out-of-bound access");
|
||||
|
||||
ptr = p->u.array.u.uint8_ptr + ((uintptr_t)idx << size_log2);
|
||||
|
||||
switch(size_log2) {
|
||||
case 0:
|
||||
atomic_store((_Atomic(uint8_t) *)ptr, v);
|
||||
@ -59352,8 +59338,10 @@ static JSValue js_atomics_wait(JSContext *ctx,
|
||||
JSValueConst this_obj,
|
||||
int argc, JSValueConst *argv)
|
||||
{
|
||||
JSObject *p;
|
||||
int64_t v;
|
||||
int32_t v32;
|
||||
uint64_t idx;
|
||||
void *ptr;
|
||||
int64_t timeout;
|
||||
struct timespec ts;
|
||||
@ -59361,9 +59349,12 @@ static JSValue js_atomics_wait(JSContext *ctx,
|
||||
int ret, size_log2, res;
|
||||
double d;
|
||||
|
||||
if (js_atomics_get_ptr(ctx, &ptr, NULL, NULL, &size_log2, NULL,
|
||||
argv[0], argv[1], 2))
|
||||
p = js_atomics_get_buf(ctx, argv[0], argv[1], &idx, 2);
|
||||
if (!p)
|
||||
return JS_EXCEPTION;
|
||||
size_log2 = typed_array_size_log2(p->class_id);
|
||||
ptr = p->u.array.u.uint8_ptr + ((uintptr_t)idx << size_log2);
|
||||
|
||||
/* 'argv[0]' is a SharedArrayBuffer so it cannot be detached nor reduced */
|
||||
if (size_log2 == 3) {
|
||||
if (JS_ToBigInt64(ctx, &v, argv[2]))
|
||||
@ -59437,13 +59428,17 @@ static JSValue js_atomics_notify(JSContext *ctx,
|
||||
{
|
||||
struct list_head *el, *el1, waiter_list;
|
||||
int32_t count, n;
|
||||
uint64_t idx;
|
||||
int size_log2;
|
||||
void *ptr;
|
||||
JSAtomicsWaiter *waiter;
|
||||
JSArrayBuffer *abuf;
|
||||
JSObject *p;
|
||||
|
||||
if (js_atomics_get_ptr(ctx, &ptr, &p, NULL, NULL, NULL, argv[0], argv[1], 1))
|
||||
p = js_atomics_get_buf(ctx, argv[0], argv[1], &idx, 1);
|
||||
if (!p)
|
||||
return JS_EXCEPTION;
|
||||
size_log2 = typed_array_size_log2(p->class_id);
|
||||
|
||||
if (JS_IsUndefined(argv[2])) {
|
||||
count = INT32_MAX;
|
||||
@ -59456,6 +59451,7 @@ static JSValue js_atomics_notify(JSContext *ctx,
|
||||
abuf = p->u.typed_array->buffer->u.array_buffer;
|
||||
if (abuf->shared && count > 0) {
|
||||
/* 'argv[0]' is a SharedArrayBuffer so it cannot be detached nor reduced */
|
||||
ptr = p->u.array.u.uint8_ptr + ((uintptr_t)idx << size_log2);
|
||||
pthread_mutex_lock(&js_atomics_mutex);
|
||||
init_list_head(&waiter_list);
|
||||
list_for_each_safe(el, el1, &js_atomics_waiter_list) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user