aboutsummaryrefslogtreecommitdiff
path: root/src/compiler/decl.zc
diff options
context:
space:
mode:
authorGravatar zinc <zinc@downsta.ir> 2026-10-14 16:09:07 +0330
committerGravatar zinc <zinc@downsta.ir> 2026-10-14 16:09:07 +0330
commite228e7609929763d5acddb728ba543832fcffc6a (patch)
tree9b4ecc4d46bf38e8d20234d631a6d41543daa211 /src/compiler/decl.zc
parentmerge: memdebug obj_base via size classes (diff)
parentbounds checking: constant loop bound proof works, plain-op fixed-array check,... (diff)
merge bounds checking
Diffstat (limited to 'src/compiler/decl.zc')
-rw-r--r--src/compiler/decl.zc34
1 files changed, 21 insertions, 13 deletions
diff --git a/src/compiler/decl.zc b/src/compiler/decl.zc
index 0870756..3a02b90 100644
--- a/src/compiler/decl.zc
+++ b/src/compiler/decl.zc
@@ -153,7 +153,7 @@ int unit_stdin() {
// that a nested compile would otherwise clobber (locals, depth, frame size,
// loop stack position, the expression-state globals). closures use the same
// pair.
-const int CTX_WORDS = 49;
+const int CTX_WORDS = 50;
int ctx_push() {
af_forget();
word f;
@@ -164,7 +164,7 @@ int ctx_push() {
f[13] = lv; f[14] = lvk; f[15] = lvi; f[16] = kw_expr; f[17] = xcls; f[18] = snaptop;
f[19] = fty; f[20] = ntp; f[21] = xty; rt.copy_w(f + 22, tpn, 8);
f[30] = finsym; f[31] = finfer; f[32] = ifcur; f[33] = ifcall; f[34] = effect_current; f[35] = borrow_slots; f[36] = borrow_pending; f[37] = borrow_depth; f[38] = borrow_jump; f[39] = borrow_entry; f[40] = capture_enabled; f[41] = effect_value; f[42] = xprojection; f[43] = effect_floor; f[44] = module_name; f[45] = module_imports;
- f[46] = fn_return_type; f[47] = if_value; f[48] = dfr_base;
+ f[46] = fn_return_type; f[47] = if_value; f[48] = dfr_base; f[49] = fbnd;
return 0;
}
// pop the innermost function context.
@@ -186,7 +186,7 @@ int ctx_pop() {
lv = f[13]; lvk = f[14]; lvi = f[15]; kw_expr = f[16]; xcls = f[17]; snaptop = f[18];
fty = f[19]; ntp = f[20]; xty = f[21]; rt.copy_w(tpn, f + 22, 8);
finsym = f[30]; finfer = f[31]; ifcur = f[32]; ifcall = f[33]; effect_current = f[34]; borrow_slots = f[35]; borrow_pending = f[36]; borrow_depth = f[37]; borrow_jump = f[38]; borrow_entry = f[39]; capture_enabled = f[40]; effect_value = f[41]; xprojection = f[42]; effect_floor = f[43]; module_name = f[44]; module_imports = f[45]; xvk = 0;
- fn_return_type = f[46]; if_value = f[47];
+ fn_return_type = f[46]; if_value = f[47]; fbnd = f[49];
return 0;
}
@@ -206,10 +206,12 @@ int fn_begin(int chk, int ret) {
if (cmode && svkind && !dry) rt.fill_w(svkind, 0, nsym); xvk = 0;
lend_drop(1 << 30, nloc);
dfr_base = ndfr;
- lbase = nloc; fdepth = 1; fslots = 0; fchk = chk && check_on; fret = ret; fty = 0; finfer = 0; fn_return_type = 0;
+ lbase = nloc; fdepth = 1; fslots = 0; fchk = chk && check_on; fbnd = !bnxt && bound_on; bnxt = 0; fret = ret; fty = 0; finfer = 0; fn_return_type = 0;
live = 1; bxdepth = 0; epichain = 0; infn = 1; loopbase = lsp; lv = 0; lvk = LV_NONE; xbor = -1;
return 0;
}
+// the bounds flag of the function that was being compiled when the innermost context was pushed
+int ctx_bnd() { return R_CTX[(ctxsp - 1) * CTX_WORDS + 49]; }
// allocate the frame, retaining the caller's pointer until any growth finishes.
int prologue() {
int k, busy, done, helper = !nclo && (sname[finsym] == s_frame_grow || sname[finsym] == s_frame_leave);
@@ -570,7 +572,7 @@ int topsync() {
if (is_op(s_lb)) depth++;
else if (is_op(s_rb)) { depth--; if (depth < 0) depth = 0; }
else if (!depth && tk == T_ID && (tv == s_fn || tv == s_var || tv == s_const || tv == s_struct || tv == s_type || tv == s_typedef
- || tv == s_enhance || tv == s_typecheck || tv == s_docs || tv == s_lines || tv == s_unchecked || tv == s_immediate || tv == s_o3
+ || tv == s_enhance || tv == s_typecheck || tv == s_docs || tv == s_lines || tv == s_unchecked || tv == s_unbounded || tv == s_immediate || tv == s_o3
|| tv == s_memdebug || tv == s_enum || tv == s_include)) break;
next();
}
@@ -647,14 +649,20 @@ int topitem0() {
int topitem1() {
int chk = 1, imm = 0, s, k, n;
if (panic) return topsync();
- if (is_id(s_unchecked)) {
- next();
- if (accept(s_semi)) { check_on = 0; return 0; } // unchecked; switches the analyzer off from here on
- chk = 0;
+ o3nxt = 0; bnxt = 0;
+ while (1) { // the prefixes, in any order
+ if (is_id(s_unchecked)) {
+ next();
+ if (accept(s_semi)) { check_on = 0; return 0; } // unchecked; switches the analyzer off from here on
+ chk = 0;
+ } else if (is_id(s_unbounded)) {
+ next();
+ if (accept(s_semi)) { bound_on = 0; return 0; } // unbounded; switches the index bounds checks off from here on
+ bnxt = 1;
+ } else if (is_id(s_immediate)) { next(); imm = 1; }
+ else if (is_id(s_o3)) { next(); o3nxt = 1; }
+ else break;
}
- if (is_id(s_immediate)) { next(); imm = 1; }
- o3nxt = 0;
- if (is_id(s_o3)) { next(); o3nxt = 1; }
ntp = 0; ifkk = 0;
if (is_id(s_fn)) {
peek();
@@ -669,7 +677,7 @@ int topitem1() {
return fndone(fndef(chk, 0, 0, n), imm);
}
}
- if (!chk || imm || o3nxt) { // has to be a function, with a return type
+ if (!chk || imm || o3nxt || bnxt) { // has to be a function, with a return type
ifkp = tpack(); ifkk = 0 - 1; if (is_op(s_dot)) ifkk = 2;
if (isp != 0) ifkk = 0;
rettype(); n = name(); if (ginst) n = ginsn; genparams();