aboutsummaryrefslogtreecommitdiff
path: root/src/compiler/stmt.zc
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler/stmt.zc')
-rw-r--r--src/compiler/stmt.zc10
1 files changed, 7 insertions, 3 deletions
diff --git a/src/compiler/stmt.zc b/src/compiler/stmt.zc
index 0182728..6d5abe7 100644
--- a/src/compiler/stmt.zc
+++ b/src/compiler/stmt.zc
@@ -30,7 +30,7 @@ int stmt_inner() {
if (tv == s_semi) { next(); return 0; }
if (tv == s_lb) { block(); return 0; }
}
- c = expr(); rval(); op(O_DROP);
+ c = expr(); rval(); if (c == C_FRESH && drop_tail == here) c = plainuse(c); op(O_DROP);
expect(s_semi);
discard(c);
return 0;
@@ -145,7 +145,7 @@ int localdecl(int typed) {
if (t && t[0] == TY_DYN && is_op(s_lb)) c = array_dynamic_literal(t); else c = expr();
rval(); nomagic = 0; kc = xconst && !xfloat;
if (kc) ltag[i] = ltag[i] | LCONST;
- if (c == C_FRESH) { lnsz[i] = newsz; lleaf[i] = newleaf; }
+ if (c == C_FRESH) { lnsz[i] = newsz; lleaf[i] = newleaf; if (drop_tail == here) local_dropset[i] = 1; }
if (t) fcoerce(t);
vaddr(i);
op(O_ST);
@@ -683,6 +683,7 @@ int kw_return() {
borrow_cleanup();
defer_run(1, 0); // the value is on the stack; the deferred code is stack neutral
exit_vars(1, 0);
+ if (o3blk) { callname(intern("rt.o3_leave")); op(O_DROP); } // a return leaves the o3 block too
epichain = fixnew(here, epichain);
lit(rt.MW - 1); op(O_JMP);
live = 0;
@@ -699,7 +700,9 @@ int kw_o3() {
next();
if (!is_op(s_lb)) { o3one = 1; localdecl(1); o3one = 0; return 0; }
if (o3on || !infn) return block();
+ o3_enter_code();
reserve_code(2); lo = here + 2; lit(lo); op(O_JMP);
+ o3blk++;
o3on = 1; o3reset();
save = nloc; outer = nloc;
i = lbase;
@@ -713,7 +716,7 @@ int kw_o3() {
i++;
}
block();
- o3on = 0;
+ o3on = 0; o3blk--;
if (no3pend >= o3pendcap) { o3pend = chk_resize(o3pend, no3pend * 67, o3pendcap * 2 * 67); o3pendcap = o3pendcap * 2; }
{
p = o3pend + no3pend * 67; p[0] = lo; p[1] = here; p[2] = no3sl;
@@ -733,6 +736,7 @@ int kw_o3() {
}
i++;
}
+ callname(intern("rt.o3_leave")); op(O_DROP);
return 0;
}
// unchecked turns the analyzer off for one statement