Ablenv.cpp 44 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477
  1. //===========================================================================//
  2. // Copyright (C) Microsoft Corporation. All rights reserved. //
  3. //===========================================================================//
  4. //***************************************************************************
  5. //
  6. // ABLENV.CPP
  7. //
  8. //***************************************************************************
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #ifndef ABLGEN_H
  13. #include "ablgen.h"
  14. #endif
  15. #ifndef ABLERR_H
  16. #include "ablerr.h"
  17. #endif
  18. #ifndef ABLSCAN_H
  19. #include "ablscan.h"
  20. #endif
  21. #ifndef ABLEXEC_H
  22. #include "ablexec.h"
  23. #endif
  24. #ifndef ABLENV_H
  25. #include "ablenv.h"
  26. #endif
  27. #ifndef ABLDBUG_H
  28. #include "abldbug.h"
  29. #endif
  30. //***************************************************************************
  31. long ABLi_preProcess (char* sourceFileName,
  32. long* numErrors = NULL,
  33. long* numLinesProcessed = NULL,
  34. long* numFilesProcessed = NULL,
  35. bool printLines = false);
  36. ABLModulePtr ABLi_loadLibrary (char* sourceFileName,
  37. long* numErrors = NULL,
  38. long* numLinesProcessed = NULL,
  39. long* numFilesProcessed = NULL,
  40. bool printLines = false,
  41. bool createInstance = true);
  42. //-------------------
  43. // EXTERNAL variables
  44. extern long lineNumber;
  45. extern long errorCount;
  46. extern long execStatementCount;
  47. extern TokenCodeType curToken;
  48. extern char wordString[];
  49. extern SymTableNodePtr symTableDisplay[];
  50. extern long level;
  51. extern bool blockFlag;
  52. extern BlockType blockType;
  53. extern bool printFlag;
  54. extern SymTableNodePtr CurModuleIdPtr;
  55. extern SymTableNodePtr CurRoutineIdPtr;
  56. extern long CurModuleHandle;
  57. extern bool CallModuleInit;
  58. extern long FileNumber;
  59. extern Type DummyType;
  60. extern char* codeBuffer;
  61. extern char* codeBufferPtr;
  62. extern StackItem* stack;
  63. //extern StackItem* eternalStack;
  64. extern StackItemPtr tos;
  65. extern StackItemPtr stackFrameBasePtr;
  66. extern long eternalOffset;
  67. extern TokenCodeType statementStartList[];
  68. extern TokenCodeType statementEndList[];
  69. extern TokenCodeType declarationStartList[];
  70. extern char tokenString[MAXLEN_TOKENSTRING];
  71. extern CharCodeType charTable[256];
  72. extern ABLFile* sourceFile;
  73. extern char sourceBuffer[MAXLEN_SOURCELINE];
  74. extern long bufferOffset;
  75. extern char* bufferp;
  76. extern char* tokenp;
  77. extern long digitCount;
  78. extern bool countError;
  79. extern bool eofFlag;
  80. extern long pageNumber;
  81. extern SymTableNodePtr SymTableDisplay[MAX_NESTING_LEVEL];
  82. extern TypePtr IntegerTypePtr;
  83. extern TypePtr RealTypePtr;
  84. extern TypePtr BooleanTypePtr;
  85. extern unsigned long* OrderCompletionFlags;
  86. extern StackItemPtr StaticDataPtr;
  87. extern StackItem returnValue;
  88. extern DebuggerPtr debugger;
  89. extern long* EternalVariablesSizes;
  90. //-----------------------
  91. // CLASS static variables
  92. long NumModules = 0;
  93. //-----------------
  94. // GLOBAL variables
  95. ModuleEntryPtr ModuleRegistry = NULL;
  96. ABLModulePtr* ModuleInstanceRegistry = NULL;
  97. long MaxModules = 0;
  98. long NumModulesRegistered = 0;
  99. long NumModuleInstances = 0;
  100. long MaxWatchesPerModule = 20;
  101. long MaxBreakPointsPerModule = 20;
  102. ABLModulePtr CurModule = NULL;
  103. ABLModulePtr CurFSM = NULL;
  104. ABLModulePtr CurLibrary = NULL;
  105. ABLModulePtr* LibraryInstanceRegistry = NULL;
  106. long NumStateTransitions = 0;
  107. long MaxLibraries = 0;
  108. bool NewStateSet = false;
  109. extern long numLibrariesLoaded;
  110. extern long NumExecutions;
  111. long CallStackLevel = 0;
  112. #define MAX_PROFILE_LINELEN 128
  113. #define MAX_PROFILE_LINES 256
  114. long NumProfileLogLines = 0;
  115. long TotalProfileLogLines = 0;
  116. char ProfileLogBuffer[MAX_PROFILE_LINES][MAX_PROFILE_LINELEN];
  117. ABLFile* ProfileLog = NULL;
  118. long ProfileLogFunctionTimeLimit = 5;
  119. UserFilePtr UserFile::files[MAX_USER_FILES];
  120. //***************************************************************************
  121. // PROFILING LOG routines
  122. //***************************************************************************
  123. void DumpProfileLog (void) {
  124. //----------------
  125. // Dump to file...
  126. for (long i = 0; i < NumProfileLogLines; i++)
  127. ProfileLog->writeString(ProfileLogBuffer[i]);
  128. NumProfileLogLines = 0;
  129. }
  130. //---------------------------------------------------------------------------
  131. void ABL_CloseProfileLog (void) {
  132. if (ProfileLog)
  133. {
  134. DumpProfileLog();
  135. char s[512];
  136. sprintf(s, "\nNum Total Lines = %d\n", TotalProfileLogLines);
  137. ProfileLog->writeString(s);
  138. ProfileLog->close();
  139. delete ProfileLog;
  140. ProfileLog = NULL;
  141. NumProfileLogLines = 0;
  142. TotalProfileLogLines = 0;
  143. }
  144. }
  145. //---------------------------------------------------------------------------
  146. void ABL_OpenProfileLog (void) {
  147. if (ProfileLog)
  148. ABL_CloseProfileLog();
  149. NumProfileLogLines = 0;
  150. ProfileLog = new ABLFile;
  151. if (!ProfileLog)
  152. ABL_Fatal(0, " unable to malloc ABL ProfileLog ");
  153. if (ProfileLog->create("abl.log") != ABL_NO_ERR)
  154. ABL_Fatal(0, " unable to create ABL ProfileLog ");
  155. }
  156. //---------------------------------------------------------------------------
  157. void ABL_AddToProfileLog (char* profileString) {
  158. if (NumProfileLogLines == MAX_PROFILE_LINES)
  159. DumpProfileLog();
  160. strncpy(ProfileLogBuffer[NumProfileLogLines], profileString, MAX_PROFILE_LINELEN - 1);
  161. ProfileLogBuffer[NumProfileLogLines][MAX_PROFILE_LINELEN] = NULL;
  162. NumProfileLogLines++;
  163. TotalProfileLogLines++;
  164. }
  165. //***************************************************************************
  166. // USER FILE routines
  167. //***************************************************************************
  168. void* UserFile::operator new (size_t mySize) {
  169. void* result = NULL;
  170. result = ABLSystemMallocCallback(mySize);
  171. return(result);
  172. }
  173. //---------------------------------------------------------------------------
  174. void UserFile::operator delete (void* us) {
  175. ABLSystemFreeCallback(us);
  176. }
  177. //---------------------------------------------------------------------------
  178. void UserFile::dump (void) {
  179. //----------------
  180. // Dump to file...
  181. for (long i = 0; i < numLines; i++)
  182. filePtr->writeString(lines[i]);
  183. numLines = 0;
  184. }
  185. //---------------------------------------------------------------------------
  186. void UserFile::close (void) {
  187. if (filePtr && inUse) {
  188. dump();
  189. char s[512];
  190. sprintf(s, "\nNum Total Lines = %d\n", totalLines);
  191. filePtr->writeString(s);
  192. filePtr->close();
  193. inUse = false;
  194. numLines = 0;
  195. totalLines = 0;
  196. }
  197. }
  198. //---------------------------------------------------------------------------
  199. long UserFile::open (char* fileName) {
  200. numLines = 0;
  201. totalLines = 0;
  202. if (filePtr->create(fileName) != ABL_NO_ERR)
  203. return(-1);
  204. inUse = true;
  205. return(0);
  206. }
  207. //---------------------------------------------------------------------------
  208. void UserFile::write (char* s) {
  209. static char buffer[MAX_USER_FILE_LINELEN];
  210. if (numLines == MAX_USER_FILE_LINES)
  211. dump();
  212. if (strlen(s) > (MAX_USER_FILE_LINELEN - 1))
  213. s[MAX_USER_FILE_LINELEN - 1] = NULL;
  214. sprintf(buffer, "%s\n", s);
  215. strncpy(lines[numLines], buffer, MAX_USER_FILE_LINELEN - 1);
  216. numLines++;
  217. totalLines++;
  218. }
  219. //---------------------------------------------------------------------------
  220. UserFile* UserFile::getNewFile (void) {
  221. long fileHandle = -1;
  222. for (long i = 0; i < MAX_USER_FILES; i++)
  223. if (!files[i]->inUse) {
  224. fileHandle = i;
  225. break;
  226. }
  227. return(files[i]);
  228. }
  229. //---------------------------------------------------------------------------
  230. void UserFile::setup (void) {
  231. for (long i = 0; i < MAX_USER_FILES; i++) {
  232. files[i] = (UserFile*)ABLSystemMallocCallback(sizeof(UserFile));
  233. files[i]->init();
  234. files[i]->handle = i;
  235. files[i]->inUse = false;
  236. files[i]->filePtr = new ABLFile;
  237. if (!files[i]->filePtr)
  238. ABL_Fatal(0, " ABL: Unable to malloc UserFiles ");
  239. }
  240. }
  241. //---------------------------------------------------------------------------
  242. void UserFile::cleanup (void) {
  243. for (long i = 0; i < MAX_USER_FILES; i++)
  244. {
  245. if (files[i]) {
  246. if (files[i]->inUse)
  247. files[i]->close();
  248. //Should actually free the memory allocated above here!
  249. delete files[i]->filePtr;
  250. files[i]->filePtr = NULL;
  251. ABLSystemFreeCallback(files[i]);
  252. files[i] = NULL;
  253. }
  254. }
  255. }
  256. //***************************************************************************
  257. // MODULE REGISTRY routines
  258. //***************************************************************************
  259. void initModuleRegistry (long maxModules) {
  260. //---------------------------------------------------------------------
  261. // First, set the max number of modules that may be loaded into the ABL
  262. // environment at a time...
  263. MaxModules = maxModules;
  264. //------------------------------
  265. // Create the module registry...
  266. ModuleRegistry = (ModuleEntryPtr)ABLStackMallocCallback(sizeof(ModuleEntry) * MaxModules);
  267. if (!ModuleRegistry)
  268. ABL_Fatal(0, " ABL: Unable to AblStackHeap->malloc Module Registry ");
  269. memset(ModuleRegistry, 0, sizeof(ModuleEntry) * MaxModules);
  270. //-------------------------------------------------
  271. // Create the active (ABLModule) module registry...
  272. ModuleInstanceRegistry = (ABLModulePtr*)ABLStackMallocCallback(sizeof(ABLModulePtr) * MaxModules);
  273. if (!ModuleInstanceRegistry)
  274. ABL_Fatal(0, " ABL: Unable to malloc AblStackHeap->Module Instance Registry ");
  275. memset(ModuleInstanceRegistry, 0, sizeof(ABLModulePtr) * MaxModules);
  276. }
  277. //***************************************************************************
  278. void destroyModuleRegistry (void) {
  279. //-----------------------------------------------------------
  280. // First, go through the registry, free'n each module and its
  281. // associated data...
  282. for (long i = 0; i < NumModulesRegistered; i++) {
  283. ABLStackFreeCallback(ModuleRegistry[i].fileName);
  284. ModuleRegistry[i].fileName = NULL;
  285. ModuleRegistry[i].moduleIdPtr = NULL;
  286. for (long j = 0; j < ModuleRegistry[i].numSourceFiles; j++) {
  287. ABLStackFreeCallback(ModuleRegistry[i].sourceFiles[j]);
  288. ModuleRegistry[i].sourceFiles[j] = NULL;
  289. }
  290. }
  291. ABLStackFreeCallback(ModuleRegistry);
  292. ModuleRegistry = NULL;
  293. ABLStackFreeCallback(ModuleInstanceRegistry);
  294. ModuleInstanceRegistry = NULL;
  295. }
  296. //***************************************************************************
  297. // LIBRARY REGISTRY routines
  298. //***************************************************************************
  299. void initLibraryRegistry (long maxLibraries) {
  300. //-----------------------------------------------------------------------
  301. // First, set the max number of libraries that may be loaded into the ABL
  302. // environment at a time...
  303. MaxLibraries = maxLibraries;
  304. //--------------------------------------------------
  305. // Create the active (ABLModule) library registry...
  306. LibraryInstanceRegistry = (ABLModulePtr*)ABLStackMallocCallback(sizeof(ABLModulePtr) * MaxLibraries);
  307. if (!LibraryInstanceRegistry)
  308. ABL_Fatal(0, " ABL: Unable to malloc AblStackHeap->Library Instance Registry ");
  309. memset(LibraryInstanceRegistry, 0, sizeof(ABLModulePtr) * MaxLibraries);
  310. }
  311. //***************************************************************************
  312. void destroyLibraryRegistry (void) {
  313. //-----------------------------------------------------------------
  314. // Kinda need to do the same thing here as in the normal Registry.
  315. // Or leak o RAMA!!!!!!!
  316. // The actual data held by the pointer is removed in destroyModuleRegistry.
  317. // However, the classes holding the actual ABLModulePtr are then responsible
  318. // for deleting the ABLModulePtr. Libraries have no owner class which, I'm guessing,
  319. // this class was supposed to do. This class now does that!!!!
  320. // -fs 1/25/98
  321. for (long i=0;i<numLibrariesLoaded;i++)
  322. {
  323. delete LibraryInstanceRegistry[i];
  324. LibraryInstanceRegistry[i] = NULL;
  325. }
  326. ABLStackFreeCallback(LibraryInstanceRegistry);
  327. LibraryInstanceRegistry = NULL;
  328. }
  329. //***************************************************************************
  330. // ABLMODULE class
  331. //***************************************************************************
  332. void* ABLModule::operator new (size_t mySize) {
  333. void* result = NULL;
  334. result = ABLSystemMallocCallback(mySize);
  335. return(result);
  336. }
  337. //---------------------------------------------------------------------------
  338. void ABLModule::operator delete (void* us) {
  339. ABLSystemFreeCallback(us);
  340. }
  341. //---------------------------------------------------------------------------
  342. long ABLModule::getRealId (void)
  343. {
  344. //Scan through the ModuleInstanceRegistry and find the pointer that matches
  345. // this. DO NOT COUNT ANY NULLs!!!! These will go away when we reload a
  346. // QuickSave!!
  347. long actualCount = 0;
  348. bool foundBrain = false;
  349. for (long i=0;i<NumModuleInstances;i++)
  350. {
  351. if (this == ModuleInstanceRegistry[i])
  352. {
  353. foundBrain = true;
  354. break;
  355. }
  356. if (ModuleInstanceRegistry[i])
  357. actualCount++;
  358. }
  359. if (!foundBrain)
  360. ABL_Fatal(0,"Could not find this Brain in the ModuleInstanceRegistry");
  361. return actualCount;
  362. }
  363. //---------------------------------------------------------------------------
  364. long ABLModule::init (long moduleHandle) {
  365. if (moduleHandle == -1) {
  366. //----------
  367. // Clean up!
  368. return(-1);
  369. }
  370. id = NumModules++;
  371. handle = moduleHandle;
  372. staticData = NULL;
  373. long numStatics = ModuleRegistry[handle].numStaticVars;
  374. if (numStatics) {
  375. staticData = (StackItemPtr)ABLStackMallocCallback(sizeof(StackItem) * numStatics);
  376. if (!staticData) {
  377. char err[255];
  378. sprintf(err, "ABL: Unable to AblStackHeap->malloc staticData [Module %d]", id);
  379. ABL_Fatal(0, err);
  380. }
  381. long* sizeList = ModuleRegistry[handle].sizeStaticVars;
  382. for (long i = 0; i < numStatics; i++)
  383. if (sizeList[i] > 0) {
  384. staticData[i].address = (char*)ABLStackMallocCallback(sizeList[i]);
  385. if (!staticData) {
  386. char err[255];
  387. sprintf(err, "ABL: Unable to AblStackHeap->malloc staticData address [Module %d]", id);
  388. ABL_Fatal(0, err);
  389. }
  390. }
  391. else
  392. staticData[i].integer = 0;
  393. }
  394. if (ModuleRegistry[handle].numOrderCalls) {
  395. long numLongs = 1 + ModuleRegistry[handle].numOrderCalls / 32;
  396. orderCallFlags = (unsigned long*)ABLStackMallocCallback(sizeof(unsigned long) * numLongs);
  397. if (!orderCallFlags) {
  398. char err[255];
  399. sprintf(err, "ABL: Unable to AblStackHeap->malloc orderCallFlags [Module %d]", id);
  400. ABL_Fatal(0, err);
  401. }
  402. for (long i = 0; i < numLongs; i++)
  403. orderCallFlags[i] = 0;
  404. }
  405. ModuleRegistry[handle].numInstances++;
  406. initCalled = false;
  407. //------------------------------------------------------
  408. // This Active Module is now on the instance registry...
  409. ModuleInstanceRegistry[NumModuleInstances++] = this;
  410. if (debugger) {
  411. watchManager = new WatchManager;
  412. if (!watchManager)
  413. ABL_Fatal(0, " Unable to AblStackHeap->malloc WatchManager ");
  414. long result = watchManager->init(MaxWatchesPerModule);
  415. if (result != ABL_NO_ERR)
  416. ABL_Fatal(0, " Unable to AblStackHeap->malloc WatchManager ");
  417. breakPointManager = new BreakPointManager;
  418. if (!breakPointManager)
  419. ABL_Fatal(0, " Unable to AblStackHeap->malloc BreakPointManager ");
  420. result = breakPointManager->init(MaxBreakPointsPerModule);
  421. if (result != ABL_NO_ERR)
  422. ABL_Fatal(0, " Unable to AblStackHeap->malloc BreakPointManager ");
  423. }
  424. if (ModuleRegistry[handle].moduleIdPtr->defn.info.routine.flags & ROUTINE_FLAG_FSM) {
  425. //--------------------------------
  426. // Always starts in START state...
  427. SymTableNodePtr startState = searchSymTable("start", ModuleRegistry[handle].moduleIdPtr->defn.info.routine.localSymTable);
  428. if (!startState) {
  429. char err[255];
  430. sprintf(err, "ABL: FSM has no Start state [%s]", CurModule->getName());
  431. ABL_Fatal(0, err);
  432. }
  433. prevState = NULL;
  434. state = startState;
  435. }
  436. //--------------------
  437. // Can this ever fail?
  438. return(ABL_NO_ERR);
  439. }
  440. //---------------------------------------------------------------------------
  441. void ABLModule::write (ABLFile* moduleFile) {
  442. moduleFile->writeString(name);
  443. moduleFile->writeByte(NULL);
  444. moduleFile->writeLong(handle);
  445. if (prevState == NULL)
  446. moduleFile->writeString("NULLPrevState");
  447. else
  448. moduleFile->writeString(prevState->name);
  449. moduleFile->writeByte(NULL);
  450. if (state == NULL)
  451. moduleFile->writeString("NULLState");
  452. else
  453. moduleFile->writeString(state->name);
  454. moduleFile->writeByte(NULL);
  455. moduleFile->writeLong(initCalled ? 1 : 0);
  456. long numStatics = ModuleRegistry[handle].numStaticVars;
  457. long* sizeList = ModuleRegistry[handle].sizeStaticVars;
  458. for (long i = 0; i < numStatics; i++) {
  459. if (sizeList[i] > 0)
  460. moduleFile->write((unsigned char*)staticData[i].address, sizeList[i]);
  461. else
  462. moduleFile->write((unsigned char*)&staticData[i], sizeof(StackItem));
  463. }
  464. }
  465. //---------------------------------------------------------------------------
  466. void ABLModule::read (ABLFile* moduleFile) {
  467. //----------------------------------------------------------------------------
  468. // If this is called on a newly init'd module, then it will do all appropriate
  469. // memory alloc, etc. If it's being called on a module that's already been
  470. // setup (via a call to init(moduleHandle)), then it simply loads the
  471. // module's data...
  472. bool fresh = (id == -1);
  473. if (fresh) {
  474. id = NumModules++;
  475. moduleFile->readString((unsigned char*)name);
  476. handle = moduleFile->readLong();
  477. staticData = NULL;
  478. }
  479. else {
  480. char tempName[1024];
  481. moduleFile->readString((unsigned char*)tempName);
  482. long ignore = moduleFile->readLong();
  483. }
  484. char stateName[256];
  485. memset(stateName,0,256);
  486. moduleFile->readString((unsigned char*)stateName);
  487. prevState = NULL;
  488. if (strcmp(stateName, "NULLPrevState"))
  489. prevState = findState(stateName);
  490. memset(stateName,0,256);
  491. moduleFile->readString((unsigned char*)stateName);
  492. state = NULL;
  493. if (strcmp(stateName, "NULLState"))
  494. state = findState(stateName);
  495. bool savedInitCalled = (moduleFile->readLong() == 1);
  496. long numStatics = ModuleRegistry[handle].numStaticVars;
  497. if (numStatics) {
  498. if (fresh) {
  499. staticData = (StackItemPtr)ABLStackMallocCallback(sizeof(StackItem) * numStatics);
  500. if (!staticData) {
  501. char err[255];
  502. sprintf(err, "ABL: Unable to AblStackHeap->malloc staticData [Module %d]", id);
  503. ABL_Fatal(0, err);
  504. }
  505. }
  506. long* sizeList = ModuleRegistry[handle].sizeStaticVars;
  507. for (long i = 0; i < numStatics; i++)
  508. if (sizeList[i] > 0) {
  509. if (fresh) {
  510. staticData[i].address = (char*)ABLStackMallocCallback(sizeList[i]);
  511. if (!staticData) {
  512. char err[255];
  513. sprintf(err, "ABL: Unable to AblStackHeap->malloc staticData address [Module %d]", id);
  514. ABL_Fatal(0, err);
  515. }
  516. }
  517. long result = moduleFile->read((unsigned char*)staticData[i].address, sizeList[i]);
  518. if (!result) {
  519. char err[255];
  520. sprintf(err, "ABL: Unable to read staticData.address [Module %d]", id);
  521. ABL_Fatal(0, err);
  522. }
  523. }
  524. else {
  525. staticData[i].integer = 0;
  526. long result = moduleFile->read((unsigned char*)&staticData[i], sizeof(StackItem));
  527. if (!result) {
  528. char err[255];
  529. sprintf(err, "ABL: Unable to read staticData [Module %d]", id);
  530. ABL_Fatal(0, err);
  531. }
  532. }
  533. }
  534. if (ModuleRegistry[handle].numOrderCalls) {
  535. long numLongs = 1 + ModuleRegistry[handle].numOrderCalls / 32;
  536. orderCallFlags = (unsigned long*)ABLStackMallocCallback(sizeof(unsigned long) * numLongs);
  537. if (!orderCallFlags) {
  538. char err[255];
  539. sprintf(err, "ABLModule.read: Unable to AblStackHeap->malloc orderCallFlags [Module %d]", id);
  540. ABL_Fatal(0, err);
  541. }
  542. for (long i = 0; i < numLongs; i++)
  543. orderCallFlags[i] = 0;
  544. }
  545. if (fresh) {
  546. ModuleRegistry[handle].numInstances++;
  547. initCalled = savedInitCalled;
  548. //------------------------------------------------------
  549. // This Active Module is now on the instance registry...
  550. ModuleInstanceRegistry[NumModuleInstances++] = this;
  551. if (debugger) {
  552. watchManager = new WatchManager;
  553. if (!watchManager)
  554. ABL_Fatal(0, " Unable to AblStackHeap->malloc WatchManager ");
  555. long result = watchManager->init(MaxWatchesPerModule);
  556. if (result != ABL_NO_ERR)
  557. ABL_Fatal(0, " Unable to AblStackHeap->malloc WatchManager ");
  558. breakPointManager = new BreakPointManager;
  559. if (!breakPointManager)
  560. ABL_Fatal(0, " Unable to AblStackHeap->malloc BreakPointManager ");
  561. result = breakPointManager->init(MaxBreakPointsPerModule);
  562. if (result != ABL_NO_ERR)
  563. ABL_Fatal(0, " Unable to AblStackHeap->malloc BreakPointManager ");
  564. }
  565. }
  566. }
  567. //---------------------------------------------------------------------------
  568. char* ABLModule::getFileName (void) {
  569. return(ModuleRegistry[handle].fileName);
  570. }
  571. //---------------------------------------------------------------------------
  572. void ABLModule::setName (char* _name) {
  573. strncpy(name, _name, MAX_ABLMODULE_NAME);
  574. name[MAX_ABLMODULE_NAME] = NULL;
  575. }
  576. //---------------------------------------------------------------------------
  577. bool ABLModule::isLibrary (void) {
  578. return(ModuleRegistry[handle].moduleIdPtr->library != NULL);
  579. }
  580. //---------------------------------------------------------------------------
  581. void ABLModule::resetOrderCallFlags (void) {
  582. if (ModuleRegistry[handle].numOrderCalls == 0)
  583. return;
  584. long numLongs = 1 + ModuleRegistry[handle].numOrderCalls / 32;
  585. for (long i = 0; i < numLongs; i++)
  586. orderCallFlags[i] = 0;
  587. }
  588. //---------------------------------------------------------------------------
  589. void ABLModule::setOrderCallFlag (unsigned char dword, unsigned char bit) {
  590. orderCallFlags[dword] |= (1 << bit);
  591. }
  592. //---------------------------------------------------------------------------
  593. void ABLModule::clearOrderCallFlag(unsigned char dword, unsigned char bit) {
  594. orderCallFlags[dword] &= ((1 << bit) ^ 0xFFFFFFFF);
  595. }
  596. //---------------------------------------------------------------------------
  597. long ABLModule::getPrevStateHandle (void) {
  598. if (!prevState)
  599. return(0);
  600. for (long i = 0; i < ModuleRegistry[handle].numStateHandles; i++)
  601. if (strcmp(prevState->name, ModuleRegistry[handle].stateHandles[i].name) == 0)
  602. return(i);
  603. return(0);
  604. }
  605. //---------------------------------------------------------------------------
  606. long ABLModule::getStateHandle (void) {
  607. if (!state)
  608. return(0);
  609. for (long i = 0; i < ModuleRegistry[handle].numStateHandles; i++)
  610. if (strcmp(state->name, ModuleRegistry[handle].stateHandles[i].name) == 0)
  611. return(i);
  612. return(0);
  613. }
  614. //---------------------------------------------------------------------------
  615. long ABLModule::execute (ABLParamPtr paramList) {
  616. CurModule = this;
  617. if (debugger)
  618. debugger->setModule(this);
  619. //--------------------------
  620. // Execute the ABL module...
  621. SymTableNodePtr moduleIdPtr = ModuleRegistry[handle].moduleIdPtr;
  622. if (moduleIdPtr->defn.info.routine.flags & ROUTINE_FLAG_FSM)
  623. CurFSM = this;
  624. else
  625. CurFSM = NULL;
  626. NumStateTransitions = 0;
  627. //--------------------------------------------
  628. // Point to this module's static data space...
  629. StaticDataPtr = staticData;
  630. OrderCompletionFlags = orderCallFlags;
  631. //---------------------------------
  632. // Init some important variables...
  633. CurModuleIdPtr = NULL;
  634. CurRoutineIdPtr = NULL;
  635. FileNumber = -1;
  636. errorCount = 0;
  637. execStatementCount = 0;
  638. NumExecutions++;
  639. //------------------
  640. // Init the stack...
  641. stackFrameBasePtr = tos = (stack + eternalOffset);
  642. //---------------------------------------
  643. // Initialize the module's stack frame...
  644. level = 1;
  645. CallStackLevel = 0;
  646. stackFrameBasePtr = tos + 1;
  647. //-------------------------
  648. // Function return value...
  649. pushInteger(0);
  650. //---------------
  651. // Static Link...
  652. pushAddress(NULL);
  653. //----------------
  654. // Dynamic Link...
  655. pushAddress(NULL);
  656. //------------------
  657. // Return Address...
  658. pushAddress(NULL);
  659. //initDebugger();
  660. //----------
  661. // Run it...
  662. if (paramList) {
  663. //------------------------------------------------------------------------------
  664. // NOTE: Currently, parameter passing of arrays is not functioning. This MUST be
  665. // done...
  666. long curParam = 0;
  667. for (SymTableNodePtr formalIdPtr = (SymTableNodePtr)(moduleIdPtr->defn.info.routine.params);
  668. formalIdPtr != NULL;
  669. formalIdPtr = formalIdPtr->next) {
  670. TypePtr formalTypePtr = (TypePtr)(formalIdPtr->typePtr);
  671. if (formalIdPtr->defn.key == DFN_VALPARAM) {
  672. if (formalTypePtr == RealTypePtr) {
  673. if (paramList[curParam].type == ABL_PARAM_INTEGER) {
  674. //---------------------------------------------
  675. // Real formal parameter, but integer actual...
  676. pushReal((float)(paramList[curParam].integer));
  677. }
  678. else if (paramList[curParam].type == ABL_PARAM_REAL)
  679. pushReal(paramList[curParam].real);
  680. }
  681. else if (formalTypePtr == IntegerTypePtr) {
  682. if (paramList[curParam].type== ABL_PARAM_INTEGER)
  683. pushInteger(paramList[curParam].integer);
  684. else
  685. return(0);
  686. }
  687. //----------------------------------------------------------
  688. // Formal parameter is an array or record, so make a copy...
  689. if ((formalTypePtr->form == FRM_ARRAY)/* || (formalTypePtr->form == FRM_RECORD)*/) {
  690. //------------------------------------------------------------------------------
  691. // The following is a little inefficient, but is kept this way to keep it clear.
  692. // Once it's verified to work, optimize...
  693. long size = formalTypePtr->size;
  694. char* dest = (char*)ABLStackMallocCallback((size_t)size);
  695. if (!dest) {
  696. char err[255];
  697. sprintf(err, "ABL: Unable to AblStackHeap->malloc array parameter [Module %d]", id);
  698. ABL_Fatal(0, err);
  699. }
  700. char* src = tos->address;
  701. char* savePtr = dest;
  702. memcpy(dest, src, size);
  703. tos->address = savePtr;
  704. }
  705. }
  706. else {
  707. //-------------------------------
  708. // pass by reference parameter...
  709. if (formalTypePtr == RealTypePtr)
  710. pushAddress((Address)&(paramList[curParam].real));
  711. else if (formalTypePtr == IntegerTypePtr)
  712. pushAddress((Address)&(paramList[curParam].integer));
  713. else
  714. return(0);
  715. //SymTableNodePtr idPtr = getCodeSymTableNodePtr();
  716. //execVariable(idPtr, USE_REFPARAM);
  717. }
  718. curParam++;
  719. }
  720. }
  721. CurModuleHandle = handle;
  722. //--------------------------------------------------------------------
  723. // No init function in FSM. Put all init stuff into the start state...
  724. CallModuleInit = !initCalled;
  725. initCalled = true;
  726. NewStateSet = false;
  727. ::execute(moduleIdPtr);
  728. memcpy(&returnVal, &returnValue, sizeof(StackItem));
  729. //-----------
  730. // Summary...
  731. return(execStatementCount);
  732. }
  733. //---------------------------------------------------------------------------
  734. long ABLModule::execute (ABLParamPtr moduleParamList, SymTableNodePtr functionIdPtr) {
  735. CurModule = this;
  736. if (debugger)
  737. debugger->setModule(this);
  738. //--------------------------
  739. // Execute the ABL module...
  740. SymTableNodePtr moduleIdPtr = ModuleRegistry[handle].moduleIdPtr;
  741. if (moduleIdPtr->defn.info.routine.flags & ROUTINE_FLAG_FSM)
  742. CurFSM = this;
  743. else
  744. CurFSM = NULL;
  745. NumStateTransitions = 0;
  746. //--------------------------------------------
  747. // Point to this module's static data space...
  748. StaticDataPtr = staticData;
  749. OrderCompletionFlags = orderCallFlags;
  750. //---------------------------------
  751. // Init some important variables...
  752. CurModuleIdPtr = NULL;
  753. CurRoutineIdPtr = NULL;
  754. FileNumber = -1;
  755. errorCount = 0;
  756. execStatementCount = 0;
  757. NumExecutions++;
  758. NewStateSet = false;
  759. //------------------
  760. // Init the stack...
  761. stackFrameBasePtr = tos = (stack + eternalOffset);
  762. //---------------------------------------
  763. // Initialize the module's stack frame...
  764. level = 1;
  765. CallStackLevel = 0;
  766. stackFrameBasePtr = tos + 1;
  767. //-------------------------
  768. // Function return value...
  769. pushInteger(0);
  770. //---------------
  771. // Static Link...
  772. pushAddress(NULL);
  773. //----------------
  774. // Dynamic Link...
  775. pushAddress(NULL);
  776. //------------------
  777. // Return Address...
  778. pushAddress(NULL);
  779. //initDebugger();
  780. //----------
  781. // Run it...
  782. if (moduleParamList) {
  783. //------------------------------------------------------------------------------
  784. // NOTE: Currently, parameter passing of arrays is not functioning. This MUST be
  785. // done...
  786. long curParam = 0;
  787. for (SymTableNodePtr formalIdPtr = (SymTableNodePtr)(moduleIdPtr->defn.info.routine.params);
  788. formalIdPtr != NULL;
  789. formalIdPtr = formalIdPtr->next) {
  790. TypePtr formalTypePtr = (TypePtr)(formalIdPtr->typePtr);
  791. if (formalIdPtr->defn.key == DFN_VALPARAM) {
  792. if (formalTypePtr == RealTypePtr) {
  793. if (moduleParamList[curParam].type == ABL_PARAM_INTEGER) {
  794. //---------------------------------------------
  795. // Real formal parameter, but integer actual...
  796. pushReal((float)(moduleParamList[curParam].integer));
  797. }
  798. else if (moduleParamList[curParam].type == ABL_PARAM_REAL)
  799. pushReal(moduleParamList[curParam].real);
  800. }
  801. else if (formalTypePtr == IntegerTypePtr) {
  802. if (moduleParamList[curParam].type== ABL_PARAM_INTEGER)
  803. pushInteger(moduleParamList[curParam].integer);
  804. else
  805. return(0);
  806. }
  807. //----------------------------------------------------------
  808. // Formal parameter is an array or record, so make a copy...
  809. if ((formalTypePtr->form == FRM_ARRAY)/* || (formalTypePtr->form == FRM_RECORD)*/) {
  810. //------------------------------------------------------------------------------
  811. // The following is a little inefficient, but is kept this way to keep it clear.
  812. // Once it's verified to work, optimize...
  813. long size = formalTypePtr->size;
  814. char* dest = (char*)ABLStackMallocCallback((size_t)size);
  815. if (!dest) {
  816. char err[255];
  817. sprintf(err, "ABL: Unable to AblStackHeap->malloc array parameter [Module %d]", id);
  818. ABL_Fatal(0, err);
  819. }
  820. char* src = tos->address;
  821. char* savePtr = dest;
  822. memcpy(dest, src, size);
  823. tos->address = savePtr;
  824. }
  825. }
  826. else {
  827. //-------------------------------
  828. // pass by reference parameter...
  829. if (formalTypePtr == RealTypePtr)
  830. pushAddress((Address)&(moduleParamList[curParam].real));
  831. else if (formalTypePtr == IntegerTypePtr)
  832. pushAddress((Address)&(moduleParamList[curParam].integer));
  833. else
  834. return(0);
  835. }
  836. curParam++;
  837. }
  838. }
  839. CurModuleHandle = handle;
  840. CallModuleInit = !initCalled;
  841. initCalled = true;
  842. ::executeChild(moduleIdPtr, functionIdPtr);
  843. memcpy(&returnVal, &returnValue, sizeof(StackItem));
  844. //-----------
  845. // Summary...
  846. return(execStatementCount);
  847. }
  848. //---------------------------------------------------------------------------
  849. SymTableNodePtr ABLModule::findSymbol (char* symbolName, SymTableNodePtr curFunction, bool searchLibraries) {
  850. if (curFunction) {
  851. SymTableNodePtr symbol = searchSymTable(strlwr(symbolName), curFunction->defn.info.routine.localSymTable);
  852. if (symbol)
  853. return(symbol);
  854. }
  855. SymTableNodePtr symbol = searchSymTable(strlwr(symbolName), ModuleRegistry[handle].moduleIdPtr->defn.info.routine.localSymTable);
  856. if (!symbol && searchLibraries) {
  857. for (long i = 0; i < ModuleRegistry[handle].numLibrariesUsed; i++) {
  858. symbol = searchSymTable(strlwr(symbolName), ModuleRegistry[ModuleRegistry[handle].librariesUsed[i]->handle].moduleIdPtr->defn.info.routine.localSymTable);
  859. if (symbol)
  860. break;
  861. }
  862. }
  863. return(symbol);
  864. }
  865. //---------------------------------------------------------------------------
  866. SymTableNodePtr ABLModule::findFunction (char* functionName, bool searchLibraries) {
  867. SymTableNodePtr symbol = searchSymTableForFunction(functionName, ModuleRegistry[handle].moduleIdPtr->defn.info.routine.localSymTable);
  868. if (!symbol && searchLibraries)
  869. {
  870. for (long i = 0; i < ModuleRegistry[handle].numLibrariesUsed; i++)
  871. {
  872. char temp[1024];
  873. memset(temp, 0, 1024 );
  874. strncpy( temp, functionName, (strlen(functionName) > 1020) ? 1020 : strlen(functionName) );
  875. symbol = searchSymTable(_strlwr(temp), ModuleRegistry[ModuleRegistry[handle].librariesUsed[i]->handle].moduleIdPtr->defn.info.routine.localSymTable);
  876. if (symbol)
  877. break;
  878. }
  879. }
  880. return(symbol);
  881. }
  882. //---------------------------------------------------------------------------
  883. SymTableNodePtr ABLModule::findState (char* stateName) {
  884. SymTableNodePtr symbol = searchSymTableForState(stateName, ModuleRegistry[handle].moduleIdPtr->defn.info.routine.localSymTable);
  885. return(symbol);
  886. }
  887. //---------------------------------------------------------------------------
  888. long ABLModule::findStateHandle (char* stateName) {
  889. for (long i = 1; i < ModuleRegistry[handle].numStateHandles; i++)
  890. if (strcmp(stateName, ModuleRegistry[handle].stateHandles[i].name) == 0)
  891. return(i);
  892. return(0);
  893. }
  894. //---------------------------------------------------------------------------
  895. long ABLModule::setStaticInteger (char* name, long value) {
  896. SymTableNodePtr symbol = findSymbol(name);
  897. if (!symbol)
  898. return(1);
  899. if (symbol->typePtr != IntegerTypePtr)
  900. return(2);
  901. if (symbol->defn.info.data.varType != VAR_TYPE_STATIC)
  902. return(3);
  903. StackItemPtr dataPtr = staticData + symbol->defn.info.data.offset;
  904. *((long*)dataPtr) = value;
  905. return(0);
  906. }
  907. //---------------------------------------------------------------------------
  908. long ABLModule::getStaticInteger (char* name) {
  909. SymTableNodePtr symbol = findSymbol(name);
  910. if (!symbol)
  911. return(0xFFFFFFFF);
  912. if (symbol->typePtr != IntegerTypePtr)
  913. return(0xFFFFFFFF);
  914. if (symbol->defn.info.data.varType != VAR_TYPE_STATIC)
  915. return(0xFFFFFFFF);
  916. StackItemPtr dataPtr = staticData + symbol->defn.info.data.offset;
  917. return(*((long*)dataPtr));
  918. }
  919. //---------------------------------------------------------------------------
  920. long ABLModule::setStaticReal (char* name, float value) {
  921. SymTableNodePtr symbol = findSymbol(name);
  922. if (!symbol)
  923. return(1);
  924. if (symbol->typePtr != RealTypePtr)
  925. return(2);
  926. if (symbol->defn.info.data.varType != VAR_TYPE_STATIC)
  927. return(3);
  928. StackItemPtr dataPtr = staticData + symbol->defn.info.data.offset;
  929. *((float*)dataPtr) = value;
  930. return(0);
  931. }
  932. //---------------------------------------------------------------------------
  933. float ABLModule::getStaticReal (char* name) {
  934. SymTableNodePtr symbol = findSymbol(name);
  935. if (!symbol)
  936. return(-999999.0);
  937. if (symbol->typePtr != RealTypePtr)
  938. return(-999999.0);
  939. if (symbol->defn.info.data.varType != VAR_TYPE_STATIC)
  940. return(-999999.0);
  941. StackItemPtr dataPtr = staticData + symbol->defn.info.data.offset;
  942. return(*((float*)dataPtr));
  943. }
  944. //---------------------------------------------------------------------------
  945. long ABLModule::setStaticIntegerArray (char* name, long numValues, long* values) {
  946. SymTableNodePtr symbol = findSymbol(name);
  947. if (!symbol)
  948. return(1);
  949. //--------------------------------------------------------------------------
  950. // NOTE: This function is not dummy-proof. Essentially, this routine copies
  951. // the values data into the array's data space WITHOUT checking to make sure
  952. // the array really is an array (single or mult-dimensional) of reals. User
  953. // beware!
  954. if (symbol->defn.info.data.varType != VAR_TYPE_STATIC)
  955. return(3);
  956. StackItemPtr dataPtr = staticData + symbol->defn.info.data.offset;
  957. memcpy(dataPtr->address, values, 4 * numValues);
  958. return(0);
  959. }
  960. //---------------------------------------------------------------------------
  961. long ABLModule::getStaticIntegerArray (char* name, long numValues, long* values) {
  962. SymTableNodePtr symbol = findSymbol(name);
  963. if (!symbol)
  964. return(0);
  965. //--------------------------------------------------------------------------
  966. // NOTE: This function is not dummy-proof. Essentially, this routine copies
  967. // the values data into the array's data space WITHOUT checking to make sure
  968. // the array really is an array (single or mult-dimensional) of reals. User
  969. // beware!
  970. if (symbol->defn.info.data.varType != VAR_TYPE_STATIC)
  971. return(0);
  972. StackItemPtr dataPtr = staticData + symbol->defn.info.data.offset;
  973. memcpy(values, dataPtr->address, 4 * numValues);
  974. return(1);
  975. }
  976. //---------------------------------------------------------------------------
  977. long ABLModule::setStaticRealArray (char* name, long numValues, float* values) {
  978. SymTableNodePtr symbol = findSymbol(name);
  979. if (!symbol)
  980. return(1);
  981. //--------------------------------------------------------------------------
  982. // NOTE: This function is not dummy-proof. Essentially, this routine copies
  983. // the values data into the array's data space WITHOUT checking to make sure
  984. // the array really is an array (single or mult-dimensional) of reals. User
  985. // beware!
  986. if (symbol->defn.info.data.varType != VAR_TYPE_STATIC)
  987. return(3);
  988. StackItemPtr dataPtr = staticData + symbol->defn.info.data.offset;
  989. memcpy(dataPtr->address, values, 4 * numValues);
  990. return(0);
  991. }
  992. //---------------------------------------------------------------------------
  993. long ABLModule::getStaticRealArray (char* name, long numValues, float* values) {
  994. SymTableNodePtr symbol = findSymbol(name);
  995. if (!symbol)
  996. return(0);
  997. //--------------------------------------------------------------------------
  998. // NOTE: This function is not dummy-proof. Essentially, this routine copies
  999. // the values data into the array's data space WITHOUT checking to make sure
  1000. // the array really is an array (single or mult-dimensional) of reals. User
  1001. // beware!
  1002. if (symbol->defn.info.data.varType != VAR_TYPE_STATIC)
  1003. return(0);
  1004. StackItemPtr dataPtr = staticData + symbol->defn.info.data.offset;
  1005. memcpy(values, dataPtr->address, 4 * numValues);
  1006. return(1);
  1007. }
  1008. //---------------------------------------------------------------------------
  1009. char* ABLModule::getSourceFile (long fileNumber) {
  1010. return(ModuleRegistry[handle].sourceFiles[fileNumber]);
  1011. }
  1012. //---------------------------------------------------------------------------
  1013. char* ABLModule::getSourceDirectory (long fileNumber, char* directory) {
  1014. char* fileName = ModuleRegistry[handle].sourceFiles[fileNumber];
  1015. long curChar = strlen(fileName);
  1016. while ((curChar > -1) && (fileName[curChar] != '\\'))
  1017. curChar--;
  1018. if (curChar == -1)
  1019. return(NULL);
  1020. strcpy(directory, fileName);
  1021. directory[curChar + 1] = NULL;
  1022. return(directory);
  1023. }
  1024. //---------------------------------------------------------------------------
  1025. void buildRoutineList (SymTableNodePtr curSymbol, ModuleInfo* moduleInfo) {
  1026. if (curSymbol) {
  1027. buildRoutineList(curSymbol->left, moduleInfo);
  1028. if (curSymbol->defn.key == DFN_FUNCTION) {
  1029. if (moduleInfo->numRoutines < 1024) {
  1030. strcpy(moduleInfo->routineInfo[moduleInfo->numRoutines].name, curSymbol->name);
  1031. moduleInfo->routineInfo[moduleInfo->numRoutines].codeSegmentSize = curSymbol->defn.info.routine.codeSegmentSize;
  1032. moduleInfo->numRoutines++;
  1033. }
  1034. }
  1035. buildRoutineList(curSymbol->right, moduleInfo);
  1036. }
  1037. }
  1038. //---------------------------------------------------------------------------
  1039. void ABLModule::getInfo (ModuleInfo* moduleInfo) {
  1040. strcpy(moduleInfo->name, name);
  1041. strcpy(moduleInfo->fileName, ModuleRegistry[handle].fileName);
  1042. moduleInfo->numRoutines = 0;
  1043. buildRoutineList(ModuleRegistry[handle].moduleIdPtr->defn.info.routine.localSymTable, moduleInfo);
  1044. for (long i = 0; i < moduleInfo->numRoutines; i++)
  1045. moduleInfo->totalCodeSegmentSize += moduleInfo->routineInfo[i].codeSegmentSize;
  1046. moduleInfo->numStaticVars = ModuleRegistry[handle].numStaticVars;
  1047. moduleInfo->totalSizeStaticVars = ModuleRegistry[handle].totalSizeStaticVars;
  1048. long largest = 0;
  1049. for (i = 0; i < moduleInfo->numStaticVars; i++) {
  1050. if (ModuleRegistry[handle].sizeStaticVars[i] > ModuleRegistry[handle].sizeStaticVars[largest])
  1051. largest = i;
  1052. }
  1053. moduleInfo->largestStaticVar.size = 0;
  1054. if (ModuleRegistry[handle].sizeStaticVars)
  1055. moduleInfo->largestStaticVar.size = ModuleRegistry[handle].sizeStaticVars[largest];
  1056. moduleInfo->largestStaticVar.name[0] = NULL;
  1057. }
  1058. //---------------------------------------------------------------------------
  1059. void ABLModule::destroy (void) {
  1060. if ((id > -1) && ModuleInstanceRegistry) {
  1061. //-----------------------------------------------
  1062. // It's on the active registry, so pull it off...
  1063. for (long i = 0; i < NumModuleInstances; i++)
  1064. if (ModuleInstanceRegistry[i] == this) {
  1065. ModuleInstanceRegistry[i] = ModuleInstanceRegistry[NumModuleInstances - 1];
  1066. ModuleInstanceRegistry[NumModuleInstances - 1] = NULL;
  1067. NumModuleInstances--;
  1068. NumModules--;
  1069. break;
  1070. }
  1071. }
  1072. if (watchManager) {
  1073. delete watchManager;
  1074. watchManager = NULL;
  1075. }
  1076. if (breakPointManager) {
  1077. delete breakPointManager;
  1078. breakPointManager = NULL;
  1079. }
  1080. if (staticData) {
  1081. ABLStackFreeCallback(staticData);
  1082. staticData = NULL;
  1083. }
  1084. }
  1085. //***************************************************************************
  1086. // MISC routines
  1087. //***************************************************************************
  1088. void ABLi_saveEnvironment (ABLFile* ablFile) {
  1089. ablFile->writeLong(numLibrariesLoaded);
  1090. ablFile->writeLong(NumModulesRegistered);
  1091. ablFile->writeLong(NumModules);
  1092. for (long i = 0; i < NumModulesRegistered; i++) {
  1093. ablFile->writeString(ModuleRegistry[i].fileName);
  1094. ablFile->writeByte(NULL);
  1095. }
  1096. ablFile->writeLong(999);
  1097. for (i = 0; i < eternalOffset; i++) {
  1098. StackItemPtr dataPtr = (StackItemPtr)stack + i;
  1099. if (EternalVariablesSizes[i] > 0)
  1100. ablFile->write((unsigned char*)dataPtr->address, EternalVariablesSizes[i]);
  1101. else
  1102. ablFile->write((unsigned char*)dataPtr, sizeof(StackItem));
  1103. }
  1104. for (i = 0; i < NumModules; i++)
  1105. {
  1106. if (ModuleInstanceRegistry[i])
  1107. ModuleInstanceRegistry[i]->write(ablFile);
  1108. }
  1109. }
  1110. //---------------------------------------------------------------------------
  1111. void ABLi_loadEnvironment (ABLFile* ablFile, bool malloc) {
  1112. long numLibs = ablFile->readLong();
  1113. long numModsRegistered = ablFile->readLong();
  1114. long numMods = ablFile->readLong();
  1115. for (long i = 0; i < numLibs; i++) {
  1116. unsigned char fileName[1024];
  1117. long result = ablFile->readString(fileName);
  1118. if (!result) {
  1119. char err[255];
  1120. sprintf(err, "ABLi_loadEnvironment: Unable to read filename [Module %d]", i);
  1121. ABL_Fatal(0, err);
  1122. }
  1123. if (malloc) {
  1124. long numErrors, numLinesProcessed;
  1125. ABLModulePtr library = ABLi_loadLibrary((char*)fileName, &numErrors, &numLinesProcessed, NULL, false, false);
  1126. if (!library) {
  1127. char err[255];
  1128. sprintf(err, "ABLi_loadEnvironment: Unable to load library [Module %d]", i);
  1129. ABL_Fatal(0, err);
  1130. }
  1131. }
  1132. }
  1133. for (i = 0; i < (numModsRegistered - numLibs); i++) {
  1134. unsigned char fileName[1024];
  1135. long result = ablFile->readString(fileName);
  1136. if (!result) {
  1137. char err[255];
  1138. sprintf(err, "ABLi_loadEnvironment: Unable to read filename [Module %d]", i);
  1139. ABL_Fatal(0, err);
  1140. }
  1141. long numErrors, numLinesProcessed;
  1142. if (malloc) {
  1143. long handle = ABLi_preProcess((char*)fileName, &numErrors, &numLinesProcessed);
  1144. if (handle < 0) {
  1145. char err[255];
  1146. sprintf(err, "ABLi_loadEnvironment: Unable to preprocess [Module %d]", i);
  1147. ABL_Fatal(0, err);
  1148. }
  1149. }
  1150. }
  1151. long mark = ablFile->readLong();
  1152. for (i = 0; i < eternalOffset; i++) {
  1153. StackItemPtr dataPtr = (StackItemPtr)stack + i;
  1154. if (EternalVariablesSizes[i] > 0)
  1155. ablFile->read((unsigned char*)dataPtr->address, EternalVariablesSizes[i]);
  1156. else
  1157. ablFile->read((unsigned char*)dataPtr, sizeof(StackItem));
  1158. }
  1159. for (i = 0; i < numLibs; i++) {
  1160. ABLModulePtr library = LibraryInstanceRegistry[i];
  1161. library->read(ablFile);
  1162. }
  1163. for (i = 0; i < (numMods - numLibs); i++) {
  1164. ABLModulePtr module = NULL;
  1165. if (malloc)
  1166. module = new ABLModule;
  1167. else
  1168. module = ModuleInstanceRegistry[numLibs + i];
  1169. module->read(ablFile);
  1170. }
  1171. }
  1172. //***************************************************************************