diff --git a/quickjs.c b/quickjs.c index f000ff74e..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) @@ -53439,6 +53453,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..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); @@ -845,8 +846,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,