aboutsummaryrefslogtreecommitdiff
path: root/src/compiler/types.zc
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler/types.zc')
-rw-r--r--src/compiler/types.zc32
1 files changed, 31 insertions, 1 deletions
diff --git a/src/compiler/types.zc b/src/compiler/types.zc
index 81547a5..322d0fd 100644
--- a/src/compiler/types.zc
+++ b/src/compiler/types.zc
@@ -105,6 +105,35 @@ word tsized(char* name, int bytes, int sgn) {
return t;
}
// the function type with this return, parameter list and signature.
+// ---- borrow returns ----
+// `borrows s` after a parameter list says the result is a borrow of parameter s
+// (several, comma separated, in a declaration). a parameter is named, or given by
+// its position from 0 where it has no name (an extern, a function type). the mask
+// lives in bits 50 to 61 of the signature, so a function type carries it too.
+const int SIG_BORROWS = 50;
+int sig_borrows(int sig) { return (sig >> SIG_BORROWS) & 4095; }
+// the declared borrow mask of a call's callee: its symbol's signature, or the function type.
+int callee_borrows(int s, word ft) {
+ if (s >= 0 && s < nsym && (sflag[s] & F_SIG)) return sig_borrows(ssig[s]);
+ if (ft && ft[0] == TY_FN) return sig_borrows(ft[5]);
+ return 0;
+}
+int borrows_clause(char** names, int np, int many) {
+ int mask = 0, k;
+ if (tk != T_ID || !rt.eq_w(tv, "borrows")) return 0;
+ next();
+ while (1) {
+ k = 0 - 1;
+ if (tk == T_NUM) { if (tv >= 0 && tv < np) k = tv; }
+ else if (tk == T_ID && names) { int j = 0; while (j < np) { if (names[j] && rt.eq_w(names[j], tv)) k = j; j++; } }
+ if (k < 0) { serr("borrows names a parameter, by name or by its position from 0"); next(); return mask; }
+ if (k >= 12) serr("only the first 12 parameters can be borrowed by the result");
+ else mask = mask | (1 << k);
+ next();
+ if (!many || !accept(s_comma)) break;
+ }
+ return mask;
+}
word tfn(int ret, int np, word ps, int sig) {
int i = 0, j; word t;
while (i < ntl) {
@@ -388,7 +417,8 @@ int ptype() {
}
}
expect(s_rp);
- t = tfn(t, np, ps, np + np + tags * 64);
+ tag = borrows_clause(0, np, 0);
+ t = tfn(t, np, ps, np + np + tags * 64 + (tag << SIG_BORROWS));
}
ht_note(start, toff, t);
return t;