PCOF.Mod 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299
  1. (* Paco, Copyright 2000 - 2002, Patrik Reali, ETH Zurich *)
  2. MODULE PCOF; (** AUTHOR "prk / be"; PURPOSE "Parallel Compiler: object file plug-in"; *)
  3. IMPORT
  4. SYSTEM, KernelLog,
  5. StringPool, PCDebug, PCBT, PCLIR, PCM, PCT, PCOM;
  6. CONST
  7. AddressSize = SIZEOF(ADDRESS);
  8. TraceUse = FALSE;
  9. Optimize = FALSE;
  10. NewRefSection = TRUE;
  11. Sentinel = LONGINT(0FFFFFFFFH);
  12. EUEnd = 0X; EURecord = 1X; EUProcFlag = LONGINT(080000000H);
  13. TYPE
  14. StringBuf = ARRAY 256 OF CHAR;
  15. OffsetList = POINTER TO RECORD
  16. offset : LONGINT;
  17. nextOffset : OffsetList
  18. END;
  19. ExTableEntry = POINTER TO RECORD
  20. pcFrom, pcTo, pcHandler: LONGINT;
  21. next: ExTableEntry;
  22. END;
  23. VAR
  24. refSize: LONGINT;
  25. nofCmds, nofImp, nofVarCons, nofLinks: INTEGER;
  26. dsize: LONGINT;
  27. globR: PCM.Rider; (* used for OutReference *)
  28. (* stat counters *)
  29. Nreschedule0, Nreschedule1, Nreschedule2: LONGINT;
  30. exTable: ExTableEntry;
  31. exTableLen: LONGINT;
  32. (* ---------- Helper Procedures -------------- *)
  33. PROCEDURE OutRefType(t: PCT.Struct; procHeader: BOOLEAN);
  34. VAR val, off, dim, td: LONGINT; u: PCT.Struct; tdptr: PCBT.GlobalVariable;
  35. BEGIN
  36. td := 0; off := 0; dim := 0;
  37. IF ~procHeader (*& (t IS PCT.Array) *) THEN
  38. IF (t IS PCT.Array) THEN (** fof *)
  39. WITH t: PCT.Array DO
  40. off := 80H;
  41. u := t.base;
  42. IF ~(u IS PCT.Basic) THEN u := PCT.Ptr END;
  43. IF t.mode = PCT.static THEN dim := t.len END
  44. END;
  45. t := u
  46. (** fof >> *)
  47. ELSIF (t IS PCT.EnhArray) THEN
  48. WITH t: PCT.EnhArray DO
  49. off := 80H; u := t.base;
  50. IF ~(u IS PCT.Basic) THEN u := PCT.Ptr END;
  51. IF (t.mode = PCT.static) THEN dim := t.len END
  52. END;
  53. t := u
  54. ELSIF (t IS PCT.Tensor) THEN
  55. WITH t: PCT.Tensor DO
  56. off := 80H; u := t.base;
  57. u := PCT.Ptr ;
  58. END;
  59. t := u
  60. END;
  61. (** << fof *)
  62. END;
  63. IF t = PCT.Int64 THEN
  64. val := 10H
  65. ELSIF t = PCT.Char16 THEN
  66. val := PCT.Int16.sym(PCOM.Struct).fp
  67. ELSIF t = PCT.Char32 THEN
  68. val := PCT.Int32.sym(PCOM.Struct).fp
  69. ELSIF t IS PCT.Basic THEN
  70. val := t.sym(PCOM.Struct).fp
  71. ELSIF t = PCT.NoType THEN
  72. val := 0
  73. ELSIF t IS PCT.Record THEN
  74. val := 16H;
  75. tdptr := t.size(PCBT.RecSize).td;
  76. IF tdptr # NIL THEN td := tdptr.offset ELSE val := 6 END
  77. ELSIF procHeader & PCT.IsPointer(t) THEN
  78. val := 0DH
  79. ELSIF t IS PCT.Pointer THEN
  80. WITH t: PCT.Pointer DO
  81. IF t.baseR # NIL (* IS PCT.Record *) THEN
  82. val := 1DH;
  83. tdptr := t.base.size(PCBT.RecSize).td;
  84. IF tdptr # NIL THEN td := tdptr.offset ELSE val := 0DH END
  85. ELSE
  86. val := 0DH
  87. END
  88. END;
  89. ELSIF t = PCT.Ptr THEN
  90. val := 0DH;
  91. ELSIF t IS PCT.Delegate THEN
  92. val := 0EH
  93. ELSIF procHeader & (t IS PCT.Array) THEN
  94. WITH t: PCT.Array DO
  95. IF t.mode = PCT.static THEN val := 12H
  96. ELSIF t.mode = PCT.open THEN val := 15H
  97. ELSE HALT(98)
  98. END
  99. END
  100. (** fof >> *)
  101. ELSIF procHeader & (t IS PCT.EnhArray) THEN
  102. WITH t: PCT.EnhArray DO
  103. IF t.mode = PCT.static THEN val := 12H
  104. ELSIF t.mode = PCT.open THEN val := 15H
  105. ELSE HALT( 98 )
  106. END
  107. END
  108. ELSIF procHeader & (t IS PCT.Tensor) THEN
  109. val := 15H; (* ???? *)
  110. (** << fof *)
  111. ELSE
  112. HALT(99)
  113. END;
  114. IF procHeader THEN
  115. PCM.RefW(globR, CHR(val))
  116. ELSE
  117. PCM.RefW(globR, CHR(off+val));
  118. IF off = 80H THEN PCM.RefWNum(globR, dim)
  119. ELSIF td # 0 THEN PCM.RefWNum(globR, td)
  120. END
  121. END
  122. END OutRefType;
  123. PROCEDURE OutRefVar(p: PCT.Variable; isRef: BOOLEAN);
  124. VAR arr: PCT.Array; dim, off: LONGINT; type: PCT.Struct; name: StringBuf;earr: PCT.EnhArray; (*fof*)
  125. BEGIN
  126. StringPool.GetString(p.name, name);
  127. IF NewRefSection THEN
  128. IF isRef THEN PCM.RefW(globR, 3X) ELSE PCM.RefW(globR, 1X) END;
  129. OutRefType(p.type, FALSE);
  130. PCM.RefWNum(globR, p.adr(PCBT.Variable).offset);
  131. PCM.RefWString(globR, name)
  132. ELSE
  133. type := p.type;
  134. IF (type IS PCT.Record) THEN
  135. (*skip*)
  136. ELSIF (type IS PCT.Array) & ~(type(PCT.Array).base IS PCT.Basic) THEN
  137. (*skip*)
  138. (** fof >> *)
  139. ELSIF (type IS PCT.EnhArray) & (type( PCT.EnhArray ).base IS PCT.Basic) THEN
  140. (* skip *)
  141. (** << fof *)
  142. ELSIF (type = PCT.Int64) THEN
  143. (*skip*)
  144. ELSE
  145. IF isRef THEN PCM.RefW(globR, 3X) ELSE PCM.RefW(globR, 1X) END;
  146. off := 0; dim := 0;
  147. IF type IS PCT.Array THEN
  148. off := 80H; dim := 1;
  149. REPEAT
  150. arr := type(PCT.Array);
  151. dim := dim * arr.len;
  152. type := arr.base
  153. UNTIL ~(type IS PCT.Array)
  154. END;
  155. (** fof >> *)
  156. IF type IS PCT.EnhArray THEN
  157. off := 80H; dim := 1;
  158. REPEAT earr := type( PCT.EnhArray ); dim := dim * earr.len; type := earr.base UNTIL ~(type IS PCT.EnhArray)
  159. END;
  160. (** << fof *)
  161. IF type = PCT.Byte THEN PCM.RefW(globR, CHR(off+1))
  162. ELSIF type = PCT.Bool THEN PCM.RefW(globR, CHR(off+2))
  163. ELSIF type = PCT.Char8 THEN PCM.RefW(globR, CHR(off+3))
  164. ELSIF type = PCT.Char16 THEN PCM.RefW(globR, CHR(off+5))
  165. ELSIF type = PCT.Char32 THEN PCM.RefW(globR, CHR(off+6))
  166. ELSIF type = PCT.Int8 THEN PCM.RefW(globR, CHR(off+4))
  167. ELSIF type = PCT.Int16 THEN PCM.RefW(globR, CHR(off+5))
  168. ELSIF type = PCT.Int32 THEN PCM.RefW(globR, CHR(off+6))
  169. ELSIF type = PCT.Float32 THEN PCM.RefW(globR, CHR(off+7))
  170. ELSIF type = PCT.Float64 THEN PCM.RefW(globR, CHR(off+8))
  171. ELSIF type = PCT.Set THEN PCM.RefW(globR, CHR(off+9))
  172. ELSIF PCT.IsPointer(type) THEN PCM.RefW(globR, CHR(off+0DH))
  173. ELSIF type IS PCT.Delegate THEN PCM.RefW(globR, CHR(off+0EH))
  174. END;
  175. IF off = 80H THEN PCM.RefW(globR, CHR(dim)) END;
  176. PCM.RefWNum(globR, p.adr(PCBT.Variable).offset);
  177. PCM.RefWString(globR, name);
  178. END
  179. END;
  180. END OutRefVar;
  181. (* fof 070731 moved warnings to PCP : removed CheckAll, CheckModules here *)
  182. PROCEDURE OutReference(scope: PCT.Scope);
  183. VAR owner: PCT.Proc; i: LONGINT; var: PCT.Variable; par: PCT.Parameter; name: StringBuf; entry: ExTableEntry; mod: PCT.Module;
  184. BEGIN
  185. (*
  186. IF (scope.code = NIL) THEN RETURN END;
  187. *)
  188. IF scope IS PCT.ModScope THEN
  189. PCM.RefW(globR, 0F8X);
  190. COPY("$$", name);
  191. PCM.RefWNum(globR, 0); (* offset *)
  192. PCM.RefWString(globR, "$$"); (* name *)
  193. var := scope.firstVar;
  194. WHILE var # NIL DO OutRefVar(var, FALSE); var := var.nextVar END;
  195. mod := scope(PCT.ModScope).owner;
  196. IF mod.adr(PCBT.Module).finallyOff > -1 THEN
  197. NEW(entry);
  198. entry.pcFrom := 0;
  199. entry.pcTo := mod.adr(PCBT.Module).finallyOff;
  200. entry.pcHandler := mod.adr(PCBT.Module).finallyOff;
  201. entry.next := NIL;
  202. IF exTable # NIL THEN
  203. entry.next := exTable;
  204. END;
  205. exTable := entry;
  206. INC(exTableLen);
  207. END;
  208. ELSIF scope IS PCT.ProcScope THEN
  209. WITH scope: PCT.ProcScope DO
  210. owner := scope.ownerO;
  211. IF ~(PCT.Inline IN owner.flags) THEN
  212. IF NewRefSection THEN
  213. PCM.RefW(globR, 0F9X);
  214. PCM.RefWNum(globR, owner.adr(PCBT.Procedure).codeoffset);
  215. PCM.RefWNum(globR, scope.parCount);
  216. OutRefType(owner.type, TRUE);
  217. PCM.RefWNum(globR, owner.level);
  218. PCM.RefWNum(globR, 0)
  219. ELSE
  220. PCM.RefW(globR, 0F8X);
  221. PCM.RefWNum(globR, owner.adr(PCBT.Procedure).codeoffset);
  222. END;
  223. IF owner IS PCT.Method THEN
  224. WITH owner: PCT.Method DO
  225. PCT.GetTypeName(owner.boundTo, name);
  226. i := 0;
  227. WHILE name[i] # 0X DO PCM.RefW(globR, name[i]); INC(i) END;
  228. PCM.RefW(globR, ".")
  229. END
  230. END;
  231. StringPool.GetString(owner.name, name);
  232. PCM.RefWString(globR, name);
  233. par := scope.firstPar;
  234. WHILE par # NIL DO OutRefVar(par, par.ref); par := par.nextPar END;
  235. var := scope.firstVar;
  236. WHILE var # NIL DO OutRefVar(var, FALSE); var := var.nextVar END
  237. END;
  238. IF owner.adr(PCBT.Procedure). finallyOff > -1 THEN
  239. NEW(entry);
  240. entry.pcFrom := owner.adr(PCBT.Procedure).codeoffset;
  241. entry.pcTo := owner.adr(PCBT.Procedure).finallyOff;
  242. entry.pcHandler := owner.adr(PCBT.Procedure).finallyOff;
  243. entry.next := NIL;
  244. IF exTable # NIL THEN
  245. entry.next := exTable;
  246. END;
  247. exTable := entry;
  248. INC(exTableLen);
  249. END;
  250. END;
  251. END
  252. END OutReference;
  253. PROCEDURE Generate*(VAR R: PCM.Rider; scope: PCT.ModScope; VAR codeSize: LONGINT);
  254. VAR commands: ARRAY 128 OF PCT.Proc;
  255. i, nofptrs, nofProcs, maxPtrs, EntriesPos, PtrPos, nofProcsPos, maxPtrsPos, LinksPos, VarConsPos: LONGINT;
  256. typeDescsSize, typeDescsSizePos: LONGINT; (* ug: temporary *)
  257. adr: PCBT.Module; mod: PCT.Module; sym: PCOM.Module; emptyR: PCM.Rider;
  258. code: PCLIR.CodeArray; str: StringBuf; hdrCodeSize, addressFactor: LONGINT;
  259. PROCEDURE UseModule(m: PCBT.Module);
  260. BEGIN
  261. IF m.nr = 0 THEN
  262. INC(nofImp);
  263. m.nr := -1 (*mark*)
  264. END
  265. END UseModule;
  266. PROCEDURE FindCommands;
  267. VAR proc : PCT.Proc;
  268. BEGIN
  269. nofCmds := 0;
  270. proc := scope.firstProc;
  271. WHILE (proc # NIL) DO
  272. IF (proc.vis = PCT.Public) & (~(PCT.Inline IN proc.flags) OR (PCT.Indexer IN proc.flags)) THEN
  273. IF PCT.GetProcedureAllowed(proc.scope, proc.type) THEN
  274. commands[nofCmds] := proc; INC(nofCmds);
  275. END;
  276. END;
  277. proc := proc.nextProc
  278. END;
  279. END FindCommands;
  280. PROCEDURE CollectInfo;
  281. VAR proc: PCT.Proc; o: PCT.Symbol; p: PCBT.GlobalVariable; rec: PCT.Record; bsym: PCOM.Struct;
  282. BEGIN
  283. globR := R; PCT.TraverseScopes(scope, OutReference); R := globR; globR := emptyR;
  284. FindCommands;
  285. (* detect imported modules *)
  286. IF mod.imports # NIL THEN
  287. i := 0;
  288. WHILE (i < LEN(mod.imports)) & (mod.imports[i] # NIL) DO
  289. mod.imports[i].adr(PCBT.Module).nr := 0;
  290. INC(i)
  291. END;
  292. nofImp := 0;
  293. o := scope.sorted;
  294. WHILE o # NIL DO
  295. IF (o IS PCT.Module) & (o.adr # PCT.System.adr) THEN UseModule(o.adr(PCBT.Module)) END;
  296. o := o.sorted;
  297. END;
  298. p := adr.ExtVars;
  299. WHILE p # PCBT.sentinel DO
  300. IF p.link # NIL THEN UseModule(p.owner) END;
  301. p := p.next
  302. END;
  303. rec := scope.records;
  304. WHILE rec # NIL DO
  305. IF (rec.brec # NIL) & (rec.brec.sym # NIL) THEN
  306. bsym := rec.brec.sym(PCOM.Struct);
  307. IF bsym.mod # scope.owner THEN UseModule(bsym.mod.adr(PCBT.Module)) END
  308. END;
  309. rec := rec.link;
  310. ASSERT(rec # scope.records, MAX(INTEGER));
  311. (* Fix bug, sometimes this assertion fails. *)
  312. (* fof 070920: done, cf. PCC.MakeTD *)
  313. END
  314. END;
  315. (*
  316. IF mod.imports # NIL THEN
  317. nofImp := SHORT(LEN(mod.imports));
  318. WHILE (mod.imports[nofImp-1] = NIL) DO DEC(nofImp) END
  319. END
  320. *)
  321. END CollectInfo;
  322. PROCEDURE OutPtrs(offset: LONGINT; type: PCT.Struct; debug : BOOLEAN);
  323. VAR i, n, off: LONGINT; f: PCT.Variable; scope: PCT.Scope; base: PCT.Struct; size: PCBT.Size;
  324. name: StringBuf; state: LONGINT;
  325. BEGIN
  326. IF type.size(PCBT.Size).containPtrs THEN
  327. IF PCT.IsPointer(type) THEN
  328. PCM.ObjWNum(R, offset); INC(nofptrs);
  329. IF debug THEN
  330. KernelLog.Int(offset, 0); KernelLog.String(" "); (* KernelLog.Ln; *)
  331. END
  332. ELSIF PCT.IsDynamicDelegate(type) THEN
  333. PCM.ObjWNum(R, offset+4); INC(nofptrs);
  334. IF debug THEN
  335. KernelLog.Int(offset+4, 0); KernelLog.String(" "); (* KernelLog.Ln; *)
  336. END
  337. ELSIF type IS PCT.Record THEN
  338. WITH type: PCT.Record DO
  339. IF type.brec # NIL THEN OutPtrs(offset, type.brec, debug) END;
  340. scope := type.scope;
  341. END;
  342. f := scope.firstVar;
  343. WHILE f # NIL DO
  344. IF ~(PCM.Untraced IN f.flags) THEN
  345. StringPool.GetString(f.name, name); state := scope.state;
  346. ASSERT(state >= PCT.structallocated);
  347. type := f.type; off := f.adr(PCBT.Variable).offset;
  348. OutPtrs(offset+off, type, debug)
  349. END;
  350. f := f.nextVar
  351. END;
  352. ELSIF type IS PCT.Array THEN
  353. WITH type: PCT.Array DO
  354. IF type.mode = PCT.static THEN
  355. n := type.len;
  356. base := type.base;
  357. WHILE (base IS PCT.Array) DO
  358. type := base(PCT.Array); base := type.base;
  359. ASSERT(type.mode = PCT.static);
  360. n := n * type.len
  361. END;
  362. size := base.size(PCBT.Size);
  363. IF size.containPtrs THEN
  364. FOR i := 0 TO n-1 DO OutPtrs(offset+i*size.size, base, debug) END
  365. END
  366. ELSE
  367. PCDebug.ToDo(PCDebug.NotImplemented); (*find pointers in the array, call NewPtr for each one*)
  368. END
  369. END
  370. (** fof >> *)
  371. ELSIF type IS PCT.EnhArray THEN
  372. WITH type: PCT.EnhArray DO
  373. IF type.mode = PCT.static THEN
  374. n := type.len; base := type.base;
  375. WHILE (base IS PCT.EnhArray) DO type := base( PCT.EnhArray ); base := type.base;
  376. ASSERT ( (type.mode = PCT.static) );
  377. n := n * type.len
  378. END;
  379. size := base.size( PCBT.Size );
  380. IF size.containPtrs THEN
  381. FOR i := 0 TO n - 1 DO OutPtrs( offset + i * size.size, base,FALSE ) END
  382. END
  383. ELSE
  384. PCM.ObjWNum( R, offset ); INC( nofptrs );
  385. (* pointer to array in heap is located at first position ! *)
  386. (*
  387. PCDebug.ToDo( PCDebug.NotImplemented ); (*find pointers in the array, call NewPtr for each one*)
  388. *)
  389. END
  390. END
  391. ELSIF type IS PCT.Tensor THEN
  392. WITH type: PCT.Tensor DO
  393. PCM.ObjWNum(R,offset); INC(nofptrs);
  394. END;
  395. (** << fof *)
  396. END
  397. END
  398. END OutPtrs;
  399. PROCEDURE FixupList(l: PCBT.Fixup; addressFactor: LONGINT; base: ADDRESS; sentinel: LONGINT; prev: PCBT.Fixup; VAR tail: PCBT.Fixup);
  400. (* Insert fixup list into code *)
  401. VAR offset: LONGINT;
  402. BEGIN
  403. tail := NIL;
  404. IF l # NIL THEN
  405. IF prev # NIL THEN
  406. SYSTEM.PUT(base + prev.offset*addressFactor, l.offset);
  407. END;
  408. offset := l.offset;
  409. tail := l;
  410. l := l.next;
  411. WHILE l # NIL DO
  412. SYSTEM.PUT(base+offset*addressFactor, l.offset);
  413. offset := l.offset;
  414. tail := l;
  415. l := l.next;
  416. END;
  417. SYSTEM.PUT(base+offset*addressFactor, sentinel);
  418. END;
  419. END FixupList;
  420. PROCEDURE InsertFixupLists(addressFactor: LONGINT);
  421. VAR p: PCBT.Procedure; i: LONGINT; codebase: ADDRESS; dummy : PCBT.Fixup;
  422. BEGIN
  423. codebase := ADDRESSOF(code[0]);
  424. FOR i := 0 TO PCBT.NofSysCalls-1 DO
  425. IF i # PCBT.casetable THEN
  426. FixupList(adr.syscalls[i], addressFactor, codebase, Sentinel, NIL, dummy)
  427. END
  428. END;
  429. p := adr.ExtProcs;
  430. WHILE p # PCBT.psentinel DO
  431. ASSERT(p.owner # PCBT.context);
  432. FixupList(p.link, addressFactor, codebase, Sentinel, NIL, dummy);
  433. p := p.next
  434. END;
  435. END InsertFixupLists;
  436. PROCEDURE EntryBlock(addressFactor: LONGINT);
  437. VAR nofEntries, firstOffset: LONGINT; codebase: ADDRESS;
  438. PROCEDURE Traverse(p: PCBT.Procedure);
  439. VAR prev, tail : PCBT.Fixup;
  440. BEGIN
  441. prev := NIL;
  442. WHILE p # PCBT.psentinel DO
  443. IF (p.public) OR (p.link # NIL) OR (p IS PCBT.Method) THEN
  444. PCM.ObjWNum(R, p.codeoffset);
  445. p.entryNr := nofEntries;
  446. INC(nofEntries);
  447. FixupList(p.link, addressFactor, codebase, Sentinel, prev, tail);
  448. IF tail # NIL THEN
  449. prev := tail
  450. END;
  451. IF (p.link # NIL) & (firstOffset = -1) THEN
  452. firstOffset := p.link.offset
  453. END;
  454. END;
  455. p := p.next
  456. END
  457. END Traverse;
  458. BEGIN
  459. PCM.ObjW(R, 82X);
  460. nofEntries := 0;
  461. codebase := ADDRESSOF(code[0]);
  462. firstOffset := -1;
  463. Traverse(adr.OwnProcs);
  464. (*
  465. Traverse(adr.ExtProcs);
  466. *)
  467. IF firstOffset # -1 THEN adr.UseSyscall(PCBT.procaddr, firstOffset) END;
  468. IF nofEntries # 0 THEN PCM.ObjWLIntAt(R, EntriesPos, nofEntries) END
  469. END EntryBlock;
  470. PROCEDURE CommandBlock;
  471. VAR i: LONGINT; str: StringBuf;
  472. PROCEDURE WriteType(type : PCT.Struct);
  473. VAR size : PCBT.RecSize; num : LONGINT;
  474. BEGIN
  475. ASSERT((type # NIL) & ((type = PCT.NoType) OR (type IS PCT.Record) OR ((type IS PCT.Pointer) & (type(PCT.Pointer).baseR # NIL))));
  476. num := 0;
  477. IF (type = PCT.NoType) THEN
  478. (* num = 0 *)
  479. ELSIF (type IS PCT.Record) THEN
  480. size := type(PCT.Record).size(PCBT.RecSize);
  481. ELSE
  482. size := type(PCT.Pointer).baseR.size(PCBT.RecSize);
  483. END;
  484. IF (type # PCT.NoType) THEN
  485. IF (size.td # NIL) THEN
  486. num := size.td.offset;
  487. ELSE
  488. KernelLog.String("ERROR: size.td = NIL"); KernelLog.Ln; (* TODO: CHECK WHY THIS HAPPENS *)
  489. END;
  490. END;
  491. PCM.ObjWNum(R, num);
  492. END WriteType;
  493. BEGIN
  494. PCM.ObjW(R, 83X);
  495. i := 0;
  496. WHILE i < nofCmds DO
  497. IF (commands[i].scope.formalParCount = 0) THEN
  498. PCM.ObjWNum(R, 0);
  499. ELSIF (commands[i].scope.formalParCount = 1) & (commands[i].scope.firstPar.type = PCT.Ptr) THEN
  500. PCM.ObjWNum(R, 1); (* ANY , TO BE REMOVED *)
  501. ELSE
  502. WriteType(commands[i].scope.firstPar.type);
  503. END;
  504. IF (commands[i].type = PCT.Ptr) THEN
  505. PCM.ObjWNum(R, 1); (* ANY, TO BE REMOVED *)
  506. ELSE
  507. WriteType(commands[i].type);
  508. END;
  509. (* cmdName cmdOffset 4) *)
  510. StringPool.GetString(commands[i].name, str);
  511. PCM.ObjWName(R, str);
  512. PCM.ObjWNum(R, commands[i].adr(PCBT.Procedure).codeoffset);
  513. INC(i);
  514. END;
  515. END CommandBlock;
  516. PROCEDURE PointerBlock;
  517. VAR p: PCT.Variable;
  518. BEGIN
  519. PCM.ObjW(R, 84X);
  520. nofptrs := 0;
  521. p := scope.firstVar;
  522. WHILE p # NIL DO
  523. IF ~(PCM.Untraced IN p.flags) & (p.adr # NIL) THEN
  524. OutPtrs(p.adr(PCBT.GlobalVariable).offset, p.type, FALSE) (* debug = FALSE *)
  525. END;
  526. p := p.nextVar
  527. END;
  528. p := scope.firstHiddenVar;
  529. WHILE p # NIL DO
  530. IF p.adr # NIL THEN (* ug: checking for PCM.Untraced not necessary here, flags of hidden variables always {} *)
  531. OutPtrs(p.adr(PCBT.GlobalVariable).offset, p.type, FALSE) (* debug = FALSE *)
  532. END;
  533. p := p.nextVar
  534. END;
  535. IF nofptrs > MAX(INTEGER) THEN PCM.Error(222, 0, "") END;
  536. IF nofptrs # 0 THEN PCM.ObjWLIntAt(R, PtrPos, nofptrs) END;
  537. END PointerBlock;
  538. PROCEDURE ImportBlock;
  539. VAR i, j, k: LONGINT; m: PCT.Module; str: StringBuf; adr: PCBT.Module;
  540. BEGIN
  541. PCM.ObjW(R, 85X);
  542. IF mod.imports # NIL THEN
  543. i := 0; j := 0;
  544. k := LEN(mod.imports);
  545. WHILE (i < k) & (mod.imports[i] # NIL) DO
  546. m := mod.imports[i];
  547. adr := m.adr(PCBT.Module);
  548. IF adr.nr = -1 THEN
  549. INC(j); adr.nr := SHORT(j);
  550. StringPool.GetString(m.name, str); PCM.ObjWName(R, str);
  551. END;
  552. INC(i)
  553. END
  554. END;
  555. ASSERT(j = nofImp);
  556. END ImportBlock;
  557. (*
  558. PROCEDURE ImportBlock;
  559. VAR i, j, k, len: LONGINT; m: PCT.Module; str: StringBuf; adr: PCBT.Module;
  560. BEGIN
  561. PCM.ObjW(R, 85X);
  562. IF mod.imports # NIL THEN
  563. j := 0;
  564. k := LEN(mod.imports);
  565. REPEAT DEC(k) UNTIL (k < 0) OR (mod.imports[k] # NIL);
  566. i := 0;
  567. WHILE (i <= k) DO
  568. m := mod.imports[i];
  569. adr := m.adr(PCBT.Module);
  570. IF adr.nr = -1 THEN
  571. INC(j); adr.nr := SHORT(j);
  572. StringPool.GetString(m.name, str); PCM.ObjWName(R, str);
  573. END;
  574. INC(i)
  575. END
  576. END;
  577. ASSERT(j = nofImp);
  578. END ImportBlock;
  579. *)
  580. PROCEDURE VarConsBlock;
  581. VAR p: PCBT.GlobalVariable; pos, count: LONGINT;
  582. PROCEDURE FixList(p: PCBT.Fixup);
  583. BEGIN
  584. WHILE p # NIL DO
  585. PCM.ObjWNum(R, p.offset); p := p.next; INC(count)
  586. END
  587. END FixList;
  588. BEGIN
  589. PCM.ObjW(R, 8DX);
  590. (*first pass: local GVars*)
  591. nofVarCons := 0;
  592. PCM.ObjW(R, 0X); PCM.ObjWNum(R, -1); PCM.ObjWGetPos(R, pos); PCM.ObjWLInt(R, -1);
  593. p := adr.OwnVars; count := 0;
  594. WHILE p # PCBT.sentinel DO
  595. FixList(p.link);
  596. ASSERT(p.entryNo = PCBT.UndefEntryNo);
  597. p := p.next
  598. END;
  599. PCM.ObjWLIntAt(R, pos, count);
  600. INC(nofVarCons);
  601. (*second pass: imported GVars*)
  602. p := adr.ExtVars;
  603. WHILE p # PCBT.sentinel DO
  604. IF (p.link # NIL) THEN
  605. p.entryNo := nofVarCons; (* remember the position for the UseSection *)
  606. count := 0; INC(nofVarCons);
  607. PCM.ObjW(R, CHR(p.owner.nr)); PCM.ObjWNum(R, 0); PCM.ObjWGetPos(R, pos); PCM.ObjWLInt(R, -1);
  608. FixList(p.link);
  609. PCM.ObjWLIntAt(R, pos, count);
  610. END;
  611. p := p.next
  612. END;
  613. END VarConsBlock;
  614. PROCEDURE LinkBlock;
  615. VAR nofLinks: LONGINT; p: PCBT.Procedure; count : LONGINT;
  616. (* ug *)
  617. PROCEDURE CountFixups(p: PCBT.Procedure; VAR count: LONGINT);
  618. VAR f : PCBT.Fixup;
  619. BEGIN
  620. count := 0;
  621. f := p.link;
  622. WHILE f # NIL DO
  623. INC(count);
  624. f := f.next;
  625. END
  626. END CountFixups;
  627. BEGIN
  628. PCM.ObjW(R, 86X);
  629. FOR i := 0 TO PCBT.NofSysCalls-1 DO
  630. IF adr.syscalls[i] # NIL THEN
  631. PCM.ObjW(R, 0X); PCM.ObjW(R, PCLIR.CG.SysCallMap[i]); PCM.ObjWNum(R, adr.syscalls[i].offset);
  632. INC(nofLinks)
  633. END
  634. END;
  635. (* ug *)
  636. p := adr.OwnProcs;
  637. WHILE p # PCBT.psentinel DO
  638. IF (p.public) OR (p.link # NIL) OR (p IS PCBT.Method) THEN
  639. CountFixups(p, count);
  640. PCM.ObjWNum(R, count)
  641. END;
  642. p := p.next;
  643. END;
  644. PCM.ObjWNum(R, adr.casetablesize);
  645. IF nofLinks # 0 THEN PCM.ObjWLIntAt(R, LinksPos, nofLinks) END
  646. END LinkBlock;
  647. PROCEDURE UseBlock;
  648. VAR m: PCT.Module;
  649. e, i: LONGINT; modname, name: StringBuf;
  650. v: PCT.Variable; p: PCT.Proc; t: PCT.Type; c: PCT.Value;
  651. PROCEDURE UseEntry(m: PCT.Module; p: PCT.Symbol; offset: LONGINT);
  652. BEGIN
  653. StringPool.GetString(p.name, name);
  654. PCOM.FPrintObj(p, m);
  655. PCM.ObjWNum(R, p.sym(PCOM.Symbol).fp);
  656. PCM.ObjWName(R, name);
  657. PCM.ObjWNum(R, offset);
  658. END UseEntry;
  659. PROCEDURE UseType(t: PCT.Struct);
  660. VAR size: PCBT.RecSize; sym: PCOM.Struct; j: LONGINT;
  661. BEGIN
  662. LOOP
  663. IF t IS PCT.Pointer THEN t := t(PCT.Pointer).base
  664. ELSIF t IS PCT.Array THEN t := t(PCT.Array).base
  665. (** fof >> *)
  666. ELSIF t IS PCT.EnhArray THEN
  667. t := t( PCT.EnhArray ).base
  668. ELSIF t IS PCT.Tensor THEN
  669. t := t( PCT.Tensor).base
  670. (** << fof *)
  671. ELSE EXIT
  672. END
  673. END;
  674. IF (t IS PCT.Record) THEN
  675. WITH t: PCT.Record DO
  676. size := t.size(PCBT.RecSize);
  677. IF (size.td # NIL) THEN
  678. IF (t.scope.module = m) THEN
  679. sym := t.sym(PCOM.Struct);
  680. IF (t.owner # NIL) & (t.owner.sym = NIL) THEN PCOM.FPrintObj(t.owner, m) END;
  681. PCM.ObjW(R, EURecord);
  682. PCM.ObjWNum(R, -size.td.offset);
  683. (*! fof: weakened consistency for new compiler, should be replaced by new fp rules
  684. IF t.pvused THEN
  685. PCM.ObjWNum(R, sym.pvfp);
  686. PCM.ObjWName(R, "@");
  687. ELSIF t.pbused THEN
  688. PCM.ObjWNum(R, sym.pbfp);
  689. PCM.ObjWName(R, "@")
  690. END;
  691. *)
  692. PCM.ObjW(R, EUEnd);
  693. size.td := NIL; (*avoid double tracing*)
  694. ELSE
  695. (* aliasing of imported type: schedule module for emission in use list *)
  696. j := i+1;
  697. LOOP
  698. IF j = LEN(mod.imports) THEN
  699. INC(Nreschedule0);
  700. PCT.ExtendModArray(mod.imports);
  701. mod.imports[j] := t.scope.module;
  702. EXIT
  703. ELSIF mod.imports[j] = NIL THEN
  704. INC(Nreschedule1);
  705. mod.imports[j] := t.scope.module;
  706. EXIT
  707. ELSIF mod.imports[j] = t.scope.module THEN
  708. INC(Nreschedule2);
  709. EXIT
  710. END;
  711. INC(j)
  712. END
  713. END
  714. END
  715. END
  716. END
  717. END UseType;
  718. BEGIN
  719. PCM.ObjW(R, 8AX);
  720. IF mod.imports # NIL THEN
  721. i := 0;
  722. WHILE (i < LEN(mod.imports)) & (mod.imports[i] # NIL) DO
  723. m := mod.imports[i];
  724. ASSERT(m = m.scope.owner);
  725. StringPool.GetString(m.name, modname);
  726. PCM.ObjWName(R, modname);
  727. IF TraceUse THEN PCM.LogWLn; PCM.LogWStr("Use: "); PCM.LogWStr(modname) END;
  728. c := m.scope.firstValue;
  729. WHILE c # NIL DO
  730. IF (PCT.used IN c.flags) & (c.vis # PCT.Internal) THEN UseEntry(m, c, 0) END;
  731. EXCL(c.flags, PCT.used);
  732. c := c.nextVal
  733. END;
  734. v := m.scope.firstVar;
  735. WHILE v # NIL DO
  736. e := v.adr(PCBT.GlobalVariable).entryNo;
  737. IF (e # PCBT.UndefEntryNo) THEN
  738. UseEntry(m, v, e); UseType(v.type);
  739. IF Optimize THEN
  740. v.adr(PCBT.GlobalVariable).entryNo := PCBT.UndefEntryNo
  741. ELSE
  742. ASSERT(v.adr(PCBT.GlobalVariable).next # NIL, 500);
  743. ASSERT(v.adr(PCBT.GlobalVariable).link # NIL, 501);
  744. END
  745. END;
  746. v := v.nextVar
  747. END;
  748. t := m.scope.firstType;
  749. WHILE t # NIL DO
  750. IF (PCT.used IN t.flags) & (t.vis # PCT.Internal) THEN UseEntry(m, t, 0); UseType(t.type) END;
  751. EXCL(t.flags, PCT.used);
  752. t := t.nextType
  753. END;
  754. p := m.scope.firstProc;
  755. WHILE p # NIL DO
  756. IF (p.adr # NIL) & (p.adr(PCBT.Procedure).link # NIL) THEN
  757. UseEntry(m, p, p.adr(PCBT.Procedure).link.offset + EUProcFlag)
  758. ELSIF (p.flags * {PCT.used, PCT.Inline} = {PCT.used, PCT.Inline}) & (p.vis # PCT.Internal) THEN
  759. UseEntry(m, p, 0)
  760. END;
  761. p := p.nextProc
  762. END;
  763. PCM.ObjW(R, 0X);
  764. INC(i)
  765. END
  766. END;
  767. PCM.ObjW(R, 0X)
  768. END UseBlock;
  769. (*
  770. ExportSection = count { fp link [ Type ] }
  771. Type = 1 ( ref | (link count pbfp pvfp [Type] {fldfp [Type] | mthfp} 0 ) )
  772. Vars: link < 0 (offset[SB])
  773. Proc: link > 0 (offset[code base])
  774. Other: link = 0
  775. *)
  776. PROCEDURE ExportBlock;
  777. TYPE ExpList = POINTER TO ARRAY OF LONGINT;
  778. VAR count, nofstr: INTEGER; pos: LONGINT;
  779. explist: ExpList; exppos, explen: LONGINT;
  780. v: PCT.Variable; p: PCT.Proc; t: PCT.Type; c: PCT.Value;
  781. PROCEDURE ExportType(t: PCT.Struct);
  782. VAR count: INTEGER; pos: LONGINT; sym: PCOM.Struct; p: PCT.Proc; v: PCT.Variable;
  783. BEGIN
  784. WHILE (t IS PCT.Pointer) OR (t IS PCT.Array) DO
  785. IF t IS PCT.Pointer THEN t := t(PCT.Pointer).base ELSE t := t(PCT.Array).base END
  786. END;
  787. (** fof >> *)
  788. WHILE (t IS PCT.EnhArray) DO t := t( PCT.EnhArray ).base END;
  789. IF (t IS PCT.Tensor) THEN t := t(PCT.Tensor).base END;
  790. (** << fof *)
  791. sym := t.sym(PCOM.Struct);
  792. IF (t IS PCT.Record) & ((sym.mod = NIL)OR(sym.mod = mod)) THEN
  793. WITH t: PCT.Record DO
  794. PCM.ObjW(R, EURecord);
  795. IF sym.uref # 0 THEN
  796. PCM.ObjWNum(R, -sym.uref)
  797. ELSE
  798. count := 0;
  799. INC(nofstr); sym.uref := nofstr; (*remember it's exported*)
  800. PCM.ObjWNum(R, t.size(PCBT.RecSize).td.offset); (* link address in the constant section*)
  801. PCM.ObjWGetPos(R, pos); PCM.ObjWLInt(R, 2); (* number of entries *)
  802. ExportType(t.btyp);
  803. PCM.ObjWNum(R, sym.pbfp); PCM.ObjWNum(R, sym.pvfp);
  804. v := t.scope.firstVar;
  805. WHILE v # NIL DO
  806. IF v.vis # PCT.Internal THEN
  807. PCM.ObjWNum(R, v.sym(PCOM.Symbol).fp); ExportType(v.type); INC(count);
  808. END;
  809. v := v.nextVar
  810. END;
  811. p := t.scope.firstProc;
  812. WHILE p # NIL DO
  813. IF (p.vis # PCT.Internal) & (p # t.scope.body) THEN
  814. PCM.ObjWNum(R, p.sym(PCOM.Symbol).fp); INC(count);
  815. END;
  816. p := p.nextProc
  817. END;
  818. IF count # 0 THEN PCM.ObjWLIntAt(R, pos, count+2) END;
  819. PCM.ObjW(R, EUEnd)
  820. END
  821. END
  822. END;
  823. END ExportType;
  824. PROCEDURE ExportSymbol(p: PCT.Symbol; offset: LONGINT; s: PCT.Symbol);
  825. VAR i, fp: LONGINT; name,prefix: ARRAY 256 OF CHAR; explist2: ExpList;
  826. BEGIN
  827. StringPool.GetString(p.name, name);
  828. fp := p.sym(PCOM.Symbol).fp;
  829. IF s # NIL THEN
  830. StringPool.GetString(s.name,prefix);
  831. PCOM.FPrintName(fp,prefix);
  832. END;
  833. FOR i := 0 TO exppos-1 DO
  834. IF fp = explist[i] THEN PCM.ErrorN(280, PCM.InvalidPosition, p.name) END
  835. END;
  836. IF exppos >= explen THEN
  837. NEW(explist2, 2*explen);
  838. SYSTEM.MOVE(ADDRESSOF(explist[0]), ADDRESSOF(explist2[0]), 4*explen);
  839. explist := explist2; explen := 2*explen
  840. END;
  841. explist[exppos] := fp; INC(exppos);
  842. PCM.ObjWNum(R, fp);
  843. PCM.ObjWNum(R, offset);
  844. INC(count);
  845. END ExportSymbol;
  846. PROCEDURE ExportMethods(s: PCT.Symbol);
  847. VAR sym: PCOM.Struct; p: PCT.Proc; t: PCT.Struct;
  848. BEGIN
  849. t := s.type;
  850. WHILE (t IS PCT.Pointer) OR (t IS PCT.Array) DO
  851. IF t IS PCT.Pointer THEN t := t(PCT.Pointer).base ELSE t := t(PCT.Array).base END
  852. END;
  853. WHILE (t IS PCT.EnhArray) DO t := t( PCT.EnhArray ).base END;
  854. IF (t IS PCT.Tensor) THEN t := t(PCT.Tensor).base END;
  855. sym := t.sym(PCOM.Struct);
  856. IF (t IS PCT.Record) & ((sym.mod = NIL)OR(sym.mod = mod)) THEN
  857. WITH t: PCT.Record DO
  858. p := t.scope.firstProc;
  859. WHILE p # NIL DO
  860. IF (p.vis # PCT.Internal) (*& ~(PCT.Inline IN p.flags)*) THEN
  861. ExportSymbol(p, p.adr(PCBT.Procedure).codeoffset,s);
  862. END;
  863. p := p.nextProc
  864. END
  865. END
  866. END;
  867. END ExportMethods;
  868. BEGIN
  869. PCM.ObjW(R, 88X);
  870. PCM.ObjWGetPos(R, pos); PCM.ObjWLInt(R, 0);
  871. nofstr := 0; count := 0; exppos := 0;
  872. NEW(explist, 256); explen := 256;
  873. c := scope.firstValue;
  874. WHILE c # NIL DO
  875. IF c.vis # PCT.Internal THEN
  876. ExportSymbol(c, 0,NIL);
  877. END;
  878. c := c.nextVal
  879. END;
  880. v := scope.firstVar;
  881. WHILE v # NIL DO
  882. IF v.vis # PCT.Internal THEN
  883. ExportSymbol(v, v.adr(PCBT.GlobalVariable).offset,NIL);
  884. ExportType(v.type)
  885. END;
  886. v := v.nextVar
  887. END;
  888. t := scope.firstType;
  889. WHILE t # NIL DO
  890. IF t.vis # PCT.Internal THEN
  891. ExportSymbol(t, 0,NIL);
  892. ExportType(t.type)
  893. END;
  894. t:= t.nextType
  895. END;
  896. p := scope.firstProc;
  897. WHILE p # NIL DO
  898. IF (p.vis # PCT.Internal) (*& ~(PCT.Inline IN p.flags)*) THEN
  899. ExportSymbol(p, p.adr(PCBT.Procedure).codeoffset,NIL);
  900. END;
  901. p := p.nextProc
  902. END;
  903. t := scope.firstType;
  904. WHILE t # NIL DO
  905. IF t.vis # PCT.Internal THEN
  906. ExportMethods(t);
  907. END;
  908. t:= t.nextType
  909. END;
  910. IF count # 0 THEN PCM.ObjWLIntAt(R, pos, count) END;
  911. PCM.ObjW(R, EUEnd)
  912. END ExportBlock;
  913. PROCEDURE RawBlock(tag: CHAR; size: LONGINT; VAR block: ARRAY OF CHAR);
  914. VAR i: LONGINT;
  915. BEGIN
  916. PCM.ObjW(R, tag);
  917. i := 0;
  918. WHILE i < size DO PCM.ObjW(R, block[i]); INC(i) END
  919. END RawBlock;
  920. PROCEDURE WriteType(rec: PCT.Record; VAR tdSize: LONGINT (* ug *));
  921. CONST MaxTags = 16; (* ug: temporary solution, Modules.MaxTags *)
  922. VAR size: PCBT.RecSize; nofptrsPos, tdSizePos, oldmth: LONGINT; base: PCT.Record; m: PCT.Method;
  923. adr: PCBT.Method; bsym: PCOM.Struct; name, name2: StringBuf;
  924. basenr: INTEGER; baseid: LONGINT;
  925. upperPartTdSize, lowerPartTdSize: LONGINT;
  926. BEGIN
  927. PCT.GetTypeName(rec, name);
  928. size := rec.size(PCBT.RecSize);
  929. PCM.ObjWNum(R, size.size);
  930. PCM.ObjWNum(R, size.td.offset);
  931. IF rec.brec = NIL THEN
  932. oldmth := 0;
  933. basenr := -1;
  934. baseid := -1
  935. ELSE
  936. base := rec.brec;
  937. basenr := 0;
  938. IF (base.sym # NIL) THEN
  939. bsym := base.sym(PCOM.Struct);
  940. ASSERT(bsym.mod # NIL);
  941. IF bsym.mod # scope.owner THEN basenr := SHORT(bsym.mod.adr(PCBT.Module).nr) END
  942. END;
  943. IF basenr = 0 THEN
  944. baseid := base.size(PCBT.RecSize).td.offset
  945. ELSIF base.owner = NIL THEN
  946. baseid := base.ptr.owner.sym(PCOM.Symbol).fp
  947. ELSE
  948. StringPool.GetString(base.owner.name, name2);
  949. baseid := base.owner.sym(PCOM.Symbol).fp
  950. END;
  951. oldmth := base.size(PCBT.RecSize).nofMethods;
  952. END;
  953. PCM.ObjWNum(R, basenr);
  954. PCM.ObjWNum(R, baseid);
  955. IF rec.scope.IsProtected () THEN
  956. PCM.ObjWNum(R, -size.nofMethods); (* NofMethods *)
  957. ELSE
  958. PCM.ObjWNum(R, size.nofMethods); (* NofMethods *)
  959. END;
  960. PCM.ObjWNum(R, oldmth); (* InheritedMethods *)
  961. PCM.ObjWNum(R, size.nofLocalMethods); (* NewMethods *)
  962. PCM.ObjWGetPos(R, nofptrsPos);
  963. PCM.ObjWLInt(R, 0);
  964. PCM.ObjWName(R, name);
  965. PCM.ObjWGetPos(R, tdSizePos);
  966. PCM.ObjWLInt(R, 0);
  967. (*New Methods in Record*)
  968. i := 0; m := rec.scope.firstMeth;
  969. WHILE m # NIL DO
  970. IF ~(PCT.Inline IN m.flags) OR (PCT.Indexer IN m.flags) THEN
  971. adr := m.adr(PCBT.Method);
  972. PCM.ObjWNum(R, adr.mthNo);
  973. PCM.ObjWNum(R, adr.entryNr);
  974. INC(i);
  975. END;
  976. m := m.nextMeth
  977. END;
  978. ASSERT(i = size.nofLocalMethods, 500); (*sanity check*)
  979. (* Ptrs in Record *)
  980. nofptrs := 0;
  981. OutPtrs(0, rec, FALSE); (* debug = FALSE *)
  982. IF nofptrs > MAX(INTEGER) THEN PCM.Error(221, 0, "") END;
  983. IF nofptrs # 0 THEN PCM.ObjWLIntAt(R, nofptrsPos, nofptrs) END;
  984. (* ug *) upperPartTdSize := AddressSize * (MaxTags + size.nofMethods + 1 + 1); (* tags, methods, methods end marker (sentinel), address of TypeInfo *)
  985. (* ug *) (* lowerPartTdSize := AddressSize * (1 + nofptrs + 1); (* recsize, no. pointers and sentinel *) *)
  986. (* ug *) lowerPartTdSize := AddressSize * (2 + (4 + nofptrs) + 1); (* SIZEOF(Heaps.StaticTypeDesc), data part of dynamic array of pointer offsets,
  987. padding field to observe 0 mod 8 boundary of dynamic array *)
  988. (* ug *) tdSize := upperPartTdSize + lowerPartTdSize;
  989. (* ug *) PCM.ObjWLIntAt(R, tdSizePos, tdSize)
  990. END WriteType;
  991. PROCEDURE WriteInterface(rec: PCT.Record);
  992. VAR size: PCBT.RecSize; name: StringBuf;
  993. BEGIN
  994. PCT.GetTypeName(rec, name);
  995. size := rec.size(PCBT.RecSize);
  996. PCM.ObjWNum(R, 4 + 4*rec.scope.procCount);
  997. PCM.ObjWNum(R, size.td.offset);
  998. PCM.ObjWNum(R, -1);
  999. PCM.ObjWNum(R, -1);
  1000. PCM.ObjWNum(R, 0); (* NofMethods *)
  1001. PCM.ObjWNum(R, 0); (* InheritedMethods *)
  1002. PCM.ObjWNum(R, 0); (* NewMethods *)
  1003. PCM.ObjWLInt(R, 0); (* no. pointers (fixed size) *)
  1004. PCM.ObjWName(R, name);
  1005. END WriteInterface;
  1006. PROCEDURE TypeBlock;
  1007. VAR rec: PCT.Record; tdSize: LONGINT; (* ug *)
  1008. BEGIN PCM.ObjW(R, 8BX);
  1009. typeDescsSize := 0; (* ug *)
  1010. rec := scope.records;
  1011. WHILE rec # NIL DO
  1012. IF PCT.interface IN rec.mode THEN
  1013. WriteInterface(rec)
  1014. ELSE
  1015. WriteType(rec, tdSize); (* ug *)
  1016. typeDescsSize := typeDescsSize + tdSize (* ug *)
  1017. END;
  1018. rec := rec.link
  1019. END;
  1020. PCM.ObjWLIntAt(R, typeDescsSizePos, typeDescsSize); (* ug *)
  1021. rec := scope.records;
  1022. WHILE rec # NIL DO
  1023. rec.size(PCBT.RecSize).td := NIL;
  1024. rec := rec.link
  1025. END;
  1026. END TypeBlock;
  1027. (* Stores the exception handle table in the following format
  1028. ExceptionHandlerTable ::= 8EX {ExceptionTableEntry}
  1029. ExceptionTableEntry ::= 0FFX pcFrom(4 bytes) pcTo(4 bytes) pcHandler(4 bytes)
  1030. Since there is only one FINALLY in every procedure, method, body, ... we don't need
  1031. to obtain an order for nesting.
  1032. *)
  1033. PROCEDURE ExTableBlock;
  1034. VAR
  1035. entry: ExTableEntry;
  1036. BEGIN
  1037. PCM.ObjW(R, 8EX);
  1038. entry := exTable;
  1039. WHILE entry # NIL DO
  1040. PCM.ObjW(R, 0FEX);
  1041. PCM.ObjWNum(R, entry.pcFrom);
  1042. PCM.ObjWNum(R, entry.pcTo);
  1043. PCM.ObjWNum(R, entry.pcHandler);
  1044. entry := entry.next;
  1045. END;
  1046. END ExTableBlock;
  1047. (* ug *)
  1048. PROCEDURE PointerInProcBlock;
  1049. PROCEDURE PointerOffsets(s : PCT.Scope; codeoffset, beginOffset, endOffset: LONGINT);
  1050. VAR v: PCT.Variable; p: PCT.Proc; t: PCT.Type; par: PCT.Parameter;
  1051. rs: PCT.RecScope; adr: PCBT.Procedure;
  1052. nofPtrPos : LONGINT;
  1053. BEGIN
  1054. IF s # NIL THEN
  1055. IF s IS PCT.ModScope THEN
  1056. PCM.ObjWNum(R, codeoffset);
  1057. PCM.ObjWNum(R, beginOffset);
  1058. PCM.ObjWNum(R, endOffset);
  1059. PCM.ObjWLInt(R, 0); (* nofptrs *)
  1060. INC(nofProcs);
  1061. ELSIF s IS PCT.ProcScope THEN
  1062. PCM.ObjWNum(R, codeoffset);
  1063. PCM.ObjWNum(R, beginOffset);
  1064. PCM.ObjWNum(R, endOffset);
  1065. nofptrs := 0;
  1066. PCM.ObjWGetPos(R, nofPtrPos); PCM.ObjWLInt(R, nofptrs);
  1067. v := s.firstVar;
  1068. WHILE v # NIL DO
  1069. IF (v.adr # NIL) & ~(PCM.Untraced IN v.flags) THEN OutPtrs(v.adr(PCBT.Variable).offset, v.type, FALSE) (* debug = FALSE *) END;
  1070. v := v.nextVar
  1071. END;
  1072. v := s.firstHiddenVar;
  1073. WHILE v # NIL DO
  1074. IF v.adr # NIL THEN OutPtrs(v.adr(PCBT.Variable).offset, v.type, FALSE) (* debug = FALSE *) END;
  1075. v := v.nextVar
  1076. END;
  1077. par := s(PCT.ProcScope).firstPar;
  1078. WHILE par # NIL DO
  1079. IF ~par.ref THEN
  1080. OutPtrs(par.adr(PCBT.Variable).offset, par.type, FALSE) (* debug = FALSE *)
  1081. END;
  1082. par := par.nextPar
  1083. END;
  1084. PCM.ObjWLIntAt(R, nofPtrPos, nofptrs);
  1085. IF nofptrs > maxPtrs THEN maxPtrs := nofptrs END;
  1086. INC(nofProcs);
  1087. END;
  1088. p := s.firstProc;
  1089. WHILE p # NIL DO
  1090. adr := p.adr(PCBT.Procedure);
  1091. IF adr.codeoffset # 0 THEN
  1092. PointerOffsets(p.scope, adr.codeoffset, adr.beginOffset, adr.endOffset)
  1093. END;
  1094. p := p.nextProc
  1095. END;
  1096. t := s.firstType;
  1097. WHILE t # NIL DO
  1098. IF (t.type IS PCT.Pointer) & (t.type(PCT.Pointer).base IS PCT.Record)THEN
  1099. rs := t.type(PCT.Pointer).baseR.scope;
  1100. PointerOffsets(rs, 0, 0, 0)
  1101. END;
  1102. t := t.nextType
  1103. END
  1104. END
  1105. END PointerOffsets;
  1106. BEGIN
  1107. PCM.ObjW(R, 8FX);
  1108. nofProcs := 0;
  1109. maxPtrs := 0;
  1110. PointerOffsets(scope, adr.codeoffset, adr.beginOffset, adr.endOffset);
  1111. PCM.ObjWLIntAt(R, nofProcsPos, nofProcs);
  1112. PCM.ObjWLIntAt(R, maxPtrsPos, maxPtrs);
  1113. END PointerInProcBlock;
  1114. (* ug *)
  1115. BEGIN
  1116. exTable := NIL; exTableLen := 0;
  1117. mod := scope.owner;
  1118. adr := mod.adr(PCBT.Module);
  1119. sym := NIL;
  1120. IF mod.sym # NIL THEN sym := mod.sym(PCOM.Module) END;
  1121. PCLIR.CG.GetCode(code, codeSize, hdrCodeSize, addressFactor);
  1122. InsertFixupLists(addressFactor);
  1123. CollectInfo;
  1124. dsize := adr.locsize;
  1125. ASSERT(codeSize < PCLIR.CG.MaxCodeSize); (*objfile restriction*)
  1126. (* header block *)
  1127. PCM.ObjWLInt (R, PCM.RefSize(R)+1);
  1128. PCM.ObjWGetPos(R, EntriesPos); PCM.ObjWLInt (R, 0);
  1129. PCM.ObjWLInt (R, nofCmds);
  1130. PCM.ObjWGetPos(R, PtrPos); PCM.ObjWLInt (R, 0);
  1131. PCM.ObjWLInt (R, scope.nofRecs);
  1132. PCM.ObjWLInt (R, nofImp);
  1133. PCM.ObjWGetPos(R, VarConsPos); PCM.ObjWLInt (R, 0);
  1134. PCM.ObjWGetPos(R, LinksPos); PCM.ObjWLInt (R, 0);
  1135. PCM.ObjWLInt (R, dsize);
  1136. PCM.ObjWLInt (R, adr.constsize);
  1137. PCM.ObjWLInt (R, hdrCodeSize);
  1138. PCM.ObjWLInt(R, exTableLen);
  1139. PCM.ObjWGetPos(R, nofProcsPos); PCM.ObjWLInt(R, 0); (* ug *)
  1140. PCM.ObjWGetPos(R, maxPtrsPos); PCM.ObjWLInt(R, 0); (* ug *)
  1141. PCM.ObjWGetPos(R, typeDescsSizePos); PCM.ObjWLInt(R, 0); (* ug *)
  1142. StringPool.GetString(mod.name, str); PCM.ObjWName (R, str);
  1143. EntryBlock(addressFactor);
  1144. CommandBlock;
  1145. PointerBlock;
  1146. ImportBlock;
  1147. VarConsBlock;
  1148. IF nofVarCons # 0 THEN PCM.ObjWLIntAt(R, VarConsPos, nofVarCons) END;
  1149. LinkBlock;
  1150. RawBlock(87X, adr.constsize, adr.const^);
  1151. ExportBlock;
  1152. RawBlock(89X, codeSize, code^);
  1153. UseBlock;
  1154. TypeBlock;
  1155. ExTableBlock;
  1156. PointerInProcBlock; (* ug *)
  1157. (* ref block *)
  1158. PCM.ObjW(R, 8CX);
  1159. PCM.CloseObj(R);
  1160. adr.ResetLists;
  1161. END Generate;
  1162. PROCEDURE Init*;
  1163. BEGIN
  1164. refSize := 0;
  1165. nofCmds := 0;
  1166. nofImp := 0;
  1167. nofVarCons := 0; nofLinks := 0;
  1168. dsize := 0;
  1169. END Init;
  1170. PROCEDURE Install*;
  1171. BEGIN
  1172. Init();
  1173. PCBT.generate := Generate
  1174. END Install;
  1175. BEGIN
  1176. IF TraceUse THEN PCM.LogWLn; PCM.LogWStr("PCOF.TraceUse on") END;
  1177. PCBT.generate := Generate
  1178. END PCOF.
  1179. (*
  1180. 20.02.02 be refinement in the code generator plugin
  1181. 13.04.02 prk export and use of inlined assembler procedures fixed
  1182. 18.03.02 prk PCBT code cleanup and redesign
  1183. 20.02.02 be refinement in the code generator plugin
  1184. 23.01.02 prk fixed bug in use list with aliases of imported types
  1185. 22.01.02 prk ToDo list moved to PCDebug
  1186. 28.11.01 prk import section: list only used modules
  1187. 27.08.01 prk scope.unsorted list removed; use var, proc, const and type lists instead
  1188. 16.08.01 prk keep PCBT.Variable offset, ignore for imported vars
  1189. 11.08.01 prk Fixup and use lists for procedures in PCBT cleaned up
  1190. 10.08.01 prk PCBT.Procedure: imported: BOOLEAN replaced by owner: Module
  1191. 06.08.01 prk make code generator and object file generator indipendent
  1192. 02.08.01 prk Aos-Style Commands added to the Command list (by pjm)
  1193. 02.07.01 prk access flags, new design
  1194. 27.06.01 prk StringPool cleaned up
  1195. 14.06.01 prk type descs for dynamic arrays of ptrs generated by the compiler
  1196. 06.06.01 prk use string pool for object names
  1197. 29.05.01 be syscall structures moved to backend (PCLIR & code generators)
  1198. 28.05.01 prk don't insert invisible symbols in the "use" section
  1199. 28.05.01 prk issue error 221/222 when more than MAX(INTEGER) pointers in global data / record
  1200. 03.05.01 be Installable code generators
  1201. 26.03.01 prk New Reference Section format
  1202. 25.03.01 prk limited HUGEINT implementation (as abstract type)
  1203. 14.03.01 prk OutRefs, don't list ARRAYs of user defined types
  1204. 14.03.01 prk OutRefs, don't list inlined procedures
  1205. *)