mirror of
https://github.com/bellard/quickjs.git
synced 2025-05-15 02:36:17 +08:00
optimized js_parse_class_default_ctor() (bnoordhuis)
This commit is contained in:
parent
9106fa0b58
commit
4cc4c6c1c5
@ -110,6 +110,7 @@ DEF( return, 1, 1, 0, none)
|
|||||||
DEF( return_undef, 1, 0, 0, none)
|
DEF( return_undef, 1, 0, 0, none)
|
||||||
DEF(check_ctor_return, 1, 1, 2, none)
|
DEF(check_ctor_return, 1, 1, 2, none)
|
||||||
DEF( check_ctor, 1, 0, 0, none)
|
DEF( check_ctor, 1, 0, 0, none)
|
||||||
|
DEF( init_ctor, 1, 0, 1, none)
|
||||||
DEF( check_brand, 1, 2, 2, none) /* this_obj func -> this_obj func */
|
DEF( check_brand, 1, 2, 2, none) /* this_obj func -> this_obj func */
|
||||||
DEF( add_brand, 1, 2, 0, none) /* this_obj home_obj -> */
|
DEF( add_brand, 1, 2, 0, none) /* this_obj home_obj -> */
|
||||||
DEF( return_async, 1, 1, 0, none)
|
DEF( return_async, 1, 1, 0, none)
|
||||||
|
91
quickjs.c
91
quickjs.c
@ -16677,10 +16677,27 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
|
|||||||
BREAK;
|
BREAK;
|
||||||
CASE(OP_check_ctor):
|
CASE(OP_check_ctor):
|
||||||
if (JS_IsUndefined(new_target)) {
|
if (JS_IsUndefined(new_target)) {
|
||||||
|
non_ctor_call:
|
||||||
JS_ThrowTypeError(ctx, "class constructors must be invoked with 'new'");
|
JS_ThrowTypeError(ctx, "class constructors must be invoked with 'new'");
|
||||||
goto exception;
|
goto exception;
|
||||||
}
|
}
|
||||||
BREAK;
|
BREAK;
|
||||||
|
CASE(OP_init_ctor):
|
||||||
|
{
|
||||||
|
JSValue super, ret;
|
||||||
|
sf->cur_pc = pc;
|
||||||
|
if (JS_IsUndefined(new_target))
|
||||||
|
goto non_ctor_call;
|
||||||
|
super = JS_GetPrototype(ctx, func_obj);
|
||||||
|
if (JS_IsException(super))
|
||||||
|
goto exception;
|
||||||
|
ret = JS_CallConstructor2(ctx, super, new_target, argc, (JSValueConst *)argv);
|
||||||
|
JS_FreeValue(ctx, super);
|
||||||
|
if (JS_IsException(ret))
|
||||||
|
goto exception;
|
||||||
|
*sp++ = ret;
|
||||||
|
}
|
||||||
|
BREAK;
|
||||||
CASE(OP_check_brand):
|
CASE(OP_check_brand):
|
||||||
{
|
{
|
||||||
int ret = JS_CheckBrand(ctx, sp[-2], sp[-1]);
|
int ret = JS_CheckBrand(ctx, sp[-2], sp[-1]);
|
||||||
@ -22714,45 +22731,73 @@ static __exception int js_parse_object_literal(JSParseState *s)
|
|||||||
#define PF_POW_FORBIDDEN (1 << 3)
|
#define PF_POW_FORBIDDEN (1 << 3)
|
||||||
|
|
||||||
static __exception int js_parse_postfix_expr(JSParseState *s, int parse_flags);
|
static __exception int js_parse_postfix_expr(JSParseState *s, int parse_flags);
|
||||||
|
static void emit_class_field_init(JSParseState *s);
|
||||||
|
static JSFunctionDef *js_new_function_def(JSContext *ctx,
|
||||||
|
JSFunctionDef *parent,
|
||||||
|
BOOL is_eval,
|
||||||
|
BOOL is_func_expr,
|
||||||
|
const char *filename, int line_num);
|
||||||
|
static void emit_return(JSParseState *s, BOOL hasval);
|
||||||
|
|
||||||
static __exception int js_parse_left_hand_side_expr(JSParseState *s)
|
static __exception int js_parse_left_hand_side_expr(JSParseState *s)
|
||||||
{
|
{
|
||||||
return js_parse_postfix_expr(s, PF_POSTFIX_CALL);
|
return js_parse_postfix_expr(s, PF_POSTFIX_CALL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* XXX: could generate specific bytecode */
|
|
||||||
static __exception int js_parse_class_default_ctor(JSParseState *s,
|
static __exception int js_parse_class_default_ctor(JSParseState *s,
|
||||||
BOOL has_super,
|
BOOL has_super,
|
||||||
JSFunctionDef **pfd)
|
JSFunctionDef **pfd)
|
||||||
{
|
{
|
||||||
JSParsePos pos;
|
|
||||||
const char *str;
|
|
||||||
int ret, line_num;
|
|
||||||
JSParseFunctionEnum func_type;
|
JSParseFunctionEnum func_type;
|
||||||
const uint8_t *saved_buf_end;
|
JSFunctionDef *fd = s->cur_func;
|
||||||
|
int idx;
|
||||||
|
|
||||||
js_parse_get_pos(s, &pos);
|
fd = js_new_function_def(s->ctx, fd, FALSE, FALSE, s->filename,
|
||||||
|
s->token.line_num);
|
||||||
|
if (!fd)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
s->cur_func = fd;
|
||||||
|
fd->has_home_object = TRUE;
|
||||||
|
fd->super_allowed = TRUE;
|
||||||
|
fd->has_prototype = FALSE;
|
||||||
|
fd->has_this_binding = TRUE;
|
||||||
|
fd->new_target_allowed = TRUE;
|
||||||
|
|
||||||
|
push_scope(s); /* enter body scope */
|
||||||
|
fd->body_scope = fd->scope_level;
|
||||||
if (has_super) {
|
if (has_super) {
|
||||||
/* spec change: no argument evaluation */
|
fd->is_derived_class_constructor = TRUE;
|
||||||
str = "(){super(...arguments);}";
|
fd->super_call_allowed = TRUE;
|
||||||
|
fd->arguments_allowed = TRUE;
|
||||||
|
fd->has_arguments_binding = TRUE;
|
||||||
func_type = JS_PARSE_FUNC_DERIVED_CLASS_CONSTRUCTOR;
|
func_type = JS_PARSE_FUNC_DERIVED_CLASS_CONSTRUCTOR;
|
||||||
|
emit_op(s, OP_init_ctor);
|
||||||
|
// TODO(bnoordhuis) roll into OP_init_ctor
|
||||||
|
emit_op(s, OP_scope_put_var_init);
|
||||||
|
emit_atom(s, JS_ATOM_this);
|
||||||
|
emit_u16(s, 0);
|
||||||
|
emit_class_field_init(s);
|
||||||
} else {
|
} else {
|
||||||
str = "(){}";
|
|
||||||
func_type = JS_PARSE_FUNC_CLASS_CONSTRUCTOR;
|
func_type = JS_PARSE_FUNC_CLASS_CONSTRUCTOR;
|
||||||
|
/* error if not invoked as a constructor */
|
||||||
|
emit_op(s, OP_check_ctor);
|
||||||
|
emit_class_field_init(s);
|
||||||
}
|
}
|
||||||
line_num = s->token.line_num;
|
|
||||||
saved_buf_end = s->buf_end;
|
fd->func_kind = JS_FUNC_NORMAL;
|
||||||
s->buf_ptr = (uint8_t *)str;
|
fd->func_type = func_type;
|
||||||
s->buf_end = (uint8_t *)(str + strlen(str));
|
emit_return(s, FALSE);
|
||||||
ret = next_token(s);
|
|
||||||
if (!ret) {
|
s->cur_func = fd->parent;
|
||||||
ret = js_parse_function_decl2(s, func_type, JS_FUNC_NORMAL,
|
if (pfd)
|
||||||
JS_ATOM_NULL, (uint8_t *)str,
|
*pfd = fd;
|
||||||
line_num, JS_PARSE_EXPORT_NONE, pfd);
|
|
||||||
}
|
/* the real object will be set at the end of the compilation */
|
||||||
s->buf_end = saved_buf_end;
|
idx = cpool_add(s, JS_NULL);
|
||||||
ret |= js_parse_seek_token(s, &pos);
|
fd->parent_cpool_idx = idx;
|
||||||
return ret;
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* find field in the current scope */
|
/* find field in the current scope */
|
||||||
@ -25466,8 +25511,6 @@ static __exception int js_parse_cond_expr(JSParseState *s, int parse_flags)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void emit_return(JSParseState *s, BOOL hasval);
|
|
||||||
|
|
||||||
/* allowed parse_flags: PF_IN_ACCEPTED */
|
/* allowed parse_flags: PF_IN_ACCEPTED */
|
||||||
static __exception int js_parse_assign_expr2(JSParseState *s, int parse_flags)
|
static __exception int js_parse_assign_expr2(JSParseState *s, int parse_flags)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user