no more string class type
This commit is contained in:
418
source/quickjs.c
418
source/quickjs.c
@@ -172,17 +172,13 @@ enum {
|
||||
JS_CLASS_OBJECT = 1, /* must be first */
|
||||
JS_CLASS_ARRAY, /* u.array | length */
|
||||
JS_CLASS_ERROR,
|
||||
JS_CLASS_NUMBER, /* u.object_data */
|
||||
JS_CLASS_STRING, /* u.object_data */
|
||||
JS_CLASS_BOOLEAN, /* u.object_data */
|
||||
JS_CLASS_SYMBOL, /* u.object_data */
|
||||
JS_CLASS_C_FUNCTION, /* u.cfunc */
|
||||
JS_CLASS_BYTECODE_FUNCTION, /* u.func */
|
||||
JS_CLASS_BOUND_FUNCTION, /* u.bound_function */
|
||||
JS_CLASS_C_FUNCTION_DATA, /* u.c_function_data_record */
|
||||
JS_CLASS_REGEXP, /* u.regexp */
|
||||
JS_CLASS_FINALIZATION_REGISTRY,
|
||||
JS_CLASS_BLOB, /* u.opaque (blob *) */
|
||||
JS_CLASS_BLOB, /* u.opaque (blob *) */
|
||||
|
||||
JS_CLASS_INIT_COUNT, /* last entry for predefined classes */
|
||||
};
|
||||
@@ -591,9 +587,7 @@ typedef struct JSFunctionBytecode {
|
||||
uint8_t js_mode;
|
||||
uint8_t has_prototype : 1; /* true if a prototype field is necessary */
|
||||
uint8_t has_simple_parameter_list : 1;
|
||||
uint8_t is_derived_class_constructor : 1;
|
||||
uint8_t func_kind : 2;
|
||||
uint8_t new_target_allowed : 1;
|
||||
uint8_t has_debug : 1;
|
||||
uint8_t read_only_bytecode : 1;
|
||||
uint8_t is_direct_or_indirect_eval : 1; /* used by JS_GetScriptOrModuleName() */
|
||||
@@ -701,52 +695,6 @@ typedef struct JSRegExp {
|
||||
JSString *bytecode; /* also contains the flags */
|
||||
} JSRegExp;
|
||||
|
||||
typedef enum {
|
||||
/* binary operators */
|
||||
JS_OVOP_ADD,
|
||||
JS_OVOP_SUB,
|
||||
JS_OVOP_MUL,
|
||||
JS_OVOP_DIV,
|
||||
JS_OVOP_MOD,
|
||||
JS_OVOP_POW,
|
||||
JS_OVOP_OR,
|
||||
JS_OVOP_AND,
|
||||
JS_OVOP_XOR,
|
||||
JS_OVOP_SHL,
|
||||
JS_OVOP_SAR,
|
||||
JS_OVOP_SHR,
|
||||
JS_OVOP_LESS,
|
||||
|
||||
JS_OVOP_BINARY_COUNT,
|
||||
/* unary operators */
|
||||
JS_OVOP_POS = JS_OVOP_BINARY_COUNT,
|
||||
JS_OVOP_NEG,
|
||||
JS_OVOP_INC,
|
||||
JS_OVOP_DEC,
|
||||
JS_OVOP_NOT,
|
||||
|
||||
JS_OVOP_COUNT,
|
||||
} JSOverloadableOperatorEnum;
|
||||
|
||||
typedef struct {
|
||||
uint32_t operator_index;
|
||||
JSObject *ops[JS_OVOP_BINARY_COUNT]; /* self operators */
|
||||
} JSBinaryOperatorDefEntry;
|
||||
|
||||
typedef struct {
|
||||
int count;
|
||||
JSBinaryOperatorDefEntry *tab;
|
||||
} JSBinaryOperatorDef;
|
||||
|
||||
typedef struct {
|
||||
uint32_t operator_counter;
|
||||
BOOL is_primitive; /* OperatorSet for a primitive type */
|
||||
/* NULL if no operator is defined */
|
||||
JSObject *self_ops[JS_OVOP_COUNT]; /* self operators */
|
||||
JSBinaryOperatorDef left;
|
||||
JSBinaryOperatorDef right;
|
||||
} JSOperatorSetData;
|
||||
|
||||
typedef struct JSProperty {
|
||||
union {
|
||||
JSValue value; /* JS_PROP_NORMAL */
|
||||
@@ -830,18 +778,17 @@ struct JSObject {
|
||||
uint8_t cproto;
|
||||
int16_t magic;
|
||||
} cfunc;
|
||||
/* array part for fast arrays and typed arrays */
|
||||
struct { /* JS_CLASS_ARRAY, JS_CLASS_UINT8C_ARRAY..JS_CLASS_FLOAT64_ARRAY */
|
||||
/* array part for fast arrays */
|
||||
struct { /* JS_CLASS_ARRAY */
|
||||
union {
|
||||
uint32_t size; /* JS_CLASS_ARRAY */
|
||||
} u1;
|
||||
union {
|
||||
JSValue *values; /* JS_CLASS_ARRAY */
|
||||
} u;
|
||||
uint32_t count; /* <= 2^31-1. 0 for a detached typed array */
|
||||
uint32_t count; /* <= 2^31-1 */
|
||||
} array; /* 12/20 bytes */
|
||||
JSRegExp regexp; /* JS_CLASS_REGEXP: 8/16 bytes */
|
||||
JSValue object_data; /* for JS_SetObjectData(): 8/16/16 bytes */
|
||||
} u;
|
||||
};
|
||||
|
||||
@@ -927,8 +874,6 @@ static JSValue js_function_apply(JSContext *ctx, JSValueConst this_val,
|
||||
int argc, JSValueConst *argv, int magic);
|
||||
static void js_array_finalizer(JSRuntime *rt, JSValue val);
|
||||
static void js_array_mark(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func);
|
||||
static void js_object_data_finalizer(JSRuntime *rt, JSValue val);
|
||||
static void js_object_data_mark(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func);
|
||||
static void js_c_function_finalizer(JSRuntime *rt, JSValue val);
|
||||
static void js_c_function_mark(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func);
|
||||
static void js_bytecode_function_finalizer(JSRuntime *rt, JSValue val);
|
||||
@@ -940,10 +885,8 @@ static void js_bound_function_mark(JSRuntime *rt, JSValueConst val,
|
||||
static void js_regexp_finalizer(JSRuntime *rt, JSValue val);
|
||||
|
||||
#define HINT_STRING 0
|
||||
#define HINT_NUMBER 1
|
||||
#define HINT_NONE 2
|
||||
#define HINT_FORCE_ORDINARY (1 << 4) // don't try Symbol.toPrimitive
|
||||
static JSValue JS_ToPrimitiveFree(JSContext *ctx, JSValue val, int hint);
|
||||
static JSValue JS_ToStringFree(JSContext *ctx, JSValue val);
|
||||
static int JS_ToBoolFree(JSContext *ctx, JSValue val);
|
||||
static int JS_ToInt32Free(JSContext *ctx, int32_t *pres, JSValue val);
|
||||
@@ -1032,7 +975,6 @@ static JSValue js_regexp_toString(JSContext *ctx, JSValueConst this_val,
|
||||
static JSValue js_error_toString(JSContext *ctx, JSValueConst this_val,
|
||||
int argc, JSValueConst *argv);
|
||||
|
||||
static const JSClassExoticMethods js_string_exotic_methods;
|
||||
JSClassID js_class_id_alloc = JS_CLASS_INIT_COUNT;
|
||||
|
||||
static void js_trigger_gc(JSRuntime *rt, size_t size)
|
||||
@@ -1217,16 +1159,12 @@ typedef struct JSClassShortDef {
|
||||
static JSClassShortDef const js_std_class_def[] = {
|
||||
{ JS_ATOM_Object, NULL, NULL }, /* JS_CLASS_OBJECT */
|
||||
{ JS_ATOM_Array, js_array_finalizer, js_array_mark }, /* JS_CLASS_ARRAY */
|
||||
{ JS_ATOM_Error, NULL, NULL }, /* JS_CLASS_ERROR */
|
||||
{ JS_ATOM_Number, js_object_data_finalizer, js_object_data_mark }, /* JS_CLASS_NUMBER */
|
||||
{ JS_ATOM_String, js_object_data_finalizer, js_object_data_mark }, /* JS_CLASS_STRING */
|
||||
{ JS_ATOM_Boolean, js_object_data_finalizer, js_object_data_mark }, /* JS_CLASS_BOOLEAN */
|
||||
{ JS_ATOM_Symbol, js_object_data_finalizer, js_object_data_mark }, /* JS_CLASS_SYMBOL */
|
||||
{ JS_ATOM_Error, NULL, NULL }, /* JS_CLASS_ERROR */
|
||||
{ JS_ATOM_Function, js_c_function_finalizer, js_c_function_mark }, /* JS_CLASS_C_FUNCTION */
|
||||
{ JS_ATOM_Function, js_bytecode_function_finalizer, js_bytecode_function_mark }, /* JS_CLASS_BYTECODE_FUNCTION */
|
||||
{ JS_ATOM_Function, js_bound_function_finalizer, js_bound_function_mark }, /* JS_CLASS_BOUND_FUNCTION */
|
||||
{ JS_ATOM_Function, js_c_function_data_finalizer, js_c_function_data_mark }, /* JS_CLASS_C_FUNCTION_DATA */
|
||||
{ JS_ATOM_RegExp, js_regexp_finalizer, NULL }, /* JS_CLASS_REGEXP */
|
||||
{ JS_ATOM_RegExp, js_regexp_finalizer, NULL }, /* JS_CLASS_REGEXP */
|
||||
};
|
||||
|
||||
static int init_class_range(JSRuntime *rt, JSClassShortDef const *tab,
|
||||
@@ -1309,8 +1247,6 @@ JSRuntime *JS_NewRuntime2(const JSMallocFunctions *mf, void *opaque)
|
||||
if (init_class_range(rt, js_std_class_def, JS_CLASS_OBJECT,
|
||||
countof(js_std_class_def)) < 0)
|
||||
goto fail;
|
||||
rt->class_array[JS_CLASS_STRING].exotic = &js_string_exotic_methods;
|
||||
|
||||
rt->class_array[JS_CLASS_C_FUNCTION].call = js_call_c_function;
|
||||
rt->class_array[JS_CLASS_C_FUNCTION_DATA].call = js_c_function_data_call;
|
||||
rt->class_array[JS_CLASS_BOUND_FUNCTION].call = js_call_bound_function;
|
||||
@@ -4785,18 +4721,14 @@ static JSValue JS_NewObjectFromShape(JSContext *ctx, JSShape *sh, JSClassID clas
|
||||
case JS_CLASS_C_FUNCTION:
|
||||
p->prop[0].u.value = JS_NULL;
|
||||
break;
|
||||
case JS_CLASS_NUMBER:
|
||||
case JS_CLASS_STRING:
|
||||
case JS_CLASS_BOOLEAN:
|
||||
case JS_CLASS_SYMBOL:
|
||||
p->u.object_data = JS_NULL;
|
||||
goto set_exotic;
|
||||
case JS_CLASS_REGEXP:
|
||||
p->u.regexp.pattern = NULL;
|
||||
p->u.regexp.bytecode = NULL;
|
||||
goto set_exotic;
|
||||
if (ctx->rt->class_array[class_id].exotic) {
|
||||
p->is_exotic = 1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
set_exotic:
|
||||
if (ctx->rt->class_array[class_id].exotic) {
|
||||
p->is_exotic = 1;
|
||||
}
|
||||
@@ -4834,30 +4766,6 @@ JSValue JS_NewObjectProtoClass(JSContext *ctx, JSValueConst proto_val,
|
||||
return JS_NewObjectFromShape(ctx, sh, class_id);
|
||||
}
|
||||
|
||||
static int JS_SetObjectData(JSContext *ctx, JSValueConst obj, JSValue val)
|
||||
{
|
||||
JSObject *p;
|
||||
|
||||
if (JS_VALUE_GET_TAG(obj) == JS_TAG_OBJECT) {
|
||||
p = JS_VALUE_GET_OBJ(obj);
|
||||
switch(p->class_id) {
|
||||
case JS_CLASS_NUMBER:
|
||||
case JS_CLASS_STRING:
|
||||
case JS_CLASS_BOOLEAN:
|
||||
case JS_CLASS_SYMBOL:
|
||||
JS_FreeValue(ctx, p->u.object_data);
|
||||
p->u.object_data = val; /* for JS_CLASS_STRING, 'val' must
|
||||
be JS_TAG_STRING (and not a
|
||||
rope) */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
JS_FreeValue(ctx, val);
|
||||
if (!JS_IsException(obj))
|
||||
JS_ThrowTypeError(ctx, "invalid object type");
|
||||
return -1;
|
||||
}
|
||||
|
||||
JSValue JS_NewObjectClass(JSContext *ctx, int class_id)
|
||||
{
|
||||
return JS_NewObjectProtoClass(ctx, ctx->class_proto[class_id], class_id);
|
||||
@@ -5205,20 +5113,6 @@ static void js_array_mark(JSRuntime *rt, JSValueConst val,
|
||||
}
|
||||
}
|
||||
|
||||
static void js_object_data_finalizer(JSRuntime *rt, JSValue val)
|
||||
{
|
||||
JSObject *p = JS_VALUE_GET_OBJ(val);
|
||||
JS_FreeValueRT(rt, p->u.object_data);
|
||||
p->u.object_data = JS_NULL;
|
||||
}
|
||||
|
||||
static void js_object_data_mark(JSRuntime *rt, JSValueConst val,
|
||||
JS_MarkFunc *mark_func)
|
||||
{
|
||||
JSObject *p = JS_VALUE_GET_OBJ(val);
|
||||
JS_MarkValue(rt, p->u.object_data, mark_func);
|
||||
}
|
||||
|
||||
static void js_c_function_finalizer(JSRuntime *rt, JSValue val)
|
||||
{
|
||||
JSObject *p = JS_VALUE_GET_OBJ(val);
|
||||
@@ -5865,12 +5759,6 @@ void JS_ComputeMemoryUsage(JSRuntime *rt, JSMemoryUsage *s)
|
||||
}
|
||||
}
|
||||
break;
|
||||
case JS_CLASS_NUMBER: /* u.object_data */
|
||||
case JS_CLASS_STRING: /* u.object_data */
|
||||
case JS_CLASS_BOOLEAN: /* u.object_data */
|
||||
case JS_CLASS_SYMBOL: /* u.object_data */
|
||||
compute_value_size(p->u.object_data, hp);
|
||||
break;
|
||||
case JS_CLASS_C_FUNCTION: /* u.cfunc */
|
||||
s->c_func_count++;
|
||||
break;
|
||||
@@ -6895,21 +6783,6 @@ JSValue JS_GetPropertyInternal(JSContext *ctx, JSValueConst obj,
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t js_string_obj_get_length(JSContext *ctx,
|
||||
JSValueConst obj)
|
||||
{
|
||||
JSObject *p;
|
||||
uint32_t len = 0;
|
||||
|
||||
/* This is a class exotic method: obj class_id is JS_CLASS_STRING */
|
||||
p = JS_VALUE_GET_OBJ(obj);
|
||||
if (JS_VALUE_GET_TAG(p->u.object_data) == JS_TAG_STRING) {
|
||||
JSString *p1 = JS_VALUE_GET_STRING(p->u.object_data);
|
||||
len = p1->len;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
static int num_keys_cmp(const void *p1, const void *p2, void *opaque)
|
||||
{
|
||||
JSContext *ctx = opaque;
|
||||
@@ -7005,11 +6878,7 @@ static int __exception JS_GetOwnPropertyNamesInternal(JSContext *ctx,
|
||||
if (flags & JS_GPN_STRING_MASK) {
|
||||
num_keys_count += p->u.array.count;
|
||||
}
|
||||
} else if (p->class_id == JS_CLASS_STRING) {
|
||||
if (flags & JS_GPN_STRING_MASK) {
|
||||
num_keys_count += js_string_obj_get_length(ctx, JS_MKPTR(JS_TAG_OBJECT, p));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* fill them */
|
||||
@@ -7067,16 +6936,9 @@ static int __exception JS_GetOwnPropertyNamesInternal(JSContext *ctx,
|
||||
}
|
||||
|
||||
if (p->is_exotic) {
|
||||
int len;
|
||||
if (p->fast_array) {
|
||||
if (flags & JS_GPN_STRING_MASK) {
|
||||
len = p->u.array.count;
|
||||
goto add_array_keys;
|
||||
}
|
||||
} else if (p->class_id == JS_CLASS_STRING) {
|
||||
if (flags & JS_GPN_STRING_MASK) {
|
||||
len = js_string_obj_get_length(ctx, JS_MKPTR(JS_TAG_OBJECT, p));
|
||||
add_array_keys:
|
||||
int len = p->u.array.count;
|
||||
for(i = 0; i < len; i++) {
|
||||
tab_atom[num_index].atom = __JS_AtomFromUInt32(i);
|
||||
if (tab_atom[num_index].atom == JS_ATOM_NULL) {
|
||||
@@ -9180,32 +9042,6 @@ void *JS_GetAnyOpaque(JSValueConst obj, JSClassID *class_id)
|
||||
return p->u.opaque;
|
||||
}
|
||||
|
||||
static JSValue JS_ToPrimitiveFree(JSContext *ctx, JSValue val, int hint)
|
||||
{
|
||||
JSValue ret;
|
||||
|
||||
if (JS_VALUE_GET_TAG(val) != JS_TAG_OBJECT)
|
||||
return val;
|
||||
|
||||
hint &= ~HINT_FORCE_ORDINARY;
|
||||
|
||||
/* For string/default hint, use text() to convert */
|
||||
if (hint == HINT_STRING || hint == HINT_NONE) {
|
||||
ret = js_cell_text(ctx, JS_NULL, 1, (JSValueConst *)&val);
|
||||
JS_FreeValue(ctx, val);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* For number hint, objects cannot be converted */
|
||||
JS_FreeValue(ctx, val);
|
||||
return JS_ThrowTypeError(ctx, "cannot convert record to number");
|
||||
}
|
||||
|
||||
static JSValue JS_ToPrimitive(JSContext *ctx, JSValueConst val, int hint)
|
||||
{
|
||||
return JS_ToPrimitiveFree(ctx, JS_DupValue(ctx, val), hint);
|
||||
}
|
||||
|
||||
static int JS_ToBoolFree(JSContext *ctx, JSValue val)
|
||||
{
|
||||
uint32_t tag = JS_VALUE_GET_TAG(val);
|
||||
@@ -11579,7 +11415,6 @@ static JSValue js_call_bound_function(JSContext *ctx, JSValueConst func_obj,
|
||||
/* argument of OP_special_object */
|
||||
typedef enum {
|
||||
OP_SPECIAL_OBJECT_THIS_FUNC,
|
||||
OP_SPECIAL_OBJECT_NEW_TARGET,
|
||||
OP_SPECIAL_OBJECT_VAR_OBJECT,
|
||||
} OPSpecialObjectEnum;
|
||||
|
||||
@@ -12090,10 +11925,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
|
||||
case OP_SPECIAL_OBJECT_THIS_FUNC:
|
||||
*sp++ = JS_DupValue(ctx, sf->cur_func);
|
||||
break;
|
||||
case OP_SPECIAL_OBJECT_NEW_TARGET:
|
||||
/* new.target is always null (constructors not supported) */
|
||||
*sp++ = JS_NULL;
|
||||
break;
|
||||
case OP_SPECIAL_OBJECT_VAR_OBJECT:
|
||||
*sp++ = JS_NewObjectProto(ctx, JS_NULL);
|
||||
if (unlikely(JS_IsException(sp[-1])))
|
||||
@@ -14379,16 +14210,6 @@ static JSContext *JS_GetFunctionRealm(JSContext *ctx, JSValueConst func_obj)
|
||||
return realm;
|
||||
}
|
||||
|
||||
static JSValue js_create_from_ctor(JSContext *ctx, JSValueConst ctor,
|
||||
int class_id)
|
||||
{
|
||||
/* Simplified: always use the default class prototype */
|
||||
JSValue proto = JS_DupValue(ctx, ctx->class_proto[class_id]);
|
||||
JSValue obj = JS_NewObjectProtoClass(ctx, proto, class_id);
|
||||
JS_FreeValue(ctx, proto);
|
||||
return obj;
|
||||
}
|
||||
|
||||
JSValue JS_Invoke(JSContext *ctx, JSValueConst this_val, JSAtom atom,
|
||||
int argc, JSValueConst *argv)
|
||||
{
|
||||
@@ -14602,11 +14423,7 @@ typedef struct JSFunctionDef {
|
||||
BOOL has_parameter_expressions; /* if true, an argument scope is created */
|
||||
BOOL has_use_strict; /* to reject directive in special cases */
|
||||
BOOL has_eval_call; /* true if the function contains a call to eval() */
|
||||
BOOL has_this_binding; /* true if the 'this' and new.target binding are
|
||||
available in the function */
|
||||
BOOL new_target_allowed; /* true if the 'new.target' does not
|
||||
throw a syntax error */
|
||||
BOOL is_derived_class_constructor;
|
||||
BOOL has_this_binding; /* true if the 'this' binding is available in the function */
|
||||
BOOL in_function_body;
|
||||
JSParseFunctionEnum func_type : 8;
|
||||
uint8_t js_mode; /* bitmap of JS_MODE_x */
|
||||
@@ -14625,7 +14442,6 @@ typedef struct JSFunctionDef {
|
||||
if none, only used if is_func_expr is true) */
|
||||
int eval_ret_idx; /* variable containing the return value of the eval, -1 if none */
|
||||
int this_var_idx; /* variable containg the 'this' value, -1 if none */
|
||||
int new_target_var_idx; /* variable containg the 'new.target' value, -1 if none */
|
||||
int this_active_func_var_idx; /* variable containg the 'this.active_func' value, -1 if none */
|
||||
|
||||
int scope_level; /* index into fd->scopes if the current lexical scope */
|
||||
@@ -20172,7 +19988,6 @@ static JSFunctionDef *js_new_function_def(JSContext *ctx,
|
||||
fd->func_var_idx = -1;
|
||||
fd->eval_ret_idx = -1;
|
||||
fd->this_var_idx = -1;
|
||||
fd->new_target_var_idx = -1;
|
||||
fd->this_active_func_var_idx = -1;
|
||||
|
||||
/* XXX: should distinguish arg, var and var object and body scopes */
|
||||
@@ -20918,15 +20733,7 @@ static int optimize_scope_make_global_ref(JSContext *ctx, JSFunctionDef *s,
|
||||
|
||||
static int add_var_this(JSContext *ctx, JSFunctionDef *fd)
|
||||
{
|
||||
int idx;
|
||||
idx = add_var(ctx, fd, JS_ATOM_this);
|
||||
if (idx >= 0 && fd->is_derived_class_constructor) {
|
||||
JSVarDef *vd = &fd->vars[idx];
|
||||
/* XXX: should have is_this flag or var type */
|
||||
vd->is_lexical = 1; /* used to trigger 'uninitialized' checks
|
||||
in a derived class constructor */
|
||||
}
|
||||
return idx;
|
||||
return add_var(ctx, fd, JS_ATOM_this);
|
||||
}
|
||||
|
||||
static int resolve_pseudo_var(JSContext *ctx, JSFunctionDef *s,
|
||||
@@ -20944,10 +20751,8 @@ static int resolve_pseudo_var(JSContext *ctx, JSFunctionDef *s,
|
||||
var_idx = s->this_active_func_var_idx;
|
||||
break;
|
||||
case JS_ATOM_new_target:
|
||||
/* 'new.target' pseudo variable */
|
||||
if (s->new_target_var_idx < 0)
|
||||
s->new_target_var_idx = add_var(ctx, s, var_name);
|
||||
var_idx = s->new_target_var_idx;
|
||||
/* 'new.target' not supported - constructors removed */
|
||||
var_idx = -1;
|
||||
break;
|
||||
case JS_ATOM_this:
|
||||
/* 'this' pseudo variable */
|
||||
@@ -21422,10 +21227,6 @@ static void add_eval_variables(JSContext *ctx, JSFunctionDef *s)
|
||||
if (has_this_binding) {
|
||||
if (s->this_var_idx < 0)
|
||||
s->this_var_idx = add_var_this(ctx, s);
|
||||
if (s->new_target_var_idx < 0)
|
||||
s->new_target_var_idx = add_var(ctx, s, JS_ATOM_new_target);
|
||||
if (s->is_derived_class_constructor && s->this_active_func_var_idx < 0)
|
||||
s->this_active_func_var_idx = add_var(ctx, s, JS_ATOM_this_active_func);
|
||||
}
|
||||
if (s->is_func_expr && s->func_name != JS_ATOM_NULL)
|
||||
add_func_var(ctx, s, s->func_name);
|
||||
@@ -21447,10 +21248,6 @@ static void add_eval_variables(JSContext *ctx, JSFunctionDef *s)
|
||||
if (!has_this_binding && fd->has_this_binding) {
|
||||
if (fd->this_var_idx < 0)
|
||||
fd->this_var_idx = add_var_this(ctx, fd);
|
||||
if (fd->new_target_var_idx < 0)
|
||||
fd->new_target_var_idx = add_var(ctx, fd, JS_ATOM_new_target);
|
||||
if (fd->is_derived_class_constructor && fd->this_active_func_var_idx < 0)
|
||||
fd->this_active_func_var_idx = add_var(ctx, fd, JS_ATOM_this_active_func);
|
||||
has_this_binding = TRUE;
|
||||
}
|
||||
/* add function name */
|
||||
@@ -22560,22 +22357,10 @@ static __exception int resolve_labels(JSContext *ctx, JSFunctionDef *s)
|
||||
dbuf_putc(&bc_out, OP_SPECIAL_OBJECT_THIS_FUNC);
|
||||
put_short_code(&bc_out, OP_put_loc, s->this_active_func_var_idx);
|
||||
}
|
||||
/* initialize the 'new.target' variable if needed */
|
||||
if (s->new_target_var_idx >= 0) {
|
||||
dbuf_putc(&bc_out, OP_special_object);
|
||||
dbuf_putc(&bc_out, OP_SPECIAL_OBJECT_NEW_TARGET);
|
||||
put_short_code(&bc_out, OP_put_loc, s->new_target_var_idx);
|
||||
}
|
||||
/* initialize the 'this' variable if needed. In a derived class
|
||||
constructor, this is initially uninitialized. */
|
||||
/* initialize the 'this' variable if needed */
|
||||
if (s->this_var_idx >= 0) {
|
||||
if (s->is_derived_class_constructor) {
|
||||
dbuf_putc(&bc_out, OP_set_loc_uninitialized);
|
||||
dbuf_put_u16(&bc_out, s->this_var_idx);
|
||||
} else {
|
||||
dbuf_putc(&bc_out, OP_push_this);
|
||||
put_short_code(&bc_out, OP_put_loc, s->this_var_idx);
|
||||
}
|
||||
dbuf_putc(&bc_out, OP_push_this);
|
||||
put_short_code(&bc_out, OP_put_loc, s->this_var_idx);
|
||||
}
|
||||
/* initialize a reference to the current function if needed */
|
||||
if (s->func_var_idx >= 0) {
|
||||
@@ -23684,7 +23469,6 @@ static JSValue js_create_function(JSContext *ctx, JSFunctionDef *fd)
|
||||
b->has_prototype = fd->has_prototype;
|
||||
b->has_simple_parameter_list = fd->has_simple_parameter_list;
|
||||
b->js_mode = fd->js_mode;
|
||||
b->is_derived_class_constructor = fd->is_derived_class_constructor;
|
||||
|
||||
#ifdef DUMP_PROFILE
|
||||
/* Initialize profiling data */
|
||||
@@ -23701,7 +23485,6 @@ static JSValue js_create_function(JSContext *ctx, JSFunctionDef *fd)
|
||||
b->ic_slots = NULL;
|
||||
b->ic_count = 0;
|
||||
|
||||
b->new_target_allowed = fd->new_target_allowed;
|
||||
b->is_direct_or_indirect_eval = (fd->eval_type == JS_EVAL_TYPE_DIRECT ||
|
||||
fd->eval_type == JS_EVAL_TYPE_INDIRECT);
|
||||
b->realm = JS_DupContext(ctx);
|
||||
@@ -24009,14 +23792,6 @@ static __exception int js_parse_function_decl2(JSParseState *s,
|
||||
|
||||
fd->has_this_binding = (func_type != JS_PARSE_FUNC_ARROW &&
|
||||
func_type != JS_PARSE_FUNC_CLASS_STATIC_INIT);
|
||||
fd->is_derived_class_constructor = (func_type == JS_PARSE_FUNC_DERIVED_CLASS_CONSTRUCTOR);
|
||||
if (func_type == JS_PARSE_FUNC_ARROW) {
|
||||
fd->new_target_allowed = fd->parent->new_target_allowed;
|
||||
} else if (func_type == JS_PARSE_FUNC_CLASS_STATIC_INIT) {
|
||||
fd->new_target_allowed = TRUE; // although new.target === undefined
|
||||
} else {
|
||||
fd->new_target_allowed = TRUE;
|
||||
}
|
||||
|
||||
/* fd->in_function_body == FALSE prevents yield/await during the parsing
|
||||
of the arguments in generator/async functions. They are parsed as
|
||||
@@ -24511,11 +24286,6 @@ static JSValue __JS_EvalInternal(JSContext *ctx, JSValueConst this_obj,
|
||||
s->cur_func = fd;
|
||||
fd->eval_type = eval_type;
|
||||
fd->has_this_binding = (eval_type != JS_EVAL_TYPE_DIRECT);
|
||||
if (eval_type == JS_EVAL_TYPE_DIRECT) {
|
||||
fd->new_target_allowed = b->new_target_allowed;
|
||||
} else {
|
||||
fd->new_target_allowed = FALSE;
|
||||
}
|
||||
fd->js_mode = js_mode;
|
||||
fd->func_name = JS_DupAtom(ctx, JS_ATOM__eval_);
|
||||
if (b) {
|
||||
@@ -25008,9 +24778,7 @@ static int JS_WriteFunctionTag(BCWriterState *s, JSValueConst obj)
|
||||
flags = idx = 0;
|
||||
bc_set_flags(&flags, &idx, b->has_prototype, 1);
|
||||
bc_set_flags(&flags, &idx, b->has_simple_parameter_list, 1);
|
||||
bc_set_flags(&flags, &idx, b->is_derived_class_constructor, 1);
|
||||
bc_set_flags(&flags, &idx, b->func_kind, 2);
|
||||
bc_set_flags(&flags, &idx, b->new_target_allowed, 1);
|
||||
bc_set_flags(&flags, &idx, b->has_debug, 1);
|
||||
bc_set_flags(&flags, &idx, b->is_direct_or_indirect_eval, 1);
|
||||
assert(idx <= 16);
|
||||
@@ -25246,12 +25014,6 @@ static int JS_WriteObjectRec(BCWriterState *s, JSValueConst obj)
|
||||
case JS_CLASS_OBJECT:
|
||||
ret = JS_WriteObjectTag(s, obj);
|
||||
break;
|
||||
case JS_CLASS_NUMBER:
|
||||
case JS_CLASS_STRING:
|
||||
case JS_CLASS_BOOLEAN:
|
||||
bc_put_u8(s, BC_TAG_OBJECT_VALUE);
|
||||
ret = JS_WriteObjectRec(s, p->u.object_data);
|
||||
break;
|
||||
default:
|
||||
JS_ThrowTypeError(s->ctx, "unsupported object class");
|
||||
ret = -1;
|
||||
@@ -25710,9 +25472,7 @@ static JSValue JS_ReadFunctionTag(BCReaderState *s)
|
||||
idx = 0;
|
||||
bc.has_prototype = bc_get_flags(v16, &idx, 1);
|
||||
bc.has_simple_parameter_list = bc_get_flags(v16, &idx, 1);
|
||||
bc.is_derived_class_constructor = bc_get_flags(v16, &idx, 1);
|
||||
bc.func_kind = bc_get_flags(v16, &idx, 2);
|
||||
bc.new_target_allowed = bc_get_flags(v16, &idx, 1);
|
||||
bc.has_debug = bc_get_flags(v16, &idx, 1);
|
||||
bc.is_direct_or_indirect_eval = bc_get_flags(v16, &idx, 1);
|
||||
bc.read_only_bytecode = s->is_rom_data;
|
||||
@@ -27040,96 +26800,6 @@ static JSValue js_create_array(JSContext *ctx, int len, JSValueConst *tab)
|
||||
return obj;
|
||||
}
|
||||
|
||||
/* String */
|
||||
static int js_string_get_own_property(JSContext *ctx,
|
||||
JSPropertyDescriptor *desc,
|
||||
JSValueConst obj, JSAtom prop)
|
||||
{
|
||||
JSObject *p;
|
||||
JSString *p1;
|
||||
uint32_t idx, ch;
|
||||
|
||||
/* This is a class exotic method: obj class_id is JS_CLASS_STRING */
|
||||
if (__JS_AtomIsTaggedInt(prop)) {
|
||||
p = JS_VALUE_GET_OBJ(obj);
|
||||
if (JS_VALUE_GET_TAG(p->u.object_data) == JS_TAG_STRING) {
|
||||
p1 = JS_VALUE_GET_STRING(p->u.object_data);
|
||||
idx = __JS_AtomToUInt32(prop);
|
||||
if (idx < p1->len) {
|
||||
if (desc) {
|
||||
ch = string_get(p1, idx);
|
||||
desc->flags = JS_PROP_ENUMERABLE;
|
||||
desc->value = js_new_string_char(ctx, ch);
|
||||
desc->getter = JS_NULL;
|
||||
desc->setter = JS_NULL;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static int js_string_define_own_property(JSContext *ctx,
|
||||
JSValueConst this_obj,
|
||||
JSAtom prop, JSValueConst val,
|
||||
JSValueConst getter,
|
||||
JSValueConst setter, int flags)
|
||||
{
|
||||
uint32_t idx;
|
||||
JSObject *p;
|
||||
JSString *p1, *p2;
|
||||
|
||||
if (__JS_AtomIsTaggedInt(prop)) {
|
||||
idx = __JS_AtomToUInt32(prop);
|
||||
p = JS_VALUE_GET_OBJ(this_obj);
|
||||
if (JS_VALUE_GET_TAG(p->u.object_data) != JS_TAG_STRING)
|
||||
goto def;
|
||||
p1 = JS_VALUE_GET_STRING(p->u.object_data);
|
||||
if (idx >= p1->len)
|
||||
goto def;
|
||||
if (!check_define_prop_flags(JS_PROP_ENUMERABLE, flags))
|
||||
goto fail;
|
||||
/* check that the same value is configured */
|
||||
if (flags & JS_PROP_HAS_VALUE) {
|
||||
if (JS_VALUE_GET_TAG(val) != JS_TAG_STRING)
|
||||
goto fail;
|
||||
p2 = JS_VALUE_GET_STRING(val);
|
||||
if (p2->len != 1)
|
||||
goto fail;
|
||||
if (string_get(p1, idx) != string_get(p2, 0)) {
|
||||
fail:
|
||||
return JS_ThrowTypeErrorOrFalse(ctx, flags, "property is not configurable");
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
} else {
|
||||
def:
|
||||
return JS_DefineProperty(ctx, this_obj, prop, val, getter, setter,
|
||||
flags | JS_PROP_NO_EXOTIC);
|
||||
}
|
||||
}
|
||||
|
||||
static int js_string_delete_property(JSContext *ctx,
|
||||
JSValueConst obj, JSAtom prop)
|
||||
{
|
||||
uint32_t idx;
|
||||
|
||||
if (__JS_AtomIsTaggedInt(prop)) {
|
||||
idx = __JS_AtomToUInt32(prop);
|
||||
if (idx < js_string_obj_get_length(ctx, obj)) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static const JSClassExoticMethods js_string_exotic_methods = {
|
||||
.get_own_property = js_string_get_own_property,
|
||||
.define_own_property = js_string_define_own_property,
|
||||
.delete_property = js_string_delete_property,
|
||||
};
|
||||
|
||||
static int string_cmp(JSString *p1, JSString *p2, int x1, int x2, int len)
|
||||
{
|
||||
int i, c1, c2;
|
||||
@@ -28346,24 +28016,6 @@ static int js_json_to_str(JSContext *ctx, JSONStringifyContext *jsc,
|
||||
}
|
||||
|
||||
if (JS_IsObject(val)) {
|
||||
p = JS_VALUE_GET_OBJ(val);
|
||||
cl = p->class_id;
|
||||
if (cl == JS_CLASS_STRING) {
|
||||
val = JS_ToStringFree(ctx, val);
|
||||
if (JS_IsException(val))
|
||||
goto exception;
|
||||
goto concat_primitive;
|
||||
} else if (cl == JS_CLASS_NUMBER) {
|
||||
val = JS_ToNumberFree(ctx, val);
|
||||
if (JS_IsException(val))
|
||||
goto exception;
|
||||
goto concat_primitive;
|
||||
} else if (cl == JS_CLASS_BOOLEAN)
|
||||
{
|
||||
/* This will thow the same error as for the primitive object */
|
||||
set_value(ctx, &val, JS_DupValue(ctx, p->u.object_data));
|
||||
goto concat_primitive;
|
||||
}
|
||||
v = js_array_includes(ctx, jsc->stack, 1, (JSValueConst *)&val);
|
||||
if (JS_IsException(v))
|
||||
goto exception;
|
||||
@@ -28550,16 +28202,9 @@ JSValue JS_JSONStringify(JSContext *ctx, JSValueConst obj,
|
||||
if (JS_IsException(v))
|
||||
goto exception;
|
||||
if (JS_IsObject(v)) {
|
||||
JSObject *p = JS_VALUE_GET_OBJ(v);
|
||||
if (p->class_id == JS_CLASS_STRING ||
|
||||
p->class_id == JS_CLASS_NUMBER) {
|
||||
v = JS_ToStringFree(ctx, v);
|
||||
if (JS_IsException(v))
|
||||
goto exception;
|
||||
} else {
|
||||
JS_FreeValue(ctx, v);
|
||||
continue;
|
||||
}
|
||||
/* Objects are not valid property list items */
|
||||
JS_FreeValue(ctx, v);
|
||||
continue;
|
||||
} else if (JS_IsNumber(v)) {
|
||||
v = JS_ToStringFree(ctx, v);
|
||||
if (JS_IsException(v))
|
||||
@@ -28583,18 +28228,6 @@ JSValue JS_JSONStringify(JSContext *ctx, JSValueConst obj,
|
||||
}
|
||||
}
|
||||
space = JS_DupValue(ctx, space0);
|
||||
if (JS_IsObject(space)) {
|
||||
JSObject *p = JS_VALUE_GET_OBJ(space);
|
||||
if (p->class_id == JS_CLASS_NUMBER) {
|
||||
space = JS_ToNumberFree(ctx, space);
|
||||
} else if (p->class_id == JS_CLASS_STRING) {
|
||||
space = JS_ToStringFree(ctx, space);
|
||||
}
|
||||
if (JS_IsException(space)) {
|
||||
JS_FreeValue(ctx, space);
|
||||
goto exception;
|
||||
}
|
||||
}
|
||||
if (JS_IsNumber(space)) {
|
||||
int n;
|
||||
if (JS_ToInt32Clamp(ctx, &n, space, 0, 10, 0))
|
||||
@@ -32921,13 +32554,6 @@ void JS_AddIntrinsicBaseObjects(JSContext *ctx)
|
||||
ctx->array_proto_values =
|
||||
JS_GetProperty(ctx, ctx->class_proto[JS_CLASS_ARRAY], JS_ATOM_values);
|
||||
|
||||
/* String - no constructor, just use text() global function */
|
||||
ctx->class_proto[JS_CLASS_STRING] = JS_NewObjectProtoClass(ctx, ctx->class_proto[JS_CLASS_OBJECT],
|
||||
JS_CLASS_STRING);
|
||||
|
||||
/* Symbol - no constructor, but keep symbol type for object keys */
|
||||
ctx->class_proto[JS_CLASS_SYMBOL] = JS_NewObject(ctx);
|
||||
|
||||
/* global properties */
|
||||
JS_DefinePropertyValue(ctx, ctx->global_obj, JS_ATOM_globalThis,
|
||||
JS_DupValue(ctx, ctx->global_obj),
|
||||
|
||||
Reference in New Issue
Block a user