2
0

CPE.txt 36 KB

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