Specialize bytecode for default ctor (#112)
This commit is contained in:
parent
4e73bcf42d
commit
a8a5ecb095
1 changed files with 93 additions and 37 deletions
130
quickjs.c
130
quickjs.c
|
@ -20515,41 +20515,6 @@ 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,
|
|
||||||
BOOL has_super,
|
|
||||||
JSFunctionDef **pfd)
|
|
||||||
{
|
|
||||||
JSParsePos pos;
|
|
||||||
const char *str;
|
|
||||||
int ret, line_num;
|
|
||||||
JSParseFunctionEnum func_type;
|
|
||||||
const uint8_t *saved_buf_end;
|
|
||||||
|
|
||||||
js_parse_get_pos(s, &pos);
|
|
||||||
if (has_super) {
|
|
||||||
/* spec change: no argument evaluation */
|
|
||||||
str = "(){super(...arguments);}";
|
|
||||||
func_type = JS_PARSE_FUNC_DERIVED_CLASS_CONSTRUCTOR;
|
|
||||||
} else {
|
|
||||||
str = "(){}";
|
|
||||||
func_type = JS_PARSE_FUNC_CLASS_CONSTRUCTOR;
|
|
||||||
}
|
|
||||||
line_num = s->token.line_num;
|
|
||||||
saved_buf_end = s->buf_end;
|
|
||||||
s->buf_ptr = (uint8_t *)str;
|
|
||||||
s->buf_end = (uint8_t *)(str + strlen(str));
|
|
||||||
ret = next_token(s);
|
|
||||||
if (!ret) {
|
|
||||||
ret = js_parse_function_decl2(s, func_type, JS_FUNC_NORMAL,
|
|
||||||
JS_ATOM_NULL, (uint8_t *)str,
|
|
||||||
line_num, JS_PARSE_EXPORT_NONE, pfd);
|
|
||||||
}
|
|
||||||
s->buf_end = saved_buf_end;
|
|
||||||
ret |= js_parse_seek_token(s, &pos);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* find field in the current scope */
|
/* find field in the current scope */
|
||||||
static int find_private_class_field(JSContext *ctx, JSFunctionDef *fd,
|
static int find_private_class_field(JSContext *ctx, JSFunctionDef *fd,
|
||||||
JSAtom name, int scope_level)
|
JSAtom name, int scope_level)
|
||||||
|
@ -20671,6 +20636,99 @@ static void emit_class_init_end(JSParseState *s, ClassFieldsDef *cf)
|
||||||
emit_op(s, OP_set_home_object);
|
emit_op(s, OP_set_home_object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void emit_return(JSParseState *s, BOOL hasval);
|
||||||
|
|
||||||
|
static JSFunctionDef *js_new_function_def(JSContext *ctx,
|
||||||
|
JSFunctionDef *parent,
|
||||||
|
BOOL is_eval,
|
||||||
|
BOOL is_func_expr,
|
||||||
|
const char *filename, int line_num);
|
||||||
|
|
||||||
|
static __exception int js_parse_class_default_ctor(JSParseState *s,
|
||||||
|
BOOL has_super,
|
||||||
|
JSFunctionDef **pfd)
|
||||||
|
{
|
||||||
|
JSParseFunctionEnum func_type;
|
||||||
|
JSFunctionDef *fd = s->cur_func;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
/* error if not invoked as a constructor */
|
||||||
|
emit_op(s, OP_check_ctor);
|
||||||
|
|
||||||
|
push_scope(s); /* enter body scope */
|
||||||
|
fd->body_scope = fd->scope_level;
|
||||||
|
if (has_super) {
|
||||||
|
fd->is_derived_class_constructor = TRUE;
|
||||||
|
fd->super_call_allowed = TRUE;
|
||||||
|
fd->arguments_allowed = TRUE;
|
||||||
|
fd->has_arguments_binding = TRUE;
|
||||||
|
|
||||||
|
func_type = JS_PARSE_FUNC_DERIVED_CLASS_CONSTRUCTOR;
|
||||||
|
/* super */
|
||||||
|
emit_op(s, OP_scope_get_var);
|
||||||
|
emit_atom(s, JS_ATOM_this_active_func);
|
||||||
|
emit_u16(s, 0);
|
||||||
|
|
||||||
|
emit_op(s, OP_get_super);
|
||||||
|
|
||||||
|
emit_op(s, OP_scope_get_var);
|
||||||
|
emit_atom(s, JS_ATOM_new_target);
|
||||||
|
emit_u16(s, 0);
|
||||||
|
|
||||||
|
emit_op(s, OP_array_from);
|
||||||
|
emit_u16(s, 0);
|
||||||
|
emit_op(s, OP_push_i32);
|
||||||
|
emit_u32(s, 0);
|
||||||
|
|
||||||
|
/* arguments */
|
||||||
|
emit_op(s, OP_scope_get_var);
|
||||||
|
emit_atom(s, JS_ATOM_arguments);
|
||||||
|
emit_u16(s, 0);
|
||||||
|
|
||||||
|
emit_op(s, OP_append);
|
||||||
|
/* drop the index */
|
||||||
|
emit_op(s, OP_drop);
|
||||||
|
|
||||||
|
emit_op(s, OP_apply);
|
||||||
|
emit_u16(s, 1);
|
||||||
|
/* set the 'this' value */
|
||||||
|
emit_op(s, OP_dup);
|
||||||
|
emit_op(s, OP_scope_put_var_init);
|
||||||
|
emit_atom(s, JS_ATOM_this);
|
||||||
|
emit_u16(s, 0);
|
||||||
|
emit_class_field_init(s);
|
||||||
|
} else {
|
||||||
|
func_type = JS_PARSE_FUNC_CLASS_CONSTRUCTOR;
|
||||||
|
emit_class_field_init(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
fd->func_kind = JS_FUNC_NORMAL;
|
||||||
|
fd->func_type = func_type;
|
||||||
|
emit_return(s, FALSE);
|
||||||
|
|
||||||
|
s->cur_func = fd->parent;
|
||||||
|
if (pfd)
|
||||||
|
*pfd = fd;
|
||||||
|
|
||||||
|
int idx;
|
||||||
|
/* the real object will be set at the end of the compilation */
|
||||||
|
idx = cpool_add(s, JS_NULL);
|
||||||
|
fd->parent_cpool_idx = idx;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static __exception int js_parse_class(JSParseState *s, BOOL is_class_expr,
|
static __exception int js_parse_class(JSParseState *s, BOOL is_class_expr,
|
||||||
JSParseExportEnum export_flag)
|
JSParseExportEnum export_flag)
|
||||||
|
@ -23106,8 +23164,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…
Reference in a new issue