guards in mcode

This commit is contained in:
2026-02-13 02:30:41 -06:00
parent e346348eb5
commit 4a50d0587d
14 changed files with 72485 additions and 69473 deletions

View File

@@ -782,13 +782,12 @@ var mcode = function(ast) {
var name_str = alloc_slot()
emit_const_str(name_str, prop)
var args_arr = alloc_slot()
var arr_instr = ["array", args_arr, argc]
add_instr(["array", args_arr, 0])
_i = 0
while (_i < argc) {
push(arr_instr, args[_i])
emit_2("push", args_arr, args[_i])
_i = _i + 1
}
add_instr(arr_instr)
var pf = alloc_slot()
emit_3("frame", pf, obj, 2)
emit_3("setarg", pf, 0, null_slot)
@@ -836,13 +835,12 @@ var mcode = function(ast) {
var null_slot = alloc_slot()
emit_const_null(null_slot)
var args_arr = alloc_slot()
var arr_instr = ["array", args_arr, argc]
add_instr(["array", args_arr, 0])
_i = 0
while (_i < argc) {
push(arr_instr, args[_i])
emit_2("push", args_arr, args[_i])
_i = _i + 1
}
add_instr(arr_instr)
var pf = alloc_slot()
emit_3("frame", pf, obj, 2)
emit_3("setarg", pf, 0, null_slot)
@@ -1181,17 +1179,29 @@ var mcode = function(ast) {
var obj_slot = 0
var idx_expr = null
var idx_slot = 0
var guard_t = 0
var guard_err = null
var guard_done = null
if (cop != null) {
return gen_compound_assign(node, cop)
}
// Push syntax: arr[] = val
// Push syntax: arr[] = val (guarded)
if (node.push == true) {
arr_expr = left.left
arr_slot = gen_expr(arr_expr, -1)
val_slot = gen_expr(right, -1)
guard_t = alloc_slot()
guard_err = gen_label("push_err")
guard_done = gen_label("push_done")
emit_2("is_array", guard_t, arr_slot)
emit_jump_cond("jump_false", guard_t, guard_err)
emit_2("push", arr_slot, val_slot)
emit_jump(guard_done)
emit_label(guard_err)
emit_0("disrupt")
emit_label(guard_done)
return val_slot
}
@@ -1306,6 +1316,9 @@ var mcode = function(ast) {
var kname = null
var func = null
var func_id = 0
var guard_t = 0
var guard_err = null
var guard_done = null
if (expr == null) {
return -1
@@ -1343,13 +1356,12 @@ var mcode = function(ast) {
}
// Create array from expression results
arr_slot = alloc_slot()
arr_instr = ["array", arr_slot, nexpr]
add_instr(["array", arr_slot, 0])
_i = 0
while (_i < nexpr) {
push(arr_instr, expr_slots[_i])
emit_2("push", arr_slot, expr_slots[_i])
_i = _i + 1
}
add_instr(arr_instr)
// Load format intrinsic
fmt_func_slot = find_intrinsic("format")
if (fmt_func_slot < 0) {
@@ -1546,11 +1558,20 @@ var mcode = function(ast) {
return d
}
}
// 2-arg push: push(arr, val) → direct opcode
// 2-arg push: push(arr, val) → guarded direct opcode
if (nargs == 2 && fname == "push") {
a0 = gen_expr(args_list[0], -1)
a1 = gen_expr(args_list[1], -1)
guard_t = alloc_slot()
guard_err = gen_label("push_err")
guard_done = gen_label("push_done")
emit_2("is_array", guard_t, a0)
emit_jump_cond("jump_false", guard_t, guard_err)
emit_2("push", a0, a1)
emit_jump(guard_done)
emit_label(guard_err)
emit_0("disrupt")
emit_label(guard_done)
return a1
}
}
@@ -1732,13 +1753,12 @@ var mcode = function(ast) {
_i = _i + 1
}
dest = alloc_slot()
instr = ["array", dest, count]
add_instr(["array", dest, 0])
_i = 0
while (_i < count) {
push(instr, elem_slots[_i])
emit_2("push", dest, elem_slots[_i])
_i = _i + 1
}
push(s_instructions, instr)
return dest
}
@@ -1856,6 +1876,9 @@ var mcode = function(ast) {
var func = null
var func_id = 0
var dest = 0
var guard_t = 0
var guard_err = null
var guard_done = null
if (stmt == null) {
return null
@@ -1871,12 +1894,21 @@ var mcode = function(ast) {
right = stmt.right
name = left.name
local_slot = find_var(name)
// Pop: var val = arr[]
// Pop: var val = arr[] (guarded)
if (stmt.pop == true && right != null) {
arr_expr = right.left
arr_slot = gen_expr(arr_expr, -1)
if (local_slot >= 0) {
guard_t = alloc_slot()
guard_err = gen_label("pop_err")
guard_done = gen_label("pop_done")
emit_2("is_array", guard_t, arr_slot)
emit_jump_cond("jump_false", guard_t, guard_err)
emit_2("pop", local_slot, arr_slot)
emit_jump(guard_done)
emit_label(guard_err)
emit_0("disrupt")
emit_label(guard_done)
}
return null
}