wary jumps
This commit is contained in:
102
qbe_emit.cm
102
qbe_emit.cm
@@ -633,6 +633,15 @@ ${sr("gc", "%idx_slot")}
|
||||
${sr("a", "%fn_slot")}
|
||||
%r =l call $cell_rt_frame(l %ctx, l %a, l %nargs)
|
||||
${alloc_tail("%r")}
|
||||
}`
|
||||
|
||||
// apply(ctx, fp, dest, fn_slot, arg_slot)
|
||||
h[] = `export function l $__apply_ss(l %ctx, l %fp, l %dest, l %fn_slot, l %arg_slot) ${lb}
|
||||
@entry
|
||||
${sr("a", "%fn_slot")}
|
||||
${sr("b", "%arg_slot")}
|
||||
%r =l call $cell_rt_apply(l %ctx, l %a, l %b)
|
||||
${alloc_tail("%r")}
|
||||
}`
|
||||
|
||||
// goframe(ctx, fp, dest, fn_slot, nargs)
|
||||
@@ -1023,6 +1032,18 @@ var qbe_emit = function(ir, qbe, export_name) {
|
||||
var jnn_lbl = null
|
||||
var jnn_idx = null
|
||||
var jnn_backedge = false
|
||||
var wt_lbl = null
|
||||
var wt_idx = null
|
||||
var wt_backedge = false
|
||||
var wf_lbl = null
|
||||
var wf_idx = null
|
||||
var wf_backedge = false
|
||||
var jn_lbl = null
|
||||
var jn_idx = null
|
||||
var jn_backedge = false
|
||||
var je_lbl = null
|
||||
var je_idx = null
|
||||
var je_backedge = false
|
||||
var truthy = null
|
||||
var lhs_d = null
|
||||
var rhs_d = null
|
||||
@@ -2625,8 +2646,8 @@ var qbe_emit = function(ir, qbe, export_name) {
|
||||
jt_lbl = sanitize(a2)
|
||||
jt_idx = label_pos[jt_lbl]
|
||||
jt_backedge = jt_idx != null && jt_idx < instr_idx
|
||||
truthy = emit_truthy_w(v)
|
||||
emit(` jnz ${truthy}, @${p}_take, @${p}_f`)
|
||||
emit(` %${p}_take =w ceql ${v}, ${text(qbe.js_true)}`)
|
||||
emit(` jnz %${p}_take, @${p}_take, @${p}_f`)
|
||||
emit(`@${p}_take`)
|
||||
if (jt_backedge) {
|
||||
emit_backedge_branch(jt_lbl)
|
||||
@@ -2642,8 +2663,8 @@ var qbe_emit = function(ir, qbe, export_name) {
|
||||
jf_lbl = sanitize(a2)
|
||||
jf_idx = label_pos[jf_lbl]
|
||||
jf_backedge = jf_idx != null && jf_idx < instr_idx
|
||||
truthy = emit_truthy_w(v)
|
||||
emit(` jnz ${truthy}, @${p}_t, @${p}_take`)
|
||||
emit(` %${p}_take =w ceql ${v}, ${text(qbe.js_false)}`)
|
||||
emit(` jnz %${p}_take, @${p}_take, @${p}_t`)
|
||||
emit(`@${p}_take`)
|
||||
if (jf_backedge) {
|
||||
emit_backedge_branch(jf_lbl)
|
||||
@@ -2653,6 +2674,74 @@ var qbe_emit = function(ir, qbe, export_name) {
|
||||
emit(`@${p}_t`)
|
||||
continue
|
||||
}
|
||||
if (op == "wary_true") {
|
||||
v = s_read(a1)
|
||||
p = fresh()
|
||||
wt_lbl = sanitize(a2)
|
||||
wt_idx = label_pos[wt_lbl]
|
||||
wt_backedge = wt_idx != null && wt_idx < instr_idx
|
||||
truthy = emit_truthy_w(v)
|
||||
emit(` jnz ${truthy}, @${p}_take, @${p}_f`)
|
||||
emit(`@${p}_take`)
|
||||
if (wt_backedge) {
|
||||
emit_backedge_branch(wt_lbl)
|
||||
} else {
|
||||
emit(` jmp @${wt_lbl}`)
|
||||
}
|
||||
emit(`@${p}_f`)
|
||||
continue
|
||||
}
|
||||
if (op == "wary_false") {
|
||||
v = s_read(a1)
|
||||
p = fresh()
|
||||
wf_lbl = sanitize(a2)
|
||||
wf_idx = label_pos[wf_lbl]
|
||||
wf_backedge = wf_idx != null && wf_idx < instr_idx
|
||||
truthy = emit_truthy_w(v)
|
||||
emit(` jnz ${truthy}, @${p}_t, @${p}_take`)
|
||||
emit(`@${p}_take`)
|
||||
if (wf_backedge) {
|
||||
emit_backedge_branch(wf_lbl)
|
||||
} else {
|
||||
emit(` jmp @${wf_lbl}`)
|
||||
}
|
||||
emit(`@${p}_t`)
|
||||
continue
|
||||
}
|
||||
if (op == "jump_null") {
|
||||
v = s_read(a1)
|
||||
p = fresh()
|
||||
jn_lbl = sanitize(a2)
|
||||
jn_idx = label_pos[jn_lbl]
|
||||
jn_backedge = jn_idx != null && jn_idx < instr_idx
|
||||
emit(` %${p} =w ceql ${v}, ${text(qbe.js_null)}`)
|
||||
if (jn_backedge) {
|
||||
emit(` jnz %${p}, @${p}_bn, @${p}_n`)
|
||||
emit(`@${p}_bn`)
|
||||
emit_backedge_branch(jn_lbl)
|
||||
} else {
|
||||
emit(` jnz %${p}, @${jn_lbl}, @${p}_n`)
|
||||
}
|
||||
emit(`@${p}_n`)
|
||||
continue
|
||||
}
|
||||
if (op == "jump_empty") {
|
||||
v = s_read(a1)
|
||||
p = fresh()
|
||||
je_lbl = sanitize(a2)
|
||||
je_idx = label_pos[je_lbl]
|
||||
je_backedge = je_idx != null && je_idx < instr_idx
|
||||
emit(` %${p} =w ceql ${v}, ${text(qbe.js_empty_text)}`)
|
||||
if (je_backedge) {
|
||||
emit(` jnz %${p}, @${p}_bn, @${p}_n`)
|
||||
emit(`@${p}_bn`)
|
||||
emit_backedge_branch(je_lbl)
|
||||
} else {
|
||||
emit(` jnz %${p}, @${je_lbl}, @${p}_n`)
|
||||
}
|
||||
emit(`@${p}_n`)
|
||||
continue
|
||||
}
|
||||
if (op == "jump_not_null") {
|
||||
v = s_read(a1)
|
||||
p = fresh()
|
||||
@@ -2678,6 +2767,11 @@ var qbe_emit = function(ir, qbe, export_name) {
|
||||
emit_exc_check()
|
||||
continue
|
||||
}
|
||||
if (op == "apply") {
|
||||
emit(` %fp =l call $__apply_ss(l %ctx, l %fp, l ${text(a1)}, l ${text(a2)}, l ${text(a3)})`)
|
||||
emit_exc_check()
|
||||
continue
|
||||
}
|
||||
if (op == "setarg") {
|
||||
v = s_read(a1)
|
||||
lhs = s_read(a3)
|
||||
|
||||
Reference in New Issue
Block a user