fppu.pas 46 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 by Florian Klaempfl
  4. This unit implements the first loading and searching of the modules
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. ****************************************************************************
  17. }
  18. unit fppu;
  19. {$i fpcdefs.inc}
  20. { close ppufiles on system that are
  21. short on file handles like DOS system PM }
  22. {$ifdef GO32V2}
  23. {$define SHORT_ON_FILE_HANDLES}
  24. {$endif GO32V2}
  25. interface
  26. uses
  27. cutils,cclasses,
  28. globtype,globals,finput,fmodule,
  29. symbase,symppu,ppu;
  30. type
  31. tppumodule = class(tmodule)
  32. ppufile : tcompilerppufile; { the PPU file }
  33. sourcefn : pstring; { Source specified with "uses .. in '..'" }
  34. {$ifdef Test_Double_checksum}
  35. crc_array : pointer;
  36. crc_size : longint;
  37. crc_array2 : pointer;
  38. crc_size2 : longint;
  39. {$endif def Test_Double_checksum}
  40. constructor create(LoadedFrom:TModule;const s:string;const fn:string;_is_unit:boolean);
  41. destructor destroy;override;
  42. procedure reset;override;
  43. function openppu:boolean;
  44. procedure getppucrc;
  45. procedure writeppu;
  46. procedure loadppu;
  47. private
  48. function search_unit(onlysource,shortname:boolean):boolean;
  49. procedure load_interface;
  50. procedure load_implementation;
  51. procedure load_symtable_refs;
  52. procedure load_usedunits;
  53. procedure writeusedmacro(p:TNamedIndexItem;arg:pointer);
  54. procedure writeusedmacros;
  55. procedure writesourcefiles;
  56. procedure writeusedunit;
  57. procedure writelinkcontainer(var p:tlinkcontainer;id:byte;strippath:boolean);
  58. procedure putasmsymbol_in_idx(s:tnamedindexitem;arg:pointer);
  59. procedure writeasmsymbols;
  60. procedure readusedmacros;
  61. procedure readsourcefiles;
  62. procedure readloadunit;
  63. procedure readlinkcontainer(var p:tlinkcontainer);
  64. procedure readasmsymbols;
  65. end;
  66. function registerunit(callermodule:tmodule;const s : stringid;const fn:string) : tppumodule;
  67. implementation
  68. uses
  69. verbose,systems,version,
  70. symtable,
  71. scanner,
  72. aasmbase,
  73. parser;
  74. {****************************************************************************
  75. TPPUMODULE
  76. ****************************************************************************}
  77. constructor tppumodule.create(LoadedFrom:TModule;const s:string;const fn:string;_is_unit:boolean);
  78. begin
  79. inherited create(LoadedFrom,s,_is_unit);
  80. ppufile:=nil;
  81. sourcefn:=stringdup(fn);
  82. end;
  83. destructor tppumodule.Destroy;
  84. begin
  85. if assigned(ppufile) then
  86. ppufile.free;
  87. ppufile:=nil;
  88. inherited Destroy;
  89. end;
  90. procedure tppumodule.reset;
  91. begin
  92. if assigned(ppufile) then
  93. begin
  94. ppufile.free;
  95. ppufile:=nil;
  96. end;
  97. inherited reset;
  98. end;
  99. function tppumodule.openppu:boolean;
  100. var
  101. ppufiletime : longint;
  102. begin
  103. openppu:=false;
  104. Message1(unit_t_ppu_loading,ppufilename^);
  105. { Get ppufile time (also check if the file exists) }
  106. ppufiletime:=getnamedfiletime(ppufilename^);
  107. if ppufiletime=-1 then
  108. exit;
  109. { Open the ppufile }
  110. Message1(unit_u_ppu_name,ppufilename^);
  111. ppufile:=tcompilerppufile.create(ppufilename^);
  112. if not ppufile.openfile then
  113. begin
  114. ppufile.free;
  115. ppufile:=nil;
  116. Message(unit_u_ppu_file_too_short);
  117. exit;
  118. end;
  119. { check for a valid PPU file }
  120. if not ppufile.CheckPPUId then
  121. begin
  122. ppufile.free;
  123. ppufile:=nil;
  124. Message(unit_u_ppu_invalid_header);
  125. exit;
  126. end;
  127. { check for allowed PPU versions }
  128. if not (ppufile.GetPPUVersion = CurrentPPUVersion) then
  129. begin
  130. Message1(unit_u_ppu_invalid_version,tostr(ppufile.GetPPUVersion));
  131. ppufile.free;
  132. ppufile:=nil;
  133. exit;
  134. end;
  135. { check the target processor }
  136. if tsystemcpu(ppufile.header.cpu)<>target_cpu then
  137. begin
  138. ppufile.free;
  139. ppufile:=nil;
  140. Message(unit_u_ppu_invalid_processor);
  141. exit;
  142. end;
  143. { check target }
  144. if tsystem(ppufile.header.target)<>target_info.system then
  145. begin
  146. ppufile.free;
  147. ppufile:=nil;
  148. Message(unit_u_ppu_invalid_target);
  149. exit;
  150. end;
  151. {$ifdef cpufpemu}
  152. { check if floating point emulation is on?}
  153. if ((ppufile.header.flags and uf_fpu_emulation)<>0) and
  154. (cs_fp_emulation in aktmoduleswitches) then
  155. begin
  156. ppufile.free;
  157. ppufile:=nil;
  158. Message(unit_u_ppu_invalid_fpumode);
  159. exit;
  160. end;
  161. {$endif cpufpemu}
  162. { Load values to be access easier }
  163. flags:=ppufile.header.flags;
  164. crc:=ppufile.header.checksum;
  165. interface_crc:=ppufile.header.interface_checksum;
  166. { Show Debug info }
  167. Message1(unit_u_ppu_time,filetimestring(ppufiletime));
  168. Message1(unit_u_ppu_flags,tostr(flags));
  169. Message1(unit_u_ppu_crc,hexstr(ppufile.header.checksum,8));
  170. Message1(unit_u_ppu_crc,hexstr(ppufile.header.interface_checksum,8)+' (intfc)');
  171. do_compile:=false;
  172. openppu:=true;
  173. end;
  174. function tppumodule.search_unit(onlysource,shortname:boolean):boolean;
  175. var
  176. singlepathstring,
  177. filename : string;
  178. Function UnitExists(const ext:string;var foundfile:string):boolean;
  179. begin
  180. Message1(unit_t_unitsearch,Singlepathstring+filename+ext);
  181. UnitExists:=FindFile(FileName+ext,Singlepathstring,foundfile);
  182. end;
  183. Function PPUSearchPath(const s:string):boolean;
  184. var
  185. found : boolean;
  186. hs : string;
  187. begin
  188. Found:=false;
  189. singlepathstring:=FixPath(s,false);
  190. { Check for PPU file }
  191. Found:=UnitExists(target_info.unitext,hs);
  192. if Found then
  193. Begin
  194. SetFileName(hs,false);
  195. Found:=OpenPPU;
  196. End;
  197. PPUSearchPath:=Found;
  198. end;
  199. Function SourceSearchPath(const s:string):boolean;
  200. var
  201. found : boolean;
  202. hs : string;
  203. begin
  204. Found:=false;
  205. singlepathstring:=FixPath(s,false);
  206. { Check for Sources }
  207. ppufile:=nil;
  208. do_compile:=true;
  209. recompile_reason:=rr_noppu;
  210. {Check for .pp file}
  211. Found:=UnitExists(target_info.sourceext,hs);
  212. if not Found then
  213. begin
  214. { Check for .pas }
  215. Found:=UnitExists(target_info.pasext,hs);
  216. end;
  217. stringdispose(mainsource);
  218. if Found then
  219. begin
  220. sources_avail:=true;
  221. { Load Filenames when found }
  222. mainsource:=StringDup(hs);
  223. SetFileName(hs,false);
  224. end
  225. else
  226. sources_avail:=false;
  227. SourceSearchPath:=Found;
  228. end;
  229. Function SearchPath(const s:string):boolean;
  230. var
  231. found : boolean;
  232. begin
  233. { First check for a ppu, then for the source }
  234. found:=false;
  235. if not onlysource then
  236. found:=PPUSearchPath(s);
  237. if not found then
  238. found:=SourceSearchPath(s);
  239. SearchPath:=found;
  240. end;
  241. Function SearchPathList(list:TSearchPathList):boolean;
  242. var
  243. hp : TStringListItem;
  244. found : boolean;
  245. begin
  246. found:=false;
  247. hp:=TStringListItem(list.First);
  248. while assigned(hp) do
  249. begin
  250. found:=SearchPath(hp.Str);
  251. if found then
  252. break;
  253. hp:=TStringListItem(hp.next);
  254. end;
  255. SearchPathList:=found;
  256. end;
  257. var
  258. fnd : boolean;
  259. hs : string;
  260. begin
  261. if shortname then
  262. filename:=FixFileName(Copy(realmodulename^,1,8))
  263. else
  264. filename:=FixFileName(realmodulename^);
  265. { try to find unit
  266. 1. look for ppu in cwd
  267. 2. look for ppu in outputpath if set, this is tp7 compatible (PFV)
  268. 3. look for the specified source file (from the uses line)
  269. 4. look for source in cwd
  270. 5. local unit pathlist
  271. 6. global unit pathlist }
  272. fnd:=false;
  273. if not onlysource then
  274. begin
  275. fnd:=PPUSearchPath('.');
  276. if (not fnd) and (outputpath^<>'') then
  277. fnd:=PPUSearchPath(outputpath^);
  278. end;
  279. if (not fnd) and (sourcefn^<>'') then
  280. begin
  281. { the full filename is specified so we can't use here the
  282. searchpath (PFV) }
  283. Message1(unit_t_unitsearch,AddExtension(sourcefn^,target_info.sourceext));
  284. fnd:=FindFile(AddExtension(sourcefn^,target_info.sourceext),'',hs);
  285. if not fnd then
  286. begin
  287. Message1(unit_t_unitsearch,AddExtension(sourcefn^,target_info.pasext));
  288. fnd:=FindFile(AddExtension(sourcefn^,target_info.pasext),'',hs);
  289. end;
  290. if fnd then
  291. begin
  292. sources_avail:=true;
  293. do_compile:=true;
  294. recompile_reason:=rr_noppu;
  295. stringdispose(mainsource);
  296. mainsource:=StringDup(hs);
  297. SetFileName(hs,false);
  298. end;
  299. end;
  300. if not fnd then
  301. fnd:=SourceSearchPath('.');
  302. if (not fnd) and Assigned(Loaded_From) then
  303. fnd:=SearchPathList(Loaded_From.LocalUnitSearchPath);
  304. if not fnd then
  305. fnd:=SearchPathList(UnitSearchPath);
  306. { try to find a file with the first 8 chars of the modulename, like
  307. dos }
  308. if (not fnd) and (length(filename)>8) then
  309. begin
  310. filename:=copy(filename,1,8);
  311. fnd:=SearchPath('.');
  312. if (not fnd) then
  313. fnd:=SearchPathList(LocalUnitSearchPath);
  314. if not fnd then
  315. fnd:=SearchPathList(UnitSearchPath);
  316. end;
  317. search_unit:=fnd;
  318. end;
  319. {**********************************
  320. PPU Reading/Writing Helpers
  321. ***********************************}
  322. procedure tppumodule.writeusedmacro(p:TNamedIndexItem;arg:pointer);
  323. begin
  324. if tmacro(p).is_used or tmacro(p).defined_at_startup then
  325. begin
  326. ppufile.putstring(p.name);
  327. ppufile.putbyte(byte(tmacro(p).defined_at_startup));
  328. ppufile.putbyte(byte(tmacro(p).is_used));
  329. end;
  330. end;
  331. procedure tppumodule.writeusedmacros;
  332. begin
  333. ppufile.do_crc:=false;
  334. tscannerfile(scanner).macros.foreach({$ifdef FPCPROCVAR}@{$endif}writeusedmacro,nil);
  335. ppufile.writeentry(ibusedmacros);
  336. ppufile.do_crc:=true;
  337. end;
  338. procedure tppumodule.writesourcefiles;
  339. var
  340. hp : tinputfile;
  341. i,j : longint;
  342. begin
  343. { second write the used source files }
  344. ppufile.do_crc:=false;
  345. hp:=sourcefiles.files;
  346. { write source files directly in good order }
  347. j:=0;
  348. while assigned(hp) do
  349. begin
  350. inc(j);
  351. hp:=hp.ref_next;
  352. end;
  353. while j>0 do
  354. begin
  355. hp:=sourcefiles.files;
  356. for i:=1 to j-1 do
  357. hp:=hp.ref_next;
  358. ppufile.putstring(hp.name^);
  359. ppufile.putlongint(hp.getfiletime);
  360. dec(j);
  361. end;
  362. ppufile.writeentry(ibsourcefiles);
  363. ppufile.do_crc:=true;
  364. end;
  365. procedure tppumodule.writeusedunit;
  366. var
  367. hp : tused_unit;
  368. begin
  369. { renumber the units for derefence writing }
  370. numberunits;
  371. { write a reference for each used unit }
  372. hp:=tused_unit(used_units.first);
  373. while assigned(hp) do
  374. begin
  375. { implementation units should not change
  376. the CRC PM }
  377. ppufile.do_crc:=hp.in_interface;
  378. ppufile.putstring(hp.u.realmodulename^);
  379. { the checksum should not affect the crc of this unit ! (PFV) }
  380. ppufile.do_crc:=false;
  381. ppufile.putlongint(longint(hp.checksum));
  382. ppufile.putlongint(longint(hp.interface_checksum));
  383. ppufile.putbyte(byte(hp.in_interface));
  384. ppufile.do_crc:=true;
  385. hp:=tused_unit(hp.next);
  386. end;
  387. ppufile.do_interface_crc:=true;
  388. ppufile.writeentry(ibloadunit);
  389. end;
  390. procedure tppumodule.writelinkcontainer(var p:tlinkcontainer;id:byte;strippath:boolean);
  391. var
  392. hcontainer : tlinkcontainer;
  393. s : string;
  394. mask : cardinal;
  395. begin
  396. hcontainer:=TLinkContainer.Create;
  397. while not p.empty do
  398. begin
  399. s:=p.get(mask);
  400. if strippath then
  401. ppufile.putstring(SplitFileName(s))
  402. else
  403. ppufile.putstring(s);
  404. ppufile.putlongint(mask);
  405. hcontainer.add(s,mask);
  406. end;
  407. ppufile.writeentry(id);
  408. p.Free;
  409. p:=hcontainer;
  410. end;
  411. procedure tppumodule.putasmsymbol_in_idx(s:tnamedindexitem;arg:pointer);
  412. begin
  413. if tasmsymbol(s).ppuidx<>-1 then
  414. librarydata.asmsymbolidx^[tasmsymbol(s).ppuidx-1]:=tasmsymbol(s);
  415. end;
  416. procedure tppumodule.writeasmsymbols;
  417. var
  418. s : tasmsymbol;
  419. i : longint;
  420. asmsymtype : byte;
  421. begin
  422. { get an ordered list of all symbols to put in the ppu }
  423. getmem(librarydata.asmsymbolidx,librarydata.asmsymbolppuidx*sizeof(pointer));
  424. fillchar(librarydata.asmsymbolidx^,librarydata.asmsymbolppuidx*sizeof(pointer),0);
  425. librarydata.symbolsearch.foreach({$ifdef FPCPROCVAR}@{$endif}putasmsymbol_in_idx,nil);
  426. { write the number of symbols }
  427. ppufile.putlongint(librarydata.asmsymbolppuidx);
  428. { write the symbols from the indexed list to the ppu }
  429. for i:=1 to librarydata.asmsymbolppuidx do
  430. begin
  431. s:=librarydata.asmsymbolidx^[i-1];
  432. if not assigned(s) then
  433. internalerror(200208071);
  434. asmsymtype:=1;
  435. if s.Classtype=tasmlabel then
  436. begin
  437. if tasmlabel(s).is_addr then
  438. asmsymtype:=4
  439. else if tasmlabel(s).typ=AT_DATA then
  440. asmsymtype:=3
  441. else
  442. asmsymtype:=2;
  443. end;
  444. ppufile.putbyte(asmsymtype);
  445. case asmsymtype of
  446. 1 :
  447. ppufile.putstring(s.name);
  448. 2 :
  449. ppufile.putlongint(tasmlabel(s).labelnr);
  450. end;
  451. ppufile.putbyte(byte(s.defbind));
  452. ppufile.putbyte(byte(s.typ));
  453. end;
  454. ppufile.writeentry(ibasmsymbols);
  455. end;
  456. procedure tppumodule.readusedmacros;
  457. var
  458. hs : string;
  459. mac : tmacro;
  460. was_defined_at_startup,
  461. was_used : boolean;
  462. begin
  463. { only possible when we've a scanner of the current file }
  464. if not assigned(current_scanner) then
  465. exit;
  466. while not ppufile.endofentry do
  467. begin
  468. hs:=ppufile.getstring;
  469. was_defined_at_startup:=boolean(ppufile.getbyte);
  470. was_used:=boolean(ppufile.getbyte);
  471. mac:=tmacro(tscannerfile(current_scanner).macros.search(hs));
  472. if assigned(mac) then
  473. begin
  474. {$ifndef EXTDEBUG}
  475. { if we don't have the sources why tell }
  476. if sources_avail then
  477. {$endif ndef EXTDEBUG}
  478. if (not was_defined_at_startup) and
  479. was_used and
  480. mac.defined_at_startup then
  481. Message2(unit_h_cond_not_set_in_last_compile,hs,mainsource^);
  482. end
  483. else { not assigned }
  484. if was_defined_at_startup and
  485. was_used then
  486. Message2(unit_h_cond_set_in_last_compile,hs,mainsource^);
  487. end;
  488. end;
  489. procedure tppumodule.readsourcefiles;
  490. var
  491. temp,hs : string;
  492. temp_dir : string;
  493. main_dir : string;
  494. incfile_found,
  495. main_found,
  496. is_main : boolean;
  497. orgfiletime,
  498. source_time : longint;
  499. hp : tinputfile;
  500. begin
  501. sources_avail:=true;
  502. is_main:=true;
  503. main_dir:='';
  504. while not ppufile.endofentry do
  505. begin
  506. hs:=ppufile.getstring;
  507. orgfiletime:=ppufile.getlongint;
  508. temp_dir:='';
  509. if (flags and uf_in_library)<>0 then
  510. begin
  511. sources_avail:=false;
  512. temp:=' library';
  513. end
  514. else if pos('Macro ',hs)=1 then
  515. begin
  516. { we don't want to find this file }
  517. { but there is a problem with file indexing !! }
  518. temp:='';
  519. end
  520. else
  521. begin
  522. { check the date of the source files }
  523. Source_Time:=GetNamedFileTime(path^+hs);
  524. incfile_found:=false;
  525. main_found:=false;
  526. if Source_Time<>-1 then
  527. hs:=path^+hs
  528. else
  529. if not(is_main) then
  530. begin
  531. Source_Time:=GetNamedFileTime(main_dir+hs);
  532. if Source_Time<>-1 then
  533. hs:=main_dir+hs;
  534. end;
  535. if (Source_Time=-1) then
  536. begin
  537. if is_main then
  538. main_found:=unitsearchpath.FindFile(hs,temp_dir)
  539. else
  540. incfile_found:=includesearchpath.FindFile(hs,temp_dir);
  541. if incfile_found or main_found then
  542. begin
  543. Source_Time:=GetNamedFileTime(temp_dir);
  544. if Source_Time<>-1 then
  545. hs:=temp_dir;
  546. end;
  547. end;
  548. if Source_Time=-1 then
  549. begin
  550. sources_avail:=false;
  551. temp:=' not found';
  552. end
  553. else
  554. begin
  555. if main_found then
  556. main_dir:=temp_dir;
  557. { time newer? But only allow if the file is not searched
  558. in the include path (PFV), else you've problems with
  559. units which use the same includefile names }
  560. if incfile_found then
  561. temp:=' found'
  562. else
  563. begin
  564. temp:=' time '+filetimestring(source_time);
  565. if (orgfiletime<>-1) and
  566. (source_time<>orgfiletime) then
  567. begin
  568. if ((flags and uf_release)=0) then
  569. begin
  570. do_compile:=true;
  571. recompile_reason:=rr_sourcenewer;
  572. end
  573. else
  574. Message2(unit_h_source_modified,hs,ppufilename^);
  575. temp:=temp+' *';
  576. end;
  577. end;
  578. end;
  579. hp:=tinputfile.create(hs);
  580. { the indexing is wrong here PM }
  581. sourcefiles.register_file(hp);
  582. end;
  583. if is_main then
  584. begin
  585. stringdispose(mainsource);
  586. mainsource:=stringdup(hs);
  587. end;
  588. Message1(unit_u_ppu_source,hs+temp);
  589. is_main:=false;
  590. end;
  591. { check if we want to rebuild every unit, only if the sources are
  592. available }
  593. if do_build and sources_avail and
  594. ((flags and uf_release)=0) then
  595. begin
  596. do_compile:=true;
  597. recompile_reason:=rr_build;
  598. end;
  599. end;
  600. procedure tppumodule.readloadunit;
  601. var
  602. hs : string;
  603. pu : tused_unit;
  604. hp : tppumodule;
  605. intfchecksum,
  606. checksum : cardinal;
  607. begin
  608. while not ppufile.endofentry do
  609. begin
  610. hs:=ppufile.getstring;
  611. checksum:=cardinal(ppufile.getlongint);
  612. intfchecksum:=cardinal(ppufile.getlongint);
  613. in_interface:=(ppufile.getbyte<>0);
  614. { set the state of this unit before registering, this is
  615. needed for a correct circular dependency check }
  616. hp:=registerunit(self,hs,'');
  617. pu:=addusedunit(hp,false);
  618. pu.checksum:=checksum;
  619. pu.interface_checksum:=intfchecksum;
  620. end;
  621. in_interface:=false;
  622. end;
  623. procedure tppumodule.readlinkcontainer(var p:tlinkcontainer);
  624. var
  625. s : string;
  626. m : longint;
  627. begin
  628. while not ppufile.endofentry do
  629. begin
  630. s:=ppufile.getstring;
  631. m:=ppufile.getlongint;
  632. p.add(s,m);
  633. end;
  634. end;
  635. procedure tppumodule.readasmsymbols;
  636. var
  637. labelnr,
  638. i : longint;
  639. name : string;
  640. bind : TAsmSymBind;
  641. typ : TAsmSymType;
  642. asmsymtype : byte;
  643. begin
  644. librarydata.asmsymbolppuidx:=ppufile.getlongint;
  645. if librarydata.asmsymbolppuidx>0 then
  646. begin
  647. getmem(librarydata.asmsymbolidx,librarydata.asmsymbolppuidx*sizeof(pointer));
  648. fillchar(librarydata.asmsymbolidx^,librarydata.asmsymbolppuidx*sizeof(pointer),0);
  649. for i:=1 to librarydata.asmsymbolppuidx do
  650. begin
  651. asmsymtype:=ppufile.getbyte;
  652. case asmsymtype of
  653. 1 :
  654. name:=ppufile.getstring;
  655. 2..4 :
  656. labelnr:=ppufile.getlongint;
  657. else
  658. internalerror(200208192);
  659. end;
  660. bind:=tasmsymbind(ppufile.getbyte);
  661. typ:=tasmsymtype(ppufile.getbyte);
  662. case asmsymtype of
  663. 1 :
  664. librarydata.asmsymbolidx^[i-1]:=librarydata.newasmsymboltype(name,bind,typ);
  665. 2 :
  666. librarydata.asmsymbolidx^[i-1]:=librarydata.newasmlabel(labelnr,false,false);
  667. 3 :
  668. librarydata.asmsymbolidx^[i-1]:=librarydata.newasmlabel(labelnr,true,false);
  669. 4 :
  670. librarydata.asmsymbolidx^[i-1]:=librarydata.newasmlabel(labelnr,false,true);
  671. end;
  672. end;
  673. end;
  674. end;
  675. procedure tppumodule.load_interface;
  676. var
  677. b : byte;
  678. newmodulename : string;
  679. begin
  680. { read interface part }
  681. repeat
  682. b:=ppufile.readentry;
  683. case b of
  684. ibmodulename :
  685. begin
  686. newmodulename:=ppufile.getstring;
  687. if (cs_check_unit_name in aktglobalswitches) and
  688. (upper(newmodulename)<>modulename^) then
  689. Message2(unit_f_unit_name_error,realmodulename^,newmodulename);
  690. stringdispose(modulename);
  691. stringdispose(realmodulename);
  692. modulename:=stringdup(upper(newmodulename));
  693. realmodulename:=stringdup(newmodulename);
  694. end;
  695. ibsourcefiles :
  696. readsourcefiles;
  697. ibusedmacros :
  698. readusedmacros;
  699. ibloadunit :
  700. readloadunit;
  701. iblinkunitofiles :
  702. readlinkcontainer(LinkUnitOFiles);
  703. iblinkunitstaticlibs :
  704. readlinkcontainer(LinkUnitStaticLibs);
  705. iblinkunitsharedlibs :
  706. readlinkcontainer(LinkUnitSharedLibs);
  707. iblinkotherofiles :
  708. readlinkcontainer(LinkotherOFiles);
  709. iblinkotherstaticlibs :
  710. readlinkcontainer(LinkotherStaticLibs);
  711. iblinkothersharedlibs :
  712. readlinkcontainer(LinkotherSharedLibs);
  713. ibendinterface :
  714. break;
  715. else
  716. Message1(unit_f_ppu_invalid_entry,tostr(b));
  717. end;
  718. until false;
  719. end;
  720. procedure tppumodule.load_implementation;
  721. var
  722. b : byte;
  723. oldobjectlibrary : tasmlibrarydata;
  724. begin
  725. { read implementation part }
  726. repeat
  727. b:=ppufile.readentry;
  728. case b of
  729. ibasmsymbols :
  730. readasmsymbols;
  731. ibendimplementation :
  732. break;
  733. else
  734. Message1(unit_f_ppu_invalid_entry,tostr(b));
  735. end;
  736. until false;
  737. { we can now derefence all pointers to the implementation parts }
  738. oldobjectlibrary:=objectlibrary;
  739. objectlibrary:=librarydata;
  740. tstoredsymtable(globalsymtable).derefimpl;
  741. if assigned(localsymtable) then
  742. tstoredsymtable(localsymtable).derefimpl;
  743. objectlibrary:=oldobjectlibrary;
  744. end;
  745. procedure tppumodule.load_symtable_refs;
  746. var
  747. b : byte;
  748. unitindex : word;
  749. begin
  750. { load local symtable first }
  751. if ((flags and uf_local_browser)<>0) then
  752. begin
  753. localsymtable:=tstaticsymtable.create(modulename^);
  754. tstaticsymtable(localsymtable).ppuload(ppufile);
  755. end;
  756. { load browser }
  757. if (flags and uf_has_browser)<>0 then
  758. begin
  759. tstoredsymtable(globalsymtable).load_references(ppufile,true);
  760. unitindex:=1;
  761. while assigned(map^[unitindex]) do
  762. begin
  763. { each unit wrote one browser entry }
  764. tstoredsymtable(globalsymtable).load_references(ppufile,false);
  765. inc(unitindex);
  766. end;
  767. b:=ppufile.readentry;
  768. if b<>ibendbrowser then
  769. Message1(unit_f_ppu_invalid_entry,tostr(b));
  770. end;
  771. if ((flags and uf_local_browser)<>0) then
  772. tstaticsymtable(localsymtable).load_references(ppufile,true);
  773. end;
  774. procedure tppumodule.writeppu;
  775. var
  776. pu : tused_unit;
  777. begin
  778. Message1(unit_u_ppu_write,realmodulename^);
  779. { create unit flags }
  780. {$ifdef GDB}
  781. if cs_gdb_dbx in aktglobalswitches then
  782. flags:=flags or uf_has_dbx;
  783. {$endif GDB}
  784. if cs_browser in aktmoduleswitches then
  785. flags:=flags or uf_has_browser;
  786. if cs_local_browser in aktmoduleswitches then
  787. flags:=flags or uf_local_browser;
  788. if do_release then
  789. flags:=flags or uf_release;
  790. {$ifdef cpufpemu}
  791. if (cs_fp_emulation in aktmoduleswitches) then
  792. flags:=flags or uf_fpu_emulation;
  793. {$endif cpufpemu}
  794. {$ifdef Test_Double_checksum_write}
  795. Assign(CRCFile,s+'.IMP');
  796. Rewrite(CRCFile);
  797. {$endif def Test_Double_checksum_write}
  798. { create new ppufile }
  799. ppufile:=tcompilerppufile.create(ppufilename^);
  800. if not ppufile.createfile then
  801. Message(unit_f_ppu_cannot_write);
  802. { first the unitname }
  803. ppufile.putstring(realmodulename^);
  804. ppufile.writeentry(ibmodulename);
  805. writesourcefiles;
  806. writeusedmacros;
  807. writeusedunit;
  808. { write the objectfiles and libraries that come for this unit,
  809. preserve the containers becuase they are still needed to load
  810. the link.res. All doesn't depend on the crc! It doesn't matter
  811. if a unit is in a .o or .a file }
  812. ppufile.do_crc:=false;
  813. writelinkcontainer(linkunitofiles,iblinkunitofiles,true);
  814. writelinkcontainer(linkunitstaticlibs,iblinkunitstaticlibs,true);
  815. writelinkcontainer(linkunitsharedlibs,iblinkunitsharedlibs,true);
  816. writelinkcontainer(linkotherofiles,iblinkotherofiles,false);
  817. writelinkcontainer(linkotherstaticlibs,iblinkotherstaticlibs,true);
  818. writelinkcontainer(linkothersharedlibs,iblinkothersharedlibs,true);
  819. ppufile.do_crc:=true;
  820. ppufile.writeentry(ibendinterface);
  821. { write the symtable entries }
  822. tstoredsymtable(globalsymtable).ppuwrite(ppufile);
  823. { everything after this doesn't affect the crc }
  824. ppufile.do_crc:=false;
  825. { write asmsymbols }
  826. writeasmsymbols;
  827. { end of implementation }
  828. ppufile.writeentry(ibendimplementation);
  829. { write static symtable
  830. needed for local debugging of unit functions }
  831. if ((flags and uf_local_browser)<>0) and
  832. assigned(localsymtable) then
  833. tstoredsymtable(localsymtable).ppuwrite(ppufile);
  834. { write all browser section }
  835. if (flags and uf_has_browser)<>0 then
  836. begin
  837. tstoredsymtable(globalsymtable).write_references(ppufile,true);
  838. pu:=tused_unit(used_units.first);
  839. while assigned(pu) do
  840. begin
  841. tstoredsymtable(pu.u.globalsymtable).write_references(ppufile,false);
  842. pu:=tused_unit(pu.next);
  843. end;
  844. ppufile.writeentry(ibendbrowser);
  845. end;
  846. if ((flags and uf_local_browser)<>0) and
  847. assigned(localsymtable) then
  848. tstaticsymtable(localsymtable).write_references(ppufile,true);
  849. { the last entry ibend is written automaticly }
  850. { flush to be sure }
  851. ppufile.flush;
  852. { create and write header }
  853. ppufile.header.size:=ppufile.size;
  854. ppufile.header.checksum:=ppufile.crc;
  855. ppufile.header.interface_checksum:=ppufile.interface_crc;
  856. ppufile.header.compiler:=wordversion;
  857. ppufile.header.cpu:=word(target_cpu);
  858. ppufile.header.target:=word(target_info.system);
  859. ppufile.header.flags:=flags;
  860. ppufile.writeheader;
  861. { save crc in current module also }
  862. crc:=ppufile.crc;
  863. interface_crc:=ppufile.interface_crc;
  864. {$ifdef Test_Double_checksum_write}
  865. close(CRCFile);
  866. {$endif Test_Double_checksum_write}
  867. ppufile.closefile;
  868. ppufile.free;
  869. ppufile:=nil;
  870. end;
  871. procedure tppumodule.getppucrc;
  872. begin
  873. {$ifdef Test_Double_checksum_write}
  874. Assign(CRCFile,s+'.INT')
  875. Rewrite(CRCFile);
  876. {$endif def Test_Double_checksum_write}
  877. { create new ppufile }
  878. ppufile:=tcompilerppufile.create(ppufilename^);
  879. ppufile.crc_only:=true;
  880. if not ppufile.createfile then
  881. Message(unit_f_ppu_cannot_write);
  882. { first the unitname }
  883. ppufile.putstring(realmodulename^);
  884. ppufile.writeentry(ibmodulename);
  885. { the interface units affect the crc }
  886. writeusedunit;
  887. ppufile.writeentry(ibendinterface);
  888. { write the symtable entries }
  889. tstoredsymtable(globalsymtable).ppuwrite(ppufile);
  890. { save crc }
  891. crc:=ppufile.crc;
  892. interface_crc:=ppufile.interface_crc;
  893. {$ifdef Test_Double_checksum}
  894. crc_array:=ppufile.crc_test;
  895. ppufile.crc_test:=nil;
  896. crc_size:=ppufile.crc_index2;
  897. crc_array2:=ppufile.crc_test2;
  898. ppufile.crc_test2:=nil;
  899. crc_size2:=ppufile.crc_index2;
  900. {$endif Test_Double_checksum}
  901. {$ifdef Test_Double_checksum_write}
  902. close(CRCFile);
  903. {$endif Test_Double_checksum_write}
  904. ppufile.closefile;
  905. ppufile.free;
  906. ppufile:=nil;
  907. end;
  908. procedure tppumodule.load_usedunits;
  909. var
  910. pu : tused_unit;
  911. load_refs : boolean;
  912. nextmapentry : longint;
  913. begin
  914. if current_module<>self then
  915. internalerror(200212284);
  916. load_refs:=true;
  917. { init the map }
  918. new(map);
  919. fillchar(map^,sizeof(tunitmap),#0);
  920. map^[0]:=self;
  921. nextmapentry:=1;
  922. { load the used units from interface }
  923. in_interface:=true;
  924. pu:=tused_unit(used_units.first);
  925. while assigned(pu) do
  926. begin
  927. if pu.in_interface then
  928. begin
  929. tppumodule(pu.u).loadppu;
  930. { if this unit is compiled we can stop }
  931. if state=ms_compiled then
  932. exit;
  933. { add this unit to the dependencies }
  934. pu.u.adddependency(self);
  935. { need to recompile the current unit ? }
  936. if pu.u.crc<>pu.checksum then
  937. begin
  938. Message2(unit_u_recompile_crc_change,realmodulename^,pu.u.realmodulename^);
  939. recompile_reason:=rr_crcchanged;
  940. do_compile:=true;
  941. dispose(map);
  942. map:=nil;
  943. exit;
  944. end;
  945. { setup the map entry for deref }
  946. map^[nextmapentry]:=pu.u;
  947. inc(nextmapentry);
  948. if nextmapentry>maxunits then
  949. Message(unit_f_too_much_units);
  950. end;
  951. pu:=tused_unit(pu.next);
  952. end;
  953. { ok, now load the interface of this unit }
  954. if current_module<>self then
  955. internalerror(200208187);
  956. globalsymtable:=tglobalsymtable.create(modulename^);
  957. tstoredsymtable(globalsymtable).ppuload(ppufile);
  958. { now only read the implementation uses }
  959. in_interface:=false;
  960. pu:=tused_unit(used_units.first);
  961. while assigned(pu) do
  962. begin
  963. if (not pu.in_interface) then
  964. begin
  965. tppumodule(pu.u).loadppu;
  966. { if this unit is compiled we can stop }
  967. if state=ms_compiled then
  968. exit;
  969. { add this unit to the dependencies }
  970. pu.u.adddependency(self);
  971. { need to recompile the current unit ? }
  972. if (pu.u.interface_crc<>pu.interface_checksum) then
  973. begin
  974. Message2(unit_u_recompile_crc_change,realmodulename^,pu.u.realmodulename^+' {impl}');
  975. recompile_reason:=rr_crcchanged;
  976. do_compile:=true;
  977. dispose(map);
  978. map:=nil;
  979. exit;
  980. end;
  981. { setup the map entry for deref }
  982. map^[nextmapentry]:=pu.u;
  983. inc(nextmapentry);
  984. if nextmapentry>maxunits then
  985. Message(unit_f_too_much_units);
  986. end;
  987. pu:=tused_unit(pu.next);
  988. end;
  989. { read the implementation/objectdata part }
  990. load_implementation;
  991. { load browser info if stored }
  992. if ((flags and uf_has_browser)<>0) and load_refs then
  993. begin
  994. if current_module<>self then
  995. internalerror(200208188);
  996. load_symtable_refs;
  997. end;
  998. { remove the map, it's not needed anymore }
  999. dispose(map);
  1000. map:=nil;
  1001. end;
  1002. procedure tppumodule.loadppu;
  1003. const
  1004. ImplIntf : array[boolean] of string[15]=('implementation','interface');
  1005. var
  1006. second_time : boolean;
  1007. hp,
  1008. old_current_module : tmodule;
  1009. begin
  1010. old_current_module:=current_module;
  1011. Message3(unit_u_load_unit,old_current_module.modulename^,
  1012. ImplIntf[old_current_module.in_interface],
  1013. modulename^);
  1014. { check if the globalsymtable is already available, but
  1015. we must reload when the do_reload flag is set }
  1016. if do_reload then
  1017. begin
  1018. Comment(V_Used,'Forced reloading');
  1019. do_reload:=false;
  1020. end
  1021. else
  1022. begin
  1023. if assigned(globalsymtable) then
  1024. exit;
  1025. end;
  1026. { reset }
  1027. second_time:=false;
  1028. current_module:=self;
  1029. SetCompileModule(current_module);
  1030. { we are loading a new module, save the state of the scanner
  1031. and reset scanner+module }
  1032. if assigned(current_scanner) then
  1033. current_scanner.tempcloseinputfile;
  1034. current_scanner:=nil;
  1035. { loading the unit for a second time? }
  1036. if state=ms_registered then
  1037. state:=ms_load
  1038. else
  1039. begin
  1040. { try to load the unit a second time first }
  1041. Message1(unit_u_second_load_unit,modulename^);
  1042. Comment(V_Used,'Previous state '+modulename^+': '+ModuleStateStr[state]);
  1043. { Flag modules to reload }
  1044. flagdependent(old_current_module);
  1045. { Reset the module }
  1046. reset;
  1047. if state=ms_compile then
  1048. begin
  1049. Comment(V_Used,'Already compiling '+modulename^+' setting second compile');
  1050. state:=ms_second_compile;
  1051. do_compile:=true;
  1052. end
  1053. else
  1054. state:=ms_second_load;
  1055. second_time:=true;
  1056. end;
  1057. { close old_current_ppu on system that are
  1058. short on file handles like DOS PM }
  1059. {$ifdef SHORT_ON_FILE_HANDLES}
  1060. if old_current_module.is_unit and
  1061. assigned(tppumodule(old_current_module).ppufile) then
  1062. tppumodule(old_current_module).ppufile.tempclose;
  1063. {$endif SHORT_ON_FILE_HANDLES}
  1064. { try to opening ppu, skip this when we already
  1065. know that we need to compile the unit }
  1066. if not do_compile then
  1067. begin
  1068. Comment(V_Used,'Loading module '+modulename^);
  1069. search_unit(false,false);
  1070. if not do_compile then
  1071. begin
  1072. load_interface;
  1073. if not do_compile then
  1074. begin
  1075. load_usedunits;
  1076. if not do_compile then
  1077. Comment(V_Used,'Finished loading module '+modulename^);
  1078. end;
  1079. end;
  1080. { PPU is not needed anymore }
  1081. if assigned(ppufile) then
  1082. begin
  1083. ppufile.closefile;
  1084. ppufile.free;
  1085. ppufile:=nil;
  1086. end;
  1087. end;
  1088. { Do we need to recompile the unit }
  1089. if do_compile then
  1090. begin
  1091. { recompile the unit or give a fatal error if sources not available }
  1092. if not(sources_avail) then
  1093. begin
  1094. if (not search_unit(true,false)) and
  1095. (length(modulename^)>8) then
  1096. search_unit(true,true);
  1097. if not(sources_avail) then
  1098. begin
  1099. if recompile_reason=rr_noppu then
  1100. Message1(unit_f_cant_find_ppu,modulename^)
  1101. else
  1102. Message1(unit_f_cant_compile_unit,modulename^);
  1103. end;
  1104. end;
  1105. { Flag modules to reload }
  1106. flagdependent(old_current_module);
  1107. { Reset the module }
  1108. reset;
  1109. { compile this module }
  1110. if not(state in [ms_compile,ms_second_compile]) then
  1111. state:=ms_compile;
  1112. compile(mainsource^);
  1113. end;
  1114. { set compiled flag }
  1115. if current_module<>self then
  1116. internalerror(200212282);
  1117. state:=ms_compiled;
  1118. if in_interface then
  1119. internalerror(200212283);
  1120. { for a second_time recompile reload all dependent units,
  1121. for a first time compile register the unit _once_ }
  1122. if second_time then
  1123. begin
  1124. { now reload all dependent units }
  1125. hp:=tmodule(loaded_units.first);
  1126. while assigned(hp) do
  1127. begin
  1128. if hp.do_reload then
  1129. tppumodule(hp).loadppu;
  1130. hp:=tmodule(hp.next);
  1131. end;
  1132. end
  1133. else
  1134. usedunits.concat(tused_unit.create(self,true,false));
  1135. { reopen the old module }
  1136. {$ifdef SHORT_ON_FILE_HANDLES}
  1137. if old_current_module.is_unit and
  1138. assigned(tppumodule(old_current_module).ppufile) then
  1139. tppumodule(old_current_module).ppufile.tempopen;
  1140. {$endif SHORT_ON_FILE_HANDLES}
  1141. { we are back, restore current_module and current_scanner }
  1142. current_module:=old_current_module;
  1143. current_scanner:=tscannerfile(current_module.scanner);
  1144. if assigned(current_scanner) then
  1145. current_scanner.tempopeninputfile;
  1146. SetCompileModule(current_module);
  1147. end;
  1148. {*****************************************************************************
  1149. RegisterUnit
  1150. *****************************************************************************}
  1151. function registerunit(callermodule:tmodule;const s : stringid;const fn:string) : tppumodule;
  1152. var
  1153. ups : stringid;
  1154. hp : tppumodule;
  1155. hp2,
  1156. shortnamehp : tmodule;
  1157. begin
  1158. { Info }
  1159. ups:=upper(s);
  1160. { search all loaded units }
  1161. shortnamehp:=nil;
  1162. hp:=tppumodule(loaded_units.first);
  1163. while assigned(hp) do
  1164. begin
  1165. if hp.modulename^=ups then
  1166. begin
  1167. { only check for units. The main program is also
  1168. as a unit in the loaded_units list. We simply need
  1169. to ignore this entry (PFV) }
  1170. if hp.is_unit then
  1171. begin
  1172. { both units in interface ? }
  1173. if callermodule.in_interface and
  1174. hp.in_interface then
  1175. begin
  1176. { check for a cycle }
  1177. hp2:=callermodule.loaded_from;
  1178. while assigned(hp2) and (hp2<>hp) do
  1179. begin
  1180. if hp2.in_interface then
  1181. hp2:=hp2.loaded_from
  1182. else
  1183. hp2:=nil;
  1184. end;
  1185. if assigned(hp2) then
  1186. Message2(unit_f_circular_unit_reference,callermodule.modulename^,hp.modulename^);
  1187. end;
  1188. break;
  1189. end;
  1190. end
  1191. else
  1192. if copy(hp.modulename^,1,8)=ups then
  1193. shortnamehp:=hp;
  1194. { the next unit }
  1195. hp:=tppumodule(hp.next);
  1196. end;
  1197. if assigned(shortnamehp) and not assigned(hp) then
  1198. Message2(unit_w_unit_name_error,s,shortnamehp.modulename^);
  1199. { the unit is not in the loaded units,
  1200. we create an entry and register the unit }
  1201. if not assigned(hp) then
  1202. begin
  1203. Comment(V_Used,'Registering new unit '+Upper(s));
  1204. hp:=tppumodule.create(callermodule,s,fn,true);
  1205. hp.loaded_from:=callermodule;
  1206. loaded_units.insert(hp);
  1207. end;
  1208. { return }
  1209. registerunit:=hp;
  1210. end;
  1211. end.
  1212. {
  1213. $Log$
  1214. Revision 1.29 2002-12-29 14:57:50 peter
  1215. * unit loading changed to first register units and load them
  1216. afterwards. This is needed to support uses xxx in yyy correctly
  1217. * unit dependency check fixed
  1218. Revision 1.28 2002/12/06 16:56:57 peter
  1219. * only compile cs_fp_emulation support when cpufpuemu is defined
  1220. * define cpufpuemu for m68k only
  1221. Revision 1.27 2002/11/20 12:36:24 mazen
  1222. * $UNITPATH directive is now working
  1223. Revision 1.26 2002/11/15 01:58:46 peter
  1224. * merged changes from 1.0.7 up to 04-11
  1225. - -V option for generating bug report tracing
  1226. - more tracing for option parsing
  1227. - errors for cdecl and high()
  1228. - win32 import stabs
  1229. - win32 records<=8 are returned in eax:edx (turned off by default)
  1230. - heaptrc update
  1231. - more info for temp management in .s file with EXTDEBUG
  1232. Revision 1.25 2002/10/20 14:49:31 peter
  1233. * store original source time in ppu so it can be compared instead of
  1234. comparing with the ppu time
  1235. Revision 1.24 2002/10/04 20:13:10 peter
  1236. * set in_second_load flag before resetting the module, this is
  1237. required to skip some checkings
  1238. Revision 1.23 2002/08/19 19:36:42 peter
  1239. * More fixes for cross unit inlining, all tnodes are now implemented
  1240. * Moved pocall_internconst to po_internconst because it is not a
  1241. calling type at all and it conflicted when inlining of these small
  1242. functions was requested
  1243. Revision 1.22 2002/08/18 19:58:28 peter
  1244. * more current_scanner fixes
  1245. Revision 1.21 2002/08/15 15:09:41 carl
  1246. + fpu emulation helpers (ppu checking also)
  1247. Revision 1.20 2002/08/12 16:46:04 peter
  1248. * tscannerfile is now destroyed in tmodule.reset and current_scanner
  1249. is updated accordingly. This removes all the loading and saving of
  1250. the old scanner and the invalid flag marking
  1251. Revision 1.19 2002/08/11 14:28:19 peter
  1252. * TScannerFile.SetInvalid added that will also reset inputfile
  1253. Revision 1.18 2002/08/11 13:24:11 peter
  1254. * saving of asmsymbols in ppu supported
  1255. * asmsymbollist global is removed and moved into a new class
  1256. tasmlibrarydata that will hold the info of a .a file which
  1257. corresponds with a single module. Added librarydata to tmodule
  1258. to keep the library info stored for the module. In the future the
  1259. objectfiles will also be stored to the tasmlibrarydata class
  1260. * all getlabel/newasmsymbol and friends are moved to the new class
  1261. Revision 1.17 2002/07/26 21:15:37 florian
  1262. * rewrote the system handling
  1263. Revision 1.16 2002/05/16 19:46:36 carl
  1264. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  1265. + try to fix temp allocation (still in ifdef)
  1266. + generic constructor calls
  1267. + start of tassembler / tmodulebase class cleanup
  1268. Revision 1.15 2002/05/14 19:34:41 peter
  1269. * removed old logs and updated copyright year
  1270. Revision 1.14 2002/05/12 16:53:05 peter
  1271. * moved entry and exitcode to ncgutil and cgobj
  1272. * foreach gets extra argument for passing local data to the
  1273. iterator function
  1274. * -CR checks also class typecasts at runtime by changing them
  1275. into as
  1276. * fixed compiler to cycle with the -CR option
  1277. * fixed stabs with elf writer, finally the global variables can
  1278. be watched
  1279. * removed a lot of routines from cga unit and replaced them by
  1280. calls to cgobj
  1281. * u32bit-s32bit updates for and,or,xor nodes. When one element is
  1282. u32bit then the other is typecasted also to u32bit without giving
  1283. a rangecheck warning/error.
  1284. * fixed pascal calling method with reversing also the high tree in
  1285. the parast, detected by tcalcst3 test
  1286. Revision 1.13 2002/04/04 19:05:56 peter
  1287. * removed unused units
  1288. * use tlocation.size in cg.a_*loc*() routines
  1289. Revision 1.12 2002/03/28 20:46:44 carl
  1290. - remove go32v1 support
  1291. Revision 1.11 2002/01/19 14:20:13 peter
  1292. * check for -Un when loading ppu with wrong name
  1293. }