diff --git a/.clang-format b/.clang-format index c43c9290..a542d474 100644 --- a/.clang-format +++ b/.clang-format @@ -10,6 +10,7 @@ AllowShortFunctionsOnASingleLine: true AllowShortBlocksOnASingleLine: true AllowShortIfStatementsOnASingleLine: true BreakBeforeBraces: Attach +ColumnLimit: 0 # --- Fix the "static T\nname(...)" style --- AlwaysBreakAfterDefinitionReturnType: None diff --git a/source/quickjs.c b/source/quickjs.c index 3224b094..a35064fe 100644 --- a/source/quickjs.c +++ b/source/quickjs.c @@ -310,8 +310,6 @@ typedef enum JSErrorEnum { /* Forward declaration for bytecode freeing */ struct JSFunctionBytecode; -static void free_function_bytecode (JSRuntime *rt, - struct JSFunctionBytecode *b); #define JS_VALUE_GET_ARRAY(v) ((JSArray*)JS_VALUE_GET_PTR(v)) #define JS_VALUE_GET_OBJ(v) ((JSRecord *)JS_VALUE_GET_PTR (v)) @@ -505,7 +503,7 @@ typedef struct JSRecord { // slot[0].value = opaque c object from class id } JSRecord; -typedef struct JSFunction { +/*typedef struct JSFunction { objdr_t hdr; JSCode *code; JSFrame *outer; @@ -527,7 +525,7 @@ typedef struct JSCode { word_t entry_point; uint8_t *bytecode; }; - +*/ /* ============================================================ Record key helpers (JSValue keys) ============================================================ */ @@ -940,13 +938,6 @@ typedef struct JSRegExp { * share layout) */ #define JS_OBJ_GET_PROTO(p) ((JSRecord *)((JSRecord *)(p))->proto) -/* Check if a JSValue is a JSRecord */ -static inline JS_BOOL JS_VALUE_IS_RECORD (JSValue v) { - if (!JS_IsPtr (v)) return FALSE; - return ((JSGCObjectHeader *)JS_VALUE_GET_PTR (v))->gc_obj_type - == JS_GC_OBJ_TYPE_RECORD; -} - /* Initial capacity for new records (mask = 7, 8 slots total) */ #define JS_RECORD_INITIAL_MASK 7 @@ -1147,7 +1138,6 @@ static int rec_resize (JSContext *ctx, JSRecord *rec, uint64_t new_mask) { /* Set own property on record, returns 0 on success, -1 on error */ static int rec_set_own (JSContext *ctx, JSRecord *rec, JSValue k, JSValue val) { if (rec_key_is_empty (k) || rec_key_is_tomb (k)) { - JS_FreeValue (ctx, val); return -1; } @@ -1155,7 +1145,6 @@ static int rec_set_own (JSContext *ctx, JSRecord *rec, JSValue k, JSValue val) { if (slot > 0) { /* Existing key - replace value */ - JS_FreeValue (ctx, rec->tab[slot].val); rec->tab[slot].val = val; return 0; } @@ -1198,10 +1187,7 @@ static JSRecord *js_new_record_class (JSContext *ctx, uint32_t initial_mask, JSRecord *rec = js_malloc(ctx, total_size); if (!rec) return NULL; - rec->header.ref_count = 1; - rec->header.gc_obj_type = JS_GC_OBJ_TYPE_RECORD; - rec->mist_hdr - = objhdr_make (initial_mask, OBJ_RECORD, false, false, false, false); + rec->hdr = objhdr_make (initial_mask, OBJ_RECORD, false, false, false, false); rec->shape = NULL; rec->proto = NULL; rec->len = 0; @@ -1224,10 +1210,6 @@ static JSRecord *js_new_record (JSContext *ctx, uint32_t initial_mask) { return js_new_record_class (ctx, initial_mask, JS_CLASS_OBJECT); } -/* Forward declaration for remove_gc_object */ -static void remove_gc_object (JSGCObjectHeader *h); - - typedef enum { JS_FUNC_KIND_C, JS_FUNC_KIND_BYTECODE, @@ -1236,7 +1218,7 @@ typedef enum { } JSFunctionKind; typedef struct JSFunction { - JSGCObjectHeader header; /* must come first */ + objhdr_t header; /* must come first */ JSValue name; /* function name as JSValue text */ uint16_t length; /* arity: max allowed arguments */ uint8_t kind; @@ -1257,78 +1239,6 @@ typedef struct JSFunction { } u; } JSFunction; -#define JS_VALUE_GET_ARRAY(v) ((JSArray *)JS_VALUE_GET_PTR (v)) -#define JS_VALUE_GET_FUNCTION(v) ((JSFunction *)JS_VALUE_GET_PTR (v)) - -/* ============================================================ - Pointer Type Checking Helpers - ============================================================ - With the new tagging system, JS_VALUE_GET_TAG returns JS_TAG_PTR - for all pointer types. To distinguish objects, arrays, functions, - etc., we check the gc_obj_type field in JSGCObjectHeader. - ============================================================ */ - -/* Check if value is a GC object (record, array, function, etc) */ -static inline JS_BOOL js_is_gc_object (JSValue v) { - return JS_IsPtr (v); -} - -/* Get gc_obj_type from a pointer JSValue */ -static inline JSGCObjectTypeEnum js_get_gc_type (JSValue v) { - return ((JSGCObjectHeader *)JS_VALUE_GET_PTR (v))->gc_obj_type; -} - -/* Check if value is a Record (JS_GC_OBJ_TYPE_RECORD) */ -static inline JS_BOOL js_is_record (JSValue v) { - if (!JS_IsPtr (v)) return FALSE; - return js_get_gc_type (v) == JS_GC_OBJ_TYPE_RECORD; -} - -/* Check if value is an Array (JS_GC_OBJ_TYPE_ARRAY) */ -static inline JS_BOOL js_is_array (JSValue v) { - if (!JS_IsPtr (v)) return FALSE; - return js_get_gc_type (v) == JS_GC_OBJ_TYPE_ARRAY; -} - -/* Check if value is a Function (JS_GC_OBJ_TYPE_FUNCTION) */ -static inline JS_BOOL js_is_function (JSValue v) { - if (!JS_IsPtr (v)) return FALSE; - return js_get_gc_type (v) == JS_GC_OBJ_TYPE_FUNCTION; -} - -/* Check if value is a FunctionBytecode (JS_GC_OBJ_TYPE_FUNCTION_BYTECODE) */ -static inline JS_BOOL js_is_function_bytecode (JSValue v) { - if (!JS_IsPtr (v)) return FALSE; - return js_get_gc_type (v) == JS_GC_OBJ_TYPE_FUNCTION_BYTECODE; -} - -/* Check if value is an "object" - record or array (can have properties set) */ -static inline JS_BOOL js_is_object (JSValue v) { - if (!JS_IsPtr (v)) return FALSE; - JSGCObjectTypeEnum t = js_get_gc_type (v); - return t == JS_GC_OBJ_TYPE_RECORD || t == JS_GC_OBJ_TYPE_ARRAY; -} - -/* Check if value is a callable (function) */ -static inline JS_BOOL js_is_callable (JSValue v) { - return js_is_function (v); -} - -/* Check if a JSValue is an intrinsic array (OBJ_ARRAY via gc_obj_type) */ -static inline JS_BOOL JS_VALUE_IS_INTRINSIC_ARRAY (JSValue v) { - return js_is_array (v); -} - -/* Public API: check if value is a function */ -JS_BOOL JS_IsFunction (JSValue v) { - return js_is_function (v); -} - -/* Public API: check if value is an object (record or array) */ -JS_BOOL JS_IsObject (JSValue v) { - return js_is_object (v); -} - typedef struct JSClosureVar { uint8_t is_local : 1; uint8_t is_arg : 1; @@ -1396,7 +1306,7 @@ typedef struct JSVarDef { #define PC2LINE_DIFF_PC_MAX ((255 - PC2LINE_OP_FIRST) / PC2LINE_RANGE) typedef struct JSFunctionBytecode { - JSGCObjectHeader header; /* must come first */ + objhdr_t header; /* must come first */ uint8_t js_mode; uint8_t has_prototype : 1; /* true if a prototype field is necessary */ uint8_t has_simple_parameter_list : 1; @@ -1509,7 +1419,6 @@ static void js_varref_object_finalizer (JSRuntime *rt, JSValue val); static void js_varref_object_gc_mark (JSRuntime *rt, JSValue val, JS_MarkFunc *mark_func); static JSValue js_new_function (JSContext *ctx, JSFunctionKind kind); -static void free_function (JSRuntime *rt, JSFunction *func); static void mark_function_children (JSRuntime *rt, JSFunction *func, JS_MarkFunc *mark_func); static void mark_function_children_decref (JSRuntime *rt, JSFunction *func); @@ -1520,7 +1429,7 @@ static void gc_decref_child (JSRuntime *rt, JSGCObjectHeader *p); Internal use only. */ int JS_SetPropertyInternal (JSContext *ctx, JSValue this_obj, JSValue prop, JSValue val) { - if (!js_is_object (this_obj)) { + if (!JS_IsRecord (this_obj)) { JS_FreeValue (ctx, val); return -1; } @@ -1776,7 +1685,6 @@ static JSValue js_key_from_string (JSContext *ctx, JSValue val) { } static JSClass const js_std_class_def[] = { - { "object", NULL, NULL }, /* JS_CLASS_OBJECT */ { "error", NULL, NULL }, /* JS_CLASS_ERROR */ { "regexp", js_regexp_finalizer, NULL }, /* JS_CLASS_REGEXP */ { "blob", NULL, NULL }, /* JS_CLASS_BLOB - registered separately */ @@ -2702,7 +2610,7 @@ JSClassID JS_NewClassID (JSClassID *pclass_id) { JSClassID JS_GetClassID (JSValue v) { JSRecord *rec; - if (!js_is_record (v)) return JS_INVALID_CLASS_ID; + if (!JS_IsRecord (v)) return JS_INVALID_CLASS_ID; rec = JS_VALUE_GET_RECORD (v); return rec->class_id; } @@ -3302,7 +3210,7 @@ static JSValue JS_ConcatString (JSContext *ctx, JSValue op1, JSValue op2) { } static JSRecord *get_proto_obj (JSValue proto_val) { - if (!js_is_record (proto_val)) + if (!JS_IsRecord (proto_val)) return NULL; else return JS_VALUE_GET_OBJ (proto_val); @@ -3315,7 +3223,7 @@ JSValue JS_NewObjectProtoClass (JSContext *ctx, JSValue proto_val, if (!rec) return JS_EXCEPTION; /* Set prototype if provided */ - if (js_is_record (proto_val)) { + if (JS_IsRecord (proto_val)) { rec->proto = JS_VALUE_GET_RECORD (proto_val); } @@ -3685,40 +3593,6 @@ static void mark_function_children_decref (JSRuntime *rt, JSFunction *func) { } } -static void free_gc_object (JSRuntime *rt, JSGCObjectHeader *gp) { - switch (gp->gc_obj_type) { - case JS_GC_OBJ_TYPE_RECORD: - free_record (rt, (JSRecord *)gp); - break; - case JS_GC_OBJ_TYPE_FUNCTION_BYTECODE: - free_function_bytecode (rt, (JSFunctionBytecode *)gp); - break; - case JS_GC_OBJ_TYPE_ARRAY: - free_array (rt, (JSArray *)gp); - break; - case JS_GC_OBJ_TYPE_FUNCTION: - free_function (rt, (JSFunction *)gp); - break; - default: - abort (); - } -} - -static void free_zero_refcount (JSRuntime *rt) { - struct list_head *el; - JSGCObjectHeader *p; - - rt->gc_phase = JS_GC_PHASE_DECREF; - for (;;) { - el = rt->gc_zero_ref_count_list.next; - if (el == &rt->gc_zero_ref_count_list) break; - p = list_entry (el, JSGCObjectHeader, link); - assert (p->ref_count == 0); - free_gc_object (rt, p); - } - rt->gc_phase = JS_GC_PHASE_NONE; -} - /* Compute memory used by various object types */ /* XXX: poor man's approach to handling multiply referenced objects */ typedef struct JSMemoryUsage_helper { @@ -4118,7 +3992,7 @@ fail: when dumping the stack trace or in debug print). */ static const char *get_prop_string (JSContext *ctx, JSValue obj, JSValue prop) { - if (!js_is_record (obj)) return NULL; + if (!JS_IsRecord (obj)) return NULL; JSRecord *rec = (JSRecord *)JS_VALUE_GET_OBJ (obj); int slot = rec_find_slot (rec, prop); @@ -4141,7 +4015,7 @@ static const char *get_prop_string (JSContext *ctx, JSValue obj, generation, we only look at simple 'name' properties containing a string. */ static const char *get_func_name (JSContext *ctx, JSValue func) { - if (!js_is_record (func)) return NULL; + if (!JS_IsRecord (func)) return NULL; JSRecord *rec = (JSRecord *)JS_VALUE_GET_OBJ (func); /* Create "name" key as immediate ASCII string */ @@ -4251,7 +4125,7 @@ static void build_backtrace (JSContext *ctx, JSValue error_obj, /* Note: it is important that no exception is returned by this function */ static BOOL is_backtrace_needed (JSContext *ctx, JSValue obj) { JSRecord *p; - if (!js_is_record (obj)) return FALSE; + if (!JS_IsRecord (obj)) return FALSE; p = JS_VALUE_GET_OBJ (obj); if (p->class_id != JS_CLASS_ERROR) return FALSE; /* Check if "stack" property already exists */ @@ -4437,7 +4311,7 @@ static inline __exception int js_poll_interrupts (JSContext *ctx) { /* Return an Object, JS_NULL or JS_EXCEPTION in case of exotic object. */ JSValue JS_GetPrototype (JSContext *ctx, JSValue obj) { JSValue val; - if (js_is_record (obj)) { + if (JS_IsRecord (obj)) { JSRecord *p; p = JS_VALUE_GET_OBJ (obj); p = JS_OBJ_GET_PROTO (p); @@ -4464,7 +4338,7 @@ JSValue JS_GetProperty (JSContext *ctx, JSValue obj, JSValue prop) { if (JS_IsNull (obj)) return JS_NULL; if (JS_IsException (obj)) return JS_EXCEPTION; - if (unlikely (!js_is_object (obj))) { + if (unlikely (!JS_IsRecord (obj))) { /* Primitives have no properties */ return JS_NULL; } @@ -4481,7 +4355,7 @@ JSValue JS_GetOwnPropertyNames (JSContext *ctx, JSValue obj) { uint32_t mask, count, i; JSValue arr; - if (!js_is_record (obj)) { + if (!JS_IsRecord (obj)) { JS_ThrowTypeErrorNotAnObject (ctx); return JS_EXCEPTION; } @@ -4524,7 +4398,7 @@ static int JS_GetOwnPropertyInternal (JSContext *ctx, } int JS_GetOwnProperty (JSContext *ctx, JSValue *desc, JSValue obj, JSValue prop) { - if (!js_is_record (obj)) { + if (!JS_IsRecord (obj)) { JS_ThrowTypeErrorNotAnObject (ctx); return -1; } @@ -4535,7 +4409,7 @@ int JS_GetOwnProperty (JSContext *ctx, JSValue *desc, JSValue obj, JSValue prop) int JS_HasProperty (JSContext *ctx, JSValue obj, JSValue prop) { JSRecord *p; int ret; - if (unlikely (!js_is_record (obj))) return FALSE; + if (unlikely (!JS_IsRecord (obj))) return FALSE; p = JS_VALUE_GET_OBJ (obj); for (;;) { /* JS_GetOwnPropertyInternal can free the prototype */ @@ -4593,7 +4467,7 @@ static JSValue JS_GetPropertyValue (JSContext *ctx, JSValue this_obj, /* Check for string property (immediate or heap) */ if (JS_IsText (prop)) { /* Intrinsic arrays don't support string keys */ - if (js_is_array (this_obj)) { + if (JS_IsArray (this_obj)) { JS_FreeValue (ctx, prop); return JS_NULL; } @@ -4606,9 +4480,9 @@ static JSValue JS_GetPropertyValue (JSContext *ctx, JSValue this_obj, } /* Handle object keys directly via objkey map */ - if (js_is_record (prop)) { + if (JS_IsRecord (prop)) { /* Intrinsic arrays don't support object keys */ - if (!js_is_record (this_obj)) { + if (!JS_IsRecord (this_obj)) { JS_FreeValue (ctx, prop); return JS_NULL; } @@ -4625,7 +4499,7 @@ static JSValue JS_GetPropertyValue (JSContext *ctx, JSValue this_obj, JSValue JS_SetPropertyNumber (JSContext *js, JSValue obj, int idx, JSValue val) { - if (!JS_VALUE_IS_INTRINSIC_ARRAY (obj)) { + if (!JS_IsArray (obj)) { JS_FreeValue (js, val); return JS_ThrowInternalError (js, "cannot set with a number on a non array"); @@ -4643,7 +4517,7 @@ JSValue JS_SetPropertyNumber (JSContext *js, JSValue obj, int idx, } JSValue JS_GetPropertyNumber (JSContext *js, JSValue obj, int idx) { - if (js_is_array (obj)) { + if (JS_IsArray (obj)) { JSArray *a = JS_VALUE_GET_ARRAY (obj); int len = a->len; if (idx < 0 || idx >= len) { return JS_NULL; } @@ -4728,7 +4602,7 @@ static int delete_property (JSContext *ctx, JSRecord *rec, JSValue key) { int JS_SetProperty (JSContext *ctx, JSValue this_obj, JSValue prop, JSValue val) { - if (!js_is_object (this_obj)) { + if (!JS_IsRecord (this_obj)) { JS_FreeValue (ctx, val); if (JS_IsNull (this_obj)) { JS_ThrowTypeError (ctx, "cannot set property of null"); @@ -4809,7 +4683,7 @@ static int JS_SetPropertyValue (JSContext *ctx, JSValue this_obj, JSValue prop, return JS_SetProperty (ctx, this_obj, key, val); } - if (js_is_record (prop)) { + if (JS_IsRecord (prop)) { JS_FreeValue (ctx, prop); return JS_SetProperty (ctx, this_obj, prop, val); } @@ -4821,8 +4695,8 @@ static int JS_SetPropertyValue (JSContext *ctx, JSValue this_obj, JSValue prop, /* Property access with JSValue key - supports object keys directly */ JSValue JS_GetPropertyKey (JSContext *ctx, JSValue this_obj, JSValue key) { - if (js_is_record (key)) { - if (!js_is_record (this_obj)) return JS_NULL; + if (JS_IsRecord (key)) { + if (!JS_IsRecord (this_obj)) return JS_NULL; JSRecord *rec = JS_VALUE_GET_RECORD (this_obj); return rec_get (ctx, rec, key); } @@ -4839,8 +4713,8 @@ JSValue JS_GetPropertyKey (JSContext *ctx, JSValue this_obj, JSValue key) { int JS_SetPropertyKey (JSContext *ctx, JSValue this_obj, JSValue key, JSValue val) { - if (js_is_record (key)) { - if (!js_is_record (this_obj)) { + if (JS_IsRecord (key)) { + if (!JS_IsRecord (this_obj)) { JS_FreeValue (ctx, val); JS_ThrowTypeError (ctx, "cannot set property on this value"); return -1; @@ -4866,8 +4740,8 @@ int JS_SetPropertyKey (JSContext *ctx, JSValue this_obj, JSValue key, /* Property existence check with JSValue key (supports object keys) */ int JS_HasPropertyKey (JSContext *ctx, JSValue obj, JSValue key) { - if (js_is_record (key)) { - if (!js_is_record (obj)) return FALSE; + if (JS_IsRecord (key)) { + if (!JS_IsRecord (obj)) return FALSE; JSRecord *rec = JS_VALUE_GET_RECORD (obj); /* Check own and prototype chain */ while (rec) { @@ -4889,8 +4763,8 @@ int JS_HasPropertyKey (JSContext *ctx, JSValue obj, JSValue key) { /* Property deletion with JSValue key (supports object keys) */ int JS_DeletePropertyKey (JSContext *ctx, JSValue obj, JSValue key) { - if (js_is_record (key)) { - if (!js_is_record (obj)) return FALSE; + if (JS_IsRecord (key)) { + if (!JS_IsRecord (obj)) return FALSE; JSRecord *rec = JS_VALUE_GET_RECORD (obj); if (obj_is_stone (rec)) { JS_ThrowTypeError (ctx, "cannot modify frozen object"); @@ -5141,7 +5015,7 @@ int JS_DeleteProperty (JSContext *ctx, JSValue obj, JSValue prop) { int slot; /* Arrays do not support property deletion */ - if (JS_VALUE_IS_INTRINSIC_ARRAY (obj)) { + if (JS_IsArray (obj)) { JS_ThrowTypeError (ctx, "cannot delete array element"); return -1; } @@ -5221,7 +5095,7 @@ void *JS_GetOpaque2 (JSContext *ctx, JSValue obj, JSClassID class_id) { void *JS_GetAnyOpaque (JSValue obj, JSClassID *class_id) { JSRecord *p; - if (!js_is_record (obj)) { + if (!JS_IsRecord (obj)) { *class_id = 0; return NULL; } @@ -5941,7 +5815,7 @@ static JSValue JS_ToStringFree (JSContext *ctx, JSValue val) { JSValue JS_ToPropertyKey (JSContext *ctx, JSValue val) { /* Objects are handled directly via objkey map, not through atoms */ - if (js_is_object (val)) { return JS_DupValue (ctx, val); } + if (JS_IsRecord (val)) { return JS_DupValue (ctx, val); } return JS_ToStringInternal (ctx, val, TRUE); } @@ -6476,7 +6350,7 @@ static __maybe_unused void JS_DumpGCObject (JSRuntime *rt, /* return -1 if exception (proxy case) or TRUE/FALSE */ int JS_IsArray (JSContext *ctx, JSValue val) { - return JS_VALUE_IS_INTRINSIC_ARRAY (val); + return JS_IsArray (val); } static double js_pow (double a, double b) { @@ -6927,7 +6801,7 @@ static JSValue js_throw_type_error (JSContext *ctx, JSValue this_val, int argc, static BOOL js_get_fast_array (JSContext *ctx, JSValue obj, JSValue **arrpp, uint32_t *countp) { /* Fast path for intrinsic arrays */ - if (JS_VALUE_IS_INTRINSIC_ARRAY (obj)) { + if (JS_IsArray (obj)) { JSArray *arr = JS_VALUE_GET_ARRAY (obj); *countp = arr->len; *arrpp = arr->values; @@ -19107,7 +18981,7 @@ static int JS_WriteObjectRec (BCWriterState *s, JSValue obj) { break; case JS_TAG_OBJECT: /* Check if this is an intrinsic array */ - if (JS_VALUE_IS_INTRINSIC_ARRAY (obj)) { + if (JS_IsArray (obj)) { JSArray *arr = JS_VALUE_GET_ARRAY (obj); uint32_t i; bc_put_u8 (s, BC_TAG_ARRAY); @@ -19995,7 +19869,7 @@ static __exception int js_get_length32 (JSContext *ctx, uint32_t *pres, int tag = JS_VALUE_GET_TAG (obj); /* Fast path for intrinsic arrays */ - if (JS_VALUE_IS_INTRINSIC_ARRAY (obj)) { + if (JS_IsArray (obj)) { JSArray *arr = JS_VALUE_GET_ARRAY (obj); *pres = arr->len; return 0; @@ -20031,7 +19905,7 @@ static __exception int js_get_length32 (JSContext *ctx, uint32_t *pres, static __exception int js_get_length64 (JSContext *ctx, int64_t *pres, JSValue obj) { /* Fast path for intrinsic arrays */ - if (JS_VALUE_IS_INTRINSIC_ARRAY (obj)) { + if (JS_IsArray (obj)) { JSArray *arr = JS_VALUE_GET_ARRAY (obj); *pres = arr->len; return 0; @@ -20064,7 +19938,7 @@ static JSValue *build_arg_list (JSContext *ctx, uint32_t *plen, JSValue *tab; /* Fast path for intrinsic arrays */ - if (JS_VALUE_IS_INTRINSIC_ARRAY (array_arg)) { + if (JS_IsArray (array_arg)) { JSArray *arr = JS_VALUE_GET_ARRAY (array_arg); len = arr->len; if (len > JS_MAX_LOCAL_VARS) { @@ -20102,7 +19976,7 @@ static JSValue js_function_apply (JSContext *ctx, JSValue this_val, int argc, return JS_Call (ctx, this_val, this_arg, 0, NULL); } /* Fast path: check arity before building arg list */ - if (JS_VALUE_IS_INTRINSIC_ARRAY (array_arg)) { + if (JS_IsArray (array_arg)) { JSArray *arr = JS_VALUE_GET_ARRAY (array_arg); if (unlikely (arr->len > f->length)) return JS_ThrowTypeError (ctx, "too many arguments"); @@ -25133,7 +25007,7 @@ static JSValue js_cell_push (JSContext *ctx, JSValue this_val, int argc, if (argc < 1) return JS_NULL; JSValue obj = argv[0]; - if (!JS_VALUE_IS_INTRINSIC_ARRAY (obj)) return JS_NULL; + if (!JS_IsArray (obj)) return JS_NULL; JSArray *arr = JS_VALUE_GET_ARRAY (obj); for (int i = 1; i < argc; i++) {