CPE.txt 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107
  1. MODULE LindevCPE;
  2. (* THIS IS TEXT COPY OF CPE.odc *)
  3. (* DO NOT EDIT *)
  4. IMPORT SYSTEM, (* Dates, *) DevCPM := LindevCPM, DevCPT := LindevCPT;
  5. CONST
  6. (* item base modes (=object modes) *)
  7. Var = 1; VarPar = 2; Con = 3; LProc = 6; XProc = 7; CProc = 9; IProc = 10; TProc = 13;
  8. (* structure forms *)
  9. Undef = 0; Byte = 1; Bool = 2; Char8 = 3; Int8 = 4; Int16 = 5; Int32 = 6;
  10. Real32 = 7; Real64 = 8; Set = 9; String8 = 10; NilTyp = 11; NoTyp = 12;
  11. Pointer = 13; ProcTyp = 14; Comp = 15;
  12. Char16 = 16; String16 = 17; Int64 = 18; Guid = 23;
  13. (* composite structure forms *)
  14. Basic = 1; Array = 2; DynArr = 3; Record = 4;
  15. (* object modes *)
  16. Fld = 4; Typ = 5; Head = 12;
  17. (* module visibility of objects *)
  18. internal = 0; external = 1; externalR = 2; inPar = 3; outPar = 4;
  19. (* history of imported objects *)
  20. inserted = 0; same = 1; pbmodified = 2; pvmodified = 3; removed = 4; inconsistent = 5;
  21. (* attribute flags (attr.adr, struct.attribute, proc.conval.setval)*)
  22. newAttr = 16; absAttr = 17; limAttr = 18; empAttr = 19; extAttr = 20;
  23. (* meta interface consts *)
  24. mConst = 1; mTyp = 2; mVar = 3; mProc = 4; mField = 5;
  25. mBool = 1; mChar8 = 2; mChar16 = 3; mInt8 = 4; mInt16 = 5; mInt32 = 6;
  26. mReal32 = 7; mReal64 = 8; mSet = 9; mInt64 = 10; mAnyRec = 11; mAnyPtr = 12; mSysPtr = 13;
  27. mProctyp = 0; mRecord = 1; mArray = 2; mPointer = 3;
  28. mInternal = 1; mReadonly = 2; mPrivate = 3; mExported = 4;
  29. mValue = 10; mInPar = 11; mOutPar = 12; mVarPar = 13;
  30. mInterface = 32; mGuid = 33; mResult = 34;
  31. (* sysflag *)
  32. untagged = 1; noAlign = 3; union = 7; interface = 10;
  33. (* fixup types *)
  34. absolute = 100; relative = 101; copy = 102; table = 103; tableend = 104; short = 105;
  35. (* kernel flags *)
  36. iptrs = 30;
  37. expAllFields = TRUE;
  38. (* implementation restrictions *)
  39. CodeBlocks = 512;
  40. CodeLength = 16384;
  41. MaxNameTab = 800000H;
  42. useAllRef = FALSE;
  43. outSignatures = TRUE;
  44. TYPE
  45. CodeBlock = POINTER TO ARRAY CodeLength OF SHORTCHAR;
  46. VAR
  47. pc*: INTEGER;
  48. dsize*: INTEGER; (* global data size *)
  49. KNewRec*, KNewArr*: DevCPT.Object;
  50. closeLbl*: INTEGER;
  51. CaseLinks*: DevCPT.LinkList;
  52. processor: INTEGER;
  53. bigEndian: BOOLEAN;
  54. procVarIndirect: BOOLEAN;
  55. idx8, idx16, idx32, idx64, namex, nofptrs, headSize: INTEGER;
  56. Const8, Const16, Const32, Const64, Code, Data, Meta, Mod, Proc, nameList, descList, untgd: DevCPT.Object;
  57. outRef, outAllRef, outURef, outSrc, outObj: BOOLEAN;
  58. codePos, srcPos: INTEGER;
  59. options: SET;
  60. code: ARRAY CodeBlocks OF CodeBlock;
  61. actual: CodeBlock;
  62. actIdx, blkIdx: INTEGER;
  63. CodeOvF: BOOLEAN;
  64. zero: ARRAY 16 OF SHORTCHAR; (* all 0X *)
  65. imports: INTEGER;
  66. dllList, dllLast: DevCPT.Object;
  67. PROCEDURE GetLongWords* (con: DevCPT.Const; OUT hi, low: INTEGER);
  68. CONST N = 4294967296.0; (* 2^32 *)
  69. VAR rh, rl: REAL;
  70. BEGIN
  71. rl := con.intval; rh := con.realval / N;
  72. IF rh >= MAX(INTEGER) + 1.0 THEN rh := rh - 1; rl := rl + N
  73. ELSIF rh < MIN(INTEGER) THEN rh := rh + 1; rl := rl - N
  74. END;
  75. hi := SHORT(ENTIER(rh));
  76. rl := rl + (rh - hi) * N;
  77. IF rl < 0 THEN hi := hi - 1; rl := rl + N
  78. ELSIF rl >= N THEN hi := hi + 1; rl := rl - N
  79. END;
  80. IF rl >= MAX(INTEGER) + 1.0 THEN rl := rl - N END;
  81. low := SHORT(ENTIER(rl))
  82. (*
  83. hi := SHORT(ENTIER((con.realval + con.intval) / 4294967296.0));
  84. r := con.realval + con.intval - hi * 4294967296.0;
  85. IF r > MAX(INTEGER) THEN r := r - 4294967296.0 END;
  86. low := SHORT(ENTIER(r))
  87. *)
  88. END GetLongWords;
  89. PROCEDURE GetRealWord* (con: DevCPT.Const; OUT x: INTEGER);
  90. VAR r: SHORTREAL;
  91. BEGIN
  92. r := SHORT(con.realval); x := SYSTEM.VAL(INTEGER, r)
  93. END GetRealWord;
  94. PROCEDURE GetRealWords* (con: DevCPT.Const; OUT hi, low: INTEGER);
  95. TYPE A = ARRAY 2 OF INTEGER;
  96. VAR a: A;
  97. BEGIN
  98. a := SYSTEM.VAL(A, con.realval);
  99. IF DevCPM.LEHost THEN hi := a[1]; low := a[0] ELSE hi := a[0]; low := a[1] END
  100. END GetRealWords;
  101. PROCEDURE IsSame (x, y: REAL): BOOLEAN;
  102. BEGIN
  103. RETURN (x = y) & ((x # 0.) OR (1. / x = 1. / y))
  104. END IsSame;
  105. PROCEDURE AllocConst* (con: DevCPT.Const; form: BYTE; VAR obj: DevCPT.Object; VAR adr: INTEGER);
  106. VAR c: DevCPT.Const;
  107. BEGIN
  108. INCL(con.setval, form);
  109. CASE form OF
  110. | String8:
  111. obj := Const8; c := obj.conval;
  112. WHILE (c # NIL) & ((con.setval # c.setval) OR (con.intval2 # c.intval2) OR (con.ext^ # c.ext^)) DO c := c.link END;
  113. IF c = NIL THEN adr := idx8; INC(idx8, (con.intval2 + 3) DIV 4 * 4) END
  114. | String16:
  115. obj := Const16; c := obj.conval;
  116. WHILE (c # NIL) & ((con.setval # c.setval) OR (con.intval2 # c.intval2) OR (con.ext^ # c.ext^)) DO c := c.link END;
  117. IF c = NIL THEN adr := idx16; INC(idx16, (con.intval2 + 1) DIV 2 * 4) END
  118. | Int64:
  119. obj := Const64; c := obj.conval;
  120. WHILE (c # NIL) & ((con.setval # c.setval) OR (con.intval # c.intval2) OR (con.realval # c.realval)) DO
  121. c := c.link
  122. END;
  123. IF c = NIL THEN con.intval2 := con.intval; adr := idx64; INC(idx64, 8) END
  124. | Real32:
  125. obj := Const32; c := obj.conval;
  126. WHILE (c # NIL) & ((con.setval # c.setval) OR ~IsSame(con.realval, c.realval)) DO c := c.link END;
  127. IF c = NIL THEN adr := idx32; INC(idx32, 4) END
  128. | Real64:
  129. obj := Const64; c := obj.conval;
  130. WHILE (c # NIL) & ((con.setval # c.setval) OR ~IsSame(con.realval, c.realval)) DO c := c.link END;
  131. IF c = NIL THEN adr := idx64; INC(idx64, 8) END
  132. | Guid:
  133. obj := Const32; c := obj.conval;
  134. WHILE (c # NIL) & ((con.setval # c.setval) OR (con.intval2 # c.intval2) OR (con.ext^ # c.ext^)) DO c := c.link END;
  135. IF c = NIL THEN adr := idx32; INC(idx32, 16) END
  136. END;
  137. IF c = NIL THEN con.link := obj.conval; obj.conval := con ELSE adr := c.intval END;
  138. con.intval := adr
  139. END AllocConst;
  140. PROCEDURE AllocTypDesc* (typ: DevCPT.Struct); (* typ.comp = Record *)
  141. VAR obj: DevCPT.Object; name: DevCPT.Name;
  142. BEGIN
  143. IF typ.strobj = NIL THEN
  144. name := "@"; DevCPT.Insert(name, obj); obj.name := DevCPT.null; (* avoid err 1 *)
  145. obj.mode := Typ; obj.typ := typ; typ.strobj := obj
  146. END
  147. END AllocTypDesc;
  148. PROCEDURE PutByte* (a, x: INTEGER);
  149. BEGIN
  150. code[a DIV CodeLength]^[a MOD CodeLength] := SHORT(CHR(x MOD 256))
  151. END PutByte;
  152. PROCEDURE PutShort* (a, x: INTEGER);
  153. BEGIN
  154. IF bigEndian THEN
  155. PutByte(a, x DIV 256); PutByte(a + 1, x)
  156. ELSE
  157. PutByte(a, x); PutByte(a + 1, x DIV 256)
  158. END
  159. END PutShort;
  160. PROCEDURE PutWord* (a, x: INTEGER);
  161. BEGIN
  162. IF bigEndian THEN
  163. PutByte(a, x DIV 1000000H); PutByte(a + 1, x DIV 10000H);
  164. PutByte(a + 2, x DIV 256); PutByte(a + 3, x)
  165. ELSE
  166. PutByte(a, x); PutByte(a + 1, x DIV 256);
  167. PutByte(a + 2, x DIV 10000H); PutByte(a + 3, x DIV 1000000H)
  168. END
  169. END PutWord;
  170. PROCEDURE ThisByte* (a: INTEGER): INTEGER;
  171. BEGIN
  172. RETURN ORD(code[a DIV CodeLength]^[a MOD CodeLength])
  173. END ThisByte;
  174. PROCEDURE ThisShort* (a: INTEGER): INTEGER;
  175. BEGIN
  176. IF bigEndian THEN
  177. RETURN ThisByte(a) * 256 + ThisByte(a+1)
  178. ELSE
  179. RETURN ThisByte(a+1) * 256 + ThisByte(a)
  180. END
  181. END ThisShort;
  182. PROCEDURE ThisWord* (a: INTEGER): INTEGER;
  183. BEGIN
  184. IF bigEndian THEN
  185. RETURN ((ThisByte(a) * 256 + ThisByte(a+1)) * 256 + ThisByte(a+2)) * 256 + ThisByte(a+3)
  186. ELSE
  187. RETURN ((ThisByte(a+3) * 256 + ThisByte(a+2)) * 256 + ThisByte(a+1)) * 256 + ThisByte(a)
  188. END
  189. END ThisWord;
  190. PROCEDURE GenByte* (x: INTEGER);
  191. BEGIN
  192. IF actIdx >= CodeLength THEN
  193. IF blkIdx < CodeBlocks THEN
  194. NEW(actual); code[blkIdx] := actual; INC(blkIdx); actIdx := 0
  195. ELSE
  196. IF ~CodeOvF THEN DevCPM.err(210); CodeOvF := TRUE END;
  197. actIdx := 0; pc := 0
  198. END
  199. END;
  200. actual^[actIdx] := SHORT(CHR(x MOD 256)); INC(actIdx); INC(pc)
  201. END GenByte;
  202. PROCEDURE GenShort* (x: INTEGER);
  203. BEGIN
  204. IF bigEndian THEN
  205. GenByte(x DIV 256); GenByte(x)
  206. ELSE
  207. GenByte(x); GenByte(x DIV 256)
  208. END
  209. END GenShort;
  210. PROCEDURE GenWord* (x: INTEGER);
  211. BEGIN
  212. IF bigEndian THEN
  213. GenByte(x DIV 1000000H); GenByte(x DIV 10000H); GenByte(x DIV 256); GenByte(x)
  214. ELSE
  215. GenByte(x); GenByte(x DIV 256); GenByte(x DIV 10000H); GenByte(x DIV 1000000H)
  216. END
  217. END GenWord;
  218. PROCEDURE WriteCode;
  219. VAR i, j, k, n: INTEGER; b: CodeBlock;
  220. BEGIN
  221. j := 0; k := 0;
  222. WHILE j < pc DO
  223. n := pc - j; i := 0; b := code[k];
  224. IF n > CodeLength THEN n := CodeLength END;
  225. WHILE i < n DO DevCPM.ObjW(b^[i]); INC(i) END;
  226. INC(j, n); INC(k)
  227. END
  228. END WriteCode;
  229. PROCEDURE OffsetLink* (obj: DevCPT.Object; offs: INTEGER): DevCPT.LinkList;
  230. VAR link: DevCPT.LinkList; m: DevCPT.Object;
  231. BEGIN
  232. ASSERT((obj.mode # Typ) OR (obj.typ # DevCPT.int32typ));
  233. ASSERT((obj.mode # Typ) OR (obj.typ # DevCPT.iunktyp) & (obj.typ # DevCPT.guidtyp));
  234. IF obj.mnolev >= 0 THEN (* not imported *)
  235. CASE obj.mode OF
  236. | Typ: IF obj.links = NIL THEN obj.link := descList; descList := obj END
  237. | TProc: IF obj.adr = -1 THEN obj := obj.nlink ELSE offs := offs + obj.adr; obj := Code END
  238. | Var: offs := offs + dsize; obj := Data
  239. | Con, IProc, XProc, LProc:
  240. END
  241. ELSIF obj.mode = Typ THEN
  242. IF obj.typ.untagged THEN (* add desc for imported untagged types *)
  243. IF obj.links = NIL THEN obj.link := descList; descList := obj END
  244. ELSE
  245. m := DevCPT.GlbMod[-obj.mnolev];
  246. IF m.library # NIL THEN RETURN NIL END (* type import from dll *)
  247. END
  248. END;
  249. link := obj.links;
  250. WHILE (link # NIL) & (link.offset # offs) DO link := link.next END;
  251. IF link = NIL THEN
  252. NEW(link); link.offset := offs; link.linkadr := 0;
  253. link.next := obj.links; obj.links := link
  254. END;
  255. RETURN link
  256. END OffsetLink;
  257. PROCEDURE TypeObj* (typ: DevCPT.Struct): DevCPT.Object;
  258. VAR obj: DevCPT.Object;
  259. BEGIN
  260. obj := typ.strobj;
  261. IF obj = NIL THEN
  262. obj := DevCPT.NewObj(); obj.leaf := TRUE; obj.mnolev := 0;
  263. obj.name := DevCPT.null; obj.mode := Typ; obj.typ := typ; typ.strobj := obj
  264. END;
  265. RETURN obj
  266. END TypeObj;
  267. PROCEDURE Align (n: INTEGER);
  268. VAR p: INTEGER;
  269. BEGIN
  270. p := DevCPM.ObjLen();
  271. DevCPM.ObjWBytes(zero, (-p) MOD n)
  272. END Align;
  273. PROCEDURE OutName (VAR name: ARRAY OF SHORTCHAR);
  274. VAR ch: SHORTCHAR; i: SHORTINT;
  275. BEGIN i := 0;
  276. REPEAT ch := name[i]; DevCPM.ObjW(ch); INC(i) UNTIL ch = 0X
  277. END OutName;
  278. PROCEDURE Out2 (x: INTEGER); (* byte ordering must correspond to target machine *)
  279. BEGIN
  280. IF bigEndian THEN
  281. DevCPM.ObjW(SHORT(CHR(x DIV 256))); DevCPM.ObjW(SHORT(CHR(x)))
  282. ELSE
  283. DevCPM.ObjW(SHORT(CHR(x))); DevCPM.ObjW(SHORT(CHR(x DIV 256)))
  284. END
  285. END Out2;
  286. PROCEDURE Out4 (x: INTEGER); (* byte ordering must correspond to target machine *)
  287. BEGIN
  288. IF bigEndian THEN
  289. DevCPM.ObjW(SHORT(CHR(x DIV 1000000H))); DevCPM.ObjW(SHORT(CHR(x DIV 10000H)));
  290. DevCPM.ObjW(SHORT(CHR(x DIV 256))); DevCPM.ObjW(SHORT(CHR(x)))
  291. ELSE
  292. DevCPM.ObjWLInt(x)
  293. END
  294. END Out4;
  295. PROCEDURE OutReference (obj: DevCPT.Object; offs, typ: INTEGER);
  296. VAR link: DevCPT.LinkList;
  297. BEGIN
  298. link := OffsetLink(obj, offs);
  299. IF link # NIL THEN
  300. Out4(typ * 1000000H + link.linkadr MOD 1000000H);
  301. link.linkadr := -(DevCPM.ObjLen() - headSize - 4)
  302. ELSE Out4(0)
  303. END
  304. END OutReference;
  305. PROCEDURE FindPtrs (typ: DevCPT.Struct; adr: INTEGER; ip: BOOLEAN; VAR num: INTEGER);
  306. VAR fld: DevCPT.Object; btyp: DevCPT.Struct; i, n: INTEGER;
  307. BEGIN
  308. IF typ.form = Pointer THEN
  309. IF ip & (typ.sysflag = interface)
  310. OR ~ip & ~typ.untagged THEN Out4(adr); INC(num) END
  311. ELSIF (typ.comp = Record) & (typ.sysflag # union) THEN
  312. btyp := typ.BaseTyp;
  313. IF btyp # NIL THEN FindPtrs(btyp, adr, ip, num) END ;
  314. fld := typ.link;
  315. WHILE (fld # NIL) & (fld.mode = Fld) DO
  316. IF ip & (fld.name^ = DevCPM.HdUtPtrName) & (fld.sysflag = interface)
  317. OR ~ip & (fld.name^ = DevCPM.HdPtrName) THEN Out4(fld.adr + adr); INC(num)
  318. ELSE FindPtrs(fld.typ, fld.adr + adr, ip, num)
  319. END;
  320. fld := fld.link
  321. END
  322. ELSIF typ.comp = Array THEN
  323. btyp := typ.BaseTyp; n := typ.n;
  324. WHILE btyp.comp = Array DO n := btyp.n * n; btyp := btyp.BaseTyp END ;
  325. IF (btyp.form = Pointer) OR (btyp.comp = Record) THEN
  326. i := num; FindPtrs(btyp, adr, ip, num);
  327. IF num # i THEN i := 1;
  328. WHILE i < n DO
  329. INC(adr, btyp.size); FindPtrs(btyp, adr, ip, num); INC(i)
  330. END
  331. END
  332. END
  333. END
  334. END FindPtrs;
  335. PROCEDURE OutRefName* (VAR name: ARRAY OF SHORTCHAR);
  336. BEGIN
  337. DevCPM.ObjW(0FCX); DevCPM.ObjWNum(pc); OutName(name)
  338. END OutRefName;
  339. PROCEDURE OutRefs* (obj: DevCPT.Object);
  340. VAR f: BYTE;
  341. BEGIN
  342. IF outRef & (obj # NIL) THEN
  343. OutRefs(obj.left);
  344. IF ((obj.mode = Var) OR (obj.mode = VarPar)) & (obj.history # removed) & (obj.name[0] # "@") THEN
  345. f := obj.typ.form;
  346. IF (f IN {Byte .. Set, Pointer, ProcTyp, Char16, Int64})
  347. OR outURef & (obj.typ.comp # DynArr)
  348. OR outAllRef & ~obj.typ.untagged
  349. OR (obj.typ.comp = Array) & (obj.typ.BaseTyp.form = Char8) THEN
  350. IF obj.mode = Var THEN DevCPM.ObjW(0FDX) ELSE DevCPM.ObjW(0FFX) END;
  351. IF obj.typ = DevCPT.anyptrtyp THEN DevCPM.ObjW(SHORT(CHR(mAnyPtr)))
  352. ELSIF obj.typ = DevCPT.anytyp THEN DevCPM.ObjW(SHORT(CHR(mAnyRec)))
  353. ELSIF obj.typ = DevCPT.sysptrtyp THEN DevCPM.ObjW(SHORT(CHR(mSysPtr)))
  354. ELSIF f = Char16 THEN DevCPM.ObjW(SHORT(CHR(mChar16)))
  355. ELSIF f = Int64 THEN DevCPM.ObjW(SHORT(CHR(mInt64)))
  356. ELSIF obj.typ = DevCPT.guidtyp THEN DevCPM.ObjW(SHORT(CHR(mGuid)))
  357. ELSIF obj.typ = DevCPT.restyp THEN DevCPM.ObjW(SHORT(CHR(mResult)))
  358. ELSIF f = Pointer THEN
  359. IF obj.typ.sysflag = interface THEN DevCPM.ObjW(SHORT(CHR(mInterface)))
  360. ELSIF obj.typ.untagged THEN DevCPM.ObjW(SHORT(CHR(mSysPtr)))
  361. ELSE DevCPM.ObjW(10X); OutReference(TypeObj(obj.typ), 0, absolute)
  362. END
  363. ELSIF (f = Comp) & outAllRef & (~obj.typ.untagged OR outURef & (obj.typ.comp # DynArr)) THEN
  364. DevCPM.ObjW(10X); OutReference(TypeObj(obj.typ), 0, absolute)
  365. ELSIF f < Int8 THEN DevCPM.ObjW(SHORT(CHR(f - 1)))
  366. ELSE DevCPM.ObjW(SHORT(CHR(f)))
  367. END;
  368. IF obj.mnolev = 0 THEN DevCPM.ObjWNum(obj.adr + dsize) ELSE DevCPM.ObjWNum(obj.adr) END;
  369. OutName(obj.name^)
  370. END
  371. END ;
  372. OutRefs(obj.right)
  373. END
  374. END OutRefs;
  375. PROCEDURE OutSourceRef* (pos: INTEGER);
  376. BEGIN
  377. IF outSrc & (pos # 0) & (pos # srcPos) & (pc > codePos) THEN
  378. WHILE pc > codePos + 250 DO
  379. DevCPM.ObjW(SHORT(CHR(250)));
  380. INC(codePos, 250);
  381. DevCPM.ObjWNum(0)
  382. END;
  383. DevCPM.ObjW(SHORT(CHR(pc - codePos)));
  384. codePos := pc;
  385. DevCPM.ObjWNum(pos - srcPos);
  386. srcPos := pos
  387. END
  388. END OutSourceRef;
  389. PROCEDURE OutPLink (link: DevCPT.LinkList; adr: INTEGER);
  390. BEGIN
  391. WHILE link # NIL DO
  392. ASSERT(link.linkadr # 0);
  393. DevCPM.ObjWNum(link.linkadr);
  394. DevCPM.ObjWNum(adr + link.offset);
  395. link := link.next
  396. END
  397. END OutPLink;
  398. PROCEDURE OutLink (link: DevCPT.LinkList);
  399. BEGIN
  400. OutPLink(link, 0); DevCPM.ObjW(0X)
  401. END OutLink;
  402. PROCEDURE OutNames;
  403. VAR a, b, c: DevCPT.Object;
  404. BEGIN
  405. a := nameList; b := NIL;
  406. WHILE a # NIL DO c := a; a := c.nlink; c.nlink := b; b := c END;
  407. DevCPM.ObjW(0X); (* names[0] = 0X *)
  408. WHILE b # NIL DO
  409. OutName(b.name^);
  410. b := b.nlink
  411. END;
  412. END OutNames;
  413. PROCEDURE OutGuid* (VAR str: ARRAY OF SHORTCHAR);
  414. PROCEDURE Copy (n: INTEGER);
  415. VAR x, y: INTEGER;
  416. BEGIN
  417. x := ORD(str[n]); y := ORD(str[n + 1]);
  418. IF x >= ORD("a") THEN DEC(x, ORD("a") - 10)
  419. ELSIF x >= ORD("A") THEN DEC(x, ORD("A") - 10)
  420. ELSE DEC(x, ORD("0"))
  421. END;
  422. IF y >= ORD("a") THEN DEC(y, ORD("a") - 10)
  423. ELSIF y >= ORD("A") THEN DEC(y, ORD("A") - 10)
  424. ELSE DEC(y, ORD("0"))
  425. END;
  426. DevCPM.ObjW(SHORT(CHR(x * 16 + y)))
  427. END Copy;
  428. BEGIN
  429. IF bigEndian THEN
  430. Copy(1); Copy(3); Copy(5); Copy(7); Copy(10); Copy(12); Copy(15); Copy(17)
  431. ELSE
  432. Copy(7); Copy(5); Copy(3); Copy(1); Copy(12); Copy(10); Copy(17); Copy(15)
  433. END;
  434. Copy(20); Copy(22); Copy(25); Copy(27); Copy(29); Copy(31); Copy(33); Copy(35)
  435. END OutGuid;
  436. PROCEDURE OutConst (obj: DevCPT.Object);
  437. TYPE A4 = ARRAY 4 OF SHORTCHAR; A8 = ARRAY 8 OF SHORTCHAR;
  438. VAR a, b, c: DevCPT.Const; r: SHORTREAL; lr: REAL; a4: A4; a8: A8; ch: SHORTCHAR; i, x, hi, low: INTEGER;
  439. BEGIN
  440. a := obj.conval; b := NIL;
  441. WHILE a # NIL DO c := a; a := c.link; c.link := b; b := c END;
  442. WHILE b # NIL DO
  443. IF String8 IN b.setval THEN
  444. DevCPM.ObjWBytes(b.ext^, b.intval2);
  445. Align(4)
  446. ELSIF String16 IN b.setval THEN
  447. i := 0; REPEAT DevCPM.GetUtf8(b.ext^, x, i); Out2(x) UNTIL x = 0;
  448. Align(4)
  449. ELSIF Real32 IN b.setval THEN
  450. r := SHORT(b.realval); a4 := SYSTEM.VAL(A4, r);
  451. IF DevCPM.LEHost = bigEndian THEN
  452. ch := a4[0]; a4[0] := a4[3]; a4[3] := ch;
  453. ch := a4[1]; a4[1] := a4[2]; a4[2] := ch
  454. END;
  455. DevCPM.ObjWBytes(a4, 4)
  456. ELSIF Real64 IN b.setval THEN
  457. a8 := SYSTEM.VAL(A8, b.realval);
  458. IF DevCPM.LEHost = bigEndian THEN
  459. ch := a8[0]; a8[0] := a8[7]; a8[7] := ch;
  460. ch := a8[1]; a8[1] := a8[6]; a8[6] := ch;
  461. ch := a8[2]; a8[2] := a8[5]; a8[5] := ch;
  462. ch := a8[3]; a8[3] := a8[4]; a8[4] := ch
  463. END;
  464. DevCPM.ObjWBytes(a8, 8)
  465. ELSIF Int64 IN b.setval THEN
  466. (* intval moved to intval2 by AllocConst *)
  467. x := b.intval; b.intval := b.intval2; GetLongWords(b, hi, low); b.intval := x;
  468. IF bigEndian THEN Out4(hi); Out4(low) ELSE Out4(low); Out4(hi) END
  469. ELSIF Guid IN b.setval THEN
  470. OutGuid(b.ext^)
  471. END;
  472. b := b.link
  473. END
  474. END OutConst;
  475. PROCEDURE OutStruct (typ: DevCPT.Struct; unt: BOOLEAN);
  476. BEGIN
  477. IF typ = NIL THEN Out4(0)
  478. ELSIF typ = DevCPT.sysptrtyp THEN Out4(mSysPtr)
  479. ELSIF typ = DevCPT.anytyp THEN Out4(mAnyRec)
  480. ELSIF typ = DevCPT.anyptrtyp THEN Out4(mAnyPtr)
  481. ELSIF typ = DevCPT.guidtyp THEN Out4(mGuid)
  482. ELSIF typ = DevCPT.restyp THEN Out4(mResult)
  483. ELSE
  484. CASE typ.form OF
  485. | Undef, Byte, String8, NilTyp, NoTyp, String16: Out4(0)
  486. | Bool, Char8: Out4(typ.form - 1)
  487. | Int8..Set: Out4(typ.form)
  488. | Char16: Out4(mChar16)
  489. | Int64: Out4(mInt64)
  490. | ProcTyp: OutReference(TypeObj(typ), 0, absolute)
  491. | Pointer:
  492. IF typ.sysflag = interface THEN Out4(mInterface)
  493. ELSIF typ.untagged THEN Out4(mSysPtr)
  494. ELSE OutReference(TypeObj(typ), 0, absolute)
  495. END
  496. | Comp:
  497. IF ~typ.untagged OR (outURef & unt) THEN OutReference(TypeObj(typ), 0, absolute)
  498. ELSE Out4(0)
  499. END
  500. END
  501. END
  502. END OutStruct;
  503. PROCEDURE NameIdx (obj: DevCPT.Object): INTEGER;
  504. VAR n: INTEGER;
  505. BEGIN
  506. n := 0;
  507. IF obj.name # DevCPT.null THEN
  508. IF obj.num = 0 THEN
  509. obj.num := namex;
  510. WHILE obj.name[n] # 0X DO INC(n) END;
  511. INC(namex, n + 1);
  512. obj.nlink := nameList; nameList := obj
  513. END;
  514. n := obj.num;
  515. END;
  516. RETURN n
  517. END NameIdx;
  518. PROCEDURE OutSignature (par: DevCPT.Object; retTyp: DevCPT.Struct; OUT pos: INTEGER);
  519. VAR p: DevCPT.Object; n, m: INTEGER;
  520. BEGIN
  521. pos := DevCPM.ObjLen() - headSize;
  522. OutStruct(retTyp, TRUE);
  523. p := par; n := 0;
  524. WHILE p # NIL DO INC(n); p := p.link END;
  525. Out4(n); p := par;
  526. WHILE p # NIL DO
  527. IF p.mode # VarPar THEN m := mValue
  528. ELSIF p.vis = inPar THEN m := mInPar
  529. ELSIF p.vis = outPar THEN m := mOutPar
  530. ELSE m := mVarPar
  531. END;
  532. Out4(NameIdx(p) * 256 + m);
  533. OutStruct(p.typ, TRUE);
  534. p := p.link
  535. END
  536. END OutSignature;
  537. PROCEDURE PrepObject (obj: DevCPT.Object);
  538. BEGIN
  539. IF (obj.mode IN {LProc, XProc, IProc}) & outSignatures THEN (* write param list *)
  540. OutSignature(obj.link, obj.typ, obj.conval.intval)
  541. END
  542. END PrepObject;
  543. PROCEDURE OutObject (mode, fprint, offs: INTEGER; typ: DevCPT.Struct; obj: DevCPT.Object);
  544. VAR vis: INTEGER;
  545. BEGIN
  546. Out4(fprint);
  547. Out4(offs);
  548. IF obj.vis = internal THEN vis := mInternal
  549. ELSIF obj.vis = externalR THEN vis := mReadonly
  550. ELSIF obj.vis = external THEN vis := mExported
  551. END;
  552. Out4(mode + vis * 16 + NameIdx(obj) * 256);
  553. IF (mode = mProc) & outSignatures THEN OutReference(Meta, obj.conval.intval, absolute) (* ref to par list *)
  554. ELSE OutStruct(typ, mode = mField)
  555. END
  556. END OutObject;
  557. PROCEDURE PrepDesc (desc: DevCPT.Struct);
  558. VAR fld: DevCPT.Object; n: INTEGER; l: DevCPT.LinkList; b: DevCPT.Struct;
  559. BEGIN
  560. IF desc.comp = Record THEN (* write field list *)
  561. desc.strobj.adr := DevCPM.ObjLen() - headSize;
  562. n := 0; fld := desc.link;
  563. WHILE (fld # NIL) & (fld.mode = Fld) DO
  564. IF expAllFields OR (fld.vis # internal) THEN INC(n) END;
  565. fld := fld.link
  566. END;
  567. Out4(n); fld := desc.link;
  568. WHILE (fld # NIL) & (fld.mode = Fld) DO
  569. IF expAllFields OR (fld.vis # internal) THEN
  570. OutObject(mField, 0, fld.adr, fld.typ, fld)
  571. END;
  572. fld := fld.link
  573. END
  574. ELSIF (desc.form = ProcTyp) & outSignatures THEN (* write param list *)
  575. OutSignature(desc.link, desc.BaseTyp, desc.n)
  576. END;
  577. (* assert name and base type are included *)
  578. IF desc.untagged THEN n := NameIdx(untgd)
  579. ELSE n := NameIdx(desc.strobj)
  580. END;
  581. IF desc.form # ProcTyp THEN b := desc.BaseTyp;
  582. IF (b # NIL) & (b # DevCPT.anytyp) & (b # DevCPT.anyptrtyp) & (b.form IN {Pointer, Comp, ProcTyp})
  583. & (b.sysflag # interface) & (b # DevCPT.guidtyp)
  584. & (~b.untagged OR outURef & (b.form = Comp)) THEN
  585. l := OffsetLink(TypeObj(b), 0)
  586. END
  587. END
  588. END PrepDesc;
  589. PROCEDURE NumMeth (root: DevCPT.Object; num: INTEGER): DevCPT.Object;
  590. VAR obj: DevCPT.Object;
  591. BEGIN
  592. IF (root = NIL) OR (root.mode = TProc) & (root.num = num) THEN RETURN root END;
  593. obj := NumMeth(root.left, num);
  594. IF obj = NIL THEN obj := NumMeth(root.right, num) END;
  595. RETURN obj
  596. END NumMeth;
  597. PROCEDURE OutDesc (desc: DevCPT.Struct);
  598. VAR m: DevCPT.Object; i, nofptr, flddir, size: INTEGER; t, xb: DevCPT.Struct; form, lev, attr: BYTE;
  599. name: DevCPT.Name;
  600. BEGIN
  601. ASSERT(~desc.untagged);
  602. IF desc.comp = Record THEN
  603. xb := desc; flddir := desc.strobj.adr;
  604. REPEAT xb := xb.BaseTyp UNTIL (xb = NIL) OR (xb.mno # 0) OR xb.untagged;
  605. Out4(-1); i := desc.n;
  606. WHILE i > 0 DO DEC(i); t := desc;
  607. REPEAT
  608. m := NumMeth(t.link, i); t := t.BaseTyp
  609. UNTIL (m # NIL) OR (t = xb);
  610. IF m # NIL THEN
  611. IF absAttr IN m.conval.setval THEN Out4(0)
  612. ELSE OutReference(m, 0, absolute)
  613. END
  614. ELSIF (xb = NIL) OR xb.untagged THEN Out4(0) (* unimplemented ANYREC method *)
  615. ELSE OutReference(xb.strobj, -4 - 4 * i, copy)
  616. END
  617. END;
  618. desc.strobj.adr := DevCPM.ObjLen() - headSize; (* desc adr *)
  619. Out4(desc.size);
  620. OutReference(Mod, 0, absolute);
  621. IF desc.untagged THEN m := untgd ELSE m := desc.strobj END;
  622. IF desc.attribute = extAttr THEN attr := 1
  623. ELSIF desc.attribute = limAttr THEN attr := 2
  624. ELSIF desc.attribute = absAttr THEN attr := 3
  625. ELSE attr := 0
  626. END;
  627. Out4(mRecord + attr * 4 + desc.extlev * 16 + NameIdx(m) * 256); i := 0;
  628. WHILE i <= desc.extlev DO
  629. t := desc;
  630. WHILE t.extlev > i DO t := t.BaseTyp END;
  631. IF t.sysflag = interface THEN Out4(0)
  632. ELSIF t.untagged THEN OutReference(TypeObj(t), 0, absolute)
  633. ELSIF (t.mno = 0) THEN OutReference(t.strobj, 0, absolute)
  634. ELSIF t = xb THEN OutReference(xb.strobj, 0, absolute)
  635. ELSE OutReference(xb.strobj, 12 + 4 * i, copy)
  636. END;
  637. INC(i)
  638. END;
  639. WHILE i <= DevCPM.MaxExts DO Out4(0); INC(i) END;
  640. OutReference(Meta, flddir, absolute); (* ref to field list *)
  641. nofptr := 0; FindPtrs(desc, 0, FALSE, nofptr);
  642. Out4(-(4 * nofptr + 4));
  643. nofptr := 0; FindPtrs(desc, 0, TRUE, nofptr);
  644. Out4(-1)
  645. ELSE
  646. desc.strobj.adr := DevCPM.ObjLen() - headSize;
  647. lev := 0; size := 0;
  648. IF desc.comp = Array THEN
  649. size := desc.n; form := mArray
  650. ELSIF desc.comp = DynArr THEN
  651. form := mArray; lev := SHORT(SHORT(desc.n + 1))
  652. ELSIF desc.form = Pointer THEN
  653. form := mPointer
  654. ELSE ASSERT(desc.form = ProcTyp);
  655. DevCPM.FPrint(size, XProc); DevCPT.FPrintSign(size, desc.BaseTyp, desc.link); form := mProctyp;
  656. END;
  657. Out4(size);
  658. OutReference(Mod, 0, absolute);
  659. IF desc.untagged THEN m := untgd ELSE m := desc.strobj END;
  660. Out4(form + lev * 16 + NameIdx(m) * 256);
  661. IF desc.form # ProcTyp THEN OutStruct(desc.BaseTyp, TRUE)
  662. ELSIF outSignatures THEN OutReference(Meta, desc.n, absolute) (* ref to par list *)
  663. END
  664. END
  665. END OutDesc;
  666. PROCEDURE OutModDesc (nofptr, refSize, namePos, ptrPos, expPos, impPos: INTEGER);
  667. VAR i: INTEGER; (* t: Dates.Time; d: Dates.Date; *)
  668. BEGIN
  669. Out4(0); (* link *)
  670. Out4(ORD(options)); (* opts *)
  671. Out4(0); (* refcnt *)
  672. (* Dates.GetDate(d); Dates.GetTime(t); (* compile time *)
  673. Out2(d.year); Out2(d.month); Out2(d.day);
  674. Out2(t.hour); Out2(t.minute); Out2(t.second); *)
  675. Out2(2007); Out2(5); Out2(25);
  676. Out2(0); Out2(0); Out2(0);
  677. Out4(0); Out4(0); Out4(0); (* load time *)
  678. Out4(0); (* ext *)
  679. IF closeLbl # 0 THEN OutReference(Code, closeLbl, absolute); (* terminator *)
  680. ELSE Out4(0)
  681. END;
  682. Out4(imports); (* nofimps *)
  683. Out4(nofptr); (* nofptrs *)
  684. Out4(pc); (* csize *)
  685. Out4(dsize); (* dsize *)
  686. Out4(refSize); (* rsize *)
  687. OutReference(Code, 0, absolute); (* code *)
  688. OutReference(Data, 0, absolute); (* data *)
  689. OutReference(Meta, 0, absolute); (* refs *)
  690. IF procVarIndirect THEN
  691. OutReference(Proc, 0, absolute); (* procBase *)
  692. ELSE
  693. OutReference(Code, 0, absolute); (* procBase *)
  694. END;
  695. OutReference(Data, 0, absolute); (* varBase *)
  696. OutReference(Meta, namePos, absolute); (* names *)
  697. OutReference(Meta, ptrPos, absolute); (* ptrs *)
  698. OutReference(Meta, impPos, absolute); (* imports *)
  699. OutReference(Meta, expPos, absolute); (* export *)
  700. i := 0; (* name *)
  701. WHILE DevCPT.SelfName[i] # 0X DO DevCPM.ObjW(DevCPT.SelfName[i]); INC(i) END;
  702. DevCPM.ObjW(0X);
  703. Align(4)
  704. END OutModDesc;
  705. PROCEDURE OutProcTable (obj: DevCPT.Object); (* 68000 *)
  706. BEGIN
  707. IF obj # NIL THEN
  708. OutProcTable(obj.left);
  709. IF obj.mode IN {XProc, IProc} THEN
  710. Out2(4EF9H); OutReference(Code, obj.adr, absolute); Out2(0);
  711. END;
  712. OutProcTable(obj.right);
  713. END;
  714. END OutProcTable;
  715. PROCEDURE PrepExport (obj: DevCPT.Object);
  716. BEGIN
  717. IF obj # NIL THEN
  718. PrepExport(obj.left);
  719. IF (obj.mode IN {LProc, XProc, IProc}) & (obj.history # removed) & (obj.vis # internal) THEN
  720. PrepObject(obj)
  721. END;
  722. PrepExport(obj.right)
  723. END
  724. END PrepExport;
  725. PROCEDURE OutExport (obj: DevCPT.Object);
  726. VAR num: INTEGER;
  727. BEGIN
  728. IF obj # NIL THEN
  729. OutExport(obj.left);
  730. IF (obj.history # removed) & ((obj.vis # internal) OR
  731. (obj.mode = Typ) & (obj.typ.strobj = obj) & (obj.typ.form = Comp)) THEN
  732. DevCPT.FPrintObj(obj);
  733. IF obj.mode IN {LProc, XProc, IProc} THEN
  734. IF procVarIndirect THEN
  735. ASSERT(obj.nlink = NIL);
  736. num := obj.num; obj.num := 0;
  737. OutObject(mProc, obj.fprint, num, NIL, obj);
  738. obj.num := num
  739. ELSE
  740. OutObject(mProc, obj.fprint, obj.adr, NIL, obj)
  741. END
  742. ELSIF obj.mode = Var THEN
  743. OutObject(mVar, obj.fprint, dsize + obj.adr, obj.typ, obj)
  744. ELSIF obj.mode = Typ THEN
  745. OutObject(mTyp, obj.typ.pbfp, obj.typ.pvfp, obj.typ, obj)
  746. ELSE ASSERT(obj.mode IN {Con, CProc});
  747. OutObject(mConst, obj.fprint, 0, NIL, obj)
  748. END
  749. END;
  750. OutExport(obj.right)
  751. END
  752. END OutExport;
  753. PROCEDURE OutCLinks (obj: DevCPT.Object);
  754. BEGIN
  755. IF obj # NIL THEN
  756. OutCLinks(obj.left);
  757. IF obj.mode IN {LProc, XProc, IProc} THEN OutPLink(obj.links, obj.adr) END;
  758. OutCLinks(obj.right)
  759. END
  760. END OutCLinks;
  761. PROCEDURE OutCPLinks (obj: DevCPT.Object; base: INTEGER);
  762. BEGIN
  763. IF obj # NIL THEN
  764. OutCPLinks(obj.left, base);
  765. IF obj.mode IN {LProc, XProc, IProc} THEN OutPLink(obj.links, obj.num + base) END;
  766. OutCPLinks(obj.right, base)
  767. END
  768. END OutCPLinks;
  769. PROCEDURE OutImport (obj: DevCPT.Object);
  770. VAR typ: DevCPT.Struct; strobj: DevCPT.Object; opt: INTEGER;
  771. BEGIN
  772. IF obj # NIL THEN
  773. OutImport(obj.left);
  774. IF obj.mode = Typ THEN typ := obj.typ;
  775. IF obj.used OR
  776. (typ.form IN {Pointer, Comp}) & (typ.strobj = obj) &
  777. ((obj.links # NIL) OR (obj.name # DevCPT.null) & (typ.pvused OR typ.pbused)) THEN
  778. DevCPT.FPrintStr(typ);
  779. DevCPM.ObjW(SHORT(CHR(mTyp))); OutName(obj.name^);
  780. IF obj.used THEN opt := 2 ELSE opt := 0 END;
  781. IF (typ.form = Comp) & ((typ.pvused) OR (obj.name = DevCPT.null)) THEN
  782. DevCPM.ObjWNum(typ.pvfp); DevCPM.ObjW(SHORT(CHR(opt + 1)));
  783. IF obj.history = inconsistent THEN DevCPT.FPrintErr(obj, 249) END
  784. ELSE DevCPM.ObjWNum(typ.pbfp); DevCPM.ObjW(SHORT(CHR(opt)))
  785. END;
  786. OutLink(obj.links)
  787. END
  788. ELSIF obj.used THEN
  789. DevCPT.FPrintObj(obj);
  790. IF obj.mode = Var THEN
  791. DevCPM.ObjW(SHORT(CHR(mVar))); OutName(obj.name^);
  792. DevCPM.ObjWNum(obj.fprint); OutLink(obj.links)
  793. ELSIF obj.mode IN {XProc, IProc} THEN
  794. DevCPM.ObjW(SHORT(CHR(mProc))); OutName(obj.name^);
  795. DevCPM.ObjWNum(obj.fprint); OutLink(obj.links)
  796. ELSE ASSERT(obj.mode IN {Con, CProc});
  797. DevCPM.ObjW(SHORT(CHR(mConst))); OutName(obj.name^); DevCPM.ObjWNum(obj.fprint)
  798. END
  799. END;
  800. OutImport(obj.right)
  801. END
  802. END OutImport;
  803. PROCEDURE OutUseBlock;
  804. VAR m, obj: DevCPT.Object; i: INTEGER;
  805. BEGIN
  806. m := dllList;
  807. WHILE m # NIL DO
  808. obj := m.nlink;
  809. WHILE obj # NIL DO
  810. IF obj.mode = Var THEN DevCPM.ObjW(SHORT(CHR(mVar)))
  811. ELSE DevCPM.ObjW(SHORT(CHR(mProc)))
  812. END;
  813. IF obj.entry # NIL THEN OutName(obj.entry^)
  814. ELSE OutName(obj.name^);
  815. END;
  816. DevCPT.FPrintObj(obj); DevCPM.ObjWNum(obj.fprint); OutLink(obj.links);
  817. obj := obj.nlink
  818. END;
  819. DevCPM.ObjW(0X); m := m.link
  820. END;
  821. i := 1;
  822. WHILE i < DevCPT.nofGmod DO
  823. obj := DevCPT.GlbMod[i];
  824. IF obj.library = NIL THEN OutImport(obj.right); DevCPM.ObjW(0X) END;
  825. INC(i)
  826. END;
  827. END OutUseBlock;
  828. PROCEDURE CollectDll (obj: DevCPT.Object; mod: DevCPT.String);
  829. VAR name: DevCPT.String; dll: DevCPT.Object;
  830. BEGIN
  831. IF obj # NIL THEN
  832. CollectDll(obj.left, mod);
  833. IF obj.used & (obj.mode IN {Var, XProc, IProc}) THEN
  834. IF obj.library # NIL THEN name := obj.library
  835. ELSE name := mod
  836. END;
  837. dll := dllList;
  838. WHILE (dll # NIL) & (dll.library^ # name^) DO dll := dll.link END;
  839. IF dll = NIL THEN
  840. NEW(dll); dll.library := name; INC(imports);
  841. IF dllList = NIL THEN dllList := dll ELSE dllLast.link := dll END;
  842. dllLast := dll; dll.left := dll;
  843. END;
  844. dll.left.nlink := obj; dll.left := obj
  845. END;
  846. CollectDll(obj.right, mod)
  847. END
  848. END CollectDll;
  849. PROCEDURE EnumXProc(obj: DevCPT.Object; VAR num: INTEGER);
  850. BEGIN
  851. IF obj # NIL THEN
  852. EnumXProc(obj.left, num);
  853. IF obj.mode IN {XProc, IProc} THEN
  854. obj.num := num; INC(num, 8);
  855. END;
  856. EnumXProc(obj.right, num)
  857. END;
  858. END EnumXProc;
  859. PROCEDURE OutHeader*;
  860. VAR i: INTEGER; m: DevCPT.Object;
  861. BEGIN
  862. DevCPM.ObjWLInt(processor); (* processor type *)
  863. DevCPM.ObjWLInt(0); DevCPM.ObjWLInt(0); DevCPM.ObjWLInt(0);
  864. DevCPM.ObjWLInt(0); DevCPM.ObjWLInt(0); (* sizes *)
  865. imports := 0; i := 1;
  866. WHILE i < DevCPT.nofGmod DO
  867. m := DevCPT.GlbMod[i];
  868. IF m.library # NIL THEN (* dll import *)
  869. CollectDll(m.right, m.library);
  870. ELSE INC(imports) (* module import *)
  871. END;
  872. INC(i)
  873. END;
  874. DevCPM.ObjWNum(imports); (* num of import *)
  875. OutName(DevCPT.SelfName);
  876. m := dllList;
  877. WHILE m # NIL DO DevCPM.ObjW("$"); OutName(m.library^); m := m.link END;
  878. i := 1;
  879. WHILE i < DevCPT.nofGmod DO
  880. m := DevCPT.GlbMod[i];
  881. IF m.library = NIL THEN OutName(m.name^) END;
  882. INC(i)
  883. END;
  884. Align(16); headSize := DevCPM.ObjLen();
  885. IF procVarIndirect THEN
  886. i := 0; EnumXProc(DevCPT.topScope.right, i)
  887. END
  888. END OutHeader;
  889. PROCEDURE OutCode*;
  890. VAR i, j, refSize, expPos, ptrPos, impPos, namePos, procPos,
  891. con8Pos, con16Pos, con32Pos, con64Pos, modPos, codePos: INTEGER;
  892. m, obj, dlist: DevCPT.Object;
  893. BEGIN
  894. (* Ref *)
  895. DevCPM.ObjW(0X); (* end mark *)
  896. refSize := DevCPM.ObjLen() - headSize;
  897. (* Export *)
  898. Align(4);
  899. IF outSignatures THEN PrepExport(DevCPT.topScope.right) END; (* procedure signatures *)
  900. Align(8); expPos := DevCPM.ObjLen();
  901. Out4(0);
  902. OutExport(DevCPT.topScope.right); (* export objects *)
  903. i := DevCPM.ObjLen(); DevCPM.ObjSet(expPos); Out4((i - expPos - 4) DIV 16); DevCPM.ObjSet(i);
  904. (* Pointers *)
  905. ptrPos := DevCPM.ObjLen();
  906. obj := DevCPT.topScope.scope; nofptrs := 0;
  907. WHILE obj # NIL DO FindPtrs(obj.typ, dsize + obj.adr, FALSE, nofptrs); obj := obj.link END;
  908. obj := DevCPT.topScope.scope; i := 0;
  909. WHILE obj # NIL DO FindPtrs(obj.typ, dsize + obj.adr, TRUE, i); obj := obj.link END;
  910. IF i > 0 THEN Out4(-1); INCL(options, iptrs) END;
  911. (* Prepare Type Descriptors *)
  912. dlist := NIL;
  913. WHILE descList # NIL DO
  914. obj := descList; descList := descList.link;
  915. PrepDesc(obj.typ);
  916. obj.link := dlist; dlist := obj
  917. END;
  918. (* Import List *)
  919. impPos := DevCPM.ObjLen(); i := 0;
  920. WHILE i < imports DO Out4(0); INC(i) END;
  921. (* Names *)
  922. namePos := DevCPM.ObjLen(); OutNames;
  923. (* Const *)
  924. Align(4); con8Pos := DevCPM.ObjLen();
  925. OutConst(Const8); con16Pos := DevCPM.ObjLen();
  926. ASSERT(con16Pos MOD 4 = 0); ASSERT(con16Pos - con8Pos = idx8);
  927. OutConst(Const16); con32Pos := DevCPM.ObjLen();
  928. ASSERT(con32Pos MOD 4 = 0); ASSERT(con32Pos - con16Pos = idx16);
  929. OutConst(Const32); con64Pos := DevCPM.ObjLen();
  930. ASSERT(con64Pos MOD 4 = 0); ASSERT(con64Pos - con32Pos = idx32);
  931. IF ODD(con64Pos DIV 4) THEN Out4(0); INC(con64Pos, 4) END;
  932. OutConst(Const64); ASSERT(DevCPM.ObjLen() - con64Pos = idx64);
  933. (* Module Descriptor *)
  934. Align(16); modPos := DevCPM.ObjLen();
  935. OutModDesc(nofptrs, refSize, namePos - headSize, ptrPos - headSize, expPos - headSize, impPos - headSize);
  936. (* Procedure Table *)
  937. procPos := DevCPM.ObjLen();
  938. OutProcTable(DevCPT.topScope.right);
  939. Out4(0); Out4(0); (* at least one entry in ProcTable *)
  940. Out4(0); (* sentinel *)
  941. (* Type Descriptors *)
  942. obj := dlist;
  943. WHILE obj # NIL DO OutDesc(obj.typ); obj := obj.link END;
  944. (* Code *)
  945. codePos := DevCPM.ObjLen(); WriteCode;
  946. WHILE pc MOD 4 # 0 DO DevCPM.ObjW(90X); INC(pc) END;
  947. (* Fixups *)
  948. OutLink(KNewRec.links); OutLink(KNewArr.links);
  949. (* metalink *)
  950. OutPLink(Const8.links, con8Pos - headSize);
  951. OutPLink(Const16.links, con16Pos - headSize);
  952. OutPLink(Const32.links, con32Pos - headSize);
  953. OutPLink(Const64.links, con64Pos - headSize);
  954. OutLink(Meta.links);
  955. (* desclink *)
  956. obj := dlist; i := modPos - headSize;
  957. WHILE obj # NIL DO OutPLink(obj.links, obj.adr - i); obj.links := NIL; obj := obj.link END;
  958. IF procVarIndirect THEN
  959. OutPLink(Proc.links, procPos - modPos);
  960. OutCPLinks(DevCPT.topScope.right, procPos - modPos)
  961. END;
  962. OutLink(Mod.links);
  963. (* codelink *)
  964. IF ~procVarIndirect THEN OutCLinks(DevCPT.topScope.right) END;
  965. OutPLink(CaseLinks, 0); OutLink(Code.links);
  966. (* datalink *)
  967. OutLink(Data.links);
  968. (* Use *)
  969. OutUseBlock;
  970. (* Header Fixups *)
  971. DevCPM.ObjSet(8);
  972. DevCPM.ObjWLInt(headSize);
  973. DevCPM.ObjWLInt(modPos - headSize);
  974. DevCPM.ObjWLInt(codePos - modPos);
  975. DevCPM.ObjWLInt(pc);
  976. DevCPM.ObjWLInt(dsize);
  977. IF namex > MaxNameTab THEN DevCPM.err(242) END;
  978. IF DevCPM.noerr & outObj THEN DevCPM.RegisterObj END
  979. END OutCode;
  980. PROCEDURE Init* (proc: INTEGER; opt: SET);
  981. CONST obj = 3; ref = 4; allref = 5; srcpos = 6; bigEnd = 15; pVarInd = 14;
  982. BEGIN
  983. processor := proc;
  984. bigEndian := bigEnd IN opt; procVarIndirect := pVarInd IN opt;
  985. outRef := ref IN opt; outAllRef := allref IN opt; outObj := obj IN opt;
  986. outURef := useAllRef & outAllRef & (DevCPM.comAware IN DevCPM.options);
  987. outSrc := srcpos IN opt;
  988. pc := 0; actIdx := CodeLength; blkIdx := 0;
  989. idx8 := 0; idx16 := 0; idx32 := 0; idx64 := 0; namex := 1;
  990. options := opt * {0..15}; CodeOvF := FALSE;
  991. KNewRec.links := NIL; KNewArr.links := NIL; CaseLinks := NIL;
  992. Const8.links := NIL; Const8.conval := NIL; Const16.links := NIL; Const16.conval := NIL;
  993. Const32.links := NIL; Const32.conval := NIL; Const64.links := NIL; Const64.conval := NIL;
  994. Code.links := NIL; Data.links := NIL; Mod.links := NIL; Proc.links := NIL; Meta.links := NIL;
  995. nameList := NIL; descList := NIL; dllList := NIL; dllLast := NIL;
  996. codePos := 0; srcPos := 0;
  997. NEW(untgd); untgd.name := DevCPT.NewName("!");
  998. closeLbl := 0
  999. END Init;
  1000. PROCEDURE Close*;
  1001. BEGIN
  1002. KNewRec.links := NIL; KNewArr.links := NIL; CaseLinks := NIL;
  1003. Const8.links := NIL; Const8.conval := NIL; Const16.links := NIL; Const16.conval := NIL;
  1004. Const32.links := NIL; Const32.conval := NIL; Const64.links := NIL; Const64.conval := NIL;
  1005. Code.links := NIL; Data.links := NIL; Mod.links := NIL; Proc.links := NIL; Meta.links := NIL;
  1006. nameList := NIL; descList := NIL; dllList := NIL; dllLast := NIL;
  1007. WHILE blkIdx > 0 DO DEC(blkIdx); code[blkIdx] := NIL END;
  1008. actual := NIL; untgd := NIL;
  1009. END Close;
  1010. BEGIN
  1011. NEW(KNewRec); KNewRec.mnolev := -128;
  1012. NEW(KNewArr); KNewArr.mnolev := -128;
  1013. NEW(Const8); Const8.mode := Con; Const8.mnolev := 0;
  1014. NEW(Const16); Const16.mode := Con; Const16.mnolev := 0;
  1015. NEW(Const32); Const32.mode := Con; Const32.mnolev := 0;
  1016. NEW(Const64); Const64.mode := Con; Const64.mnolev := 0;
  1017. NEW(Code); Code.mode := Con; Code.mnolev := 0;
  1018. NEW(Data); Data.mode := Con; Data.mnolev := 0;
  1019. NEW(Mod); Mod.mode := Con; Mod.mnolev := 0;
  1020. NEW(Proc); Proc.mode := Con; Proc.mnolev := 0;
  1021. NEW(Meta); Meta.mode := Con; Mod.mnolev := 0;
  1022. END LindevCPE.