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.

classify child closure kind

+60 -6
+60 -6
src/silver/swarm.c
··· 864 864 return (sv_func_t *)(uintptr_t)vdata(cv); 865 865 } 866 866 867 + typedef enum { 868 + JIT_CHILD_PLAIN = 0, 869 + JIT_CHILD_INHERITED_ONLY, 870 + JIT_CHILD_LOCAL_ONLY, 871 + JIT_CHILD_PARAM_ONLY, 872 + JIT_CHILD_MIXED, 873 + } jit_child_kind_t; 874 + 875 + static jit_child_kind_t classify_child_closure_kind(sv_func_t *parent, sv_func_t *child) { 876 + if (!parent || !child || child->upvalue_count <= 0) return JIT_CHILD_PLAIN; 877 + 878 + bool has_inherited = false; 879 + bool has_param = false; 880 + bool has_local = false; 881 + for (int i = 0; i < child->upvalue_count; i++) { 882 + sv_upval_desc_t *desc = &child->upval_descs[i]; 883 + if (!desc->is_local) { 884 + has_inherited = true; 885 + continue; 886 + } 887 + if (desc->index < (uint16_t)parent->param_count) has_param = true; 888 + else has_local = true; 889 + } 890 + 891 + if (has_param && !has_local && !has_inherited) return JIT_CHILD_PARAM_ONLY; 892 + if (has_local && !has_param && !has_inherited) return JIT_CHILD_LOCAL_ONLY; 893 + if (has_inherited && !has_param && !has_local) return JIT_CHILD_INHERITED_ONLY; 894 + return JIT_CHILD_MIXED; 895 + } 896 + 867 897 static bool *scan_captured_locals(sv_func_t *func, int n_locals) { 868 898 if (n_locals <= 0) return NULL; 869 899 bool *captured = calloc((size_t)n_locals, sizeof(bool)); ··· 2335 2365 MIR_reg_t r_tmp2 = MIR_new_func_reg(ctx, jit_func->u.func, MIR_JSVAL, "tmp2"); 2336 2366 MIR_reg_t r_bool = MIR_new_func_reg(ctx, jit_func->u.func, MIR_T_I64, "bool_tmp"); 2337 2367 MIR_reg_t r_err_tmp = MIR_new_func_reg(ctx, jit_func->u.func, MIR_JSVAL, "err_tmp"); 2338 - (void)r_tmp2; 2368 + mir_load_imm(ctx, jit_func, r_tmp2, 0); 2339 2369 2340 2370 jit_features_t feat = jit_prescan_features(func); 2341 2371 ··· 7109 7139 MIR_reg_t dst = vstack_push(&vs); 7110 7140 ant_value_t cv = func->constants[idx]; 7111 7141 sv_func_t *child = (sv_func_t *)(uintptr_t)vdata(cv); 7142 + jit_child_kind_t child_kind = classify_child_closure_kind(func, child); 7143 + MIR_reg_t r_child_slots = r_tmp2; 7144 + int child_slot_base = 0; 7145 + int child_slot_count = 0; 7112 7146 vs.known_func[vs.sp - 1] = (sv_func_t *)(uintptr_t)vdata(cv); 7113 - mir_emit_spill_child_captured_locals( 7114 - ctx, jit_func, func, child, local_regs, n_locals, r_lbuf); 7147 + switch (child_kind) { 7148 + case JIT_CHILD_PLAIN: 7149 + case JIT_CHILD_INHERITED_ONLY: 7150 + break; 7151 + case JIT_CHILD_PARAM_ONLY: 7152 + r_child_slots = r_slotbuf; 7153 + child_slot_count = param_count; 7154 + break; 7155 + case JIT_CHILD_LOCAL_ONLY: 7156 + mir_emit_spill_child_captured_locals( 7157 + ctx, jit_func, func, child, local_regs, n_locals, r_lbuf); 7158 + r_child_slots = r_lbuf; 7159 + child_slot_base = param_count; 7160 + child_slot_count = n_locals; 7161 + break; 7162 + case JIT_CHILD_MIXED: 7163 + mir_emit_spill_child_captured_locals( 7164 + ctx, jit_func, func, child, local_regs, n_locals, r_lbuf); 7165 + r_child_slots = r_slotbuf; 7166 + child_slot_count = slotbuf_count; 7167 + break; 7168 + } 7115 7169 MIR_append_insn(ctx, jit_func, 7116 7170 MIR_new_call_insn(ctx, 11, 7117 7171 MIR_new_ref_op(ctx, closure_proto), ··· 7121 7175 MIR_new_reg_op(ctx, r_js), 7122 7176 MIR_new_reg_op(ctx, r_closure), 7123 7177 MIR_new_reg_op(ctx, r_this), 7124 - MIR_new_reg_op(ctx, has_captured_slots ? r_slotbuf : r_lbuf), 7125 - MIR_new_int_op(ctx, has_captured_slots ? 0 : param_count), 7126 - MIR_new_int_op(ctx, has_captured_slots ? slotbuf_count : n_locals), 7178 + MIR_new_reg_op(ctx, r_child_slots), 7179 + MIR_new_int_op(ctx, child_slot_base), 7180 + MIR_new_int_op(ctx, child_slot_count), 7127 7181 MIR_new_uint_op(ctx, (uint64_t)idx))); 7128 7182 break; 7129 7183 }