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.

proper boxing for value stack operations in various contexts

+66 -47
-1
.gitignore
··· 28 28 *.todo 29 29 *.trace 30 30 31 - ant.txt 32 31 zoo.sh 33 32 AGENTS.md 34 33
+66 -46
src/silver/swarm.c
··· 240 240 MIR_new_uint_op(ctx, imm))); 241 241 } 242 242 243 + static inline void mir_emit_self_tail( 244 + MIR_context_t ctx, MIR_item_t fn, 245 + int call_argc, int param_count, 246 + MIR_reg_t r_tco_args, MIR_reg_t r_arg_arr, 247 + MIR_reg_t r_args, MIR_reg_t r_argc, 248 + MIR_reg_t *local_regs, int n_locals, 249 + bool has_captures, bool *captured_locals, 250 + MIR_reg_t r_lbuf, MIR_label_t entry 251 + ) { 252 + for (int i = 0; i < call_argc && i < param_count; i++) 253 + MIR_append_insn(ctx, fn, 254 + MIR_new_insn(ctx, MIR_MOV, 255 + MIR_new_mem_op(ctx, MIR_T_I64, 256 + (MIR_disp_t)(i * (int)sizeof(ant_value_t)), r_tco_args, 0, 1), 257 + MIR_new_mem_op(ctx, MIR_T_I64, 258 + (MIR_disp_t)(i * (int)sizeof(ant_value_t)), r_arg_arr, 0, 1))); 259 + MIR_append_insn(ctx, fn, 260 + MIR_new_insn(ctx, MIR_MOV, 261 + MIR_new_reg_op(ctx, r_args), 262 + MIR_new_reg_op(ctx, r_tco_args))); 263 + MIR_append_insn(ctx, fn, 264 + MIR_new_insn(ctx, MIR_MOV, 265 + MIR_new_reg_op(ctx, r_argc), 266 + MIR_new_int_op(ctx, (int64_t)call_argc))); 267 + for (int i = 0; i < n_locals; i++) 268 + mir_load_imm(ctx, fn, local_regs[i], mkval(T_UNDEF, 0)); 269 + if (has_captures) { 270 + for (int i = 0; i < n_locals; i++) 271 + if (captured_locals[i]) 272 + MIR_append_insn(ctx, fn, 273 + MIR_new_insn(ctx, MIR_MOV, 274 + MIR_new_mem_op(ctx, MIR_T_I64, 275 + (MIR_disp_t)(i * (int)sizeof(ant_value_t)), r_lbuf, 0, 1), 276 + MIR_new_uint_op(ctx, mkval(T_UNDEF, 0)))); 277 + } 278 + MIR_append_insn(ctx, fn, 279 + MIR_new_insn(ctx, MIR_JMP, 280 + MIR_new_label_op(ctx, entry))); 281 + } 243 282 244 283 static inline bool jit_const_is_heap(ant_value_t cv) { 245 284 uint8_t t = vtype(cv); ··· 727 766 bool needs_args_buf; 728 767 bool needs_close_upval; 729 768 bool needs_args_norm; 769 + bool needs_tco_args; 730 770 } jit_features_t; 731 771 732 772 static jit_features_t jit_prescan_features(sv_func_t *func) { 733 - jit_features_t f = {false, false, false, false, false}; 773 + jit_features_t f = {0}; 734 774 uint8_t *ip = func->code; 735 775 uint8_t *end = func->code + func->code_len; 736 776 while (ip < end) { ··· 755 795 case OP_TAIL_CALL: case OP_TAIL_CALL_METHOD: 756 796 case OP_ARRAY: case OP_NEW: 757 797 f.needs_args_buf = true; 798 + if (op == OP_TAIL_CALL || op == OP_TAIL_CALL_METHOD) 799 + f.needs_tco_args = true; 758 800 break; 759 801 case OP_CLOSE_UPVAL: case OP_CLOSURE: 760 802 f.needs_close_upval = true; ··· 1250 1292 mir_load_imm(ctx, jit_func, r_args_buf, 0); 1251 1293 } 1252 1294 1295 + MIR_reg_t r_tco_args = MIR_new_func_reg(ctx, jit_func->u.func, MIR_T_I64, "tco_args"); 1253 1296 MIR_reg_t r_cond_d = 0, r_cond_nan = 0, r_cond_zd = 0, r_cond_zero = 0; 1254 - 1255 1297 bool needs_bailout = feat.needs_bailout; 1256 1298 1257 1299 MIR_reg_t r_bailout_val = MIR_new_func_reg(ctx, jit_func->u.func, MIR_JSVAL, "bail_val"); ··· 1288 1330 } 1289 1331 1290 1332 int param_count = func->param_count; 1333 + if (feat.needs_tco_args && param_count > 0) { 1334 + MIR_append_insn(ctx, jit_func, 1335 + MIR_new_insn(ctx, MIR_ALLOCA, 1336 + MIR_new_reg_op(ctx, r_tco_args), 1337 + MIR_new_uint_op(ctx, (uint64_t)param_count * sizeof(ant_value_t)))); 1338 + } else mir_load_imm(ctx, jit_func, r_tco_args, 0); 1291 1339 if (param_count > 0 && feat.needs_args_norm) { 1292 1340 MIR_label_t args_ok = MIR_new_label(ctx); 1293 1341 MIR_append_insn(ctx, jit_func, ··· 1545 1593 1546 1594 case OP_SET_ARG: { 1547 1595 uint16_t idx = sv_get_u16(ip + 1); 1596 + vstack_ensure_boxed(&vs, vs.sp - 1, ctx, jit_func, r_d_slot); 1548 1597 MIR_reg_t val = vstack_top(&vs); 1549 1598 MIR_append_insn(ctx, jit_func, 1550 1599 MIR_new_insn(ctx, MIR_MOV, ··· 3195 3244 3196 3245 if (call_known == func) { 3197 3246 if (is_tail && jit_try_depth == 0) { 3198 - MIR_append_insn(ctx, jit_func, 3199 - MIR_new_insn(ctx, MIR_MOV, 3200 - MIR_new_reg_op(ctx, r_args), 3201 - MIR_new_reg_op(ctx, r_arg_arr))); 3202 - MIR_append_insn(ctx, jit_func, 3203 - MIR_new_insn(ctx, MIR_MOV, 3204 - MIR_new_reg_op(ctx, r_argc), 3205 - MIR_new_int_op(ctx, (int64_t)call_argc))); 3206 - for (int i = 0; i < n_locals; i++) 3207 - mir_load_imm(ctx, jit_func, local_regs[i], mkval(T_UNDEF, 0)); 3208 - if (has_captures) { 3209 - for (int i = 0; i < n_locals; i++) 3210 - if (captured_locals[i]) 3211 - MIR_append_insn(ctx, jit_func, 3212 - MIR_new_insn(ctx, MIR_MOV, 3213 - MIR_new_mem_op(ctx, MIR_T_I64, 3214 - (MIR_disp_t)(i * (int)sizeof(ant_value_t)), r_lbuf, 0, 1), 3215 - MIR_new_uint_op(ctx, mkval(T_UNDEF, 0)))); 3216 - } 3217 - MIR_append_insn(ctx, jit_func, 3218 - MIR_new_insn(ctx, MIR_JMP, 3219 - MIR_new_label_op(ctx, self_tail_entry))); 3247 + mir_emit_self_tail(ctx, jit_func, (int)call_argc, param_count, 3248 + r_tco_args, r_arg_arr, r_args, r_argc, 3249 + local_regs, n_locals, has_captures, 3250 + captured_locals, r_lbuf, self_tail_entry); 3220 3251 break; 3221 3252 } 3222 3253 MIR_append_insn(ctx, jit_func, ··· 3335 3366 3336 3367 MIR_append_insn(ctx, jit_func, lbl_self_call); 3337 3368 if (is_tail && jit_try_depth == 0) { 3338 - MIR_append_insn(ctx, jit_func, 3339 - MIR_new_insn(ctx, MIR_MOV, 3340 - MIR_new_reg_op(ctx, r_args), 3341 - MIR_new_reg_op(ctx, r_arg_arr))); 3342 - MIR_append_insn(ctx, jit_func, 3343 - MIR_new_insn(ctx, MIR_MOV, 3344 - MIR_new_reg_op(ctx, r_argc), 3345 - MIR_new_int_op(ctx, (int64_t)call_argc))); 3346 - for (int i = 0; i < n_locals; i++) 3347 - mir_load_imm(ctx, jit_func, local_regs[i], mkval(T_UNDEF, 0)); 3348 - if (has_captures) { 3349 - for (int i = 0; i < n_locals; i++) 3350 - if (captured_locals[i]) 3351 - MIR_append_insn(ctx, jit_func, 3352 - MIR_new_insn(ctx, MIR_MOV, 3353 - MIR_new_mem_op(ctx, MIR_T_I64, 3354 - (MIR_disp_t)(i * (int)sizeof(ant_value_t)), r_lbuf, 0, 1), 3355 - MIR_new_uint_op(ctx, mkval(T_UNDEF, 0)))); 3356 - } 3357 - MIR_append_insn(ctx, jit_func, 3358 - MIR_new_insn(ctx, MIR_JMP, 3359 - MIR_new_label_op(ctx, self_tail_entry))); 3369 + mir_emit_self_tail(ctx, jit_func, (int)call_argc, param_count, 3370 + r_tco_args, r_arg_arr, r_args, r_argc, 3371 + local_regs, n_locals, has_captures, 3372 + captured_locals, r_lbuf, self_tail_entry); 3360 3373 } else { 3361 3374 MIR_append_insn(ctx, jit_func, 3362 3375 MIR_new_call_insn(ctx, 8, ··· 3919 3932 uint32_t idx = sv_get_u32(ip + 1); 3920 3933 if (idx >= (uint32_t)func->atom_count) { ok = false; break; } 3921 3934 sv_atom_t *atom = &func->atoms[idx]; 3935 + vstack_ensure_boxed(&vs, vs.sp - 1, ctx, jit_func, r_d_slot); 3922 3936 MIR_reg_t val = vstack_pop(&vs); 3923 3937 MIR_reg_t obj = vstack_pop(&vs); 3924 3938 MIR_append_insn(ctx, jit_func, ··· 3964 3978 uint32_t idx = sv_get_u32(ip + 1); 3965 3979 if (idx >= (uint32_t)func->atom_count) { ok = false; break; } 3966 3980 sv_atom_t *atom = &func->atoms[idx]; 3981 + vstack_ensure_boxed(&vs, vs.sp - 1, ctx, jit_func, r_d_slot); 3967 3982 MIR_reg_t val = vstack_pop(&vs); 3968 3983 MIR_reg_t obj = vstack_top(&vs); 3969 3984 MIR_append_insn(ctx, jit_func, ··· 4058 4073 } 4059 4074 4060 4075 case OP_PUT_ELEM: { 4076 + vstack_ensure_boxed(&vs, vs.sp - 1, ctx, jit_func, r_d_slot); 4061 4077 MIR_reg_t val = vstack_pop(&vs); 4062 4078 MIR_reg_t key = vstack_pop(&vs); 4063 4079 MIR_reg_t obj = vstack_pop(&vs); ··· 4103 4119 uint32_t idx = sv_get_u32(ip + 1); 4104 4120 if (idx >= (uint32_t)func->atom_count) { ok = false; break; } 4105 4121 sv_atom_t *atom = &func->atoms[idx]; 4122 + vstack_ensure_boxed(&vs, vs.sp - 1, ctx, jit_func, r_d_slot); 4106 4123 MIR_reg_t val = vstack_pop(&vs); 4107 4124 MIR_append_insn(ctx, jit_func, 4108 4125 MIR_new_call_insn(ctx, 9, ··· 4158 4175 case OP_ARRAY: { 4159 4176 uint16_t n = sv_get_u16(ip + 1); 4160 4177 if (vs.sp < (int)n) { ok = false; break; } 4178 + for (int i = 0; i < (int)n; i++) 4179 + vstack_ensure_boxed(&vs, vs.sp - 1 - i, ctx, jit_func, r_d_slot); 4161 4180 for (int i = (int)n - 1; i >= 0; i--) { 4162 4181 MIR_reg_t elem = vstack_pop(&vs); 4163 4182 MIR_append_insn(ctx, jit_func, ··· 4181 4200 } 4182 4201 4183 4202 case OP_SET_PROTO: { 4203 + vstack_ensure_boxed(&vs, vs.sp - 1, ctx, jit_func, r_d_slot); 4184 4204 MIR_reg_t proto = vstack_pop(&vs); 4185 4205 MIR_reg_t obj = vstack_top(&vs); 4186 4206 mir_call_helper2(ctx, jit_func, r_err_tmp,