Add test for alignment computability

This commit is contained in:
David Brown 2016-08-20 20:51:31 +01:00
parent e33255b08c
commit 899ab6ff3f
2 changed files with 42 additions and 7 deletions

View file

@ -574,7 +574,7 @@ MODULE OPC; (* copyright (c) J. Templ 12.7.95 / 3.7.96 *)
END END
END Align; END Align;
PROCEDURE Base*(typ: OPT.Struct): LONGINT; PROCEDURE Base0(typ: OPT.Struct): LONGINT;
BEGIN BEGIN
CASE typ^.form OF CASE typ^.form OF
| OPM.Byte: RETURN 1 | OPM.Byte: RETURN 1
@ -589,11 +589,46 @@ MODULE OPC; (* copyright (c) J. Templ 12.7.95 / 3.7.96 *)
| OPM.Pointer: RETURN OPM.PointerAlign | OPM.Pointer: RETURN OPM.PointerAlign
| OPM.ProcTyp: RETURN OPM.ProcAlign | OPM.ProcTyp: RETURN OPM.ProcAlign
| OPM.Comp: IF typ^.comp = OPM.Record THEN RETURN typ^.align MOD 10000H | OPM.Comp: IF typ^.comp = OPM.Record THEN RETURN typ^.align MOD 10000H
ELSE RETURN Base(typ^.BaseTyp) ELSE RETURN Base0(typ^.BaseTyp)
END END
ELSE OPM.LogWStr("unhandled case in OPC.Base, typ^form = "); OPM.LogWNum(typ^.form, 0); OPM.LogWLn; ELSE OPM.LogWStr("unhandled case in OPC.BaseAlignment, typ^form = "); OPM.LogWNum(typ^.form, 0); OPM.LogWLn;
END END
END Base; END Base0;
PROCEDURE BaseAlignment*(typ: OPT.Struct): LONGINT;
VAR align, result: LONGINT;
BEGIN
IF typ.form = OPM.Comp THEN
IF typ.comp = OPM.Record THEN
result := typ.align MOD 10000H
ELSE
result := BaseAlignment(typ.BaseTyp)
END
ELSE
(* Not a compound type *)
result := Base0(typ);
(* Now determine alignment from size *)
IF typ.size < OPM.Alignment THEN
(* Round up to next power of 2 *)
align := 1; WHILE align < typ.size DO align := align * 2 END;
ELSE
align := OPM.Alignment
END;
IF align # result THEN
OPM.LogWStr("BaseAlignment. typ.form "); OPM.LogWNum(typ.form,1);
OPM.LogWStr(", typ.size "); OPM.LogWNum(typ.size,1);
OPM.LogWStr(", old alignment "); OPM.LogWNum(result,1);
OPM.LogWStr(", alignment based on size "); OPM.LogWNum(align,1); OPM.LogWLn
END;
ASSERT(align = result)
END;
RETURN result
END BaseAlignment;
PROCEDURE FillGap(gap, off, align: LONGINT; VAR n, curAlign: LONGINT); PROCEDURE FillGap(gap, off, align: LONGINT; VAR n, curAlign: LONGINT);
VAR adr: LONGINT; VAR adr: LONGINT;
@ -626,7 +661,7 @@ MODULE OPC; (* copyright (c) J. Templ 12.7.95 / 3.7.96 *)
WHILE (fld # NIL) & (fld.mode = OPM.Fld) & (fld.vis = OPM.internal) DO fld := fld.link END ; WHILE (fld # NIL) & (fld.mode = OPM.Fld) & (fld.vis = OPM.internal) DO fld := fld.link END ;
ELSE ELSE
(* mimic OPV.TypSize to detect gaps caused by private fields *) (* mimic OPV.TypSize to detect gaps caused by private fields *)
adr := off; fldAlign := Base(fld^.typ); Align(adr, fldAlign); adr := off; fldAlign := BaseAlignment(fld^.typ); Align(adr, fldAlign);
gap := fld.adr - adr; gap := fld.adr - adr;
IF fldAlign > curAlign THEN curAlign := fldAlign END ; IF fldAlign > curAlign THEN curAlign := fldAlign END ;
IF gap > 0 THEN FillGap(gap, off, align, n, curAlign) END ; IF gap > 0 THEN FillGap(gap, off, align, n, curAlign) END ;

View file

@ -82,7 +82,7 @@ MODULE OPV; (* J. Templ 16.2.95 / 3.7.96
fld := typ^.link; fld := typ^.link;
WHILE (fld # NIL) & (fld^.mode = OPM.Fld) DO WHILE (fld # NIL) & (fld^.mode = OPM.Fld) DO
btyp := fld^.typ; TypSize(btyp); btyp := fld^.typ; TypSize(btyp);
size := btyp^.size; fbase := OPC.Base(btyp); size := btyp^.size; fbase := OPC.BaseAlignment(btyp);
OPC.Align(offset, fbase); OPC.Align(offset, fbase);
fld^.adr := offset; INC(offset, size); fld^.adr := offset; INC(offset, size);
IF fbase > base THEN base := fbase END ; IF fbase > base THEN base := fbase END ;
@ -782,7 +782,7 @@ MODULE OPV; (* J. Templ 16.2.95 / 3.7.96
ELSE OPM.WriteString("NIL") ELSE OPM.WriteString("NIL")
END ; END ;
OPM.WriteString(", "); OPM.WriteString("((LONGINT)("); OPM.WriteInt(base^.size); OPM.WriteString("))"); OPM.WriteString(", "); OPM.WriteString("((LONGINT)("); OPM.WriteInt(base^.size); OPM.WriteString("))");
OPM.WriteString(", "); OPM.WriteInt(OPC.Base(base)); (* element alignment *) OPM.WriteString(", "); OPM.WriteInt(OPC.BaseAlignment(base)); (* element alignment *)
OPM.WriteString(", "); OPM.WriteInt(nofdim); (* total number of dimensions = number of additional parameters *) OPM.WriteString(", "); OPM.WriteInt(nofdim); (* total number of dimensions = number of additional parameters *)
OPM.WriteString(", "); OPM.WriteInt(nofdyn); (* number of dynamic dimensions *) OPM.WriteString(", "); OPM.WriteInt(nofdyn); (* number of dynamic dimensions *)
WHILE typ # base DO WHILE typ # base DO