aboutsummaryrefslogtreecommitdiff
path: root/src/compiler/expr.zc
diff options
context:
space:
mode:
authorGravatar zinc <zinc@downsta.ir> 2026-10-15 14:32:10 +0330
committerGravatar zinc <zinc@downsta.ir> 2026-10-15 14:32:10 +0330
commit253ac862c696d73fb17c14a847270b6e08aa8769 (patch)
tree0206220c056ad9559d6924dbd2c8428b54b326cf /src/compiler/expr.zc
parentactors: micro workers map a copy-on-write snapshot too; inherited input is on... (diff)
hold blocks: top-level hold { shared let ...; fn ... } monitors; shared values kept by the host and copied in/out at the outermost call, reentrant per-block locks in declaration order (core, micro)
Diffstat (limited to 'src/compiler/expr.zc')
-rw-r--r--src/compiler/expr.zc10
1 files changed, 10 insertions, 0 deletions
diff --git a/src/compiler/expr.zc b/src/compiler/expr.zc
index a6cc55c..141ca16 100644
--- a/src/compiler/expr.zc
+++ b/src/compiler/expr.zc
@@ -657,6 +657,15 @@ word closure_layout(int closure_index, int count) {
// the code that creates the closure runs, it allocates the block (code, then
// captured values), writes the three code words and copies each captured
// variable in. ctx_push / ctx_pop save and restore the enclosing function's
+// a shared variable is reachable only from a function of its own hold block, which holds
+// the block's lock for the whole call. a closure might run after the call returns.
+int shared_use(int s) {
+ int rank = sflag[s] / F_SHARED_RANK;
+ if (fhold == rank && !nclo && infn) return 0;
+ if (fhold == rank && nclo) { serrn(sname[s], "is shared; a closure can't use it, because it may run after the hold block's lock is released"); return 0; }
+ serrn(sname[s], "is shared in a hold block; only the functions written inside that block can use it (they hold its lock)");
+ return 0;
+}
// compiler state around the body.
int closure() {
char* xcf;
@@ -1095,6 +1104,7 @@ int primary() {
xcval = sval[s];
return C_PLAIN;
}
+ if (s >= 0 && (skind[s] == K_GVAR || skind[s] == K_GARR) && (sflag[s] & F_SHARED)) shared_use(s);
if (s >= 0 && skind[s] == K_GVAR) {
if (cmode) { vf_symbols(); xvk = svkind[s]; xvv = svvalue[s]; vf_at(rsn - 1, xvk, xvv); }
lit(sval[s]);