rm notion of object values
This commit is contained in:
@@ -163,8 +163,6 @@ DEF( gosub, 5, 0, 0, label) /* used to execute the finally block */
|
||||
DEF( ret, 1, 1, 0, none) /* used to return from the finally block */
|
||||
DEF( nip_catch, 1, 2, 1, none) /* catch ... a -> a */
|
||||
|
||||
DEF( to_object, 1, 1, 1, none)
|
||||
//DEF( to_string, 1, 1, 1, none)
|
||||
DEF( to_propkey, 1, 1, 1, none)
|
||||
|
||||
DEF( make_loc_ref, 7, 0, 2, key_u16)
|
||||
|
||||
113
source/quickjs.c
113
source/quickjs.c
@@ -213,8 +213,7 @@ static inline JS_BOOL JS_VALUE_IS_NUMBER (JSValue v) {
|
||||
are defined after JSContext (they need its fields) */
|
||||
|
||||
/* Forward declarations for memory functions (now declared in quickjs.h) */
|
||||
/* js_realloc2 is internal only */
|
||||
static void *js_realloc2 (JSContext *ctx, void *ptr, size_t size, size_t *pslack);
|
||||
void *js_realloc (JSContext *ctx, void *ptr, size_t size);
|
||||
|
||||
/* Forward declaration for string_get */
|
||||
static inline int string_get (const JSText *p, int idx);
|
||||
@@ -938,7 +937,7 @@ static int st_text_resize (JSContext *ctx) {
|
||||
}
|
||||
|
||||
/* Realloc with slack reporting (for bump allocator) */
|
||||
static void *js_realloc2 (JSContext *ctx, void *ptr, size_t size, size_t *pslack) {
|
||||
void *js_realloc (JSContext *ctx, void *ptr, size_t size) {
|
||||
void *new_ptr;
|
||||
|
||||
/* Align size to 8 bytes */
|
||||
@@ -948,7 +947,6 @@ static void *js_realloc2 (JSContext *ctx, void *ptr, size_t size, size_t *pslack
|
||||
/* New allocation */
|
||||
new_ptr = js_malloc (ctx, size);
|
||||
if (!new_ptr) return NULL;
|
||||
*pslack = 0;
|
||||
return new_ptr;
|
||||
}
|
||||
|
||||
@@ -959,7 +957,6 @@ static void *js_realloc2 (JSContext *ctx, void *ptr, size_t size, size_t *pslack
|
||||
|
||||
/* Copy old data (caller ensures safety) */
|
||||
memcpy (new_ptr, ptr, size);
|
||||
*pslack = 0;
|
||||
return new_ptr;
|
||||
}
|
||||
|
||||
@@ -1640,11 +1637,9 @@ static blob *js_get_blob (JSContext *ctx, JSValue val);
|
||||
static JSValue js_new_string8_len (JSContext *ctx, const char *buf, int len);
|
||||
static JSValue js_compile_regexp (JSContext *ctx, JSValue pattern, JSValue flags);
|
||||
static JSValue js_regexp_constructor_internal (JSContext *ctx, JSValue pattern, JSValue bc);
|
||||
static void gc_decref (JSRuntime *rt);
|
||||
static int JS_NewClass1 (JSRuntime *rt, JSClassID class_id, const JSClassDef *class_def, const char *name);
|
||||
|
||||
static BOOL js_strict_eq (JSContext *ctx, JSValue op1, JSValue op2);
|
||||
static JSValue JS_ToObject (JSContext *ctx, JSValue val);
|
||||
static JSValue js_cell_text (JSContext *ctx, JSValue this_val, int argc, JSValue *argv);
|
||||
static JSValue js_cell_push (JSContext *ctx, JSValue this_val, int argc, JSValue *argv);
|
||||
static JSValue js_cell_pop (JSContext *ctx, JSValue this_val, int argc, JSValue *argv);
|
||||
@@ -1723,48 +1718,13 @@ void js_free (JSContext *ctx, void *ptr) {
|
||||
(void)ptr;
|
||||
}
|
||||
|
||||
/* Throw out of memory in case of error */
|
||||
void *js_realloc (JSContext *ctx, void *ptr, size_t size) {
|
||||
if (!ptr) return js_malloc (ctx, size);
|
||||
if (size == 0) {
|
||||
js_free (ctx, ptr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Bump allocator: allocate new space and copy */
|
||||
void *new_ptr = js_malloc (ctx, size);
|
||||
if (!new_ptr) return NULL;
|
||||
|
||||
/* Copy old data - we don't know old size, so copy up to new size */
|
||||
/* Caller must ensure this is safe */
|
||||
memcpy (new_ptr, ptr, size);
|
||||
return new_ptr;
|
||||
}
|
||||
|
||||
/* Throw out of memory exception in case of error */
|
||||
char *js_strndup (JSContext *ctx, const char *s, size_t n) {
|
||||
char *ptr;
|
||||
ptr = js_malloc (ctx, n + 1);
|
||||
if (ptr) {
|
||||
memcpy (ptr, s, n);
|
||||
ptr[n] = '\0';
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
char *js_strdup (JSContext *ctx, const char *str) {
|
||||
return js_strndup (ctx, str, strlen (str));
|
||||
}
|
||||
|
||||
static no_inline int js_realloc_array (JSContext *ctx, void **parray, int elem_size, int *psize, int req_size) {
|
||||
int new_size;
|
||||
size_t slack;
|
||||
void *new_array;
|
||||
/* XXX: potential arithmetic overflow */
|
||||
new_size = max_int (req_size, *psize * 3 / 2);
|
||||
new_array = js_realloc2 (ctx, *parray, new_size * elem_size, &slack);
|
||||
new_array = js_realloc (ctx, *parray, new_size * elem_size);
|
||||
if (!new_array) return -1;
|
||||
new_size += slack / elem_size;
|
||||
*psize = new_size;
|
||||
*parray = new_array;
|
||||
return 0;
|
||||
@@ -2717,10 +2677,9 @@ static no_inline JSText *pretext_realloc (JSContext *ctx, JSText *s, int new_len
|
||||
|
||||
/* JSText stores UTF-32 packed into uint64_t (2 chars per word). */
|
||||
size_t new_size_bytes = sizeof (JSText) + ((new_cap + 1) / 2) * sizeof (uint64_t);
|
||||
size_t slack;
|
||||
JSText *new_str = js_realloc2 (ctx, s, new_size_bytes, &slack);
|
||||
JSText *new_str = js_realloc (ctx, s, new_size_bytes);
|
||||
if (!new_str) return NULL;
|
||||
new_cap = min_int (new_cap + (int)(slack / sizeof (uint64_t)) * 2, JS_STRING_LEN_MAX);
|
||||
new_cap = min_int (new_cap, JS_STRING_LEN_MAX);
|
||||
objhdr_set_cap56 (&new_str->hdr, new_cap);
|
||||
return new_str;
|
||||
}
|
||||
@@ -3425,7 +3384,6 @@ static int js_intrinsic_array_set (JSContext *ctx, JSArray *arr, uint32_t idx, J
|
||||
|
||||
/* Allocate intrinsic function (JS_TAG_FUNCTION) */
|
||||
static JSValue js_new_function (JSContext *ctx, JSFunctionKind kind) {
|
||||
(void)ctx->rt; /* unused with copying GC */
|
||||
JSFunction *func = js_mallocz (ctx, sizeof (JSFunction));
|
||||
if (!func) return JS_EXCEPTION;
|
||||
func->header = objhdr_make (0, OBJ_FUNCTION, false, false, false, false);
|
||||
@@ -4620,9 +4578,8 @@ int JS_DeleteProperty (JSContext *ctx, JSValue obj, JSValue prop) {
|
||||
return TRUE; /* property not found = deletion succeeded */
|
||||
}
|
||||
|
||||
BOOL JS_IsCFunction (JSContext *ctx, JSValue val, JSCFunction *func, int magic) {
|
||||
BOOL JS_IsCFunction (JSValue val, JSCFunction *func, int magic) {
|
||||
JSFunction *f;
|
||||
(void)ctx; /* unused */
|
||||
if (JS_VALUE_GET_TAG (val) != JS_TAG_FUNCTION) return FALSE;
|
||||
f = JS_VALUE_GET_FUNCTION (val);
|
||||
if (f->kind == JS_FUNC_KIND_C)
|
||||
@@ -8251,14 +8208,6 @@ restart:
|
||||
}
|
||||
BREAK;
|
||||
|
||||
CASE (OP_to_object) : if (JS_VALUE_GET_TAG (sp[-1]) != JS_TAG_PTR) {
|
||||
sf->cur_pc = pc;
|
||||
ret_val = JS_ToObject (ctx, sp[-1]);
|
||||
if (JS_IsException (ret_val)) goto exception;
|
||||
sp[-1] = ret_val;
|
||||
}
|
||||
BREAK;
|
||||
|
||||
CASE (OP_to_propkey) : switch (JS_VALUE_GET_TAG (sp[-1])) {
|
||||
case JS_TAG_INT:
|
||||
case JS_TAG_STRING:
|
||||
@@ -10568,19 +10517,17 @@ static int push_scope (JSParseState *s) {
|
||||
/* XXX: should check for scope overflow */
|
||||
if ((fd->scope_count + 1) > fd->scope_size) {
|
||||
int new_size;
|
||||
size_t slack;
|
||||
JSVarScope *new_buf;
|
||||
/* XXX: potential arithmetic overflow */
|
||||
new_size = max_int (fd->scope_count + 1, fd->scope_size * 3 / 2);
|
||||
if (fd->scopes == fd->def_scope_array) {
|
||||
new_buf = js_realloc2 (s->ctx, NULL, new_size * sizeof (*fd->scopes), &slack);
|
||||
new_buf = js_realloc (s->ctx, NULL, new_size * sizeof (*fd->scopes));
|
||||
if (!new_buf) return -1;
|
||||
memcpy (new_buf, fd->scopes, fd->scope_count * sizeof (*fd->scopes));
|
||||
} else {
|
||||
new_buf = js_realloc2 (s->ctx, fd->scopes, new_size * sizeof (*fd->scopes), &slack);
|
||||
new_buf = js_realloc (s->ctx, fd->scopes, new_size * sizeof (*fd->scopes));
|
||||
if (!new_buf) return -1;
|
||||
}
|
||||
new_size += slack / sizeof (*new_buf);
|
||||
fd->scopes = new_buf;
|
||||
fd->scope_size = new_size;
|
||||
}
|
||||
@@ -11602,8 +11549,7 @@ static int js_parse_destructuring_element (JSParseState *s, int tok, int is_arg,
|
||||
assign_addr = s->cur_func->byte_code.size;
|
||||
if (s->token.val == '{') {
|
||||
if (next_token (s)) return -1;
|
||||
/* throw an exception if the value cannot be converted to an object */
|
||||
emit_op (s, OP_to_object);
|
||||
/* XXX: throw an exception if the value cannot be converted to an object */
|
||||
while (s->token.val != '}') {
|
||||
int prop_type;
|
||||
prop_type = js_parse_property_name (s, &prop_name, FALSE, TRUE);
|
||||
@@ -17064,7 +17010,7 @@ static __exception int js_parse_function_decl2 (JSParseState *s,
|
||||
/* the end of the function source code is after the last
|
||||
token of the function source stored into s->last_ptr */
|
||||
fd->source_len = s->last_ptr - ptr;
|
||||
fd->source = js_strndup (ctx, (const char *)ptr, fd->source_len);
|
||||
fd->source = strndup ((const char *)ptr, fd->source_len);
|
||||
if (!fd->source) goto fail;
|
||||
}
|
||||
goto done;
|
||||
@@ -17084,7 +17030,7 @@ static __exception int js_parse_function_decl2 (JSParseState *s,
|
||||
if (!fd->strip_source) {
|
||||
/* save the function source code */
|
||||
fd->source_len = s->buf_ptr - ptr;
|
||||
fd->source = js_strndup (ctx, (const char *)ptr, fd->source_len);
|
||||
fd->source = strndup ((const char *)ptr, fd->source_len);
|
||||
if (!fd->source) goto fail;
|
||||
}
|
||||
|
||||
@@ -17517,7 +17463,6 @@ static const char *const bc_tag_str[] = {
|
||||
"template",
|
||||
"function",
|
||||
"module",
|
||||
"ObjectValue",
|
||||
"ObjectReference",
|
||||
};
|
||||
#endif
|
||||
@@ -18479,20 +18424,6 @@ fail:
|
||||
return JS_EXCEPTION;
|
||||
}
|
||||
|
||||
static JSValue JS_ReadObjectValue (BCReaderState *s) {
|
||||
JSContext *ctx = s->ctx;
|
||||
JSValue val, obj = JS_NULL;
|
||||
|
||||
val = JS_ReadObjectRec (s);
|
||||
if (JS_IsException (val)) goto fail;
|
||||
obj = JS_ToObject (ctx, val);
|
||||
if (JS_IsException (obj)) goto fail;
|
||||
if (BC_add_object_ref (s, obj)) goto fail;
|
||||
return obj;
|
||||
fail:
|
||||
return JS_EXCEPTION;
|
||||
}
|
||||
|
||||
static JSValue JS_ReadObjectRec (BCReaderState *s) {
|
||||
JSContext *ctx = s->ctx;
|
||||
uint8_t tag;
|
||||
@@ -18541,9 +18472,6 @@ static JSValue JS_ReadObjectRec (BCReaderState *s) {
|
||||
case BC_TAG_TEMPLATE_OBJECT:
|
||||
obj = JS_ReadArray (s, tag);
|
||||
break;
|
||||
case BC_TAG_OBJECT_VALUE:
|
||||
obj = JS_ReadObjectValue (s);
|
||||
break;
|
||||
case BC_TAG_OBJECT_REFERENCE: {
|
||||
uint32_t val;
|
||||
if (!s->allow_reference)
|
||||
@@ -18694,23 +18622,6 @@ int JS_SetPropertyFunctionList (JSContext *ctx, JSValue obj, const JSCFunctionLi
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Object class */
|
||||
|
||||
static JSValue JS_ToObject (JSContext *ctx, JSValue val) {
|
||||
int tag = JS_VALUE_GET_NORM_TAG (val);
|
||||
|
||||
switch (tag) {
|
||||
case JS_TAG_PTR:
|
||||
case JS_TAG_EXCEPTION:
|
||||
return val;
|
||||
default:
|
||||
/* Primitives cannot be converted to objects - no boxing */
|
||||
return JS_ThrowTypeError (ctx, "cannot convert to record");
|
||||
}
|
||||
}
|
||||
|
||||
/* Function class */
|
||||
|
||||
static __exception int js_get_length32 (JSContext *ctx, uint32_t *pres, JSValue obj) {
|
||||
int tag = JS_VALUE_GET_TAG (obj);
|
||||
|
||||
@@ -19540,7 +19451,7 @@ static int js_is_standard_regexp (JSContext *ctx, JSValue rx) {
|
||||
val = JS_GetProperty (ctx, rx, JS_KEY_exec);
|
||||
if (JS_IsException (val)) return -1;
|
||||
// rx.exec === RE_exec
|
||||
res = JS_IsCFunction (ctx, val, js_regexp_exec, 0);
|
||||
res = JS_IsCFunction (val, js_regexp_exec, 0);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user