|
|
@@ -2012,28 +2012,27 @@ PROCEDURE Trap;
|
|
|
(* Scalars/sets inline, array fields as inline descriptors (8-byte length
|
|
|
word + data), nested records inline. Static offsets throughout. *)
|
|
|
|
|
|
-PROCEDURE HasNestedArray (t: SymTab.TypeIndex): BOOLEAN;
|
|
|
-(* TRUE when record type t (recursively) has an ARRAY OF ARRAY field,
|
|
|
- i.e. a field whose element is itself an array. Only such record
|
|
|
- arrays need per-element expansion (their nested sub-descriptors must
|
|
|
- be emitted); plain record arrays stay a compact zero blob. *)
|
|
|
- VAR i: CARDINAL; fn: SymTab.Name; ft, et: SymTab.TypeIndex; cls: INTEGER;
|
|
|
+PROCEDURE HasArrayField (t: SymTab.TypeIndex): BOOLEAN;
|
|
|
+(* TRUE when record type t (recursively) has any ARRAY field. Such
|
|
|
+ record arrays need per-element expansion so each inline array field's
|
|
|
+ descriptor length word is initialised; a compact zero blob would
|
|
|
+ leave the count 0 and trap when the field is passed as an open array.
|
|
|
+ Records with no array field still stay a compact blob. *)
|
|
|
+ VAR i: CARDINAL; fn: SymTab.Name; ft: SymTab.TypeIndex; cls: INTEGER;
|
|
|
BEGIN
|
|
|
i := 0;
|
|
|
WHILE i < SymTab.FieldCount(t) DO
|
|
|
SymTab.FieldName(t, i, fn);
|
|
|
ft := SymTab.FieldType(t, fn);
|
|
|
cls := SymTab.ClassOf(ft);
|
|
|
- IF cls = SymTab.ClArray THEN
|
|
|
- et := SymTab.ArrayElem(ft);
|
|
|
- IF SymTab.ClassOf(et) = SymTab.ClArray THEN RETURN TRUE END
|
|
|
+ IF cls = SymTab.ClArray THEN RETURN TRUE
|
|
|
ELSIF (cls = SymTab.ClRecord) OR (cls = SymTab.ClClass) THEN
|
|
|
- IF HasNestedArray(ft) THEN RETURN TRUE END
|
|
|
+ IF HasArrayField(ft) THEN RETURN TRUE END
|
|
|
END;
|
|
|
INC(i)
|
|
|
END;
|
|
|
RETURN FALSE
|
|
|
- END HasNestedArray;
|
|
|
+ END HasArrayField;
|
|
|
|
|
|
PROCEDURE ArrBodyItems (prefix: ARRAY OF CHAR; t: INTEGER);
|
|
|
(* Inline contents of an array descriptor (no "data $name = {" wrapper
|
|
|
@@ -2107,8 +2106,9 @@ PROCEDURE ArrBodyItems (prefix: ARRAY OF CHAR; t: INTEGER);
|
|
|
INC(i)
|
|
|
END
|
|
|
ELSIF ((ecls = SymTab.ClRecord) OR (ecls = SymTab.ClClass))
|
|
|
- AND HasNestedArray(elem) THEN
|
|
|
- (* Per-element record expansion: nested-array field descriptors. *)
|
|
|
+ AND HasArrayField(elem)
|
|
|
+ AND (VAL(INTEGER, n) * VAL(INTEGER, SymTab.TypeSize(elem))
|
|
|
+ <= 131072) THEN
|
|
|
i := 0;
|
|
|
WHILE i < n DO
|
|
|
Cpy(sub, prefix); App(sub, "_");
|
|
|
@@ -2209,7 +2209,9 @@ PROCEDURE ArrData (name: ARRAY OF CHAR; t: INTEGER);
|
|
|
END
|
|
|
ELSIF ((SymTab.ClassOf(elem) = SymTab.ClRecord)
|
|
|
OR (SymTab.ClassOf(elem) = SymTab.ClClass))
|
|
|
- AND HasNestedArray(elem) THEN
|
|
|
+ AND HasArrayField(elem)
|
|
|
+ AND (VAL(INTEGER, SymTab.ArrayLen(t))
|
|
|
+ * VAL(INTEGER, SymTab.TypeSize(elem)) <= 131072) THEN
|
|
|
(* Sub-descriptors referenced (as $name_i_field_k) from the inline
|
|
|
items emitted by ArrBodyItems; one set per element. *)
|
|
|
n := SymTab.ArrayLen(t);
|