From 2df2bcf9082c4e020eac0095c354444382c3107c Mon Sep 17 00:00:00 2001 From: Dmitry Volyntsev Date: Wed, 8 May 2024 14:38:34 -0700 Subject: [PATCH 1/2] Add `JS_GetTypedArray()` --- quickjs.c | 26 ++++++++++++++++++++++++++ quickjs.h | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/quickjs.c b/quickjs.c index f000ff74e..bf5989d29 100644 --- a/quickjs.c +++ b/quickjs.c @@ -53439,6 +53439,32 @@ JSValue JS_NewTypedArray(JSContext *ctx, int argc, JSValueConst *argv, JS_CLASS_UINT8C_ARRAY + type); } +/* Return value is -1 for proxy errors, 0 if `obj` is not a typed array, + 1 if it is a typed array. + The structure pointed to by `desc` is filled on success unless `desc` + is a null pointer. */ +int JS_GetTypedArray(JSContext *ctx, JSValueConst obj, + JSTypedArrayDescriptor *desc) +{ + int class_id; + JSObject *p; + + if (js_resolve_proxy(ctx, &obj, TRUE)) + return -1; + if (JS_VALUE_GET_TAG(obj) != JS_TAG_OBJECT) + return 0; + p = JS_VALUE_GET_OBJ(obj); + class_id = p->class_id; + if (class_id < JS_CLASS_UINT8C_ARRAY || class_id > JS_CLASS_FLOAT64_ARRAY) + return 0; + if (desc) { + desc->type = JS_TYPED_ARRAY_UINT8C + (class_id - JS_CLASS_UINT8C_ARRAY); + desc->length = p->u.typed_array->length; + desc->data = p->u.array.u.ptr; + } + return 1; +} + /* Return the buffer associated to the typed array or an exception if it is not a typed array or if the buffer is detached. pbyte_offset, pbyte_length or pbytes_per_element can be NULL. */ diff --git a/quickjs.h b/quickjs.h index edc7b47b3..84a7e0b1c 100644 --- a/quickjs.h +++ b/quickjs.h @@ -845,8 +845,40 @@ typedef enum JSTypedArrayEnum { JS_TYPED_ARRAY_FLOAT64, } JSTypedArrayEnum; +static inline int JS_BytesPerElement(JSTypedArrayEnum type) +{ + switch (type) { + case JS_TYPED_ARRAY_UINT8C: + case JS_TYPED_ARRAY_INT8: + case JS_TYPED_ARRAY_UINT8: + return 1; + case JS_TYPED_ARRAY_INT16: + case JS_TYPED_ARRAY_UINT16: + return 2; + case JS_TYPED_ARRAY_INT32: + case JS_TYPED_ARRAY_UINT32: + case JS_TYPED_ARRAY_FLOAT32: + return 4; + default: + return 8; + } +} + JSValue JS_NewTypedArray(JSContext *ctx, int argc, JSValueConst *argv, JSTypedArrayEnum array_type); + +typedef struct JSTypedArrayDescriptor { + JSTypedArrayEnum type; + size_t length; + void *data; +} JSTypedArrayDescriptor; + +/* Return value is -1 for proxy errors, 0 if `obj` is not a typed array, + 1 if it is a typed array. + The structure pointed to by `desc` is filled on success unless `desc` + is a null pointer. */ +int JS_GetTypedArray(JSContext *ctx, JSValueConst obj, + JSTypedArrayDescriptor *desc); JSValue JS_GetTypedArrayBuffer(JSContext *ctx, JSValueConst obj, size_t *pbyte_offset, size_t *pbyte_length, From 696fadb3d5583854d4b5bb490f9237b82a32e241 Mon Sep 17 00:00:00 2001 From: Dmitry Volyntsev Date: Wed, 8 May 2024 15:01:35 -0700 Subject: [PATCH 2/2] Add `JS_IsArrayBuffer()` Unlike JS_GetArrayBuffer() it does not throw an exception if `val` is not an array buffer. --- quickjs.c | 14 ++++++++++++++ quickjs.h | 1 + 2 files changed, 15 insertions(+) diff --git a/quickjs.c b/quickjs.c index bf5989d29..702c4d38e 100644 --- a/quickjs.c +++ b/quickjs.c @@ -53074,6 +53074,20 @@ JSValue JS_NewArrayBufferCopy(JSContext *ctx, const uint8_t *buf, size_t len) TRUE); } +/* return -1 if exception (proxy case) or TRUE/FALSE */ +int JS_IsArrayBuffer(JSContext *ctx, JSValueConst val) +{ + JSObject *p; + + if (js_resolve_proxy(ctx, &val, TRUE)) + return -1; + if (JS_VALUE_GET_TAG(val) != JS_TAG_OBJECT) + return FALSE; + p = JS_VALUE_GET_OBJ(val); + return p->class_id == JS_CLASS_ARRAY_BUFFER || + p->class_id == JS_CLASS_SHARED_ARRAY_BUFFER; +} + static JSValue js_array_buffer_constructor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv) diff --git a/quickjs.h b/quickjs.h index 84a7e0b1c..f608b5cbb 100644 --- a/quickjs.h +++ b/quickjs.h @@ -828,6 +828,7 @@ JSValue JS_NewArrayBuffer(JSContext *ctx, uint8_t *buf, size_t len, JSFreeArrayBufferDataFunc *free_func, void *opaque, JS_BOOL is_shared); JSValue JS_NewArrayBufferCopy(JSContext *ctx, const uint8_t *buf, size_t len); +int JS_IsArrayBuffer(JSContext *ctx, JSValueConst val); void JS_DetachArrayBuffer(JSContext *ctx, JSValueConst obj); uint8_t *JS_GetArrayBuffer(JSContext *ctx, size_t *psize, JSValueConst obj);