|
|
@@ -1245,12 +1245,46 @@ PROCEDURE CheckSub (t: SymTab.TypeIndex; q: ARRAY OF CHAR);
|
|
|
END
|
|
|
END CheckSub;
|
|
|
|
|
|
+PROCEDURE AppendArg (val: ARRAY OF CHAR; ft: SymTab.TypeIndex;
|
|
|
+ isCABI: BOOLEAN; VAR tmp: QbeGen.QVal);
|
|
|
+(* Append one actual to the pending call. At a C-ABI boundary a CHAR
|
|
|
+ array is passed as a pointer to its payload (descriptor + 8), which
|
|
|
+ is NUL-terminated by the V3 array layout. Descriptor-ABI external
|
|
|
+ calls (the runtime shim) and internal calls keep the normal
|
|
|
+ descriptor/view argument. *)
|
|
|
+ VAR cl: CHAR;
|
|
|
+ BEGIN
|
|
|
+ IF isCABI THEN
|
|
|
+ QbeGen.CArg(val, ft, tmp, cl)
|
|
|
+ ELSE
|
|
|
+ QbeGen.CopyOp(val, tmp);
|
|
|
+ cl := QbeGen.ArgClass(ft)
|
|
|
+ END;
|
|
|
+ IF NOT QbeGen.CallArg(tmp, cl) THEN END
|
|
|
+ END AppendArg;
|
|
|
+
|
|
|
+PROCEDURE AppendArgL (val: ARRAY OF CHAR; ft: SymTab.TypeIndex;
|
|
|
+ isCABI: BOOLEAN; VAR tmp: QbeGen.QVal);
|
|
|
+(* Append an address actual (VAR formal or view payload). The class is
|
|
|
+ always `l`; C ABI char arrays are shifted to their payload first. *)
|
|
|
+ VAR cl: CHAR;
|
|
|
+ BEGIN
|
|
|
+ IF isCABI THEN
|
|
|
+ QbeGen.CArg(val, ft, tmp, cl)
|
|
|
+ ELSE
|
|
|
+ QbeGen.CopyOp(val, tmp);
|
|
|
+ cl := "l"
|
|
|
+ END;
|
|
|
+ IF NOT QbeGen.CallArg(tmp, cl) THEN END
|
|
|
+ END AppendArgL;
|
|
|
+
|
|
|
PROCEDURE LowerCall (n: AST.Node; VAR t: SymTab.TypeIndex;
|
|
|
VAR q: QbeGen.QVal; want: BOOLEAN);
|
|
|
- VAR nm, pn, cqn: SymTab.Name; i, ai: CARDINAL; at, ft, res: SymTab.TypeIndex;
|
|
|
+ VAR nm, pn, cqn, cm: SymTab.Name;
|
|
|
+ i, ai: CARDINAL; at, ft, res: SymTab.TypeIndex;
|
|
|
qa, qt, qe, mg, qres, qb, qn: QbeGen.QVal;
|
|
|
- conv, isV, qual, ind, isC, va: BOOLEAN;
|
|
|
- uid, depth, np: CARDINAL; ext: BOOLEAN; ck: INTEGER; pi: INTEGER;
|
|
|
+ conv, isV, qual, ind, isC, va, cabi: BOOLEAN;
|
|
|
+ uid, depth, np, md: CARDINAL; ext: BOOLEAN; ck: INTEGER; pi: INTEGER;
|
|
|
ct: SymTab.TypeIndex; csfx: BOOLEAN; cl: CHAR;
|
|
|
seq, next, arg: AST.Node;
|
|
|
vaD, vaB, vaN: ARRAY [0 .. 63] OF QbeGen.QVal;
|
|
|
@@ -1259,6 +1293,7 @@ PROCEDURE LowerCall (n: AST.Node; VAR t: SymTab.TypeIndex;
|
|
|
BEGIN
|
|
|
qual := CalleeAlias(n, nm);
|
|
|
ind := FALSE; isC := FALSE; va := FALSE; pi := -1; ext := FALSE;
|
|
|
+ cabi := FALSE;
|
|
|
nVa := 0; nFree := 0; kfree := 0;
|
|
|
IF qual AND qualIsVar THEN
|
|
|
(* M.Error where Error is a procedure-typed variable: indirect. *)
|
|
|
@@ -1324,6 +1359,15 @@ PROCEDURE LowerCall (n: AST.Node; VAR t: SymTab.TypeIndex;
|
|
|
END
|
|
|
END
|
|
|
END;
|
|
|
+ (* A FOR "C" module exposes a C ABI. Plain EXTERNAL procedures from
|
|
|
+ ordinary modules (the runtime shim) keep the descriptor ABI. *)
|
|
|
+ IF isC THEN
|
|
|
+ cabi := TRUE
|
|
|
+ ELSIF qual AND SymTab.ProcModuleByUid(qualUid, cm, md) THEN
|
|
|
+ cabi := SymTab.ModForeign(cm)
|
|
|
+ ELSIF SymTab.SymMod(nm, cm) THEN
|
|
|
+ cabi := SymTab.ModForeign(cm)
|
|
|
+ END;
|
|
|
IF CompositeRes(res) THEN
|
|
|
(* composite result: pass a hidden destination pointer first *)
|
|
|
QbeGen.AllocLocal(res, qres);
|
|
|
@@ -1392,7 +1436,7 @@ PROCEDURE LowerCall (n: AST.Node; VAR t: SymTab.TypeIndex;
|
|
|
END
|
|
|
ELSIF isOpen1 AND isExtern AND lastView THEN
|
|
|
QbeGen.ViewToOpen1D(qe, ft, qt, qb, qn);
|
|
|
- IF NOT QbeGen.CallArg(qt, "l") THEN END;
|
|
|
+ AppendArgL(qt, ft, cabi, qa);
|
|
|
IF nVa <= HIGH(vaD) THEN
|
|
|
QbeGen.CopyOp(qt, vaD[nVa]);
|
|
|
QbeGen.CopyOp(qb, vaB[nVa]);
|
|
|
@@ -1405,7 +1449,7 @@ PROCEDURE LowerCall (n: AST.Node; VAR t: SymTab.TypeIndex;
|
|
|
ELSIF lastView AND (SymTab.ClassOf(ft) = SymTab.ClArray)
|
|
|
AND (SymTab.ArrayDepth(ft) = 1) THEN
|
|
|
QbeGen.ViewToOpen1D(qe, ft, qt, qb, qn);
|
|
|
- IF NOT QbeGen.CallArg(qt, "l") THEN END;
|
|
|
+ AppendArgL(qt, ft, cabi, qa);
|
|
|
IF nVa <= HIGH(vaD) THEN
|
|
|
QbeGen.CopyOp(qt, vaD[nVa]);
|
|
|
QbeGen.CopyOp(qb, vaB[nVa]);
|
|
|
@@ -1420,14 +1464,14 @@ PROCEDURE LowerCall (n: AST.Node; VAR t: SymTab.TypeIndex;
|
|
|
AND (SymTab.ClassOf(SymTab.ArrayElem(ft)) = SymTab.ClChar)
|
|
|
AND QbeGen.IsImm(qe) THEN
|
|
|
QbeGen.DeclCharStr(qe, qa);
|
|
|
- IF NOT QbeGen.CallArg(qa, "l") THEN END
|
|
|
+ AppendArgL(qa, ft, cabi, qt)
|
|
|
ELSIF SymTab.IsByteBuf(ft)
|
|
|
AND (SymTab.ClassOf(at) # SymTab.ClArray)
|
|
|
AND (SymTab.ClassOf(at) # SymTab.ClStr) THEN
|
|
|
QbeGen.OpenScalarDesc(qe, at, ft, qa);
|
|
|
IF NOT QbeGen.CallArg(qa, "l") THEN END
|
|
|
ELSIF QbeGen.AddrOfVal(qe, qa) THEN
|
|
|
- IF NOT QbeGen.CallArg(qa, "l") THEN END
|
|
|
+ AppendArgL(qa, ft, cabi, qt)
|
|
|
END
|
|
|
ELSE
|
|
|
IF isOpen1 AND NOT isExtern THEN
|
|
|
@@ -1457,7 +1501,7 @@ PROCEDURE LowerCall (n: AST.Node; VAR t: SymTab.TypeIndex;
|
|
|
IF nFree <= HIGH(freeDesc) THEN
|
|
|
QbeGen.CopyOp(qt, freeDesc[nFree]); INC(nFree)
|
|
|
END;
|
|
|
- IF NOT QbeGen.CallArg(qe, QbeGen.ArgClass(ft)) THEN END
|
|
|
+ AppendArg(qe, ft, cabi, qa)
|
|
|
ELSIF lastView AND (SymTab.ClassOf(ft) = SymTab.ClArray)
|
|
|
AND (SymTab.ArrayDepth(ft) = 1) THEN
|
|
|
QbeGen.ViewToOpen1D(qe, ft, qt, qb, qn);
|
|
|
@@ -1465,18 +1509,22 @@ PROCEDURE LowerCall (n: AST.Node; VAR t: SymTab.TypeIndex;
|
|
|
IF nFree <= HIGH(freeDesc) THEN
|
|
|
QbeGen.CopyOp(qt, freeDesc[nFree]); INC(nFree)
|
|
|
END;
|
|
|
- IF NOT QbeGen.CallArg(qe, QbeGen.ArgClass(ft)) THEN END
|
|
|
+ AppendArg(qe, ft, cabi, qa)
|
|
|
ELSIF (SymTab.ClassOf(at) = SymTab.ClChar)
|
|
|
AND (SymTab.ClassOf(ft) = SymTab.ClArray)
|
|
|
AND (SymTab.ClassOf(SymTab.ArrayElem(ft)) = SymTab.ClChar)
|
|
|
AND QbeGen.IsImm(qe) THEN
|
|
|
QbeGen.DeclCharStr(qe, qa);
|
|
|
- IF NOT QbeGen.CallArg(qa, "l") THEN END
|
|
|
+ AppendArg(qa, ft, cabi, qt)
|
|
|
ELSIF SymTab.IsByteBuf(ft)
|
|
|
AND (SymTab.ClassOf(at) # SymTab.ClArray)
|
|
|
AND (SymTab.ClassOf(at) # SymTab.ClStr) THEN
|
|
|
QbeGen.OpenScalarDesc(qe, at, ft, qa);
|
|
|
IF NOT QbeGen.CallArg(qa, "l") THEN END
|
|
|
+ ELSIF cabi
|
|
|
+ AND (SymTab.ClassOf(ft) = SymTab.ClArray)
|
|
|
+ AND SymTab.IsCharArray(ft) THEN
|
|
|
+ AppendArg(qe, ft, cabi, qa)
|
|
|
ELSE
|
|
|
IF (SymTab.ClassOf(ft) = SymTab.ClSet)
|
|
|
AND (SymTab.ClassOf(at) = SymTab.ClSet)
|