|
@@ -4608,6 +4608,19 @@ BEGIN
|
|
|
END
|
|
END
|
|
|
END SymEpi ;
|
|
END SymEpi ;
|
|
|
|
|
|
|
|
|
|
+PROCEDURE SlotSize (cls, size : CARDINAL) : CARDINAL ;
|
|
|
|
|
+(* How many bytes a value parameter occupies in the callee's stack frame.
|
|
|
|
|
+ TP3's `tstscal' (TPSRC7 1243): a scalar-like parameter is AT LEAST two
|
|
|
|
|
+ bytes on the stack even when its type is one byte; anything larger spends
|
|
|
|
|
+ its own size. Generalised here so step 2 can put a string's 71 bytes on
|
|
|
|
|
+ the stack without changing what a scalar does today. *)
|
|
|
|
|
+BEGIN
|
|
|
|
|
+ IF (cls = TScalar) OR (cls = TChar) OR (cls = TBool) OR (cls = TEnum) THEN
|
|
|
|
|
+ RETURN 2
|
|
|
|
|
+ END ;
|
|
|
|
|
+ RETURN size
|
|
|
|
|
+END SlotSize ;
|
|
|
|
|
+
|
|
|
PROCEDURE ProcFunc () ;
|
|
PROCEDURE ProcFunc () ;
|
|
|
(* PROCEDURE name (params) ; body | FUNCTION name (params) : type ; body *)
|
|
(* PROCEDURE name (params) ; body | FUNCTION name (params) : type ; body *)
|
|
|
VAR nm : ARRAY [0..MaxName] OF CHAR ;
|
|
VAR nm : ARRAY [0..MaxName] OF CHAR ;
|
|
@@ -4688,7 +4701,7 @@ BEGIN
|
|
|
symtab [i].cls := cls ; symtab [i].size := size ;
|
|
symtab [i].cls := cls ; symtab [i].size := size ;
|
|
|
symtab [i].elem := elem ;
|
|
symtab [i].elem := elem ;
|
|
|
symtab [i].off := parmOff ;
|
|
symtab [i].off := parmOff ;
|
|
|
- parmOff := parmOff + 2 ;
|
|
|
|
|
|
|
+ parmOff := parmOff + SlotSize (cls, size) ;
|
|
|
INC (i)
|
|
INC (i)
|
|
|
END ;
|
|
END ;
|
|
|
IF MatchDelim (')') THEN
|
|
IF MatchDelim (')') THEN
|
|
@@ -4716,10 +4729,15 @@ BEGIN
|
|
|
from BP, which has to be the FIRST declared parameter's slot.
|
|
from BP, which has to be the FIRST declared parameter's slot.
|
|
|
|
|
|
|
|
During the loop the offsets were provisional, in declaration order
|
|
During the loop the offsets were provisional, in declaration order
|
|
|
- (parmOff starts at 4 and grows by 2 per parameter), so parameter k of n
|
|
|
|
|
- sat at 4 + 2*(k-1). The map `off := parmOff + 2 - off' sends that to
|
|
|
|
|
- 4 + 2*(n-k) - k = 1 to the far end, k = n to BP+4 - which is the layout
|
|
|
|
|
- above, with no offset invented and none lost.
|
|
|
|
|
|
|
+ (parmOff starts at 4 and grows by each parameter's SLOT size), so
|
|
|
|
|
+ parameter k sat at 4 + sum of the slots before it. For slot sizes s and
|
|
|
|
|
+ frame total T, the parameter's final base is
|
|
|
|
|
+ 4 + (T - prefix - s) = 8 + T - off - s, which sends the FIRST declared
|
|
|
|
|
+ parameter to the far end and the LAST to BP+4. With every slot 2 -
|
|
|
|
|
+ every scalar, which is all this compiler accepts today - that reduces
|
|
|
|
|
+ exactly to the old `parmOff + 2 - off`, so no existing frame moves.
|
|
|
|
|
+ A slot larger than 2 (a string's 71 bytes, once the caller can push it)
|
|
|
|
|
+ falls out of the same formula.
|
|
|
|
|
|
|
|
The range is exactly the parameters: the only symbol created while the
|
|
The range is exactly the parameters: the only symbol created while the
|
|
|
list is read is the parameter itself (NewSym inside the loop),
|
|
list is read is the parameter itself (NewSym inside the loop),
|
|
@@ -4727,7 +4745,8 @@ BEGIN
|
|
|
nestMark, and a function's result variable is created after this point. *)
|
|
nestMark, and a function's result variable is created after this point. *)
|
|
|
i := nestMark ;
|
|
i := nestMark ;
|
|
|
WHILE i < symTop DO
|
|
WHILE i < symTop DO
|
|
|
- symtab [i].off := parmOff + 2 - symtab [i].off ;
|
|
|
|
|
|
|
+ symtab [i].off := 8 + (parmOff - 4) - symtab [i].off
|
|
|
|
|
+ - SlotSize (symtab [i].cls, symtab [i].size) ;
|
|
|
INC (i)
|
|
INC (i)
|
|
|
END ;
|
|
END ;
|
|
|
IF isFunc THEN
|
|
IF isFunc THEN
|