rm getset

This commit is contained in:
2026-01-22 09:55:02 -06:00
parent 6c1f53ec5f
commit 420c2b859a
3 changed files with 42 additions and 448 deletions

View File

@@ -645,8 +645,6 @@ typedef struct JSFunctionBytecode {
/* Inline cache (IC) support - defined after JSFunctionBytecode */
typedef enum {
IC_NONE = 0,
IC_GET_PROP,
IC_SET_PROP,
IC_CALL,
} ic_kind;
@@ -681,11 +679,7 @@ typedef struct ICSlot {
uint8_t kind; /* ic_kind */
uint8_t state; /* ic_state */
uint16_t aux; /* auxiliary flags/data */
union {
GetPropIC get_prop;
SetPropIC set_prop;
CallIC call;
} u;
CallIC call;
} ICSlot;
typedef struct JSBoundFunction {
@@ -703,10 +697,6 @@ typedef struct JSRegExp {
typedef struct JSProperty {
union {
JSValue value; /* JS_PROP_NORMAL */
struct { /* JS_PROP_GETSET */
JSObject *getter; /* NULL if undefined */
JSObject *setter; /* NULL if undefined */
} getset;
JSVarRef *var_ref; /* JS_PROP_VARREF */
} u;
} JSProperty;
@@ -4836,11 +4826,6 @@ static int js_method_set_properties(JSContext *ctx, JSValueConst func_obj,
JSValue name_str;
name_str = js_get_function_name(ctx, name);
if (flags & JS_PROP_HAS_GET) {
name_str = JS_ConcatString3(ctx, "get ", name_str, "");
} else if (flags & JS_PROP_HAS_SET) {
name_str = JS_ConcatString3(ctx, "set ", name_str, "");
}
if (JS_IsException(name_str))
return -1;
if (JS_DefinePropertyValue(ctx, func_obj, JS_ATOM_name, name_str,
@@ -4977,12 +4962,7 @@ JSValue JS_NewCFunctionData(JSContext *ctx, JSCFunctionData *func,
static void free_property(JSRuntime *rt, JSProperty *pr, int prop_flags)
{
if (unlikely(prop_flags & JS_PROP_TMASK)) {
if ((prop_flags & JS_PROP_TMASK) == JS_PROP_GETSET) {
if (pr->u.getset.getter)
JS_FreeValueRT(rt, JS_MKPTR(JS_TAG_OBJECT, pr->u.getset.getter));
if (pr->u.getset.setter)
JS_FreeValueRT(rt, JS_MKPTR(JS_TAG_OBJECT, pr->u.getset.setter));
} else if ((prop_flags & JS_PROP_TMASK) == JS_PROP_VARREF) {
if ((prop_flags & JS_PROP_TMASK) == JS_PROP_VARREF) {
free_var_ref(rt, pr->u.var_ref);
}
} else {
@@ -5366,12 +5346,7 @@ static void mark_children(JSRuntime *rt, JSGCObjectHeader *gp,
JSProperty *pr = &p->prop[i];
if (prs->atom != JS_ATOM_NULL) {
if (prs->flags & JS_PROP_TMASK) {
if ((prs->flags & JS_PROP_TMASK) == JS_PROP_GETSET) {
if (pr->u.getset.getter)
mark_func(rt, &pr->u.getset.getter->header);
if (pr->u.getset.setter)
mark_func(rt, &pr->u.getset.setter->header);
} else if ((prs->flags & JS_PROP_TMASK) == JS_PROP_VARREF) {
if ((prs->flags & JS_PROP_TMASK) == JS_PROP_VARREF) {
/* Note: the tag does not matter
provided it is a GC object */
mark_func(rt, &pr->u.var_ref->header);
@@ -6653,16 +6628,7 @@ JSValue JS_GetPropertyInternal(JSContext *ctx, JSValueConst obj,
if (prs) {
/* found */
if (unlikely(prs->flags & JS_PROP_TMASK)) {
if ((prs->flags & JS_PROP_TMASK) == JS_PROP_GETSET) {
if (unlikely(!pr->u.getset.getter)) {
return JS_NULL;
} else {
JSValue func = JS_MKPTR(JS_TAG_OBJECT, pr->u.getset.getter);
/* Note: the field could be removed in the getter */
func = JS_DupValue(ctx, func);
return JS_CallFree(ctx, func, this_obj, 0, NULL);
}
} else if ((prs->flags & JS_PROP_TMASK) == JS_PROP_VARREF) {
if ((prs->flags & JS_PROP_TMASK) == JS_PROP_VARREF) {
JSValue val = *pr->u.var_ref->pvalue;
if (unlikely(JS_IsUninitialized(val)))
return JS_ThrowReferenceErrorUninitialized(ctx, prs->atom);
@@ -6885,13 +6851,7 @@ retry:
desc->setter = JS_NULL;
desc->value = JS_NULL;
if (unlikely(prs->flags & JS_PROP_TMASK)) {
if ((prs->flags & JS_PROP_TMASK) == JS_PROP_GETSET) {
desc->flags |= JS_PROP_GETSET;
if (pr->u.getset.getter)
desc->getter = JS_DupValue(ctx, JS_MKPTR(JS_TAG_OBJECT, pr->u.getset.getter));
if (pr->u.getset.setter)
desc->setter = JS_DupValue(ctx, JS_MKPTR(JS_TAG_OBJECT, pr->u.getset.setter));
} else if ((prs->flags & JS_PROP_TMASK) == JS_PROP_VARREF) {
if ((prs->flags & JS_PROP_TMASK) == JS_PROP_VARREF) {
JSValue val = *pr->u.var_ref->pvalue;
if (unlikely(JS_IsUninitialized(val))) {
JS_ThrowReferenceErrorUninitialized(ctx, prs->atom);
@@ -7413,8 +7373,6 @@ int JS_SetPropertyInternal(JSContext *ctx, JSValueConst obj,
/* fast case */
set_value(ctx, &pr->u.value, val);
return TRUE;
} else if ((prs->flags & JS_PROP_TMASK) == JS_PROP_GETSET) {
return call_setter(ctx, pr->u.getset.setter, this_obj, val, flags);
} else if ((prs->flags & JS_PROP_TMASK) == JS_PROP_VARREF) {
set_value(ctx, pr->u.var_ref->pvalue, val);
return TRUE;
@@ -7432,9 +7390,7 @@ int JS_SetPropertyInternal(JSContext *ctx, JSValueConst obj,
retry2:
prs = find_own_property(&pr, p1, prop);
if (prs) {
if ((prs->flags & JS_PROP_TMASK) == JS_PROP_GETSET) {
return call_setter(ctx, pr->u.getset.setter, this_obj, val, flags);
} else if (!(prs->flags & JS_PROP_WRITABLE)) {
if (!(prs->flags & JS_PROP_WRITABLE)) {
goto read_only_prop;
} else {
break;
@@ -7474,18 +7430,11 @@ int JS_SetPropertyInternal(JSContext *ctx, JSValueConst obj,
return ret;
}
if (ret) {
if (desc.flags & JS_PROP_GETSET) {
JS_FreeValue(ctx, desc.getter);
JS_FreeValue(ctx, desc.setter);
JS_FreeValue(ctx, desc.value);
if (!(desc.flags & JS_PROP_WRITABLE)) {
read_only_prop:
JS_FreeValue(ctx, val);
return JS_ThrowTypeErrorOrFalse(ctx, flags, "setter is forbidden");
} else {
JS_FreeValue(ctx, desc.value);
if (!(desc.flags & JS_PROP_WRITABLE)) {
read_only_prop:
JS_FreeValue(ctx, val);
return JS_ThrowTypeErrorReadOnly(ctx, flags, prop);
}
return JS_ThrowTypeErrorReadOnly(ctx, flags, prop);
}
ret = JS_DefineProperty(ctx, this_obj, prop, val,
JS_NULL, JS_NULL,
@@ -7680,32 +7629,15 @@ static int JS_CreateProperty(JSContext *ctx, JSObject *p,
return JS_ThrowTypeErrorOrFalse(ctx, flags, "object is not extensible");
}
if (flags & (JS_PROP_HAS_GET | JS_PROP_HAS_SET)) {
prop_flags = (flags & (JS_PROP_CONFIGURABLE | JS_PROP_ENUMERABLE)) |
JS_PROP_GETSET;
} else {
prop_flags = flags & JS_PROP_C_W_E;
}
prop_flags = flags & JS_PROP_C_W_E;
pr = add_property(ctx, p, prop, prop_flags);
if (unlikely(!pr))
return -1;
if (flags & (JS_PROP_HAS_GET | JS_PROP_HAS_SET)) {
pr->u.getset.getter = NULL;
if ((flags & JS_PROP_HAS_GET) && JS_IsFunction(ctx, getter)) {
pr->u.getset.getter =
JS_VALUE_GET_OBJ(JS_DupValue(ctx, getter));
}
pr->u.getset.setter = NULL;
if ((flags & JS_PROP_HAS_SET) && JS_IsFunction(ctx, setter)) {
pr->u.getset.setter =
JS_VALUE_GET_OBJ(JS_DupValue(ctx, setter));
}
if (flags & JS_PROP_HAS_VALUE) {
pr->u.value = JS_DupValue(ctx, val);
} else {
if (flags & JS_PROP_HAS_VALUE) {
pr->u.value = JS_DupValue(ctx, val);
} else {
pr->u.value = JS_NULL;
}
pr->u.value = JS_NULL;
}
return TRUE;
}
@@ -7713,8 +7645,6 @@ static int JS_CreateProperty(JSContext *ctx, JSObject *p,
/* return FALSE if not OK */
static BOOL check_define_prop_flags(int prop_flags, int flags)
{
BOOL has_accessor, is_getset;
if (!(prop_flags & JS_PROP_CONFIGURABLE)) {
if ((flags & (JS_PROP_HAS_CONFIGURABLE | JS_PROP_CONFIGURABLE)) ==
(JS_PROP_HAS_CONFIGURABLE | JS_PROP_CONFIGURABLE)) {
@@ -7723,13 +7653,8 @@ static BOOL check_define_prop_flags(int prop_flags, int flags)
if ((flags & JS_PROP_HAS_ENUMERABLE) &&
(flags & JS_PROP_ENUMERABLE) != (prop_flags & JS_PROP_ENUMERABLE))
return FALSE;
if (flags & (JS_PROP_HAS_VALUE | JS_PROP_HAS_WRITABLE |
JS_PROP_HAS_GET | JS_PROP_HAS_SET)) {
has_accessor = ((flags & (JS_PROP_HAS_GET | JS_PROP_HAS_SET)) != 0);
is_getset = ((prop_flags & JS_PROP_TMASK) == JS_PROP_GETSET);
if (has_accessor != is_getset)
return FALSE;
if (!is_getset && !(prop_flags & JS_PROP_WRITABLE)) {
if (flags & (JS_PROP_HAS_VALUE | JS_PROP_HAS_WRITABLE)) {
if (!(prop_flags & JS_PROP_WRITABLE)) {
/* not writable: cannot set the writable bit */
if ((flags & (JS_PROP_HAS_WRITABLE | JS_PROP_WRITABLE)) ==
(JS_PROP_HAS_WRITABLE | JS_PROP_WRITABLE))
@@ -7781,7 +7706,7 @@ static int js_update_property_flags(JSContext *ctx, JSObject *p,
/* allowed flags:
JS_PROP_CONFIGURABLE, JS_PROP_WRITABLE, JS_PROP_ENUMERABLE
JS_PROP_HAS_GET, JS_PROP_HAS_SET, JS_PROP_HAS_VALUE,
JS_PROP_HAS_VALUE,
JS_PROP_HAS_CONFIGURABLE, JS_PROP_HAS_WRITABLE, JS_PROP_HAS_ENUMERABLE,
JS_PROP_THROW, JS_PROP_NO_EXOTIC.
If JS_PROP_THROW is set, return an exception instead of FALSE.
@@ -7857,85 +7782,7 @@ int JS_DefineProperty(JSContext *ctx, JSValueConst this_obj,
return JS_ThrowTypeErrorOrFalse(ctx, flags, "property is not configurable");
}
if (flags & (JS_PROP_HAS_VALUE | JS_PROP_HAS_WRITABLE |
JS_PROP_HAS_GET | JS_PROP_HAS_SET)) {
if (flags & (JS_PROP_HAS_GET | JS_PROP_HAS_SET)) {
JSObject *new_getter, *new_setter;
if (JS_IsFunction(ctx, getter)) {
new_getter = JS_VALUE_GET_OBJ(getter);
} else {
new_getter = NULL;
}
if (JS_IsFunction(ctx, setter)) {
new_setter = JS_VALUE_GET_OBJ(setter);
} else {
new_setter = NULL;
}
if ((prs->flags & JS_PROP_TMASK) != JS_PROP_GETSET) {
if (js_shape_prepare_update(ctx, p, &prs))
return -1;
/* convert to getset */
if ((prs->flags & JS_PROP_TMASK) == JS_PROP_VARREF) {
free_var_ref(ctx->rt, pr->u.var_ref);
} else {
JS_FreeValue(ctx, pr->u.value);
}
prs->flags = (prs->flags &
(JS_PROP_CONFIGURABLE | JS_PROP_ENUMERABLE)) |
JS_PROP_GETSET;
pr->u.getset.getter = NULL;
pr->u.getset.setter = NULL;
} else {
if (!(prs->flags & JS_PROP_CONFIGURABLE)) {
if ((flags & JS_PROP_HAS_GET) &&
new_getter != pr->u.getset.getter) {
goto not_configurable;
}
if ((flags & JS_PROP_HAS_SET) &&
new_setter != pr->u.getset.setter) {
goto not_configurable;
}
}
}
if (flags & JS_PROP_HAS_GET) {
if (pr->u.getset.getter)
JS_FreeValue(ctx, JS_MKPTR(JS_TAG_OBJECT, pr->u.getset.getter));
if (new_getter)
JS_DupValue(ctx, getter);
pr->u.getset.getter = new_getter;
}
if (flags & JS_PROP_HAS_SET) {
if (pr->u.getset.setter)
JS_FreeValue(ctx, JS_MKPTR(JS_TAG_OBJECT, pr->u.getset.setter));
if (new_setter)
JS_DupValue(ctx, setter);
pr->u.getset.setter = new_setter;
}
} else {
if ((prs->flags & JS_PROP_TMASK) == JS_PROP_GETSET) {
/* convert to data descriptor */
if (js_shape_prepare_update(ctx, p, &prs))
return -1;
if (pr->u.getset.getter)
JS_FreeValue(ctx, JS_MKPTR(JS_TAG_OBJECT, pr->u.getset.getter));
if (pr->u.getset.setter)
JS_FreeValue(ctx, JS_MKPTR(JS_TAG_OBJECT, pr->u.getset.setter));
prs->flags &= ~(JS_PROP_TMASK | JS_PROP_WRITABLE);
pr->u.value = JS_NULL;
} else if ((prs->flags & JS_PROP_TMASK) == JS_PROP_VARREF) {
/* Note: JS_PROP_VARREF is always writable */
} else {
if ((prs->flags & (JS_PROP_CONFIGURABLE | JS_PROP_WRITABLE)) == 0 &&
(flags & JS_PROP_HAS_VALUE)) {
if (!js_same_value(ctx, val, pr->u.value)) {
goto not_configurable;
} else {
return TRUE;
}
}
}
if (flags & (JS_PROP_HAS_VALUE | JS_PROP_HAS_WRITABLE)) {
if ((prs->flags & JS_PROP_TMASK) == JS_PROP_VARREF) {
if (flags & JS_PROP_HAS_VALUE) {
/* update the reference */
@@ -7969,7 +7816,6 @@ int JS_DefineProperty(JSContext *ctx, JSValueConst this_obj,
return -1;
}
}
}
}
mask = 0;
if (flags & JS_PROP_HAS_CONFIGURABLE)
@@ -8041,20 +7887,6 @@ int JS_DefinePropertyValueStr(JSContext *ctx, JSValueConst this_obj,
return ret;
}
/* shortcut to add getter & setter */
int JS_DefinePropertyGetSet(JSContext *ctx, JSValueConst this_obj,
JSAtom prop, JSValue getter, JSValue setter,
int flags)
{
int ret;
ret = JS_DefineProperty(ctx, this_obj, prop, JS_NULL, getter, setter,
flags | JS_PROP_HAS_GET | JS_PROP_HAS_SET |
JS_PROP_HAS_CONFIGURABLE | JS_PROP_HAS_ENUMERABLE);
JS_FreeValue(ctx, getter);
JS_FreeValue(ctx, setter);
return ret;
}
static int JS_CreateDataPropertyUint32(JSContext *ctx, JSValueConst this_obj,
int64_t idx, JSValue val, int flags)
{
@@ -8141,9 +7973,8 @@ static int JS_CheckDefineGlobalVar(JSContext *ctx, JSAtom prop, int flags)
if (flags & DEFINE_GLOBAL_FUNC_VAR) {
if (prs) {
if (!(prs->flags & JS_PROP_CONFIGURABLE) &&
((prs->flags & JS_PROP_TMASK) == JS_PROP_GETSET ||
((prs->flags & (JS_PROP_WRITABLE | JS_PROP_ENUMERABLE)) !=
(JS_PROP_WRITABLE | JS_PROP_ENUMERABLE)))) {
((prs->flags & (JS_PROP_WRITABLE | JS_PROP_ENUMERABLE)) !=
(JS_PROP_WRITABLE | JS_PROP_ENUMERABLE))) {
define_error:
JS_ThrowTypeErrorAtom(ctx, "cannot define variable '%s'",
prop);
@@ -9632,20 +9463,7 @@ static void js_print_object(JSPrintValueState *s, JSObject *p)
js_printf(s, ": ");
/* XXX: autoinit property */
if ((prs->flags & JS_PROP_TMASK) == JS_PROP_GETSET) {
if (s->options.raw_dump) {
js_printf(s, "[Getter %p Setter %p]",
pr->u.getset.getter, pr->u.getset.setter);
} else {
if (pr->u.getset.getter && pr->u.getset.setter) {
js_printf(s, "[Getter/Setter]");
} else if (pr->u.getset.setter) {
js_printf(s, "[Setter]");
} else {
js_printf(s, "[Getter]");
}
}
} else if ((prs->flags & JS_PROP_TMASK) == JS_PROP_VARREF) {
if ((prs->flags & JS_PROP_TMASK) == JS_PROP_VARREF) {
if (s->options.raw_dump) {
js_printf(s, "[varref %p]", (void *)pr->u.var_ref);
} else {
@@ -12602,13 +12420,7 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
if (op_flags == OP_DEFINE_METHOD_METHOD) {
value = sp[-1];
flags |= JS_PROP_HAS_VALUE | JS_PROP_HAS_WRITABLE | JS_PROP_WRITABLE;
} else if (op_flags == OP_DEFINE_METHOD_GETTER) {
getter = sp[-1];
flags |= JS_PROP_HAS_GET;
} else {
setter = sp[-1];
flags |= JS_PROP_HAS_SET;
}
}
ret = js_method_set_properties(ctx, sp[-1], atom, flags, obj);
if (ret >= 0) {
ret = JS_DefineProperty(ctx, obj, atom, value,
@@ -16188,8 +16000,6 @@ static __exception int js_parse_template(JSParseState *s, int call, int *argc)
#define PROP_TYPE_IDENT 0
#define PROP_TYPE_VAR 1
#define PROP_TYPE_GET 2
#define PROP_TYPE_SET 3
static BOOL token_is_ident(int tok)
{
@@ -16209,29 +16019,6 @@ static int __exception js_parse_property_name(JSParseState *s,
int prop_type;
prop_type = PROP_TYPE_IDENT;
if (allow_method) {
/* if allow_private is true (for class field parsing) and
get/set is following by ';' (or LF with ASI), then it
is a field name */
if ((token_is_pseudo_keyword(s, JS_ATOM_get) ||
token_is_pseudo_keyword(s, JS_ATOM_set)) &&
(peek_token(s, TRUE) != '\n')) {
/* get x(), set x() */
name = JS_DupAtom(s->ctx, s->token.u.ident.atom);
if (next_token(s))
goto fail1;
if (s->token.val == ':' || s->token.val == ',' ||
s->token.val == '}' || s->token.val == '(' ||
s->token.val == '=' ||
(s->token.val == ';')) {
is_non_reserved_ident = TRUE;
goto ident_found;
}
prop_type = PROP_TYPE_GET + (name == JS_ATOM_set);
JS_FreeAtom(s->ctx, name);
}
}
if (token_is_ident(s->token.val)) {
/* variable can only be a non-reserved identifier */
is_non_reserved_ident =
@@ -16557,16 +16344,10 @@ static __exception int js_parse_object_literal(JSParseState *s)
emit_op(s, OP_define_field);
emit_atom(s, name);
} else if (s->token.val == '(') {
BOOL is_getset = (prop_type == PROP_TYPE_GET ||
prop_type == PROP_TYPE_SET);
JSParseFunctionEnum func_type;
int op_flags;
if (is_getset) {
func_type = JS_PARSE_FUNC_GETTER + prop_type - PROP_TYPE_GET;
} else {
func_type = JS_PARSE_FUNC_METHOD;
}
func_type = JS_PARSE_FUNC_METHOD;
if (js_parse_function_decl(s, func_type, JS_ATOM_NULL,
start_ptr))
goto fail;
@@ -16576,12 +16357,8 @@ static __exception int js_parse_object_literal(JSParseState *s)
emit_op(s, OP_define_method);
emit_atom(s, name);
}
if (is_getset) {
op_flags = OP_DEFINE_METHOD_GETTER +
prop_type - PROP_TYPE_GET;
} else {
op_flags = OP_DEFINE_METHOD_METHOD;
}
op_flags = OP_DEFINE_METHOD_METHOD;
emit_u8(s, op_flags | OP_DEFINE_METHOD_ENUMERABLE);
} else {
if (name == JS_ATOM_NULL) {
@@ -22926,20 +22703,6 @@ static void ic_init_call(ICSlot *slot)
slot->state = IC_STATE_UNINIT;
}
static void ic_init_get_prop(ICSlot *slot)
{
memset(slot, 0, sizeof(*slot));
slot->kind = IC_GET_PROP;
slot->state = IC_STATE_UNINIT;
}
static void ic_init_set_prop(ICSlot *slot)
{
memset(slot, 0, sizeof(*slot));
slot->kind = IC_SET_PROP;
slot->state = IC_STATE_UNINIT;
}
static void free_function_bytecode(JSRuntime *rt, JSFunctionBytecode *b)
{
int i;
@@ -25426,30 +25189,6 @@ static int JS_InstantiateFunctionListItem(JSContext *ctx, JSValueConst obj,
val = JS_NewCFunction2(ctx, e->u.func.cfunc.generic, e->name,
e->u.func.length, e->u.func.cproto, e->magic);
break;
case JS_DEF_CGETSET: /* XXX: use autoinit again ? */
case JS_DEF_CGETSET_MAGIC:
{
JSValue getter, setter;
char buf[64];
getter = JS_NULL;
if (e->u.getset.get.generic) {
snprintf(buf, sizeof(buf), "get %s", e->name);
getter = JS_NewCFunction2(ctx, e->u.getset.get.generic,
buf, 0, e->def_type == JS_DEF_CGETSET_MAGIC ? JS_CFUNC_getter_magic : JS_CFUNC_getter,
e->magic);
}
setter = JS_NULL;
if (e->u.getset.set.generic) {
snprintf(buf, sizeof(buf), "set %s", e->name);
setter = JS_NewCFunction2(ctx, e->u.getset.set.generic,
buf, 1, e->def_type == JS_DEF_CGETSET_MAGIC ? JS_CFUNC_setter_magic : JS_CFUNC_setter,
e->magic);
}
JS_DefinePropertyGetSet(ctx, obj, atom, getter, setter, prop_flags);
return 0;
}
break;
case JS_DEF_PROP_INT32:
val = JS_NewInt32(ctx, e->u.i32);
break;
@@ -26134,126 +25873,6 @@ static JSValue js_regexp_compile(JSContext *ctx, JSValueConst this_val,
return JS_EXCEPTION;
}
static JSValue js_regexp_get_source(JSContext *ctx, JSValueConst this_val)
{
JSRegExp *re;
JSString *p;
StringBuffer b_s, *b = &b_s;
int i, n, c, c2, bra;
if (JS_VALUE_GET_TAG(this_val) != JS_TAG_OBJECT)
return JS_ThrowTypeErrorNotAnObject(ctx);
if (js_same_value(ctx, this_val, ctx->class_proto[JS_CLASS_REGEXP]))
goto empty_regex;
re = js_get_regexp(ctx, this_val, TRUE);
if (!re)
return JS_EXCEPTION;
p = re->pattern;
if (p->len == 0) {
empty_regex:
return js_new_string8(ctx, "(?:)");
}
string_buffer_init2(ctx, b, p->len, p->is_wide_char);
/* Escape '/' and newline sequences as needed */
bra = 0;
for (i = 0, n = p->len; i < n;) {
c2 = -1;
switch (c = string_get(p, i++)) {
case '\\':
if (i < n)
c2 = string_get(p, i++);
break;
case ']':
bra = 0;
break;
case '[':
if (!bra) {
if (i < n && string_get(p, i) == ']')
c2 = string_get(p, i++);
bra = 1;
}
break;
case '\n':
c = '\\';
c2 = 'n';
break;
case '\r':
c = '\\';
c2 = 'r';
break;
case '/':
if (!bra) {
c = '\\';
c2 = '/';
}
break;
}
string_buffer_putc16(b, c);
if (c2 >= 0)
string_buffer_putc16(b, c2);
}
return string_buffer_end(b);
}
static JSValue js_regexp_get_flag(JSContext *ctx, JSValueConst this_val, int mask)
{
JSRegExp *re;
int flags;
if (JS_VALUE_GET_TAG(this_val) != JS_TAG_OBJECT)
return JS_ThrowTypeErrorNotAnObject(ctx);
re = js_get_regexp(ctx, this_val, FALSE);
if (!re) {
if (js_same_value(ctx, this_val, ctx->class_proto[JS_CLASS_REGEXP]))
return JS_NULL;
else
return JS_ThrowTypeErrorInvalidClass(ctx, JS_CLASS_REGEXP);
}
flags = lre_get_flags(re->bytecode->u.str8);
return JS_NewBool(ctx, flags & mask);
}
#define RE_FLAG_COUNT 8
static JSValue js_regexp_get_flags(JSContext *ctx, JSValueConst this_val)
{
char str[RE_FLAG_COUNT], *p = str;
int res, i;
static const int flag_atom[RE_FLAG_COUNT] = {
JS_ATOM_hasIndices,
JS_ATOM_global,
JS_ATOM_ignoreCase,
JS_ATOM_multiline,
JS_ATOM_dotAll,
JS_ATOM_unicode,
JS_ATOM_unicodeSets,
JS_ATOM_sticky,
};
static const char flag_char[RE_FLAG_COUNT] = { 'd', 'g', 'i', 'm', 's', 'u', 'v', 'y' };
if (JS_VALUE_GET_TAG(this_val) != JS_TAG_OBJECT)
return JS_ThrowTypeErrorNotAnObject(ctx);
for(i = 0; i < RE_FLAG_COUNT; i++) {
res = JS_ToBoolFree(ctx, JS_GetProperty(ctx, this_val, flag_atom[i]));
if (res < 0)
goto exception;
if (res)
*p++ = flag_char[i];
}
return JS_NewStringLen(ctx, str, p - str);
exception:
return JS_EXCEPTION;
}
static JSValue js_regexp_toString(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv)
{
@@ -26624,16 +26243,6 @@ static int js_is_standard_regexp(JSContext *ctx, JSValueConst rx)
}
static const JSCFunctionListEntry js_regexp_proto_funcs[] = {
JS_CGETSET_DEF("flags", js_regexp_get_flags, NULL ),
JS_CGETSET_DEF("source", js_regexp_get_source, NULL ),
JS_CGETSET_MAGIC_DEF("global", js_regexp_get_flag, NULL, LRE_FLAG_GLOBAL ),
JS_CGETSET_MAGIC_DEF("ignoreCase", js_regexp_get_flag, NULL, LRE_FLAG_IGNORECASE ),
JS_CGETSET_MAGIC_DEF("multiline", js_regexp_get_flag, NULL, LRE_FLAG_MULTILINE ),
JS_CGETSET_MAGIC_DEF("dotAll", js_regexp_get_flag, NULL, LRE_FLAG_DOTALL ),
JS_CGETSET_MAGIC_DEF("unicode", js_regexp_get_flag, NULL, LRE_FLAG_UNICODE ),
JS_CGETSET_MAGIC_DEF("unicodeSets", js_regexp_get_flag, NULL, LRE_FLAG_UNICODE_SETS ),
JS_CGETSET_MAGIC_DEF("sticky", js_regexp_get_flag, NULL, LRE_FLAG_STICKY ),
JS_CGETSET_MAGIC_DEF("hasIndices", js_regexp_get_flag, NULL, LRE_FLAG_INDICES ),
JS_CFUNC_DEF("exec", 1, js_regexp_exec ),
JS_CFUNC_DEF("compile", 2, js_regexp_compile ),
JS_CFUNC_DEF("toString", 0, js_regexp_toString ),
@@ -31487,7 +31096,6 @@ void JS_AddIntrinsicBaseObjects(JSContext *ctx)
/* add caller property to throw a TypeError */
JS_DefineProperty(ctx, ctx->function_proto, JS_ATOM_caller, JS_NULL,
ctx->throw_type_error, ctx->throw_type_error,
JS_PROP_HAS_GET | JS_PROP_HAS_SET |
JS_PROP_HAS_CONFIGURABLE | JS_PROP_CONFIGURABLE);
JS_FreeValue(ctx, js_object_seal(ctx, JS_NULL, 1, (JSValueConst *)&ctx->throw_type_error, 1));

View File

@@ -280,7 +280,6 @@ static inline JS_BOOL JS_VALUE_IS_NAN(JSValue v)
#define JS_PROP_LENGTH (1 << 3) /* used internally in Arrays */
#define JS_PROP_TMASK (3 << 4) /* mask for NORMAL, GETSET, VARREF, AUTOINIT */
#define JS_PROP_NORMAL (0 << 4)
#define JS_PROP_GETSET (1 << 4)
#define JS_PROP_VARREF (2 << 4) /* used internally */
/* flags for JS_DefineProperty */
@@ -288,8 +287,6 @@ static inline JS_BOOL JS_VALUE_IS_NAN(JSValue v)
#define JS_PROP_HAS_CONFIGURABLE (1 << 8)
#define JS_PROP_HAS_WRITABLE (1 << 9)
#define JS_PROP_HAS_ENUMERABLE (1 << 10)
#define JS_PROP_HAS_GET (1 << 11)
#define JS_PROP_HAS_SET (1 << 12)
#define JS_PROP_HAS_VALUE (1 << 13)
/* throw an exception if false would be returned
@@ -749,9 +746,6 @@ int JS_DefinePropertyValueUint32(JSContext *ctx, JSValueConst this_obj,
uint32_t idx, JSValue val, int flags);
int JS_DefinePropertyValueStr(JSContext *ctx, JSValueConst this_obj,
const char *prop, JSValue val, int flags);
int JS_DefinePropertyGetSet(JSContext *ctx, JSValueConst this_obj,
JSAtom prop, JSValue getter, JSValue setter,
int flags);
void JS_SetOpaque(JSValue obj, void *opaque);
void *JS_GetOpaque(JSValueConst obj, JSClassID class_id);
void *JS_GetOpaque2(JSContext *ctx, JSValueConst obj, JSClassID class_id);
@@ -856,10 +850,6 @@ typedef struct JSCFunctionListEntry {
uint8_t cproto; /* XXX: should move outside union */
JSCFunctionType cfunc;
} func;
struct {
JSCFunctionType get;
JSCFunctionType set;
} getset;
struct {
const char *name;
int base;
@@ -876,8 +866,6 @@ typedef struct JSCFunctionListEntry {
} JSCFunctionListEntry;
#define JS_DEF_CFUNC 0
#define JS_DEF_CGETSET 1
#define JS_DEF_CGETSET_MAGIC 2
#define JS_DEF_PROP_STRING 3
#define JS_DEF_PROP_INT32 4
#define JS_DEF_PROP_INT64 5
@@ -891,8 +879,6 @@ typedef struct JSCFunctionListEntry {
#define JS_CFUNC_MAGIC_DEF(name, length, func1, magic) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE, JS_DEF_CFUNC, magic, .u = { .func = { length, JS_CFUNC_generic_magic, { .generic_magic = func1 } } } }
#define JS_CFUNC_SPECIAL_DEF(name, length, cproto, func1) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE, JS_DEF_CFUNC, 0, .u = { .func = { length, JS_CFUNC_ ## cproto, { .cproto = func1 } } } }
#define JS_ITERATOR_NEXT_DEF(name, length, func1, magic) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE, JS_DEF_CFUNC, magic, .u = { .func = { length, JS_CFUNC_iterator_next, { .iterator_next = func1 } } } }
#define JS_CGETSET_DEF(name, fgetter, fsetter) { name, JS_PROP_CONFIGURABLE, JS_DEF_CGETSET, 0, .u = { .getset = { .get = { .getter = fgetter }, .set = { .setter = fsetter } } } }
#define JS_CGETSET_MAGIC_DEF(name, fgetter, fsetter, magic) { name, JS_PROP_CONFIGURABLE, JS_DEF_CGETSET_MAGIC, magic, .u = { .getset = { .get = { .getter_magic = fgetter }, .set = { .setter_magic = fsetter } } } }
#define JS_PROP_STRING_DEF(name, cstr, prop_flags) { name, prop_flags, JS_DEF_PROP_STRING, 0, .u = { .str = cstr } }
#define JS_PROP_INT32_DEF(name, val, prop_flags) { name, prop_flags, JS_DEF_PROP_INT32, 0, .u = { .i32 = val } }
#define JS_PROP_INT64_DEF(name, val, prop_flags) { name, prop_flags, JS_DEF_PROP_INT64, 0, .u = { .i64 = val } }