123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299 |
- (* Paco, Copyright 2000 - 2002, Patrik Reali, ETH Zurich *)
- MODULE PCOF; (** AUTHOR "prk / be"; PURPOSE "Parallel Compiler: object file plug-in"; *)
- IMPORT
- SYSTEM, KernelLog,
- StringPool, PCDebug, PCBT, PCLIR, PCM, PCT, PCOM;
- CONST
- AddressSize = SIZEOF(ADDRESS);
- TraceUse = FALSE;
- Optimize = FALSE;
- NewRefSection = TRUE;
- Sentinel = LONGINT(0FFFFFFFFH);
- EUEnd = 0X; EURecord = 1X; EUProcFlag = LONGINT(080000000H);
- TYPE
- StringBuf = ARRAY 256 OF CHAR;
- OffsetList = POINTER TO RECORD
- offset : LONGINT;
- nextOffset : OffsetList
- END;
- ExTableEntry = POINTER TO RECORD
- pcFrom, pcTo, pcHandler: LONGINT;
- next: ExTableEntry;
- END;
- VAR
- refSize: LONGINT;
- nofCmds, nofImp, nofVarCons, nofLinks: INTEGER;
- dsize: LONGINT;
- globR: PCM.Rider; (* used for OutReference *)
- (* stat counters *)
- Nreschedule0, Nreschedule1, Nreschedule2: LONGINT;
- exTable: ExTableEntry;
- exTableLen: LONGINT;
- (* ---------- Helper Procedures -------------- *)
- PROCEDURE OutRefType(t: PCT.Struct; procHeader: BOOLEAN);
- VAR val, off, dim, td: LONGINT; u: PCT.Struct; tdptr: PCBT.GlobalVariable;
- BEGIN
- td := 0; off := 0; dim := 0;
- IF ~procHeader (*& (t IS PCT.Array) *) THEN
- IF (t IS PCT.Array) THEN (** fof *)
- WITH t: PCT.Array DO
- off := 80H;
- u := t.base;
- IF ~(u IS PCT.Basic) THEN u := PCT.Ptr END;
- IF t.mode = PCT.static THEN dim := t.len END
- END;
- t := u
- (** fof >> *)
- ELSIF (t IS PCT.EnhArray) THEN
- WITH t: PCT.EnhArray DO
- off := 80H; u := t.base;
- IF ~(u IS PCT.Basic) THEN u := PCT.Ptr END;
- IF (t.mode = PCT.static) THEN dim := t.len END
- END;
- t := u
- ELSIF (t IS PCT.Tensor) THEN
- WITH t: PCT.Tensor DO
- off := 80H; u := t.base;
- u := PCT.Ptr ;
- END;
- t := u
- END;
- (** << fof *)
- END;
- IF t = PCT.Int64 THEN
- val := 10H
- ELSIF t = PCT.Char16 THEN
- val := PCT.Int16.sym(PCOM.Struct).fp
- ELSIF t = PCT.Char32 THEN
- val := PCT.Int32.sym(PCOM.Struct).fp
- ELSIF t IS PCT.Basic THEN
- val := t.sym(PCOM.Struct).fp
- ELSIF t = PCT.NoType THEN
- val := 0
- ELSIF t IS PCT.Record THEN
- val := 16H;
- tdptr := t.size(PCBT.RecSize).td;
- IF tdptr # NIL THEN td := tdptr.offset ELSE val := 6 END
- ELSIF procHeader & PCT.IsPointer(t) THEN
- val := 0DH
- ELSIF t IS PCT.Pointer THEN
- WITH t: PCT.Pointer DO
- IF t.baseR # NIL (* IS PCT.Record *) THEN
- val := 1DH;
- tdptr := t.base.size(PCBT.RecSize).td;
- IF tdptr # NIL THEN td := tdptr.offset ELSE val := 0DH END
- ELSE
- val := 0DH
- END
- END;
- ELSIF t = PCT.Ptr THEN
- val := 0DH;
- ELSIF t IS PCT.Delegate THEN
- val := 0EH
- ELSIF procHeader & (t IS PCT.Array) THEN
- WITH t: PCT.Array DO
- IF t.mode = PCT.static THEN val := 12H
- ELSIF t.mode = PCT.open THEN val := 15H
- ELSE HALT(98)
- END
- END
- (** fof >> *)
- ELSIF procHeader & (t IS PCT.EnhArray) THEN
- WITH t: PCT.EnhArray DO
- IF t.mode = PCT.static THEN val := 12H
- ELSIF t.mode = PCT.open THEN val := 15H
- ELSE HALT( 98 )
- END
- END
- ELSIF procHeader & (t IS PCT.Tensor) THEN
- val := 15H; (* ???? *)
- (** << fof *)
- ELSE
- HALT(99)
- END;
- IF procHeader THEN
- PCM.RefW(globR, CHR(val))
- ELSE
- PCM.RefW(globR, CHR(off+val));
- IF off = 80H THEN PCM.RefWNum(globR, dim)
- ELSIF td # 0 THEN PCM.RefWNum(globR, td)
- END
- END
- END OutRefType;
- PROCEDURE OutRefVar(p: PCT.Variable; isRef: BOOLEAN);
- VAR arr: PCT.Array; dim, off: LONGINT; type: PCT.Struct; name: StringBuf;earr: PCT.EnhArray; (*fof*)
- BEGIN
- StringPool.GetString(p.name, name);
- IF NewRefSection THEN
- IF isRef THEN PCM.RefW(globR, 3X) ELSE PCM.RefW(globR, 1X) END;
- OutRefType(p.type, FALSE);
- PCM.RefWNum(globR, p.adr(PCBT.Variable).offset);
- PCM.RefWString(globR, name)
- ELSE
- type := p.type;
- IF (type IS PCT.Record) THEN
- (*skip*)
- ELSIF (type IS PCT.Array) & ~(type(PCT.Array).base IS PCT.Basic) THEN
- (*skip*)
- (** fof >> *)
- ELSIF (type IS PCT.EnhArray) & (type( PCT.EnhArray ).base IS PCT.Basic) THEN
- (* skip *)
- (** << fof *)
- ELSIF (type = PCT.Int64) THEN
- (*skip*)
- ELSE
- IF isRef THEN PCM.RefW(globR, 3X) ELSE PCM.RefW(globR, 1X) END;
- off := 0; dim := 0;
- IF type IS PCT.Array THEN
- off := 80H; dim := 1;
- REPEAT
- arr := type(PCT.Array);
- dim := dim * arr.len;
- type := arr.base
- UNTIL ~(type IS PCT.Array)
- END;
- (** fof >> *)
- IF type IS PCT.EnhArray THEN
- off := 80H; dim := 1;
- REPEAT earr := type( PCT.EnhArray ); dim := dim * earr.len; type := earr.base UNTIL ~(type IS PCT.EnhArray)
- END;
- (** << fof *)
- IF type = PCT.Byte THEN PCM.RefW(globR, CHR(off+1))
- ELSIF type = PCT.Bool THEN PCM.RefW(globR, CHR(off+2))
- ELSIF type = PCT.Char8 THEN PCM.RefW(globR, CHR(off+3))
- ELSIF type = PCT.Char16 THEN PCM.RefW(globR, CHR(off+5))
- ELSIF type = PCT.Char32 THEN PCM.RefW(globR, CHR(off+6))
- ELSIF type = PCT.Int8 THEN PCM.RefW(globR, CHR(off+4))
- ELSIF type = PCT.Int16 THEN PCM.RefW(globR, CHR(off+5))
- ELSIF type = PCT.Int32 THEN PCM.RefW(globR, CHR(off+6))
- ELSIF type = PCT.Float32 THEN PCM.RefW(globR, CHR(off+7))
- ELSIF type = PCT.Float64 THEN PCM.RefW(globR, CHR(off+8))
- ELSIF type = PCT.Set THEN PCM.RefW(globR, CHR(off+9))
- ELSIF PCT.IsPointer(type) THEN PCM.RefW(globR, CHR(off+0DH))
- ELSIF type IS PCT.Delegate THEN PCM.RefW(globR, CHR(off+0EH))
- END;
- IF off = 80H THEN PCM.RefW(globR, CHR(dim)) END;
- PCM.RefWNum(globR, p.adr(PCBT.Variable).offset);
- PCM.RefWString(globR, name);
- END
- END;
- END OutRefVar;
- (* fof 070731 moved warnings to PCP : removed CheckAll, CheckModules here *)
- PROCEDURE OutReference(scope: PCT.Scope);
- VAR owner: PCT.Proc; i: LONGINT; var: PCT.Variable; par: PCT.Parameter; name: StringBuf; entry: ExTableEntry; mod: PCT.Module;
- BEGIN
- (*
- IF (scope.code = NIL) THEN RETURN END;
- *)
- IF scope IS PCT.ModScope THEN
- PCM.RefW(globR, 0F8X);
- COPY("$$", name);
- PCM.RefWNum(globR, 0); (* offset *)
- PCM.RefWString(globR, "$$"); (* name *)
- var := scope.firstVar;
- WHILE var # NIL DO OutRefVar(var, FALSE); var := var.nextVar END;
- mod := scope(PCT.ModScope).owner;
- IF mod.adr(PCBT.Module).finallyOff > -1 THEN
- NEW(entry);
- entry.pcFrom := 0;
- entry.pcTo := mod.adr(PCBT.Module).finallyOff;
- entry.pcHandler := mod.adr(PCBT.Module).finallyOff;
- entry.next := NIL;
- IF exTable # NIL THEN
- entry.next := exTable;
- END;
- exTable := entry;
- INC(exTableLen);
- END;
- ELSIF scope IS PCT.ProcScope THEN
- WITH scope: PCT.ProcScope DO
- owner := scope.ownerO;
- IF ~(PCT.Inline IN owner.flags) THEN
- IF NewRefSection THEN
- PCM.RefW(globR, 0F9X);
- PCM.RefWNum(globR, owner.adr(PCBT.Procedure).codeoffset);
- PCM.RefWNum(globR, scope.parCount);
- OutRefType(owner.type, TRUE);
- PCM.RefWNum(globR, owner.level);
- PCM.RefWNum(globR, 0)
- ELSE
- PCM.RefW(globR, 0F8X);
- PCM.RefWNum(globR, owner.adr(PCBT.Procedure).codeoffset);
- END;
- IF owner IS PCT.Method THEN
- WITH owner: PCT.Method DO
- PCT.GetTypeName(owner.boundTo, name);
- i := 0;
- WHILE name[i] # 0X DO PCM.RefW(globR, name[i]); INC(i) END;
- PCM.RefW(globR, ".")
- END
- END;
- StringPool.GetString(owner.name, name);
- PCM.RefWString(globR, name);
- par := scope.firstPar;
- WHILE par # NIL DO OutRefVar(par, par.ref); par := par.nextPar END;
- var := scope.firstVar;
- WHILE var # NIL DO OutRefVar(var, FALSE); var := var.nextVar END
- END;
- IF owner.adr(PCBT.Procedure). finallyOff > -1 THEN
- NEW(entry);
- entry.pcFrom := owner.adr(PCBT.Procedure).codeoffset;
- entry.pcTo := owner.adr(PCBT.Procedure).finallyOff;
- entry.pcHandler := owner.adr(PCBT.Procedure).finallyOff;
- entry.next := NIL;
- IF exTable # NIL THEN
- entry.next := exTable;
- END;
- exTable := entry;
- INC(exTableLen);
- END;
- END;
- END
- END OutReference;
- PROCEDURE Generate*(VAR R: PCM.Rider; scope: PCT.ModScope; VAR codeSize: LONGINT);
- VAR commands: ARRAY 128 OF PCT.Proc;
- i, nofptrs, nofProcs, maxPtrs, EntriesPos, PtrPos, nofProcsPos, maxPtrsPos, LinksPos, VarConsPos: LONGINT;
- typeDescsSize, typeDescsSizePos: LONGINT; (* ug: temporary *)
- adr: PCBT.Module; mod: PCT.Module; sym: PCOM.Module; emptyR: PCM.Rider;
- code: PCLIR.CodeArray; str: StringBuf; hdrCodeSize, addressFactor: LONGINT;
- PROCEDURE UseModule(m: PCBT.Module);
- BEGIN
- IF m.nr = 0 THEN
- INC(nofImp);
- m.nr := -1 (*mark*)
- END
- END UseModule;
- PROCEDURE FindCommands;
- VAR proc : PCT.Proc;
- BEGIN
- nofCmds := 0;
- proc := scope.firstProc;
- WHILE (proc # NIL) DO
- IF (proc.vis = PCT.Public) & (~(PCT.Inline IN proc.flags) OR (PCT.Indexer IN proc.flags)) THEN
- IF PCT.GetProcedureAllowed(proc.scope, proc.type) THEN
- commands[nofCmds] := proc; INC(nofCmds);
- END;
- END;
- proc := proc.nextProc
- END;
- END FindCommands;
- PROCEDURE CollectInfo;
- VAR proc: PCT.Proc; o: PCT.Symbol; p: PCBT.GlobalVariable; rec: PCT.Record; bsym: PCOM.Struct;
- BEGIN
- globR := R; PCT.TraverseScopes(scope, OutReference); R := globR; globR := emptyR;
- FindCommands;
- (* detect imported modules *)
- IF mod.imports # NIL THEN
- i := 0;
- WHILE (i < LEN(mod.imports)) & (mod.imports[i] # NIL) DO
- mod.imports[i].adr(PCBT.Module).nr := 0;
- INC(i)
- END;
- nofImp := 0;
- o := scope.sorted;
- WHILE o # NIL DO
- IF (o IS PCT.Module) & (o.adr # PCT.System.adr) THEN UseModule(o.adr(PCBT.Module)) END;
- o := o.sorted;
- END;
- p := adr.ExtVars;
- WHILE p # PCBT.sentinel DO
- IF p.link # NIL THEN UseModule(p.owner) END;
- p := p.next
- END;
- rec := scope.records;
- WHILE rec # NIL DO
- IF (rec.brec # NIL) & (rec.brec.sym # NIL) THEN
- bsym := rec.brec.sym(PCOM.Struct);
- IF bsym.mod # scope.owner THEN UseModule(bsym.mod.adr(PCBT.Module)) END
- END;
- rec := rec.link;
- ASSERT(rec # scope.records, MAX(INTEGER));
- (* Fix bug, sometimes this assertion fails. *)
- (* fof 070920: done, cf. PCC.MakeTD *)
- END
- END;
- (*
- IF mod.imports # NIL THEN
- nofImp := SHORT(LEN(mod.imports));
- WHILE (mod.imports[nofImp-1] = NIL) DO DEC(nofImp) END
- END
- *)
- END CollectInfo;
- PROCEDURE OutPtrs(offset: LONGINT; type: PCT.Struct; debug : BOOLEAN);
- VAR i, n, off: LONGINT; f: PCT.Variable; scope: PCT.Scope; base: PCT.Struct; size: PCBT.Size;
- name: StringBuf; state: LONGINT;
- BEGIN
- IF type.size(PCBT.Size).containPtrs THEN
- IF PCT.IsPointer(type) THEN
- PCM.ObjWNum(R, offset); INC(nofptrs);
- IF debug THEN
- KernelLog.Int(offset, 0); KernelLog.String(" "); (* KernelLog.Ln; *)
- END
- ELSIF PCT.IsDynamicDelegate(type) THEN
- PCM.ObjWNum(R, offset+4); INC(nofptrs);
- IF debug THEN
- KernelLog.Int(offset+4, 0); KernelLog.String(" "); (* KernelLog.Ln; *)
- END
- ELSIF type IS PCT.Record THEN
- WITH type: PCT.Record DO
- IF type.brec # NIL THEN OutPtrs(offset, type.brec, debug) END;
- scope := type.scope;
- END;
- f := scope.firstVar;
- WHILE f # NIL DO
- IF ~(PCM.Untraced IN f.flags) THEN
- StringPool.GetString(f.name, name); state := scope.state;
- ASSERT(state >= PCT.structallocated);
- type := f.type; off := f.adr(PCBT.Variable).offset;
- OutPtrs(offset+off, type, debug)
- END;
- f := f.nextVar
- END;
- ELSIF type IS PCT.Array THEN
- WITH type: PCT.Array DO
- IF type.mode = PCT.static THEN
- n := type.len;
- base := type.base;
- WHILE (base IS PCT.Array) DO
- type := base(PCT.Array); base := type.base;
- ASSERT(type.mode = PCT.static);
- n := n * type.len
- END;
- size := base.size(PCBT.Size);
- IF size.containPtrs THEN
- FOR i := 0 TO n-1 DO OutPtrs(offset+i*size.size, base, debug) END
- END
- ELSE
- PCDebug.ToDo(PCDebug.NotImplemented); (*find pointers in the array, call NewPtr for each one*)
- END
- END
- (** fof >> *)
- ELSIF type IS PCT.EnhArray THEN
- WITH type: PCT.EnhArray DO
- IF type.mode = PCT.static THEN
- n := type.len; base := type.base;
- WHILE (base IS PCT.EnhArray) DO type := base( PCT.EnhArray ); base := type.base;
- ASSERT ( (type.mode = PCT.static) );
- n := n * type.len
- END;
- size := base.size( PCBT.Size );
- IF size.containPtrs THEN
- FOR i := 0 TO n - 1 DO OutPtrs( offset + i * size.size, base,FALSE ) END
- END
- ELSE
- PCM.ObjWNum( R, offset ); INC( nofptrs );
- (* pointer to array in heap is located at first position ! *)
- (*
- PCDebug.ToDo( PCDebug.NotImplemented ); (*find pointers in the array, call NewPtr for each one*)
- *)
- END
- END
- ELSIF type IS PCT.Tensor THEN
- WITH type: PCT.Tensor DO
- PCM.ObjWNum(R,offset); INC(nofptrs);
- END;
- (** << fof *)
- END
- END
- END OutPtrs;
- PROCEDURE FixupList(l: PCBT.Fixup; addressFactor: LONGINT; base: ADDRESS; sentinel: LONGINT; prev: PCBT.Fixup; VAR tail: PCBT.Fixup);
- (* Insert fixup list into code *)
- VAR offset: LONGINT;
- BEGIN
- tail := NIL;
- IF l # NIL THEN
- IF prev # NIL THEN
- SYSTEM.PUT(base + prev.offset*addressFactor, l.offset);
- END;
- offset := l.offset;
- tail := l;
- l := l.next;
- WHILE l # NIL DO
- SYSTEM.PUT(base+offset*addressFactor, l.offset);
- offset := l.offset;
- tail := l;
- l := l.next;
- END;
- SYSTEM.PUT(base+offset*addressFactor, sentinel);
- END;
- END FixupList;
- PROCEDURE InsertFixupLists(addressFactor: LONGINT);
- VAR p: PCBT.Procedure; i: LONGINT; codebase: ADDRESS; dummy : PCBT.Fixup;
- BEGIN
- codebase := ADDRESSOF(code[0]);
- FOR i := 0 TO PCBT.NofSysCalls-1 DO
- IF i # PCBT.casetable THEN
- FixupList(adr.syscalls[i], addressFactor, codebase, Sentinel, NIL, dummy)
- END
- END;
- p := adr.ExtProcs;
- WHILE p # PCBT.psentinel DO
- ASSERT(p.owner # PCBT.context);
- FixupList(p.link, addressFactor, codebase, Sentinel, NIL, dummy);
- p := p.next
- END;
- END InsertFixupLists;
- PROCEDURE EntryBlock(addressFactor: LONGINT);
- VAR nofEntries, firstOffset: LONGINT; codebase: ADDRESS;
- PROCEDURE Traverse(p: PCBT.Procedure);
- VAR prev, tail : PCBT.Fixup;
- BEGIN
- prev := NIL;
- WHILE p # PCBT.psentinel DO
- IF (p.public) OR (p.link # NIL) OR (p IS PCBT.Method) THEN
- PCM.ObjWNum(R, p.codeoffset);
- p.entryNr := nofEntries;
- INC(nofEntries);
- FixupList(p.link, addressFactor, codebase, Sentinel, prev, tail);
- IF tail # NIL THEN
- prev := tail
- END;
- IF (p.link # NIL) & (firstOffset = -1) THEN
- firstOffset := p.link.offset
- END;
- END;
- p := p.next
- END
- END Traverse;
- BEGIN
- PCM.ObjW(R, 82X);
- nofEntries := 0;
- codebase := ADDRESSOF(code[0]);
- firstOffset := -1;
- Traverse(adr.OwnProcs);
- (*
- Traverse(adr.ExtProcs);
- *)
- IF firstOffset # -1 THEN adr.UseSyscall(PCBT.procaddr, firstOffset) END;
- IF nofEntries # 0 THEN PCM.ObjWLIntAt(R, EntriesPos, nofEntries) END
- END EntryBlock;
- PROCEDURE CommandBlock;
- VAR i: LONGINT; str: StringBuf;
- PROCEDURE WriteType(type : PCT.Struct);
- VAR size : PCBT.RecSize; num : LONGINT;
- BEGIN
- ASSERT((type # NIL) & ((type = PCT.NoType) OR (type IS PCT.Record) OR ((type IS PCT.Pointer) & (type(PCT.Pointer).baseR # NIL))));
- num := 0;
- IF (type = PCT.NoType) THEN
- (* num = 0 *)
- ELSIF (type IS PCT.Record) THEN
- size := type(PCT.Record).size(PCBT.RecSize);
- ELSE
- size := type(PCT.Pointer).baseR.size(PCBT.RecSize);
- END;
- IF (type # PCT.NoType) THEN
- IF (size.td # NIL) THEN
- num := size.td.offset;
- ELSE
- KernelLog.String("ERROR: size.td = NIL"); KernelLog.Ln; (* TODO: CHECK WHY THIS HAPPENS *)
- END;
- END;
- PCM.ObjWNum(R, num);
- END WriteType;
- BEGIN
- PCM.ObjW(R, 83X);
- i := 0;
- WHILE i < nofCmds DO
- IF (commands[i].scope.formalParCount = 0) THEN
- PCM.ObjWNum(R, 0);
- ELSIF (commands[i].scope.formalParCount = 1) & (commands[i].scope.firstPar.type = PCT.Ptr) THEN
- PCM.ObjWNum(R, 1); (* ANY , TO BE REMOVED *)
- ELSE
- WriteType(commands[i].scope.firstPar.type);
- END;
- IF (commands[i].type = PCT.Ptr) THEN
- PCM.ObjWNum(R, 1); (* ANY, TO BE REMOVED *)
- ELSE
- WriteType(commands[i].type);
- END;
- (* cmdName cmdOffset 4) *)
- StringPool.GetString(commands[i].name, str);
- PCM.ObjWName(R, str);
- PCM.ObjWNum(R, commands[i].adr(PCBT.Procedure).codeoffset);
- INC(i);
- END;
- END CommandBlock;
- PROCEDURE PointerBlock;
- VAR p: PCT.Variable;
- BEGIN
- PCM.ObjW(R, 84X);
- nofptrs := 0;
- p := scope.firstVar;
- WHILE p # NIL DO
- IF ~(PCM.Untraced IN p.flags) & (p.adr # NIL) THEN
- OutPtrs(p.adr(PCBT.GlobalVariable).offset, p.type, FALSE) (* debug = FALSE *)
- END;
- p := p.nextVar
- END;
- p := scope.firstHiddenVar;
- WHILE p # NIL DO
- IF p.adr # NIL THEN (* ug: checking for PCM.Untraced not necessary here, flags of hidden variables always {} *)
- OutPtrs(p.adr(PCBT.GlobalVariable).offset, p.type, FALSE) (* debug = FALSE *)
- END;
- p := p.nextVar
- END;
- IF nofptrs > MAX(INTEGER) THEN PCM.Error(222, 0, "") END;
- IF nofptrs # 0 THEN PCM.ObjWLIntAt(R, PtrPos, nofptrs) END;
- END PointerBlock;
- PROCEDURE ImportBlock;
- VAR i, j, k: LONGINT; m: PCT.Module; str: StringBuf; adr: PCBT.Module;
- BEGIN
- PCM.ObjW(R, 85X);
- IF mod.imports # NIL THEN
- i := 0; j := 0;
- k := LEN(mod.imports);
- WHILE (i < k) & (mod.imports[i] # NIL) DO
- m := mod.imports[i];
- adr := m.adr(PCBT.Module);
- IF adr.nr = -1 THEN
- INC(j); adr.nr := SHORT(j);
- StringPool.GetString(m.name, str); PCM.ObjWName(R, str);
- END;
- INC(i)
- END
- END;
- ASSERT(j = nofImp);
- END ImportBlock;
- (*
- PROCEDURE ImportBlock;
- VAR i, j, k, len: LONGINT; m: PCT.Module; str: StringBuf; adr: PCBT.Module;
- BEGIN
- PCM.ObjW(R, 85X);
- IF mod.imports # NIL THEN
- j := 0;
- k := LEN(mod.imports);
- REPEAT DEC(k) UNTIL (k < 0) OR (mod.imports[k] # NIL);
- i := 0;
- WHILE (i <= k) DO
- m := mod.imports[i];
- adr := m.adr(PCBT.Module);
- IF adr.nr = -1 THEN
- INC(j); adr.nr := SHORT(j);
- StringPool.GetString(m.name, str); PCM.ObjWName(R, str);
- END;
- INC(i)
- END
- END;
- ASSERT(j = nofImp);
- END ImportBlock;
- *)
- PROCEDURE VarConsBlock;
- VAR p: PCBT.GlobalVariable; pos, count: LONGINT;
- PROCEDURE FixList(p: PCBT.Fixup);
- BEGIN
- WHILE p # NIL DO
- PCM.ObjWNum(R, p.offset); p := p.next; INC(count)
- END
- END FixList;
- BEGIN
- PCM.ObjW(R, 8DX);
- (*first pass: local GVars*)
- nofVarCons := 0;
- PCM.ObjW(R, 0X); PCM.ObjWNum(R, -1); PCM.ObjWGetPos(R, pos); PCM.ObjWLInt(R, -1);
- p := adr.OwnVars; count := 0;
- WHILE p # PCBT.sentinel DO
- FixList(p.link);
- ASSERT(p.entryNo = PCBT.UndefEntryNo);
- p := p.next
- END;
- PCM.ObjWLIntAt(R, pos, count);
- INC(nofVarCons);
- (*second pass: imported GVars*)
- p := adr.ExtVars;
- WHILE p # PCBT.sentinel DO
- IF (p.link # NIL) THEN
- p.entryNo := nofVarCons; (* remember the position for the UseSection *)
- count := 0; INC(nofVarCons);
- PCM.ObjW(R, CHR(p.owner.nr)); PCM.ObjWNum(R, 0); PCM.ObjWGetPos(R, pos); PCM.ObjWLInt(R, -1);
- FixList(p.link);
- PCM.ObjWLIntAt(R, pos, count);
- END;
- p := p.next
- END;
- END VarConsBlock;
- PROCEDURE LinkBlock;
- VAR nofLinks: LONGINT; p: PCBT.Procedure; count : LONGINT;
- (* ug *)
- PROCEDURE CountFixups(p: PCBT.Procedure; VAR count: LONGINT);
- VAR f : PCBT.Fixup;
- BEGIN
- count := 0;
- f := p.link;
- WHILE f # NIL DO
- INC(count);
- f := f.next;
- END
- END CountFixups;
- BEGIN
- PCM.ObjW(R, 86X);
- FOR i := 0 TO PCBT.NofSysCalls-1 DO
- IF adr.syscalls[i] # NIL THEN
- PCM.ObjW(R, 0X); PCM.ObjW(R, PCLIR.CG.SysCallMap[i]); PCM.ObjWNum(R, adr.syscalls[i].offset);
- INC(nofLinks)
- END
- END;
- (* ug *)
- p := adr.OwnProcs;
- WHILE p # PCBT.psentinel DO
- IF (p.public) OR (p.link # NIL) OR (p IS PCBT.Method) THEN
- CountFixups(p, count);
- PCM.ObjWNum(R, count)
- END;
- p := p.next;
- END;
- PCM.ObjWNum(R, adr.casetablesize);
- IF nofLinks # 0 THEN PCM.ObjWLIntAt(R, LinksPos, nofLinks) END
- END LinkBlock;
- PROCEDURE UseBlock;
- VAR m: PCT.Module;
- e, i: LONGINT; modname, name: StringBuf;
- v: PCT.Variable; p: PCT.Proc; t: PCT.Type; c: PCT.Value;
- PROCEDURE UseEntry(m: PCT.Module; p: PCT.Symbol; offset: LONGINT);
- BEGIN
- StringPool.GetString(p.name, name);
- PCOM.FPrintObj(p, m);
- PCM.ObjWNum(R, p.sym(PCOM.Symbol).fp);
- PCM.ObjWName(R, name);
- PCM.ObjWNum(R, offset);
- END UseEntry;
- PROCEDURE UseType(t: PCT.Struct);
- VAR size: PCBT.RecSize; sym: PCOM.Struct; j: LONGINT;
- BEGIN
- LOOP
- IF t IS PCT.Pointer THEN t := t(PCT.Pointer).base
- ELSIF t IS PCT.Array THEN t := t(PCT.Array).base
- (** fof >> *)
- ELSIF t IS PCT.EnhArray THEN
- t := t( PCT.EnhArray ).base
- ELSIF t IS PCT.Tensor THEN
- t := t( PCT.Tensor).base
- (** << fof *)
- ELSE EXIT
- END
- END;
- IF (t IS PCT.Record) THEN
- WITH t: PCT.Record DO
- size := t.size(PCBT.RecSize);
- IF (size.td # NIL) THEN
- IF (t.scope.module = m) THEN
- sym := t.sym(PCOM.Struct);
- IF (t.owner # NIL) & (t.owner.sym = NIL) THEN PCOM.FPrintObj(t.owner, m) END;
- PCM.ObjW(R, EURecord);
- PCM.ObjWNum(R, -size.td.offset);
- (*! fof: weakened consistency for new compiler, should be replaced by new fp rules
- IF t.pvused THEN
- PCM.ObjWNum(R, sym.pvfp);
- PCM.ObjWName(R, "@");
- ELSIF t.pbused THEN
- PCM.ObjWNum(R, sym.pbfp);
- PCM.ObjWName(R, "@")
- END;
- *)
- PCM.ObjW(R, EUEnd);
- size.td := NIL; (*avoid double tracing*)
- ELSE
- (* aliasing of imported type: schedule module for emission in use list *)
- j := i+1;
- LOOP
- IF j = LEN(mod.imports) THEN
- INC(Nreschedule0);
- PCT.ExtendModArray(mod.imports);
- mod.imports[j] := t.scope.module;
- EXIT
- ELSIF mod.imports[j] = NIL THEN
- INC(Nreschedule1);
- mod.imports[j] := t.scope.module;
- EXIT
- ELSIF mod.imports[j] = t.scope.module THEN
- INC(Nreschedule2);
- EXIT
- END;
- INC(j)
- END
- END
- END
- END
- END
- END UseType;
- BEGIN
- PCM.ObjW(R, 8AX);
- IF mod.imports # NIL THEN
- i := 0;
- WHILE (i < LEN(mod.imports)) & (mod.imports[i] # NIL) DO
- m := mod.imports[i];
- ASSERT(m = m.scope.owner);
- StringPool.GetString(m.name, modname);
- PCM.ObjWName(R, modname);
- IF TraceUse THEN PCM.LogWLn; PCM.LogWStr("Use: "); PCM.LogWStr(modname) END;
- c := m.scope.firstValue;
- WHILE c # NIL DO
- IF (PCT.used IN c.flags) & (c.vis # PCT.Internal) THEN UseEntry(m, c, 0) END;
- EXCL(c.flags, PCT.used);
- c := c.nextVal
- END;
- v := m.scope.firstVar;
- WHILE v # NIL DO
- e := v.adr(PCBT.GlobalVariable).entryNo;
- IF (e # PCBT.UndefEntryNo) THEN
- UseEntry(m, v, e); UseType(v.type);
- IF Optimize THEN
- v.adr(PCBT.GlobalVariable).entryNo := PCBT.UndefEntryNo
- ELSE
- ASSERT(v.adr(PCBT.GlobalVariable).next # NIL, 500);
- ASSERT(v.adr(PCBT.GlobalVariable).link # NIL, 501);
- END
- END;
- v := v.nextVar
- END;
- t := m.scope.firstType;
- WHILE t # NIL DO
- IF (PCT.used IN t.flags) & (t.vis # PCT.Internal) THEN UseEntry(m, t, 0); UseType(t.type) END;
- EXCL(t.flags, PCT.used);
- t := t.nextType
- END;
- p := m.scope.firstProc;
- WHILE p # NIL DO
- IF (p.adr # NIL) & (p.adr(PCBT.Procedure).link # NIL) THEN
- UseEntry(m, p, p.adr(PCBT.Procedure).link.offset + EUProcFlag)
- ELSIF (p.flags * {PCT.used, PCT.Inline} = {PCT.used, PCT.Inline}) & (p.vis # PCT.Internal) THEN
- UseEntry(m, p, 0)
- END;
- p := p.nextProc
- END;
- PCM.ObjW(R, 0X);
- INC(i)
- END
- END;
- PCM.ObjW(R, 0X)
- END UseBlock;
- (*
- ExportSection = count { fp link [ Type ] }
- Type = 1 ( ref | (link count pbfp pvfp [Type] {fldfp [Type] | mthfp} 0 ) )
- Vars: link < 0 (offset[SB])
- Proc: link > 0 (offset[code base])
- Other: link = 0
- *)
- PROCEDURE ExportBlock;
- TYPE ExpList = POINTER TO ARRAY OF LONGINT;
- VAR count, nofstr: INTEGER; pos: LONGINT;
- explist: ExpList; exppos, explen: LONGINT;
- v: PCT.Variable; p: PCT.Proc; t: PCT.Type; c: PCT.Value;
- PROCEDURE ExportType(t: PCT.Struct);
- VAR count: INTEGER; pos: LONGINT; sym: PCOM.Struct; p: PCT.Proc; v: PCT.Variable;
- BEGIN
- WHILE (t IS PCT.Pointer) OR (t IS PCT.Array) DO
- IF t IS PCT.Pointer THEN t := t(PCT.Pointer).base ELSE t := t(PCT.Array).base END
- END;
- (** fof >> *)
- WHILE (t IS PCT.EnhArray) DO t := t( PCT.EnhArray ).base END;
- IF (t IS PCT.Tensor) THEN t := t(PCT.Tensor).base END;
- (** << fof *)
- sym := t.sym(PCOM.Struct);
- IF (t IS PCT.Record) & ((sym.mod = NIL)OR(sym.mod = mod)) THEN
- WITH t: PCT.Record DO
- PCM.ObjW(R, EURecord);
- IF sym.uref # 0 THEN
- PCM.ObjWNum(R, -sym.uref)
- ELSE
- count := 0;
- INC(nofstr); sym.uref := nofstr; (*remember it's exported*)
- PCM.ObjWNum(R, t.size(PCBT.RecSize).td.offset); (* link address in the constant section*)
- PCM.ObjWGetPos(R, pos); PCM.ObjWLInt(R, 2); (* number of entries *)
- ExportType(t.btyp);
- PCM.ObjWNum(R, sym.pbfp); PCM.ObjWNum(R, sym.pvfp);
- v := t.scope.firstVar;
- WHILE v # NIL DO
- IF v.vis # PCT.Internal THEN
- PCM.ObjWNum(R, v.sym(PCOM.Symbol).fp); ExportType(v.type); INC(count);
- END;
- v := v.nextVar
- END;
- p := t.scope.firstProc;
- WHILE p # NIL DO
- IF (p.vis # PCT.Internal) & (p # t.scope.body) THEN
- PCM.ObjWNum(R, p.sym(PCOM.Symbol).fp); INC(count);
- END;
- p := p.nextProc
- END;
- IF count # 0 THEN PCM.ObjWLIntAt(R, pos, count+2) END;
- PCM.ObjW(R, EUEnd)
- END
- END
- END;
- END ExportType;
- PROCEDURE ExportSymbol(p: PCT.Symbol; offset: LONGINT; s: PCT.Symbol);
- VAR i, fp: LONGINT; name,prefix: ARRAY 256 OF CHAR; explist2: ExpList;
- BEGIN
- StringPool.GetString(p.name, name);
- fp := p.sym(PCOM.Symbol).fp;
- IF s # NIL THEN
- StringPool.GetString(s.name,prefix);
- PCOM.FPrintName(fp,prefix);
- END;
- FOR i := 0 TO exppos-1 DO
- IF fp = explist[i] THEN PCM.ErrorN(280, PCM.InvalidPosition, p.name) END
- END;
- IF exppos >= explen THEN
- NEW(explist2, 2*explen);
- SYSTEM.MOVE(ADDRESSOF(explist[0]), ADDRESSOF(explist2[0]), 4*explen);
- explist := explist2; explen := 2*explen
- END;
- explist[exppos] := fp; INC(exppos);
- PCM.ObjWNum(R, fp);
- PCM.ObjWNum(R, offset);
- INC(count);
- END ExportSymbol;
- PROCEDURE ExportMethods(s: PCT.Symbol);
- VAR sym: PCOM.Struct; p: PCT.Proc; t: PCT.Struct;
- BEGIN
- t := s.type;
- WHILE (t IS PCT.Pointer) OR (t IS PCT.Array) DO
- IF t IS PCT.Pointer THEN t := t(PCT.Pointer).base ELSE t := t(PCT.Array).base END
- END;
- WHILE (t IS PCT.EnhArray) DO t := t( PCT.EnhArray ).base END;
- IF (t IS PCT.Tensor) THEN t := t(PCT.Tensor).base END;
- sym := t.sym(PCOM.Struct);
- IF (t IS PCT.Record) & ((sym.mod = NIL)OR(sym.mod = mod)) THEN
- WITH t: PCT.Record DO
- p := t.scope.firstProc;
- WHILE p # NIL DO
- IF (p.vis # PCT.Internal) (*& ~(PCT.Inline IN p.flags)*) THEN
- ExportSymbol(p, p.adr(PCBT.Procedure).codeoffset,s);
- END;
- p := p.nextProc
- END
- END
- END;
- END ExportMethods;
- BEGIN
- PCM.ObjW(R, 88X);
- PCM.ObjWGetPos(R, pos); PCM.ObjWLInt(R, 0);
- nofstr := 0; count := 0; exppos := 0;
- NEW(explist, 256); explen := 256;
- c := scope.firstValue;
- WHILE c # NIL DO
- IF c.vis # PCT.Internal THEN
- ExportSymbol(c, 0,NIL);
- END;
- c := c.nextVal
- END;
- v := scope.firstVar;
- WHILE v # NIL DO
- IF v.vis # PCT.Internal THEN
- ExportSymbol(v, v.adr(PCBT.GlobalVariable).offset,NIL);
- ExportType(v.type)
- END;
- v := v.nextVar
- END;
- t := scope.firstType;
- WHILE t # NIL DO
- IF t.vis # PCT.Internal THEN
- ExportSymbol(t, 0,NIL);
- ExportType(t.type)
- END;
- t:= t.nextType
- END;
- p := scope.firstProc;
- WHILE p # NIL DO
- IF (p.vis # PCT.Internal) (*& ~(PCT.Inline IN p.flags)*) THEN
- ExportSymbol(p, p.adr(PCBT.Procedure).codeoffset,NIL);
- END;
- p := p.nextProc
- END;
- t := scope.firstType;
- WHILE t # NIL DO
- IF t.vis # PCT.Internal THEN
- ExportMethods(t);
- END;
- t:= t.nextType
- END;
- IF count # 0 THEN PCM.ObjWLIntAt(R, pos, count) END;
- PCM.ObjW(R, EUEnd)
- END ExportBlock;
- PROCEDURE RawBlock(tag: CHAR; size: LONGINT; VAR block: ARRAY OF CHAR);
- VAR i: LONGINT;
- BEGIN
- PCM.ObjW(R, tag);
- i := 0;
- WHILE i < size DO PCM.ObjW(R, block[i]); INC(i) END
- END RawBlock;
- PROCEDURE WriteType(rec: PCT.Record; VAR tdSize: LONGINT (* ug *));
- CONST MaxTags = 16; (* ug: temporary solution, Modules.MaxTags *)
- VAR size: PCBT.RecSize; nofptrsPos, tdSizePos, oldmth: LONGINT; base: PCT.Record; m: PCT.Method;
- adr: PCBT.Method; bsym: PCOM.Struct; name, name2: StringBuf;
- basenr: INTEGER; baseid: LONGINT;
- upperPartTdSize, lowerPartTdSize: LONGINT;
- BEGIN
- PCT.GetTypeName(rec, name);
- size := rec.size(PCBT.RecSize);
- PCM.ObjWNum(R, size.size);
- PCM.ObjWNum(R, size.td.offset);
- IF rec.brec = NIL THEN
- oldmth := 0;
- basenr := -1;
- baseid := -1
- ELSE
- base := rec.brec;
- basenr := 0;
- IF (base.sym # NIL) THEN
- bsym := base.sym(PCOM.Struct);
- ASSERT(bsym.mod # NIL);
- IF bsym.mod # scope.owner THEN basenr := SHORT(bsym.mod.adr(PCBT.Module).nr) END
- END;
- IF basenr = 0 THEN
- baseid := base.size(PCBT.RecSize).td.offset
- ELSIF base.owner = NIL THEN
- baseid := base.ptr.owner.sym(PCOM.Symbol).fp
- ELSE
- StringPool.GetString(base.owner.name, name2);
- baseid := base.owner.sym(PCOM.Symbol).fp
- END;
- oldmth := base.size(PCBT.RecSize).nofMethods;
- END;
- PCM.ObjWNum(R, basenr);
- PCM.ObjWNum(R, baseid);
- IF rec.scope.IsProtected () THEN
- PCM.ObjWNum(R, -size.nofMethods); (* NofMethods *)
- ELSE
- PCM.ObjWNum(R, size.nofMethods); (* NofMethods *)
- END;
- PCM.ObjWNum(R, oldmth); (* InheritedMethods *)
- PCM.ObjWNum(R, size.nofLocalMethods); (* NewMethods *)
- PCM.ObjWGetPos(R, nofptrsPos);
- PCM.ObjWLInt(R, 0);
- PCM.ObjWName(R, name);
- PCM.ObjWGetPos(R, tdSizePos);
- PCM.ObjWLInt(R, 0);
- (*New Methods in Record*)
- i := 0; m := rec.scope.firstMeth;
- WHILE m # NIL DO
- IF ~(PCT.Inline IN m.flags) OR (PCT.Indexer IN m.flags) THEN
- adr := m.adr(PCBT.Method);
- PCM.ObjWNum(R, adr.mthNo);
- PCM.ObjWNum(R, adr.entryNr);
- INC(i);
- END;
- m := m.nextMeth
- END;
- ASSERT(i = size.nofLocalMethods, 500); (*sanity check*)
- (* Ptrs in Record *)
- nofptrs := 0;
- OutPtrs(0, rec, FALSE); (* debug = FALSE *)
- IF nofptrs > MAX(INTEGER) THEN PCM.Error(221, 0, "") END;
- IF nofptrs # 0 THEN PCM.ObjWLIntAt(R, nofptrsPos, nofptrs) END;
- (* ug *) upperPartTdSize := AddressSize * (MaxTags + size.nofMethods + 1 + 1); (* tags, methods, methods end marker (sentinel), address of TypeInfo *)
- (* ug *) (* lowerPartTdSize := AddressSize * (1 + nofptrs + 1); (* recsize, no. pointers and sentinel *) *)
- (* ug *) lowerPartTdSize := AddressSize * (2 + (4 + nofptrs) + 1); (* SIZEOF(Heaps.StaticTypeDesc), data part of dynamic array of pointer offsets,
- padding field to observe 0 mod 8 boundary of dynamic array *)
- (* ug *) tdSize := upperPartTdSize + lowerPartTdSize;
- (* ug *) PCM.ObjWLIntAt(R, tdSizePos, tdSize)
- END WriteType;
- PROCEDURE WriteInterface(rec: PCT.Record);
- VAR size: PCBT.RecSize; name: StringBuf;
- BEGIN
- PCT.GetTypeName(rec, name);
- size := rec.size(PCBT.RecSize);
- PCM.ObjWNum(R, 4 + 4*rec.scope.procCount);
- PCM.ObjWNum(R, size.td.offset);
- PCM.ObjWNum(R, -1);
- PCM.ObjWNum(R, -1);
- PCM.ObjWNum(R, 0); (* NofMethods *)
- PCM.ObjWNum(R, 0); (* InheritedMethods *)
- PCM.ObjWNum(R, 0); (* NewMethods *)
- PCM.ObjWLInt(R, 0); (* no. pointers (fixed size) *)
- PCM.ObjWName(R, name);
- END WriteInterface;
- PROCEDURE TypeBlock;
- VAR rec: PCT.Record; tdSize: LONGINT; (* ug *)
- BEGIN PCM.ObjW(R, 8BX);
- typeDescsSize := 0; (* ug *)
- rec := scope.records;
- WHILE rec # NIL DO
- IF PCT.interface IN rec.mode THEN
- WriteInterface(rec)
- ELSE
- WriteType(rec, tdSize); (* ug *)
- typeDescsSize := typeDescsSize + tdSize (* ug *)
- END;
- rec := rec.link
- END;
- PCM.ObjWLIntAt(R, typeDescsSizePos, typeDescsSize); (* ug *)
- rec := scope.records;
- WHILE rec # NIL DO
- rec.size(PCBT.RecSize).td := NIL;
- rec := rec.link
- END;
- END TypeBlock;
- (* Stores the exception handle table in the following format
- ExceptionHandlerTable ::= 8EX {ExceptionTableEntry}
- ExceptionTableEntry ::= 0FFX pcFrom(4 bytes) pcTo(4 bytes) pcHandler(4 bytes)
- Since there is only one FINALLY in every procedure, method, body, ... we don't need
- to obtain an order for nesting.
- *)
- PROCEDURE ExTableBlock;
- VAR
- entry: ExTableEntry;
- BEGIN
- PCM.ObjW(R, 8EX);
- entry := exTable;
- WHILE entry # NIL DO
- PCM.ObjW(R, 0FEX);
- PCM.ObjWNum(R, entry.pcFrom);
- PCM.ObjWNum(R, entry.pcTo);
- PCM.ObjWNum(R, entry.pcHandler);
- entry := entry.next;
- END;
- END ExTableBlock;
- (* ug *)
- PROCEDURE PointerInProcBlock;
- PROCEDURE PointerOffsets(s : PCT.Scope; codeoffset, beginOffset, endOffset: LONGINT);
- VAR v: PCT.Variable; p: PCT.Proc; t: PCT.Type; par: PCT.Parameter;
- rs: PCT.RecScope; adr: PCBT.Procedure;
- nofPtrPos : LONGINT;
- BEGIN
- IF s # NIL THEN
- IF s IS PCT.ModScope THEN
- PCM.ObjWNum(R, codeoffset);
- PCM.ObjWNum(R, beginOffset);
- PCM.ObjWNum(R, endOffset);
- PCM.ObjWLInt(R, 0); (* nofptrs *)
- INC(nofProcs);
- ELSIF s IS PCT.ProcScope THEN
- PCM.ObjWNum(R, codeoffset);
- PCM.ObjWNum(R, beginOffset);
- PCM.ObjWNum(R, endOffset);
- nofptrs := 0;
- PCM.ObjWGetPos(R, nofPtrPos); PCM.ObjWLInt(R, nofptrs);
- v := s.firstVar;
- WHILE v # NIL DO
- IF (v.adr # NIL) & ~(PCM.Untraced IN v.flags) THEN OutPtrs(v.adr(PCBT.Variable).offset, v.type, FALSE) (* debug = FALSE *) END;
- v := v.nextVar
- END;
- v := s.firstHiddenVar;
- WHILE v # NIL DO
- IF v.adr # NIL THEN OutPtrs(v.adr(PCBT.Variable).offset, v.type, FALSE) (* debug = FALSE *) END;
- v := v.nextVar
- END;
- par := s(PCT.ProcScope).firstPar;
- WHILE par # NIL DO
- IF ~par.ref THEN
- OutPtrs(par.adr(PCBT.Variable).offset, par.type, FALSE) (* debug = FALSE *)
- END;
- par := par.nextPar
- END;
- PCM.ObjWLIntAt(R, nofPtrPos, nofptrs);
- IF nofptrs > maxPtrs THEN maxPtrs := nofptrs END;
- INC(nofProcs);
- END;
- p := s.firstProc;
- WHILE p # NIL DO
- adr := p.adr(PCBT.Procedure);
- IF adr.codeoffset # 0 THEN
- PointerOffsets(p.scope, adr.codeoffset, adr.beginOffset, adr.endOffset)
- END;
- p := p.nextProc
- END;
- t := s.firstType;
- WHILE t # NIL DO
- IF (t.type IS PCT.Pointer) & (t.type(PCT.Pointer).base IS PCT.Record)THEN
- rs := t.type(PCT.Pointer).baseR.scope;
- PointerOffsets(rs, 0, 0, 0)
- END;
- t := t.nextType
- END
- END
- END PointerOffsets;
- BEGIN
- PCM.ObjW(R, 8FX);
- nofProcs := 0;
- maxPtrs := 0;
- PointerOffsets(scope, adr.codeoffset, adr.beginOffset, adr.endOffset);
- PCM.ObjWLIntAt(R, nofProcsPos, nofProcs);
- PCM.ObjWLIntAt(R, maxPtrsPos, maxPtrs);
- END PointerInProcBlock;
- (* ug *)
- BEGIN
- exTable := NIL; exTableLen := 0;
- mod := scope.owner;
- adr := mod.adr(PCBT.Module);
- sym := NIL;
- IF mod.sym # NIL THEN sym := mod.sym(PCOM.Module) END;
- PCLIR.CG.GetCode(code, codeSize, hdrCodeSize, addressFactor);
- InsertFixupLists(addressFactor);
- CollectInfo;
- dsize := adr.locsize;
- ASSERT(codeSize < PCLIR.CG.MaxCodeSize); (*objfile restriction*)
- (* header block *)
- PCM.ObjWLInt (R, PCM.RefSize(R)+1);
- PCM.ObjWGetPos(R, EntriesPos); PCM.ObjWLInt (R, 0);
- PCM.ObjWLInt (R, nofCmds);
- PCM.ObjWGetPos(R, PtrPos); PCM.ObjWLInt (R, 0);
- PCM.ObjWLInt (R, scope.nofRecs);
- PCM.ObjWLInt (R, nofImp);
- PCM.ObjWGetPos(R, VarConsPos); PCM.ObjWLInt (R, 0);
- PCM.ObjWGetPos(R, LinksPos); PCM.ObjWLInt (R, 0);
- PCM.ObjWLInt (R, dsize);
- PCM.ObjWLInt (R, adr.constsize);
- PCM.ObjWLInt (R, hdrCodeSize);
- PCM.ObjWLInt(R, exTableLen);
- PCM.ObjWGetPos(R, nofProcsPos); PCM.ObjWLInt(R, 0); (* ug *)
- PCM.ObjWGetPos(R, maxPtrsPos); PCM.ObjWLInt(R, 0); (* ug *)
- PCM.ObjWGetPos(R, typeDescsSizePos); PCM.ObjWLInt(R, 0); (* ug *)
- StringPool.GetString(mod.name, str); PCM.ObjWName (R, str);
- EntryBlock(addressFactor);
- CommandBlock;
- PointerBlock;
- ImportBlock;
- VarConsBlock;
- IF nofVarCons # 0 THEN PCM.ObjWLIntAt(R, VarConsPos, nofVarCons) END;
- LinkBlock;
- RawBlock(87X, adr.constsize, adr.const^);
- ExportBlock;
- RawBlock(89X, codeSize, code^);
- UseBlock;
- TypeBlock;
- ExTableBlock;
- PointerInProcBlock; (* ug *)
- (* ref block *)
- PCM.ObjW(R, 8CX);
- PCM.CloseObj(R);
- adr.ResetLists;
- END Generate;
- PROCEDURE Init*;
- BEGIN
- refSize := 0;
- nofCmds := 0;
- nofImp := 0;
- nofVarCons := 0; nofLinks := 0;
- dsize := 0;
- END Init;
- PROCEDURE Install*;
- BEGIN
- Init();
- PCBT.generate := Generate
- END Install;
- BEGIN
- IF TraceUse THEN PCM.LogWLn; PCM.LogWStr("PCOF.TraceUse on") END;
- PCBT.generate := Generate
- END PCOF.
- (*
- 20.02.02 be refinement in the code generator plugin
- 13.04.02 prk export and use of inlined assembler procedures fixed
- 18.03.02 prk PCBT code cleanup and redesign
- 20.02.02 be refinement in the code generator plugin
- 23.01.02 prk fixed bug in use list with aliases of imported types
- 22.01.02 prk ToDo list moved to PCDebug
- 28.11.01 prk import section: list only used modules
- 27.08.01 prk scope.unsorted list removed; use var, proc, const and type lists instead
- 16.08.01 prk keep PCBT.Variable offset, ignore for imported vars
- 11.08.01 prk Fixup and use lists for procedures in PCBT cleaned up
- 10.08.01 prk PCBT.Procedure: imported: BOOLEAN replaced by owner: Module
- 06.08.01 prk make code generator and object file generator indipendent
- 02.08.01 prk Aos-Style Commands added to the Command list (by pjm)
- 02.07.01 prk access flags, new design
- 27.06.01 prk StringPool cleaned up
- 14.06.01 prk type descs for dynamic arrays of ptrs generated by the compiler
- 06.06.01 prk use string pool for object names
- 29.05.01 be syscall structures moved to backend (PCLIR & code generators)
- 28.05.01 prk don't insert invisible symbols in the "use" section
- 28.05.01 prk issue error 221/222 when more than MAX(INTEGER) pointers in global data / record
- 03.05.01 be Installable code generators
- 26.03.01 prk New Reference Section format
- 25.03.01 prk limited HUGEINT implementation (as abstract type)
- 14.03.01 prk OutRefs, don't list ARRAYs of user defined types
- 14.03.01 prk OutRefs, don't list inlined procedures
- *)
|