guards in mcode
This commit is contained in:
62
mcode.cm
62
mcode.cm
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user