Skip to content

Commit a8a5ecb

Browse files
authored
Specialize bytecode for default ctor (#112)
1 parent 4e73bcf commit a8a5ecb

File tree

1 file changed

+93
-37
lines changed

1 file changed

+93
-37
lines changed

quickjs.c

Lines changed: 93 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -20515,41 +20515,6 @@ static __exception int js_parse_left_hand_side_expr(JSParseState *s)
2051520515
return js_parse_postfix_expr(s, PF_POSTFIX_CALL);
2051620516
}
2051720517

20518-
/* XXX: could generate specific bytecode */
20519-
static __exception int js_parse_class_default_ctor(JSParseState *s,
20520-
BOOL has_super,
20521-
JSFunctionDef **pfd)
20522-
{
20523-
JSParsePos pos;
20524-
const char *str;
20525-
int ret, line_num;
20526-
JSParseFunctionEnum func_type;
20527-
const uint8_t *saved_buf_end;
20528-
20529-
js_parse_get_pos(s, &pos);
20530-
if (has_super) {
20531-
/* spec change: no argument evaluation */
20532-
str = "(){super(...arguments);}";
20533-
func_type = JS_PARSE_FUNC_DERIVED_CLASS_CONSTRUCTOR;
20534-
} else {
20535-
str = "(){}";
20536-
func_type = JS_PARSE_FUNC_CLASS_CONSTRUCTOR;
20537-
}
20538-
line_num = s->token.line_num;
20539-
saved_buf_end = s->buf_end;
20540-
s->buf_ptr = (uint8_t *)str;
20541-
s->buf_end = (uint8_t *)(str + strlen(str));
20542-
ret = next_token(s);
20543-
if (!ret) {
20544-
ret = js_parse_function_decl2(s, func_type, JS_FUNC_NORMAL,
20545-
JS_ATOM_NULL, (uint8_t *)str,
20546-
line_num, JS_PARSE_EXPORT_NONE, pfd);
20547-
}
20548-
s->buf_end = saved_buf_end;
20549-
ret |= js_parse_seek_token(s, &pos);
20550-
return ret;
20551-
}
20552-
2055320518
/* find field in the current scope */
2055420519
static int find_private_class_field(JSContext *ctx, JSFunctionDef *fd,
2055520520
JSAtom name, int scope_level)
@@ -20671,6 +20636,99 @@ static void emit_class_init_end(JSParseState *s, ClassFieldsDef *cf)
2067120636
emit_op(s, OP_set_home_object);
2067220637
}
2067320638

20639+
static void emit_return(JSParseState *s, BOOL hasval);
20640+
20641+
static JSFunctionDef *js_new_function_def(JSContext *ctx,
20642+
JSFunctionDef *parent,
20643+
BOOL is_eval,
20644+
BOOL is_func_expr,
20645+
const char *filename, int line_num);
20646+
20647+
static __exception int js_parse_class_default_ctor(JSParseState *s,
20648+
BOOL has_super,
20649+
JSFunctionDef **pfd)
20650+
{
20651+
JSParseFunctionEnum func_type;
20652+
JSFunctionDef *fd = s->cur_func;
20653+
20654+
fd = js_new_function_def(s->ctx, fd, FALSE, FALSE,
20655+
s->filename, s->token.line_num);
20656+
if (!fd)
20657+
return -1;
20658+
20659+
s->cur_func = fd;
20660+
fd->has_home_object = TRUE;
20661+
fd->super_allowed = TRUE;
20662+
fd->has_prototype = FALSE;
20663+
fd->has_this_binding = TRUE;
20664+
fd->new_target_allowed = TRUE;
20665+
20666+
/* error if not invoked as a constructor */
20667+
emit_op(s, OP_check_ctor);
20668+
20669+
push_scope(s); /* enter body scope */
20670+
fd->body_scope = fd->scope_level;
20671+
if (has_super) {
20672+
fd->is_derived_class_constructor = TRUE;
20673+
fd->super_call_allowed = TRUE;
20674+
fd->arguments_allowed = TRUE;
20675+
fd->has_arguments_binding = TRUE;
20676+
20677+
func_type = JS_PARSE_FUNC_DERIVED_CLASS_CONSTRUCTOR;
20678+
/* super */
20679+
emit_op(s, OP_scope_get_var);
20680+
emit_atom(s, JS_ATOM_this_active_func);
20681+
emit_u16(s, 0);
20682+
20683+
emit_op(s, OP_get_super);
20684+
20685+
emit_op(s, OP_scope_get_var);
20686+
emit_atom(s, JS_ATOM_new_target);
20687+
emit_u16(s, 0);
20688+
20689+
emit_op(s, OP_array_from);
20690+
emit_u16(s, 0);
20691+
emit_op(s, OP_push_i32);
20692+
emit_u32(s, 0);
20693+
20694+
/* arguments */
20695+
emit_op(s, OP_scope_get_var);
20696+
emit_atom(s, JS_ATOM_arguments);
20697+
emit_u16(s, 0);
20698+
20699+
emit_op(s, OP_append);
20700+
/* drop the index */
20701+
emit_op(s, OP_drop);
20702+
20703+
emit_op(s, OP_apply);
20704+
emit_u16(s, 1);
20705+
/* set the 'this' value */
20706+
emit_op(s, OP_dup);
20707+
emit_op(s, OP_scope_put_var_init);
20708+
emit_atom(s, JS_ATOM_this);
20709+
emit_u16(s, 0);
20710+
emit_class_field_init(s);
20711+
} else {
20712+
func_type = JS_PARSE_FUNC_CLASS_CONSTRUCTOR;
20713+
emit_class_field_init(s);
20714+
}
20715+
20716+
fd->func_kind = JS_FUNC_NORMAL;
20717+
fd->func_type = func_type;
20718+
emit_return(s, FALSE);
20719+
20720+
s->cur_func = fd->parent;
20721+
if (pfd)
20722+
*pfd = fd;
20723+
20724+
int idx;
20725+
/* the real object will be set at the end of the compilation */
20726+
idx = cpool_add(s, JS_NULL);
20727+
fd->parent_cpool_idx = idx;
20728+
20729+
return 0;
20730+
}
20731+
2067420732

2067520733
static __exception int js_parse_class(JSParseState *s, BOOL is_class_expr,
2067620734
JSParseExportEnum export_flag)
@@ -23106,8 +23164,6 @@ static __exception int js_parse_cond_expr(JSParseState *s, int parse_flags)
2310623164
return 0;
2310723165
}
2310823166

23109-
static void emit_return(JSParseState *s, BOOL hasval);
23110-
2311123167
/* allowed parse_flags: PF_IN_ACCEPTED */
2311223168
static __exception int js_parse_assign_expr2(JSParseState *s, int parse_flags)
2311323169
{

0 commit comments

Comments
 (0)