MIRROR: javascript for ๐Ÿœ's, a tiny runtime with big ambitions
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

reduce compile times by removing fast path bypass

+65 -69
+65 -69
src/silver/compiler.c
··· 12 12 #include <string.h> 13 13 #include <stdio.h> 14 14 15 - 16 15 enum { 17 16 SV_ITER_HINT_GENERIC = 0, 18 17 SV_ITER_HINT_ARRAY = 1, ··· 3997 3996 emit_op(c, OP_POP); 3998 3997 } 3999 3998 3999 + static inline int compile_class_precompute_key(sv_compiler_t *c, sv_ast_t *key_expr) { 4000 + compile_expr(c, key_expr); 4001 + int loc = add_local(c, "", 0, false, c->scope_depth); 4002 + emit_put_local(c, loc); 4003 + return loc; 4004 + } 4005 + 4000 4006 static void compile_class(sv_compiler_t *c, sv_ast_t *node) { 4001 4007 int outer_name_local = -1; 4002 4008 bool class_repl_top = is_repl_top_level(c); 4003 - if (node->str) 4004 - outer_name_local = resolve_local(c, node->str, node->len); 4009 + sv_ast_t *ctor_method = NULL; 4010 + bool has_static_name = false; 4011 + int field_count = 0; 4012 + int computed_method_count = 0; 4005 4013 4006 - if (node->left) 4007 - compile_expr(c, node->left); 4008 - else 4009 - emit_op(c, OP_UNDEF); 4014 + if (node->str) outer_name_local = resolve_local(c, node->str, node->len); 4015 + if (node->left) compile_expr(c, node->left); 4016 + else emit_op(c, OP_UNDEF); 4010 4017 4011 - sv_ast_t *ctor_method = find_class_constructor(node); 4012 - 4013 - int field_count = 0; 4014 4018 for (int i = 0; i < node->args.count; i++) { 4015 4019 sv_ast_t *m = node->args.items[i]; 4016 4020 if (m->type != N_METHOD) continue; 4017 - if (m == ctor_method) continue; 4018 - if (m->flags & FN_STATIC) continue; 4021 + 4022 + if ( 4023 + !(m->flags & FN_STATIC) && 4024 + !(m->flags & FN_COMPUTED) && 4025 + m->left && m->left->type == N_IDENT && 4026 + m->left->len == 11 && 4027 + memcmp(m->left->str, "constructor", 11) == 0 4028 + ) { ctor_method = m; continue; } 4029 + 4030 + if ( 4031 + (m->flags & FN_STATIC) && 4032 + !(m->flags & FN_COMPUTED) && 4033 + m->left && m->left->str && 4034 + m->left->len == 4 && 4035 + memcmp(m->left->str, "name", 4) == 0 4036 + ) has_static_name = true; 4037 + 4019 4038 bool is_fn = is_class_method_def(m); 4020 - if (!is_fn) field_count++; 4039 + if (!(m->flags & FN_STATIC) && !is_fn) field_count++; 4040 + if (node->str && (m->flags & FN_COMPUTED) && (is_fn || (m->flags & FN_STATIC))) computed_method_count++; 4021 4041 } 4022 4042 4023 4043 sv_ast_t **field_inits = NULL; 4024 4044 int *computed_key_locals = NULL; 4045 + int *method_comp_keys = NULL; 4025 4046 if (field_count > 0) { 4026 4047 field_inits = malloc(sizeof(sv_ast_t *) * field_count); 4027 4048 computed_key_locals = malloc(sizeof(int) * field_count); 4028 - int fi = 0; 4029 - for (int i = 0; i < node->args.count; i++) { 4030 - sv_ast_t *m = node->args.items[i]; 4031 - if (m->type != N_METHOD) continue; 4032 - if (m == ctor_method) continue; 4033 - if (m->flags & FN_STATIC) continue; 4034 - bool is_fn = is_class_method_def(m); 4035 - if (!is_fn) { 4036 - field_inits[fi] = m; 4037 - if (m->flags & FN_COMPUTED) { 4038 - compile_expr(c, m->left); 4039 - int loc = add_local(c, "", 0, false, c->scope_depth); 4040 - emit_put_local(c, loc); 4041 - computed_key_locals[fi] = loc; 4042 - } else computed_key_locals[fi] = -1; 4043 - fi++; 4044 - } 4045 - } 4049 + } 4050 + if (computed_method_count > 0) { 4051 + method_comp_keys = malloc(sizeof(int) * node->args.count); 4052 + for (int i = 0; i < node->args.count; i++) method_comp_keys[i] = -1; 4046 4053 } 4047 4054 4048 - int *method_comp_keys = NULL; 4049 - if (node->str) { 4050 - for (int i = 0; i < node->args.count; i++) { 4051 - sv_ast_t *m = node->args.items[i]; 4052 - if (m->type != N_METHOD || !(m->flags & FN_COMPUTED)) continue; 4053 - if (m == ctor_method) continue; 4054 - bool is_fn = is_class_method_def(m); 4055 - if (!is_fn && !(m->flags & FN_STATIC)) continue; 4056 - if (!method_comp_keys) { 4057 - method_comp_keys = malloc(sizeof(int) * node->args.count); 4058 - for (int j = 0; j < node->args.count; j++) method_comp_keys[j] = -1; 4059 - } 4060 - compile_expr(c, m->left); 4061 - int loc = add_local(c, "", 0, false, c->scope_depth); 4062 - emit_put_local(c, loc); 4063 - method_comp_keys[i] = loc; 4055 + if (field_count > 0 || method_comp_keys) { 4056 + int fi = 0; 4057 + for (int i = 0; i < node->args.count; i++) { 4058 + sv_ast_t *m = node->args.items[i]; 4059 + if (m->type != N_METHOD || m == ctor_method) continue; 4060 + 4061 + bool is_fn = is_class_method_def(m); 4062 + bool is_instance_field = !(m->flags & FN_STATIC) && !is_fn; 4063 + 4064 + if (is_instance_field) { 4065 + if (field_inits) field_inits[fi] = m; 4066 + if (computed_key_locals) computed_key_locals[fi] = (m->flags & FN_COMPUTED) 4067 + ? compile_class_precompute_key(c, m->left) : -1; 4068 + fi++; 4069 + continue; 4064 4070 } 4065 - } 4071 + 4072 + if (!method_comp_keys || !(m->flags & FN_COMPUTED)) continue; 4073 + method_comp_keys[i] = compile_class_precompute_key(c, m->left); 4074 + }} 4066 4075 4067 4076 int inner_name_local = -1; 4068 4077 if (node->str) { ··· 4085 4094 comp.filename = c->filename; 4086 4095 comp.source = c->source; 4087 4096 comp.source_len = c->source_len; 4097 + comp.line_table = c->line_table; 4088 4098 comp.enclosing = c; 4089 4099 comp.scope_depth = 0; 4090 4100 comp.is_strict = c->is_strict; ··· 4156 4166 free(computed_key_locals); 4157 4167 c->computed_key_locals = NULL; 4158 4168 4159 - bool has_static_name = false; 4160 - for (int i = 0; i < node->args.count; i++) { 4161 - sv_ast_t *m = node->args.items[i]; 4162 - if (m->type != N_METHOD) continue; 4163 - if (!(m->flags & FN_STATIC)) continue; 4164 - if (m->flags & FN_COMPUTED) continue; 4165 - if (m->left && m->left->str && m->left->len == 4 && 4166 - memcmp(m->left->str, "name", 4) == 0) { 4167 - has_static_name = true; 4168 - break; 4169 - } 4170 - } 4171 - 4172 4169 if (node->str && !has_static_name) { 4173 4170 int atom = add_atom(c, node->str, node->len); 4174 4171 emit_op(c, OP_DEFINE_CLASS); ··· 4262 4259 comp.param_locals = comp.local_count; 4263 4260 4264 4261 if (!comp.is_strict && node->body && node->body->type == N_BLOCK) { 4265 - for (int i = 0; i < node->body->args.count; i++) { 4266 - sv_ast_t *stmt = node->body->args.items[i]; 4267 - if (!stmt || stmt->type == N_EMPTY) continue; 4268 - if (stmt->type != N_STRING) break; 4269 - if (sv_ast_is_use_strict(comp.js, stmt)) comp.is_strict = true; 4270 - } 4271 - } 4262 + for (int i = 0; i < node->body->args.count; i++) { 4263 + sv_ast_t *stmt = node->body->args.items[i]; 4264 + if (!stmt || stmt->type == N_EMPTY) continue; 4265 + if (stmt->type != N_STRING) break; 4266 + if (sv_ast_is_use_strict(comp.js, stmt)) comp.is_strict = true; 4267 + }} 4272 4268 4273 4269 if (comp.is_strict) { 4274 4270 const char *param_names[256]; ··· 4879 4875 root.source_len = source_len; 4880 4876 root.mode = mode; 4881 4877 root.is_strict = ((program->flags & FN_PARSE_STRICT) != 0); 4882 - 4883 4878 root.line_table = build_line_table(root.source, source_len); 4884 4879 sv_func_t *func = compile_function_body(&root, &top_fn, mode); 4885 4880 free_line_table(root.line_table); 4886 4881 if (js->thrown_exists || !func) return NULL; 4882 + 4887 4883 return func; 4888 4884 } 4889 4885