as_restore.cpp 65 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714
  1. /*
  2. AngelCode Scripting Library
  3. Copyright (c) 2003-2011 Andreas Jonsson
  4. This software is provided 'as-is', without any express or implied
  5. warranty. In no event will the authors be held liable for any
  6. damages arising from the use of this software.
  7. Permission is granted to anyone to use this software for any
  8. purpose, including commercial applications, and to alter it and
  9. redistribute it freely, subject to the following restrictions:
  10. 1. The origin of this software must not be misrepresented; you
  11. must not claim that you wrote the original software. If you use
  12. this software in a product, an acknowledgment in the product
  13. documentation would be appreciated but is not required.
  14. 2. Altered source versions must be plainly marked as such, and
  15. must not be misrepresented as being the original software.
  16. 3. This notice may not be removed or altered from any source
  17. distribution.
  18. The original version of this library can be located at:
  19. http://www.angelcode.com/angelscript/
  20. Andreas Jonsson
  21. [email protected]
  22. */
  23. //
  24. // as_restore.cpp
  25. //
  26. // Functions for saving and restoring module bytecode
  27. // asCRestore was originally written by Dennis Bollyn, [email protected]
  28. #include "as_config.h"
  29. #include "as_restore.h"
  30. #include "as_bytecode.h"
  31. #include "as_scriptobject.h"
  32. BEGIN_AS_NAMESPACE
  33. #define WRITE_NUM(N) WriteData(&(N), sizeof(N))
  34. #define READ_NUM(N) ReadData(&(N), sizeof(N))
  35. asCRestore::asCRestore(asCModule* _module, asIBinaryStream* _stream, asCScriptEngine* _engine)
  36. : module(_module), stream(_stream), engine(_engine)
  37. {
  38. error = false;
  39. }
  40. void asCRestore::WriteData(const void *data, asUINT size)
  41. {
  42. asASSERT(size == 1 || size == 2 || size == 4 || size == 8);
  43. #if defined(AS_BIG_ENDIAN)
  44. for( asUINT n = 0; n < size; n++ )
  45. stream->Write(((asBYTE*)data)+n, 1);
  46. #else
  47. for( int n = size-1; n >= 0; n-- )
  48. stream->Write(((asBYTE*)data)+n, 1);
  49. #endif
  50. }
  51. void asCRestore::ReadData(void *data, asUINT size)
  52. {
  53. asASSERT(size == 1 || size == 2 || size == 4 || size == 8);
  54. #if defined(AS_BIG_ENDIAN)
  55. for( asUINT n = 0; n < size; n++ )
  56. stream->Read(((asBYTE*)data)+n, 1);
  57. #else
  58. for( int n = size-1; n >= 0; n-- )
  59. stream->Read(((asBYTE*)data)+n, 1);
  60. #endif
  61. }
  62. int asCRestore::Save()
  63. {
  64. unsigned long i, count;
  65. // TODO: The first thing the code needs to do is build a list of the
  66. // types that are used, so that the function signatures, etc can
  67. // be encoded in a small way.
  68. //
  69. // If only a few types are used, then maybe one byte is enough.
  70. // By using a scheme similar to UTF8 I can support a high number
  71. // of types without sacrifizing space.
  72. // Store everything in the same order that the builder parses scripts
  73. // Store enums
  74. count = (asUINT)module->enumTypes.GetLength();
  75. WriteEncodedUInt(count);
  76. for( i = 0; i < count; i++ )
  77. {
  78. WriteObjectTypeDeclaration(module->enumTypes[i], 1);
  79. WriteObjectTypeDeclaration(module->enumTypes[i], 2);
  80. }
  81. // Store type declarations first
  82. count = (asUINT)module->classTypes.GetLength();
  83. WriteEncodedUInt(count);
  84. for( i = 0; i < count; i++ )
  85. {
  86. // Store only the name of the class/interface types
  87. WriteObjectTypeDeclaration(module->classTypes[i], 1);
  88. }
  89. // Store func defs
  90. count = (asUINT)module->funcDefs.GetLength();
  91. WriteEncodedUInt(count);
  92. for( i = 0; i < count; i++ )
  93. {
  94. WriteFunction(module->funcDefs[i]);
  95. }
  96. // Now store all interface methods
  97. count = (asUINT)module->classTypes.GetLength();
  98. for( i = 0; i < count; i++ )
  99. {
  100. if( module->classTypes[i]->IsInterface() )
  101. WriteObjectTypeDeclaration(module->classTypes[i], 2);
  102. }
  103. // Then store the class methods and behaviours
  104. for( i = 0; i < count; ++i )
  105. {
  106. if( !module->classTypes[i]->IsInterface() )
  107. WriteObjectTypeDeclaration(module->classTypes[i], 2);
  108. }
  109. // Then store the class properties
  110. for( i = 0; i < count; ++i )
  111. {
  112. if( !module->classTypes[i]->IsInterface() )
  113. WriteObjectTypeDeclaration(module->classTypes[i], 3);
  114. }
  115. // Store typedefs
  116. count = (asUINT)module->typeDefs.GetLength();
  117. WriteEncodedUInt(count);
  118. for( i = 0; i < count; i++ )
  119. {
  120. WriteObjectTypeDeclaration(module->typeDefs[i], 1);
  121. WriteObjectTypeDeclaration(module->typeDefs[i], 2);
  122. }
  123. // scriptGlobals[]
  124. count = (asUINT)module->scriptGlobals.GetLength();
  125. WriteEncodedUInt(count);
  126. for( i = 0; i < count; ++i )
  127. WriteGlobalProperty(module->scriptGlobals[i]);
  128. // scriptFunctions[]
  129. count = 0;
  130. for( i = 0; i < module->scriptFunctions.GetLength(); i++ )
  131. if( module->scriptFunctions[i]->objectType == 0 )
  132. count++;
  133. WriteEncodedUInt(count);
  134. for( i = 0; i < module->scriptFunctions.GetLength(); ++i )
  135. if( module->scriptFunctions[i]->objectType == 0 )
  136. WriteFunction(module->scriptFunctions[i]);
  137. // globalFunctions[]
  138. count = (int)module->globalFunctions.GetLength();
  139. WriteEncodedUInt(count);
  140. for( i = 0; i < count; i++ )
  141. {
  142. WriteFunction(module->globalFunctions[i]);
  143. }
  144. // bindInformations[]
  145. count = (asUINT)module->bindInformations.GetLength();
  146. WriteEncodedUInt(count);
  147. for( i = 0; i < count; ++i )
  148. {
  149. WriteFunction(module->bindInformations[i]->importedFunctionSignature);
  150. WriteString(&module->bindInformations[i]->importFromModule);
  151. }
  152. // usedTypes[]
  153. asUINT numValueTypes = 0;
  154. count = (asUINT)usedTypes.GetLength();
  155. WriteEncodedUInt(count);
  156. for( i = 0; i < count; ++i )
  157. {
  158. if( usedTypes[i]->flags & asOBJ_VALUE )
  159. numValueTypes++;
  160. WriteObjectType(usedTypes[i]);
  161. }
  162. // Write the size of value types so the code can be adjusted if they are not the same when reloading the code
  163. WriteEncodedUInt(numValueTypes);
  164. for( i = 0; i < count; i++ )
  165. {
  166. if( usedTypes[i]->flags & asOBJ_VALUE )
  167. {
  168. WriteEncodedUInt(i);
  169. WriteEncodedUInt(usedTypes[i]->GetSize());
  170. }
  171. }
  172. // usedTypeIds[]
  173. WriteUsedTypeIds();
  174. // usedFunctions[]
  175. WriteUsedFunctions();
  176. // usedGlobalProperties[]
  177. WriteUsedGlobalProps();
  178. // usedStringConstants[]
  179. WriteUsedStringConstants();
  180. // usedObjectProperties[]
  181. WriteUsedObjectProps();
  182. return asSUCCESS;
  183. }
  184. int asCRestore::Restore()
  185. {
  186. // Before starting the load, make sure that
  187. // any existing resources have been freed
  188. module->InternalReset();
  189. unsigned long i, count;
  190. asCScriptFunction* func;
  191. // Read enums
  192. count = ReadEncodedUInt();
  193. module->enumTypes.Allocate(count, 0);
  194. for( i = 0; i < count; i++ )
  195. {
  196. asCObjectType *ot = asNEW(asCObjectType)(engine);
  197. ReadObjectTypeDeclaration(ot, 1);
  198. engine->classTypes.PushLast(ot);
  199. module->enumTypes.PushLast(ot);
  200. ot->AddRef();
  201. ReadObjectTypeDeclaration(ot, 2);
  202. }
  203. // classTypes[]
  204. // First restore the structure names, then the properties
  205. count = ReadEncodedUInt();
  206. module->classTypes.Allocate(count, 0);
  207. for( i = 0; i < count; ++i )
  208. {
  209. asCObjectType *ot = asNEW(asCObjectType)(engine);
  210. ReadObjectTypeDeclaration(ot, 1);
  211. engine->classTypes.PushLast(ot);
  212. module->classTypes.PushLast(ot);
  213. ot->AddRef();
  214. // Add script classes to the GC
  215. if( (ot->GetFlags() & asOBJ_SCRIPT_OBJECT) && ot->GetSize() > 0 )
  216. engine->gc.AddScriptObjectToGC(ot, &engine->objectTypeBehaviours);
  217. }
  218. // Read func defs
  219. count = ReadEncodedUInt();
  220. module->funcDefs.Allocate(count, 0);
  221. for( i = 0; i < count; i++ )
  222. {
  223. asCScriptFunction *func = ReadFunction(false, true);
  224. module->funcDefs.PushLast(func);
  225. }
  226. // Read interface methods
  227. for( i = 0; i < module->classTypes.GetLength(); i++ )
  228. {
  229. if( module->classTypes[i]->IsInterface() )
  230. ReadObjectTypeDeclaration(module->classTypes[i], 2);
  231. }
  232. asCArray<void*> substitutions;
  233. module->ResolveInterfaceIds(&substitutions);
  234. // The above method may have replaced the interface object types
  235. // so we must updated this in the savedDataTypes if it is there.
  236. // All the interface methods were also substituted so the
  237. // savedFunctions must also be updated
  238. for( i = 0; i < substitutions.GetLength(); i += 2 )
  239. {
  240. for( asUINT d = 0; d < savedDataTypes.GetLength(); d++ )
  241. {
  242. if( savedDataTypes[d].GetObjectType() == substitutions[i] )
  243. savedDataTypes[d].SetObjectType(reinterpret_cast<asCObjectType*>(substitutions[i+1]));
  244. }
  245. for( asUINT f = 0; f < savedFunctions.GetLength(); f++ )
  246. {
  247. if( savedFunctions[f] == substitutions[i] )
  248. savedFunctions[f] = reinterpret_cast<asCScriptFunction*>(substitutions[i+1]);
  249. }
  250. }
  251. // Read class methods and behaviours
  252. for( i = 0; i < module->classTypes.GetLength(); ++i )
  253. {
  254. if( !module->classTypes[i]->IsInterface() )
  255. ReadObjectTypeDeclaration(module->classTypes[i], 2);
  256. }
  257. // Read class properties
  258. for( i = 0; i < module->classTypes.GetLength(); ++i )
  259. {
  260. if( !module->classTypes[i]->IsInterface() )
  261. ReadObjectTypeDeclaration(module->classTypes[i], 3);
  262. }
  263. // Read typedefs
  264. count = ReadEncodedUInt();
  265. module->typeDefs.Allocate(count, 0);
  266. for( i = 0; i < count; i++ )
  267. {
  268. asCObjectType *ot = asNEW(asCObjectType)(engine);
  269. ReadObjectTypeDeclaration(ot, 1);
  270. engine->classTypes.PushLast(ot);
  271. module->typeDefs.PushLast(ot);
  272. ot->AddRef();
  273. ReadObjectTypeDeclaration(ot, 2);
  274. }
  275. // scriptGlobals[]
  276. count = ReadEncodedUInt();
  277. module->scriptGlobals.Allocate(count, 0);
  278. for( i = 0; i < count; ++i )
  279. {
  280. ReadGlobalProperty();
  281. }
  282. // scriptFunctions[]
  283. count = ReadEncodedUInt();
  284. for( i = 0; i < count; ++i )
  285. {
  286. func = ReadFunction();
  287. }
  288. // globalFunctions[]
  289. count = ReadEncodedUInt();
  290. for( i = 0; i < count; ++i )
  291. {
  292. func = ReadFunction(false, false);
  293. module->globalFunctions.PushLast(func);
  294. func->AddRef();
  295. }
  296. // bindInformations[]
  297. count = ReadEncodedUInt();
  298. module->bindInformations.SetLength(count);
  299. for( i = 0; i < count; ++i )
  300. {
  301. sBindInfo *info = asNEW(sBindInfo);
  302. info->importedFunctionSignature = ReadFunction(false, false);
  303. if( engine->freeImportedFunctionIdxs.GetLength() )
  304. {
  305. int id = engine->freeImportedFunctionIdxs.PopLast();
  306. info->importedFunctionSignature->id = int(FUNC_IMPORTED + id);
  307. engine->importedFunctions[id] = info;
  308. }
  309. else
  310. {
  311. info->importedFunctionSignature->id = int(FUNC_IMPORTED + engine->importedFunctions.GetLength());
  312. engine->importedFunctions.PushLast(info);
  313. }
  314. ReadString(&info->importFromModule);
  315. info->boundFunctionId = -1;
  316. module->bindInformations[i] = info;
  317. }
  318. // usedTypes[]
  319. count = ReadEncodedUInt();
  320. usedTypes.Allocate(count, 0);
  321. for( i = 0; i < count; ++i )
  322. {
  323. asCObjectType *ot = ReadObjectType();
  324. usedTypes.PushLast(ot);
  325. }
  326. // Read the size of the value types so we can determine if it is necessary to adjust the code
  327. asUINT numValueTypes = ReadEncodedUInt();
  328. for( i = 0; i < numValueTypes; ++i )
  329. {
  330. asUINT idx = ReadEncodedUInt();
  331. asUINT size = ReadEncodedUInt();
  332. if( idx >= usedTypes.GetLength() )
  333. {
  334. // TODO: Write error message to the callback
  335. error = true;
  336. continue;
  337. }
  338. if( usedTypes[idx] && size != usedTypes[idx]->GetSize() )
  339. {
  340. // Keep track of the object types that have changed size
  341. // so the bytecode can be adjusted.
  342. SObjChangeSize s = { usedTypes[idx], size };
  343. oldObjectSizes.PushLast(s);
  344. }
  345. }
  346. // usedTypeIds[]
  347. ReadUsedTypeIds();
  348. // usedFunctions[]
  349. ReadUsedFunctions();
  350. // usedGlobalProperties[]
  351. ReadUsedGlobalProps();
  352. // usedStringConstants[]
  353. ReadUsedStringConstants();
  354. // usedObjectProperties
  355. ReadUsedObjectProps();
  356. for( i = 0; i < module->scriptFunctions.GetLength(); i++ )
  357. TranslateFunction(module->scriptFunctions[i]);
  358. for( i = 0; i < module->scriptGlobals.GetLength(); i++ )
  359. if( module->scriptGlobals[i]->GetInitFunc() )
  360. TranslateFunction(module->scriptGlobals[i]->GetInitFunc());
  361. // Init system functions properly
  362. engine->PrepareEngine();
  363. // Add references for all functions
  364. if( !error )
  365. {
  366. for( i = 0; i < module->scriptFunctions.GetLength(); i++ )
  367. module->scriptFunctions[i]->AddReferences();
  368. for( i = 0; i < module->scriptGlobals.GetLength(); i++ )
  369. if( module->scriptGlobals[i]->GetInitFunc() )
  370. module->scriptGlobals[i]->GetInitFunc()->AddReferences();
  371. if( engine->ep.initGlobalVarsAfterBuild )
  372. {
  373. int r = module->ResetGlobalVars(0);
  374. if( r < 0 ) error = true;
  375. }
  376. }
  377. return error ? asERROR : asSUCCESS;
  378. }
  379. int asCRestore::FindStringConstantIndex(int id)
  380. {
  381. for( asUINT i = 0; i < usedStringConstants.GetLength(); i++ )
  382. if( usedStringConstants[i] == id )
  383. return i;
  384. usedStringConstants.PushLast(id);
  385. return int(usedStringConstants.GetLength() - 1);
  386. }
  387. void asCRestore::WriteUsedStringConstants()
  388. {
  389. asUINT count = (asUINT)usedStringConstants.GetLength();
  390. WriteEncodedUInt(count);
  391. for( asUINT i = 0; i < count; ++i )
  392. WriteString(engine->stringConstants[usedStringConstants[i]]);
  393. }
  394. void asCRestore::ReadUsedStringConstants()
  395. {
  396. asCString str;
  397. asUINT count;
  398. count = ReadEncodedUInt();
  399. usedStringConstants.SetLength(count);
  400. for( asUINT i = 0; i < count; ++i )
  401. {
  402. ReadString(&str);
  403. usedStringConstants[i] = engine->AddConstantString(str.AddressOf(), str.GetLength());
  404. }
  405. }
  406. void asCRestore::WriteUsedFunctions()
  407. {
  408. asUINT count = (asUINT)usedFunctions.GetLength();
  409. WriteEncodedUInt(count);
  410. for( asUINT n = 0; n < usedFunctions.GetLength(); n++ )
  411. {
  412. char c;
  413. // Write enough data to be able to uniquely identify the function upon load
  414. // Is the function from the module or the application?
  415. c = usedFunctions[n]->module ? 'm' : 'a';
  416. WRITE_NUM(c);
  417. WriteFunctionSignature(usedFunctions[n]);
  418. }
  419. }
  420. void asCRestore::ReadUsedFunctions()
  421. {
  422. asUINT count;
  423. count = ReadEncodedUInt();
  424. usedFunctions.SetLength(count);
  425. memset(usedFunctions.AddressOf(), 0, sizeof(asCScriptFunction *)*count);
  426. for( asUINT n = 0; n < usedFunctions.GetLength(); n++ )
  427. {
  428. char c;
  429. // Read the data to be able to uniquely identify the function
  430. // Is the function from the module or the application?
  431. READ_NUM(c);
  432. asCScriptFunction func(engine, c == 'm' ? module : 0, asFUNC_DUMMY);
  433. ReadFunctionSignature(&func);
  434. // Find the correct function
  435. if( c == 'm' )
  436. {
  437. for( asUINT i = 0; i < module->scriptFunctions.GetLength(); i++ )
  438. {
  439. asCScriptFunction *f = module->scriptFunctions[i];
  440. if( !func.IsSignatureEqual(f) ||
  441. func.objectType != f->objectType ||
  442. func.funcType != f->funcType )
  443. continue;
  444. usedFunctions[n] = f;
  445. break;
  446. }
  447. }
  448. else
  449. {
  450. for( asUINT i = 0; i < engine->scriptFunctions.GetLength(); i++ )
  451. {
  452. asCScriptFunction *f = engine->scriptFunctions[i];
  453. if( f == 0 ||
  454. !func.IsSignatureEqual(f) ||
  455. func.objectType != f->objectType )
  456. continue;
  457. usedFunctions[n] = f;
  458. break;
  459. }
  460. }
  461. // Set the type to dummy so it won't try to release the id
  462. func.funcType = asFUNC_DUMMY;
  463. }
  464. }
  465. void asCRestore::WriteFunctionSignature(asCScriptFunction *func)
  466. {
  467. asUINT i, count;
  468. WriteString(&func->name);
  469. WriteDataType(&func->returnType);
  470. count = (asUINT)func->parameterTypes.GetLength();
  471. WriteEncodedUInt(count);
  472. for( i = 0; i < count; ++i )
  473. WriteDataType(&func->parameterTypes[i]);
  474. count = (asUINT)func->inOutFlags.GetLength();
  475. WriteEncodedUInt(count);
  476. for( i = 0; i < count; ++i )
  477. WriteEncodedUInt(func->inOutFlags[i]);
  478. WRITE_NUM(func->funcType);
  479. // Write the default args, from last to first
  480. count = 0;
  481. for( i = (asUINT)func->defaultArgs.GetLength(); i-- > 0; )
  482. if( func->defaultArgs[i] )
  483. count++;
  484. WriteEncodedUInt(count);
  485. for( i = (asUINT)func->defaultArgs.GetLength(); i-- > 0; )
  486. if( func->defaultArgs[i] )
  487. WriteString(func->defaultArgs[i]);
  488. WriteObjectType(func->objectType);
  489. if( func->objectType )
  490. {
  491. asBYTE b = 0;
  492. b += func->isReadOnly ? 1 : 0;
  493. b += func->isPrivate ? 2 : 0;
  494. WRITE_NUM(b);
  495. }
  496. }
  497. void asCRestore::ReadFunctionSignature(asCScriptFunction *func)
  498. {
  499. int i, count;
  500. asCDataType dt;
  501. int num;
  502. ReadString(&func->name);
  503. ReadDataType(&func->returnType);
  504. count = ReadEncodedUInt();
  505. func->parameterTypes.Allocate(count, 0);
  506. for( i = 0; i < count; ++i )
  507. {
  508. ReadDataType(&dt);
  509. func->parameterTypes.PushLast(dt);
  510. }
  511. count = ReadEncodedUInt();
  512. func->inOutFlags.Allocate(count, 0);
  513. for( i = 0; i < count; ++i )
  514. {
  515. num = ReadEncodedUInt();
  516. func->inOutFlags.PushLast(static_cast<asETypeModifiers>(num));
  517. }
  518. READ_NUM(func->funcType);
  519. // Read the default args, from last to first
  520. count = ReadEncodedUInt();
  521. if( count )
  522. {
  523. func->defaultArgs.SetLength(func->parameterTypes.GetLength());
  524. for( i = 0; i < count; i++ )
  525. {
  526. asCString *str = asNEW(asCString);
  527. func->defaultArgs[func->defaultArgs.GetLength()-1-i] = str;
  528. ReadString(str);
  529. }
  530. }
  531. func->objectType = ReadObjectType();
  532. if( func->objectType )
  533. {
  534. asBYTE b;
  535. READ_NUM(b);
  536. func->isReadOnly = (b & 1) ? true : false;
  537. func->isPrivate = (b & 2) ? true : false;
  538. }
  539. }
  540. void asCRestore::WriteFunction(asCScriptFunction* func)
  541. {
  542. char c;
  543. // If there is no function, then store a null char
  544. if( func == 0 )
  545. {
  546. c = '\0';
  547. WRITE_NUM(c);
  548. return;
  549. }
  550. // First check if the function has been saved already
  551. for( asUINT f = 0; f < savedFunctions.GetLength(); f++ )
  552. {
  553. if( savedFunctions[f] == func )
  554. {
  555. c = 'r';
  556. WRITE_NUM(c);
  557. WriteEncodedUInt(f);
  558. return;
  559. }
  560. }
  561. // Keep a reference to the function in the list
  562. savedFunctions.PushLast(func);
  563. c = 'f';
  564. WRITE_NUM(c);
  565. asUINT i, count;
  566. WriteFunctionSignature(func);
  567. if( func->funcType == asFUNC_SCRIPT )
  568. {
  569. count = (asUINT)func->byteCode.GetLength();
  570. WriteEncodedUInt(count);
  571. WriteByteCode(func->byteCode.AddressOf(), count);
  572. count = (asUINT)func->objVariablePos.GetLength();
  573. WriteEncodedUInt(count);
  574. for( i = 0; i < count; ++i )
  575. {
  576. WriteObjectType(func->objVariableTypes[i]);
  577. WriteEncodedUInt(func->objVariablePos[i]);
  578. WRITE_NUM(func->objVariableIsOnHeap[i]);
  579. }
  580. WriteEncodedUInt(func->stackNeeded);
  581. WriteEncodedUInt((asUINT)func->objVariableInfo.GetLength());
  582. for( i = 0; i < func->objVariableInfo.GetLength(); ++i )
  583. {
  584. WriteEncodedUInt(func->objVariableInfo[i].programPos);
  585. WriteEncodedUInt(func->objVariableInfo[i].variableOffset); // TODO: should be int
  586. WriteEncodedUInt(func->objVariableInfo[i].option);
  587. }
  588. asUINT length = (asUINT)func->lineNumbers.GetLength();
  589. WriteEncodedUInt(length);
  590. for( i = 0; i < length; ++i )
  591. WriteEncodedUInt(func->lineNumbers[i]);
  592. // TODO: Write variables
  593. }
  594. else if( func->funcType == asFUNC_VIRTUAL )
  595. {
  596. WriteEncodedUInt(func->vfTableIdx);
  597. }
  598. // Store script section name
  599. if( func->scriptSectionIdx >= 0 )
  600. WriteString(engine->scriptSectionNames[func->scriptSectionIdx]);
  601. else
  602. {
  603. char c = 0;
  604. WRITE_NUM(c);
  605. }
  606. }
  607. asCScriptFunction *asCRestore::ReadFunction(bool addToModule, bool addToEngine)
  608. {
  609. char c;
  610. READ_NUM(c);
  611. if( c == '\0' )
  612. {
  613. // There is no function, so return a null pointer
  614. return 0;
  615. }
  616. if( c == 'r' )
  617. {
  618. // This is a reference to a previously saved function
  619. asUINT index = ReadEncodedUInt();
  620. if( index < savedFunctions.GetLength() )
  621. return savedFunctions[index];
  622. else
  623. {
  624. // TODO: Write to message callback
  625. error = true;
  626. return 0;
  627. }
  628. }
  629. // Load the new function
  630. asCScriptFunction *func = asNEW(asCScriptFunction)(engine,module,asFUNC_DUMMY);
  631. savedFunctions.PushLast(func);
  632. int i, count;
  633. asCDataType dt;
  634. int num;
  635. ReadFunctionSignature(func);
  636. func->id = engine->GetNextScriptFunctionId();
  637. if( func->funcType == asFUNC_SCRIPT )
  638. {
  639. engine->gc.AddScriptObjectToGC(func, &engine->functionBehaviours);
  640. count = ReadEncodedUInt();
  641. func->byteCode.Allocate(count, 0);
  642. ReadByteCode(func->byteCode.AddressOf(), count);
  643. func->byteCode.SetLength(count);
  644. count = ReadEncodedUInt();
  645. func->objVariablePos.Allocate(count, 0);
  646. func->objVariableTypes.Allocate(count, 0);
  647. for( i = 0; i < count; ++i )
  648. {
  649. func->objVariableTypes.PushLast(ReadObjectType());
  650. num = ReadEncodedUInt();
  651. func->objVariablePos.PushLast(num);
  652. bool b; READ_NUM(b);
  653. func->objVariableIsOnHeap.PushLast(b);
  654. }
  655. func->stackNeeded = ReadEncodedUInt();
  656. int length = ReadEncodedUInt();
  657. func->objVariableInfo.SetLength(length);
  658. for( i = 0; i < length; ++i )
  659. {
  660. func->objVariableInfo[i].programPos = ReadEncodedUInt();
  661. func->objVariableInfo[i].variableOffset = ReadEncodedUInt(); // TODO: should be int
  662. func->objVariableInfo[i].option = ReadEncodedUInt();
  663. }
  664. length = ReadEncodedUInt();
  665. func->lineNumbers.SetLength(length);
  666. for( i = 0; i < length; ++i )
  667. func->lineNumbers[i] = ReadEncodedUInt();
  668. }
  669. else if( func->funcType == asFUNC_VIRTUAL )
  670. {
  671. func->vfTableIdx = ReadEncodedUInt();
  672. }
  673. // Read script section name
  674. asCString name;
  675. ReadString(&name);
  676. if( name.GetLength() > 0 )
  677. func->scriptSectionIdx = engine->GetScriptSectionNameIndex(name.AddressOf());
  678. if( addToModule )
  679. {
  680. // The refCount is already 1
  681. module->scriptFunctions.PushLast(func);
  682. }
  683. if( addToEngine )
  684. engine->SetScriptFunction(func);
  685. if( func->objectType )
  686. func->ComputeSignatureId();
  687. return func;
  688. }
  689. void asCRestore::WriteObjectTypeDeclaration(asCObjectType *ot, int phase)
  690. {
  691. if( phase == 1 )
  692. {
  693. // name
  694. WriteString(&ot->name);
  695. // flags
  696. WRITE_NUM(ot->flags);
  697. // size
  698. WriteEncodedUInt(ot->size);
  699. }
  700. else if( phase == 2 )
  701. {
  702. if( ot->flags & asOBJ_ENUM )
  703. {
  704. // enumValues[]
  705. int size = (int)ot->enumValues.GetLength();
  706. WriteEncodedUInt(size);
  707. for( int n = 0; n < size; n++ )
  708. {
  709. WriteString(&ot->enumValues[n]->name);
  710. WRITE_NUM(ot->enumValues[n]->value);
  711. }
  712. }
  713. else if( ot->flags & asOBJ_TYPEDEF )
  714. {
  715. eTokenType t = ot->templateSubType.GetTokenType();
  716. WRITE_NUM(t);
  717. }
  718. else
  719. {
  720. WriteObjectType(ot->derivedFrom);
  721. // interfaces[]
  722. int size = (asUINT)ot->interfaces.GetLength();
  723. WriteEncodedUInt(size);
  724. asUINT n;
  725. for( n = 0; n < ot->interfaces.GetLength(); n++ )
  726. {
  727. WriteObjectType(ot->interfaces[n]);
  728. }
  729. // behaviours
  730. if( !ot->IsInterface() && ot->flags != asOBJ_TYPEDEF && ot->flags != asOBJ_ENUM )
  731. {
  732. WriteFunction(engine->scriptFunctions[ot->beh.construct]);
  733. WriteFunction(engine->scriptFunctions[ot->beh.destruct]);
  734. WriteFunction(engine->scriptFunctions[ot->beh.factory]);
  735. size = (int)ot->beh.constructors.GetLength() - 1;
  736. WriteEncodedUInt(size);
  737. for( n = 1; n < ot->beh.constructors.GetLength(); n++ )
  738. {
  739. WriteFunction(engine->scriptFunctions[ot->beh.constructors[n]]);
  740. WriteFunction(engine->scriptFunctions[ot->beh.factories[n]]);
  741. }
  742. }
  743. // methods[]
  744. size = (int)ot->methods.GetLength();
  745. WriteEncodedUInt(size);
  746. for( n = 0; n < ot->methods.GetLength(); n++ )
  747. {
  748. WriteFunction(engine->scriptFunctions[ot->methods[n]]);
  749. }
  750. // virtualFunctionTable[]
  751. size = (int)ot->virtualFunctionTable.GetLength();
  752. WriteEncodedUInt(size);
  753. for( n = 0; n < (asUINT)size; n++ )
  754. {
  755. WriteFunction(ot->virtualFunctionTable[n]);
  756. }
  757. }
  758. }
  759. else if( phase == 3 )
  760. {
  761. // properties[]
  762. asUINT size = (asUINT)ot->properties.GetLength();
  763. WriteEncodedUInt(size);
  764. for( asUINT n = 0; n < ot->properties.GetLength(); n++ )
  765. {
  766. WriteObjectProperty(ot->properties[n]);
  767. }
  768. }
  769. }
  770. void asCRestore::ReadObjectTypeDeclaration(asCObjectType *ot, int phase)
  771. {
  772. if( phase == 1 )
  773. {
  774. // name
  775. ReadString(&ot->name);
  776. // flags
  777. READ_NUM(ot->flags);
  778. // size
  779. ot->size = ReadEncodedUInt();
  780. // Reset the size of script classes, since it will be recalculated as properties are added
  781. if( (ot->flags & asOBJ_SCRIPT_OBJECT) && ot->size != 0 )
  782. ot->size = sizeof(asCScriptObject);
  783. // Use the default script class behaviours
  784. ot->beh = engine->scriptTypeBehaviours.beh;
  785. engine->scriptFunctions[ot->beh.addref]->AddRef();
  786. engine->scriptFunctions[ot->beh.release]->AddRef();
  787. engine->scriptFunctions[ot->beh.gcEnumReferences]->AddRef();
  788. engine->scriptFunctions[ot->beh.gcGetFlag]->AddRef();
  789. engine->scriptFunctions[ot->beh.gcGetRefCount]->AddRef();
  790. engine->scriptFunctions[ot->beh.gcReleaseAllReferences]->AddRef();
  791. engine->scriptFunctions[ot->beh.gcSetFlag]->AddRef();
  792. engine->scriptFunctions[ot->beh.copy]->AddRef();
  793. engine->scriptFunctions[ot->beh.factory]->AddRef();
  794. engine->scriptFunctions[ot->beh.construct]->AddRef();
  795. for( asUINT i = 1; i < ot->beh.operators.GetLength(); i += 2 )
  796. engine->scriptFunctions[ot->beh.operators[i]]->AddRef();
  797. }
  798. else if( phase == 2 )
  799. {
  800. if( ot->flags & asOBJ_ENUM )
  801. {
  802. int count = ReadEncodedUInt();
  803. ot->enumValues.Allocate(count, 0);
  804. for( int n = 0; n < count; n++ )
  805. {
  806. asSEnumValue *e = asNEW(asSEnumValue);
  807. ReadString(&e->name);
  808. READ_NUM(e->value);
  809. ot->enumValues.PushLast(e);
  810. }
  811. }
  812. else if( ot->flags & asOBJ_TYPEDEF )
  813. {
  814. eTokenType t;
  815. READ_NUM(t);
  816. ot->templateSubType = asCDataType::CreatePrimitive(t, false);
  817. }
  818. else
  819. {
  820. ot->derivedFrom = ReadObjectType();
  821. if( ot->derivedFrom )
  822. ot->derivedFrom->AddRef();
  823. // interfaces[]
  824. int size = ReadEncodedUInt();
  825. ot->interfaces.Allocate(size,0);
  826. int n;
  827. for( n = 0; n < size; n++ )
  828. {
  829. asCObjectType *intf = ReadObjectType();
  830. ot->interfaces.PushLast(intf);
  831. }
  832. // behaviours
  833. if( !ot->IsInterface() && ot->flags != asOBJ_TYPEDEF && ot->flags != asOBJ_ENUM )
  834. {
  835. asCScriptFunction *func = ReadFunction();
  836. if( func )
  837. {
  838. engine->scriptFunctions[ot->beh.construct]->Release();
  839. ot->beh.construct = func->id;
  840. ot->beh.constructors[0] = func->id;
  841. func->AddRef();
  842. }
  843. func = ReadFunction();
  844. if( func )
  845. {
  846. ot->beh.destruct = func->id;
  847. func->AddRef();
  848. }
  849. func = ReadFunction();
  850. if( func )
  851. {
  852. engine->scriptFunctions[ot->beh.factory]->Release();
  853. ot->beh.factory = func->id;
  854. ot->beh.factories[0] = func->id;
  855. func->AddRef();
  856. }
  857. size = ReadEncodedUInt();
  858. for( n = 0; n < size; n++ )
  859. {
  860. asCScriptFunction *func = ReadFunction();
  861. if( func )
  862. {
  863. ot->beh.constructors.PushLast(func->id);
  864. func->AddRef();
  865. }
  866. func = ReadFunction();
  867. if( func )
  868. {
  869. ot->beh.factories.PushLast(func->id);
  870. func->AddRef();
  871. }
  872. }
  873. }
  874. // methods[]
  875. size = ReadEncodedUInt();
  876. for( n = 0; n < size; n++ )
  877. {
  878. asCScriptFunction *func = ReadFunction();
  879. if( func )
  880. {
  881. ot->methods.PushLast(func->id);
  882. func->AddRef();
  883. }
  884. }
  885. // virtualFunctionTable[]
  886. size = ReadEncodedUInt();
  887. for( n = 0; n < size; n++ )
  888. {
  889. asCScriptFunction *func = ReadFunction();
  890. if( func )
  891. {
  892. ot->virtualFunctionTable.PushLast(func);
  893. func->AddRef();
  894. }
  895. }
  896. }
  897. }
  898. else if( phase == 3 )
  899. {
  900. // properties[]
  901. asUINT size = ReadEncodedUInt();
  902. for( asUINT n = 0; n < size; n++ )
  903. ReadObjectProperty(ot);
  904. }
  905. }
  906. void asCRestore::WriteEncodedUInt(asUINT i)
  907. {
  908. if( i < 128 )
  909. {
  910. asBYTE b = (asBYTE)i;
  911. WRITE_NUM(b);
  912. }
  913. else if( i < 16384 )
  914. {
  915. asBYTE b = asBYTE(0x80 + (i >> 8));
  916. WRITE_NUM(b);
  917. b = asBYTE(i & 0xFF);
  918. WRITE_NUM(b);
  919. }
  920. else if( i < 2097152 )
  921. {
  922. asBYTE b = asBYTE(0xC0 + (i >> 16));
  923. WRITE_NUM(b);
  924. b = asBYTE((i >> 8) & 0xFF);
  925. WRITE_NUM(b);
  926. b = asBYTE(i & 0xFF);
  927. WRITE_NUM(b);
  928. }
  929. else if( i < 268435456 )
  930. {
  931. asBYTE b = asBYTE(0xE0 + (i >> 24));
  932. WRITE_NUM(b);
  933. b = asBYTE((i >> 16) & 0xFF);
  934. WRITE_NUM(b);
  935. b = asBYTE((i >> 8) & 0xFF);
  936. WRITE_NUM(b);
  937. b = asBYTE(i & 0xFF);
  938. WRITE_NUM(b);
  939. }
  940. else
  941. {
  942. asBYTE b = asBYTE(0xF0);
  943. WRITE_NUM(b);
  944. b = asBYTE((i >> 24) & 0xFF);
  945. WRITE_NUM(b);
  946. b = asBYTE((i >> 16) & 0xFF);
  947. WRITE_NUM(b);
  948. b = asBYTE((i >> 8) & 0xFF);
  949. WRITE_NUM(b);
  950. b = asBYTE(i & 0xFF);
  951. WRITE_NUM(b);
  952. }
  953. }
  954. asUINT asCRestore::ReadEncodedUInt()
  955. {
  956. asUINT i = 0;
  957. asBYTE b;
  958. READ_NUM(b);
  959. if( b < 128 )
  960. {
  961. i = b;
  962. }
  963. else if( b < 192 )
  964. {
  965. i = asUINT(b & 0x3F) << 8;
  966. READ_NUM(b);
  967. i += b;
  968. }
  969. else if( b < 224 )
  970. {
  971. i = asUINT(b & 0x1F) << 16;
  972. READ_NUM(b);
  973. i += asUINT(b) << 8;
  974. READ_NUM(b);
  975. i += b;
  976. }
  977. else if( b < 240 )
  978. {
  979. i = asUINT(b & 0x0F) << 24;
  980. READ_NUM(b);
  981. i += asUINT(b) << 16;
  982. READ_NUM(b);
  983. i += asUINT(b) << 8;
  984. READ_NUM(b);
  985. i += b;
  986. }
  987. else
  988. {
  989. READ_NUM(b);
  990. i += asUINT(b) << 24;
  991. READ_NUM(b);
  992. i += asUINT(b) << 16;
  993. READ_NUM(b);
  994. i += asUINT(b) << 8;
  995. READ_NUM(b);
  996. i += b;
  997. }
  998. return i;
  999. }
  1000. void asCRestore::WriteString(asCString* str)
  1001. {
  1002. // TODO: All strings should be stored in a separate section, and when
  1003. // they are used an offset into that section should be stored.
  1004. // This will make it unnecessary to store the extra byte to
  1005. // identify new versus old strings.
  1006. if( str->GetLength() == 0 )
  1007. {
  1008. char z = '\0';
  1009. WRITE_NUM(z);
  1010. return;
  1011. }
  1012. // First check if the string hasn't been saved already
  1013. for( asUINT n = 0; n < savedStrings.GetLength(); n++ )
  1014. {
  1015. if( *str == savedStrings[n] )
  1016. {
  1017. // Save a reference to the existing string
  1018. char b = 'r';
  1019. WRITE_NUM(b);
  1020. WriteEncodedUInt(n);
  1021. return;
  1022. }
  1023. }
  1024. // Save a new string
  1025. char b = 'n';
  1026. WRITE_NUM(b);
  1027. asUINT len = (asUINT)str->GetLength();
  1028. WriteEncodedUInt(len);
  1029. stream->Write(str->AddressOf(), (asUINT)len);
  1030. savedStrings.PushLast(*str);
  1031. }
  1032. void asCRestore::ReadString(asCString* str)
  1033. {
  1034. char b;
  1035. READ_NUM(b);
  1036. if( b == '\0' )
  1037. {
  1038. str->SetLength(0);
  1039. }
  1040. else if( b == 'n' )
  1041. {
  1042. asUINT len = ReadEncodedUInt();
  1043. str->SetLength(len);
  1044. stream->Read(str->AddressOf(), len);
  1045. savedStrings.PushLast(*str);
  1046. }
  1047. else
  1048. {
  1049. asUINT n = ReadEncodedUInt();
  1050. *str = savedStrings[n];
  1051. }
  1052. }
  1053. void asCRestore::WriteGlobalProperty(asCGlobalProperty* prop)
  1054. {
  1055. // TODO: We might be able to avoid storing the name and type of the global
  1056. // properties twice if we merge this with the WriteUsedGlobalProperties.
  1057. WriteString(&prop->name);
  1058. WriteDataType(&prop->type);
  1059. // Store the initialization function
  1060. if( prop->GetInitFunc() )
  1061. {
  1062. bool f = true;
  1063. WRITE_NUM(f);
  1064. WriteFunction(prop->GetInitFunc());
  1065. }
  1066. else
  1067. {
  1068. bool f = false;
  1069. WRITE_NUM(f);
  1070. }
  1071. }
  1072. void asCRestore::ReadGlobalProperty()
  1073. {
  1074. asCString name;
  1075. asCDataType type;
  1076. ReadString(&name);
  1077. ReadDataType(&type);
  1078. asCGlobalProperty *prop = module->AllocateGlobalProperty(name.AddressOf(), type);
  1079. // Read the initialization function
  1080. bool f;
  1081. READ_NUM(f);
  1082. if( f )
  1083. {
  1084. asCScriptFunction *func = ReadFunction(false, true);
  1085. prop->SetInitFunc(func);
  1086. func->Release();
  1087. }
  1088. }
  1089. void asCRestore::WriteObjectProperty(asCObjectProperty* prop)
  1090. {
  1091. WriteString(&prop->name);
  1092. WriteDataType(&prop->type);
  1093. WRITE_NUM(prop->isPrivate);
  1094. }
  1095. void asCRestore::ReadObjectProperty(asCObjectType *ot)
  1096. {
  1097. asCString name;
  1098. ReadString(&name);
  1099. asCDataType dt;
  1100. ReadDataType(&dt);
  1101. bool isPrivate;
  1102. READ_NUM(isPrivate);
  1103. ot->AddPropertyToClass(name, dt, isPrivate);
  1104. }
  1105. void asCRestore::WriteDataType(const asCDataType *dt)
  1106. {
  1107. // First check if the datatype has already been saved
  1108. for( asUINT n = 0; n < savedDataTypes.GetLength(); n++ )
  1109. {
  1110. if( *dt == savedDataTypes[n] )
  1111. {
  1112. asUINT c = 0;
  1113. WriteEncodedUInt(c);
  1114. WriteEncodedUInt(n);
  1115. return;
  1116. }
  1117. }
  1118. // Save the new datatype
  1119. savedDataTypes.PushLast(*dt);
  1120. bool b;
  1121. int t = dt->GetTokenType();
  1122. WriteEncodedUInt(t);
  1123. if( t == ttIdentifier )
  1124. {
  1125. WriteObjectType(dt->GetObjectType());
  1126. b = dt->IsObjectHandle();
  1127. WRITE_NUM(b);
  1128. b = dt->IsHandleToConst();
  1129. WRITE_NUM(b);
  1130. }
  1131. b = dt->IsReference();
  1132. WRITE_NUM(b);
  1133. b = dt->IsReadOnly();
  1134. WRITE_NUM(b);
  1135. if( t == ttIdentifier && dt->GetObjectType()->name == "_builtin_function_" )
  1136. {
  1137. WriteFunctionSignature(dt->GetFuncDef());
  1138. }
  1139. }
  1140. void asCRestore::ReadDataType(asCDataType *dt)
  1141. {
  1142. eTokenType tokenType;
  1143. tokenType = (eTokenType)ReadEncodedUInt();
  1144. if( tokenType == 0 )
  1145. {
  1146. // Get the datatype from the cache
  1147. asUINT n = ReadEncodedUInt();
  1148. *dt = savedDataTypes[n];
  1149. return;
  1150. }
  1151. // Read the datatype for the first time
  1152. asCObjectType *objType = 0;
  1153. bool isObjectHandle = false;
  1154. bool isReadOnly = false;
  1155. bool isHandleToConst = false;
  1156. bool isReference = false;
  1157. if( tokenType == ttIdentifier )
  1158. {
  1159. objType = ReadObjectType();
  1160. READ_NUM(isObjectHandle);
  1161. READ_NUM(isHandleToConst);
  1162. }
  1163. READ_NUM(isReference);
  1164. READ_NUM(isReadOnly);
  1165. asCScriptFunction *funcDef = 0;
  1166. if( tokenType == ttIdentifier && objType && objType->name == "_builtin_function_" )
  1167. {
  1168. asCScriptFunction func(engine, module, asFUNC_DUMMY);
  1169. ReadFunctionSignature(&func);
  1170. for( asUINT n = 0; n < engine->registeredFuncDefs.GetLength(); n++ )
  1171. {
  1172. // TODO: Only return the definitions for the config groups that the module has access to
  1173. if( engine->registeredFuncDefs[n]->name == func.name )
  1174. {
  1175. funcDef = engine->registeredFuncDefs[n];
  1176. break;
  1177. }
  1178. }
  1179. if( !funcDef && module )
  1180. {
  1181. for( asUINT n = 0; n < module->funcDefs.GetLength(); n++ )
  1182. {
  1183. if( module->funcDefs[n]->name == func.name )
  1184. {
  1185. funcDef = module->funcDefs[n];
  1186. break;
  1187. }
  1188. }
  1189. }
  1190. func.funcType = asFUNC_DUMMY;
  1191. }
  1192. if( funcDef )
  1193. *dt = asCDataType::CreateFuncDef(funcDef);
  1194. else if( tokenType == ttIdentifier )
  1195. *dt = asCDataType::CreateObject(objType, false);
  1196. else
  1197. *dt = asCDataType::CreatePrimitive(tokenType, false);
  1198. if( isObjectHandle )
  1199. {
  1200. dt->MakeReadOnly(isHandleToConst);
  1201. dt->MakeHandle(true);
  1202. }
  1203. dt->MakeReadOnly(isReadOnly);
  1204. dt->MakeReference(isReference);
  1205. savedDataTypes.PushLast(*dt);
  1206. }
  1207. void asCRestore::WriteObjectType(asCObjectType* ot)
  1208. {
  1209. char ch;
  1210. // Only write the object type name
  1211. if( ot )
  1212. {
  1213. // Check for template instances/specializations
  1214. if( ot->templateSubType.GetTokenType() != ttUnrecognizedToken )
  1215. {
  1216. ch = 'a';
  1217. WRITE_NUM(ch);
  1218. WriteString(&ot->name);
  1219. if( ot->templateSubType.IsObject() || ot->templateSubType.IsEnumType() )
  1220. {
  1221. ch = 's';
  1222. WRITE_NUM(ch);
  1223. WriteObjectType(ot->templateSubType.GetObjectType());
  1224. if( ot->templateSubType.IsObjectHandle() )
  1225. ch = 'h';
  1226. else
  1227. ch = 'o';
  1228. WRITE_NUM(ch);
  1229. }
  1230. else
  1231. {
  1232. ch = 't';
  1233. WRITE_NUM(ch);
  1234. eTokenType t = ot->templateSubType.GetTokenType();
  1235. WRITE_NUM(t);
  1236. }
  1237. }
  1238. else if( ot->flags & asOBJ_TEMPLATE_SUBTYPE )
  1239. {
  1240. ch = 's';
  1241. WRITE_NUM(ch);
  1242. WriteString(&ot->name);
  1243. }
  1244. else
  1245. {
  1246. ch = 'o';
  1247. WRITE_NUM(ch);
  1248. WriteString(&ot->name);
  1249. }
  1250. }
  1251. else
  1252. {
  1253. ch = '\0';
  1254. WRITE_NUM(ch);
  1255. }
  1256. }
  1257. asCObjectType* asCRestore::ReadObjectType()
  1258. {
  1259. asCObjectType *ot = 0;
  1260. char ch;
  1261. READ_NUM(ch);
  1262. if( ch == 'a' )
  1263. {
  1264. // Read the name of the template type
  1265. asCString typeName;
  1266. ReadString(&typeName);
  1267. asCObjectType *tmpl = engine->GetObjectType(typeName.AddressOf());
  1268. if( tmpl == 0 )
  1269. {
  1270. // TODO: Move text to as_texts.h
  1271. asCString str;
  1272. str.Format("Template type '%s' doesn't exist", typeName.AddressOf());
  1273. engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
  1274. error = true;
  1275. return 0;
  1276. }
  1277. READ_NUM(ch);
  1278. if( ch == 's' )
  1279. {
  1280. ot = ReadObjectType();
  1281. if( ot == 0 )
  1282. {
  1283. // TODO: Move text to as_texts.h
  1284. asCString str;
  1285. str.Format("Failed to read subtype of template type '%s'", typeName.AddressOf());
  1286. engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
  1287. error = true;
  1288. return 0;
  1289. }
  1290. asCDataType dt = asCDataType::CreateObject(ot, false);
  1291. READ_NUM(ch);
  1292. if( ch == 'h' )
  1293. dt.MakeHandle(true);
  1294. if( tmpl->templateSubType.GetObjectType() == ot )
  1295. ot = tmpl;
  1296. else
  1297. ot = engine->GetTemplateInstanceType(tmpl, dt);
  1298. if( ot == 0 )
  1299. {
  1300. // TODO: Move text to as_texts.h
  1301. asCString str;
  1302. str.Format("Attempting to instanciate invalid template type '%s<%s>'", typeName.AddressOf(), dt.Format().AddressOf());
  1303. engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
  1304. error = true;
  1305. return 0;
  1306. }
  1307. }
  1308. else
  1309. {
  1310. eTokenType tokenType;
  1311. READ_NUM(tokenType);
  1312. asCDataType dt = asCDataType::CreatePrimitive(tokenType, false);
  1313. ot = engine->GetTemplateInstanceType(tmpl, dt);
  1314. if( ot == 0 )
  1315. {
  1316. // TODO: Move text to as_texts.h
  1317. asCString str;
  1318. str.Format("Attempting to instanciate invalid template type '%s<%s>'", typeName.AddressOf(), dt.Format().AddressOf());
  1319. engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
  1320. error = true;
  1321. return 0;
  1322. }
  1323. }
  1324. }
  1325. else if( ch == 's' )
  1326. {
  1327. // Read the name of the template subtype
  1328. asCString typeName;
  1329. ReadString(&typeName);
  1330. // Find the template subtype
  1331. ot = 0;
  1332. for( asUINT n = 0; n < engine->templateSubTypes.GetLength(); n++ )
  1333. {
  1334. if( engine->templateSubTypes[n] && engine->templateSubTypes[n]->name == typeName )
  1335. {
  1336. ot = engine->templateSubTypes[n];
  1337. break;
  1338. }
  1339. }
  1340. if( ot == 0 )
  1341. {
  1342. // TODO: Move text to as_texts.h
  1343. asCString str;
  1344. str.Format("Template subtype type '%s' doesn't exist", typeName.AddressOf());
  1345. engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
  1346. error = true;
  1347. return 0;
  1348. }
  1349. }
  1350. else if( ch == 'o' )
  1351. {
  1352. // Read the object type name
  1353. asCString typeName;
  1354. ReadString(&typeName);
  1355. if( typeName.GetLength() && typeName != "_builtin_object_" && typeName != "_builtin_function_" )
  1356. {
  1357. // Find the object type
  1358. ot = module->GetObjectType(typeName.AddressOf());
  1359. if( !ot )
  1360. ot = engine->GetObjectType(typeName.AddressOf());
  1361. if( ot == 0 )
  1362. {
  1363. // TODO: Move text to as_texts.h
  1364. asCString str;
  1365. str.Format("Object type '%s' doesn't exist", typeName.AddressOf());
  1366. engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
  1367. error = true;
  1368. return 0;
  1369. }
  1370. }
  1371. else if( typeName == "_builtin_object_" )
  1372. {
  1373. ot = &engine->scriptTypeBehaviours;
  1374. }
  1375. else if( typeName == "_builtin_function_" )
  1376. {
  1377. ot = &engine->functionBehaviours;
  1378. }
  1379. else
  1380. asASSERT( false );
  1381. }
  1382. else
  1383. {
  1384. // No object type
  1385. asASSERT( ch == '\0' );
  1386. ot = 0;
  1387. }
  1388. return ot;
  1389. }
  1390. void asCRestore::WriteByteCode(asDWORD *bc, int length)
  1391. {
  1392. while( length )
  1393. {
  1394. asDWORD tmp[4]; // The biggest instructions take up 4 DWORDs
  1395. asDWORD c = *(asBYTE*)bc;
  1396. // Copy the instruction to a temp buffer so we can work on it before saving
  1397. memcpy(tmp, bc, asBCTypeSize[asBCInfo[c].type]*sizeof(asDWORD));
  1398. if( c == asBC_ALLOC ) // PTR_DW_ARG
  1399. {
  1400. // Translate the object type
  1401. asCObjectType *ot = *(asCObjectType**)(tmp+1);
  1402. *(int*)(tmp+1) = FindObjectTypeIdx(ot);
  1403. // Translate the constructor func id, if it is a script class
  1404. if( ot->flags & asOBJ_SCRIPT_OBJECT )
  1405. *(int*)&tmp[1+AS_PTR_SIZE] = FindFunctionIndex(engine->scriptFunctions[*(int*)&tmp[1+AS_PTR_SIZE]]);
  1406. }
  1407. else if( c == asBC_FREE || // wW_PTR_ARG
  1408. c == asBC_REFCPY || // PTR_ARG
  1409. c == asBC_OBJTYPE ) // PTR_ARG
  1410. {
  1411. // Translate object type pointers into indices
  1412. *(int*)(tmp+1) = FindObjectTypeIdx(*(asCObjectType**)(tmp+1));
  1413. }
  1414. else if( c == asBC_TYPEID || // DW_ARG
  1415. c == asBC_Cast ) // DW_ARG
  1416. {
  1417. // Translate type ids into indices
  1418. *(int*)(tmp+1) = FindTypeIdIdx(*(int*)(tmp+1));
  1419. }
  1420. else if( c == asBC_ADDSi || // W_DW_ARG
  1421. c == asBC_LoadThisR ) // W_DW_ARG
  1422. {
  1423. // Translate property offsets into indices
  1424. *(((short*)tmp)+1) = (short)FindObjectPropIndex(*(((short*)tmp)+1), *(int*)(tmp+1));
  1425. // Translate type ids into indices
  1426. *(int*)(tmp+1) = FindTypeIdIdx(*(int*)(tmp+1));
  1427. }
  1428. else if( c == asBC_LoadRObjR || // rW_W_DW_ARG
  1429. c == asBC_LoadVObjR ) // rW_W_DW_ARG
  1430. {
  1431. // Translate property offsets into indices
  1432. *(((short*)tmp)+2) = (short)FindObjectPropIndex(*(((short*)tmp)+2), *(int*)(tmp+2));
  1433. // Translate type ids into indices
  1434. *(int*)(tmp+2) = FindTypeIdIdx(*(int*)(tmp+2));
  1435. }
  1436. else if( c == asBC_COPY ) // W_DW_ARG
  1437. {
  1438. // Translate type ids into indices
  1439. *(int*)(tmp+1) = FindTypeIdIdx(*(int*)(tmp+1));
  1440. }
  1441. else if( c == asBC_CALL || // DW_ARG
  1442. c == asBC_CALLINTF || // DW_ARG
  1443. c == asBC_CALLSYS ) // DW_ARG
  1444. {
  1445. // Translate the function id
  1446. *(int*)(tmp+1) = FindFunctionIndex(engine->scriptFunctions[*(int*)(tmp+1)]);
  1447. }
  1448. else if( c == asBC_FuncPtr ) // PTR_ARG
  1449. {
  1450. // Translate the function pointer
  1451. *(asPTRWORD*)(tmp+1) = FindFunctionIndex(*(asCScriptFunction**)(tmp+1));
  1452. }
  1453. else if( c == asBC_STR ) // W_ARG
  1454. {
  1455. // Translate the string constant id
  1456. asWORD *arg = ((asWORD*)tmp)+1;
  1457. *arg = (asWORD)FindStringConstantIndex(*arg);
  1458. }
  1459. else if( c == asBC_CALLBND ) // DW_ARG
  1460. {
  1461. // Translate the function id
  1462. int funcId = tmp[1];
  1463. for( asUINT n = 0; n < module->bindInformations.GetLength(); n++ )
  1464. if( module->bindInformations[n]->importedFunctionSignature->id == funcId )
  1465. {
  1466. funcId = n;
  1467. break;
  1468. }
  1469. tmp[1] = funcId;
  1470. }
  1471. else if( c == asBC_PGA || // PTR_ARG
  1472. c == asBC_LDG || // PTR_ARG
  1473. c == asBC_PshG4 || // PTR_ARG
  1474. c == asBC_LdGRdR4 || // wW_PTR_ARG
  1475. c == asBC_CpyGtoV4 || // wW_PTR_ARG
  1476. c == asBC_CpyVtoG4 || // rW_PTR_ARG
  1477. c == asBC_SetG4 ) // PTR_DW_ARG
  1478. {
  1479. // Translate global variable pointers into indices
  1480. *(int*)(tmp+1) = FindGlobalPropPtrIndex(*(void**)(tmp+1));
  1481. }
  1482. // Now store the instruction in the smallest possible way
  1483. switch( asBCInfo[c].type )
  1484. {
  1485. case asBCTYPE_NO_ARG:
  1486. {
  1487. // Just write 1 byte
  1488. asBYTE b = (asBYTE)c;
  1489. WRITE_NUM(b);
  1490. }
  1491. break;
  1492. case asBCTYPE_W_ARG:
  1493. case asBCTYPE_wW_ARG:
  1494. case asBCTYPE_rW_ARG:
  1495. {
  1496. // Write the instruction code
  1497. asBYTE b = (asBYTE)c;
  1498. WRITE_NUM(b);
  1499. // Write the argument
  1500. asWORD w = *(((asWORD*)tmp)+1);
  1501. WRITE_NUM(w);
  1502. }
  1503. break;
  1504. case asBCTYPE_rW_DW_ARG:
  1505. case asBCTYPE_wW_DW_ARG:
  1506. case asBCTYPE_W_DW_ARG:
  1507. {
  1508. // Write the instruction code
  1509. asBYTE b = (asBYTE)c;
  1510. WRITE_NUM(b);
  1511. // Write the word argument
  1512. asWORD w = *(((asWORD*)tmp)+1);
  1513. WRITE_NUM(w);
  1514. // Write the dword argument
  1515. // TODO: Should be WriteEncodedInt since we do not know if it is a signed value or not
  1516. WriteEncodedUInt(tmp[1]);
  1517. }
  1518. break;
  1519. case asBCTYPE_DW_ARG:
  1520. {
  1521. // Write the instruction code
  1522. asBYTE b = (asBYTE)c;
  1523. WRITE_NUM(b);
  1524. // Write the argument
  1525. // TODO: Should be WriteEncodedInt since we do not know if it is a signed value or not
  1526. WriteEncodedUInt(tmp[1]);
  1527. }
  1528. break;
  1529. case asBCTYPE_DW_DW_ARG:
  1530. {
  1531. // Write the instruction code
  1532. asBYTE b = (asBYTE)c;
  1533. WRITE_NUM(b);
  1534. // Write the dword argument
  1535. // TODO: Should be WriteEncodedInt since we do not know if it is a signed value or not
  1536. WriteEncodedUInt(tmp[1]);
  1537. // Write the dword argument
  1538. // TODO: Should be WriteEncodedInt since we do not know if it is a signed value or not
  1539. WriteEncodedUInt(tmp[2]);
  1540. }
  1541. break;
  1542. case asBCTYPE_wW_rW_rW_ARG:
  1543. {
  1544. // Write the instruction code
  1545. asBYTE b = (asBYTE)c;
  1546. WRITE_NUM(b);
  1547. // Write the first argument
  1548. asWORD w = *(((asWORD*)tmp)+1);
  1549. WRITE_NUM(w);
  1550. // Write the second argument
  1551. w = *(((asWORD*)tmp)+2);
  1552. WRITE_NUM(w);
  1553. // Write the third argument
  1554. w = *(((asWORD*)tmp)+3);
  1555. WRITE_NUM(w);
  1556. }
  1557. break;
  1558. case asBCTYPE_wW_rW_ARG:
  1559. case asBCTYPE_rW_rW_ARG:
  1560. case asBCTYPE_wW_W_ARG:
  1561. {
  1562. // Write the instruction code
  1563. asBYTE b = (asBYTE)c;
  1564. WRITE_NUM(b);
  1565. // Write the first argument
  1566. asWORD w = *(((asWORD*)tmp)+1);
  1567. WRITE_NUM(w);
  1568. // Write the second argument
  1569. w = *(((asWORD*)tmp)+2);
  1570. WRITE_NUM(w);
  1571. }
  1572. break;
  1573. case asBCTYPE_wW_rW_DW_ARG:
  1574. case asBCTYPE_rW_W_DW_ARG:
  1575. {
  1576. // Write the instruction code
  1577. asBYTE b = (asBYTE)c;
  1578. WRITE_NUM(b);
  1579. // Write the first argument
  1580. asWORD w = *(((asWORD*)tmp)+1);
  1581. WRITE_NUM(w);
  1582. // Write the second argument
  1583. w = *(((asWORD*)tmp)+2);
  1584. WRITE_NUM(w);
  1585. // Write the third argument
  1586. // TODO: This could be encoded as an int to decrease the size
  1587. asDWORD dw = tmp[2];
  1588. WRITE_NUM(dw);
  1589. }
  1590. break;
  1591. case asBCTYPE_QW_ARG:
  1592. {
  1593. // Write the instruction code
  1594. asBYTE b = (asBYTE)c;
  1595. WRITE_NUM(b);
  1596. // Write the argument
  1597. // TODO: This could be encoded as an int to decrease the size
  1598. asQWORD qw = *(asQWORD*)&tmp[1];
  1599. WRITE_NUM(qw);
  1600. }
  1601. break;
  1602. case asBCTYPE_QW_DW_ARG:
  1603. {
  1604. // Write the instruction code
  1605. asBYTE b = (asBYTE)c;
  1606. WRITE_NUM(b);
  1607. // Write the argument
  1608. // TODO: This could be encoded as an int to decrease the size
  1609. asQWORD qw = *(asQWORD*)&tmp[1];
  1610. WRITE_NUM(qw);
  1611. // Write the second argument
  1612. // TODO: This could be encoded as an int to decrease the size
  1613. asDWORD dw = tmp[3];
  1614. WRITE_NUM(dw);
  1615. }
  1616. break;
  1617. case asBCTYPE_rW_QW_ARG:
  1618. case asBCTYPE_wW_QW_ARG:
  1619. {
  1620. // Write the instruction code
  1621. asBYTE b = (asBYTE)c;
  1622. WRITE_NUM(b);
  1623. // Write the first argument
  1624. asWORD w = *(((asWORD*)tmp)+1);
  1625. WRITE_NUM(w);
  1626. // Write the argument
  1627. // TODO: This could be encoded as an int to decrease the size
  1628. asQWORD qw = *(asQWORD*)&tmp[1];
  1629. WRITE_NUM(qw);
  1630. }
  1631. break;
  1632. default:
  1633. {
  1634. // This should never happen
  1635. asASSERT(false);
  1636. // Store the bc as is
  1637. for( int n = 0; n < asBCTypeSize[asBCInfo[c].type]; n++ )
  1638. WRITE_NUM(tmp[n]);
  1639. }
  1640. }
  1641. // Move to the next instruction
  1642. bc += asBCTypeSize[asBCInfo[c].type];
  1643. length -= asBCTypeSize[asBCInfo[c].type];
  1644. }
  1645. }
  1646. void asCRestore::ReadByteCode(asDWORD *bc, int length)
  1647. {
  1648. while( length )
  1649. {
  1650. asBYTE b;
  1651. READ_NUM(b);
  1652. switch( asBCInfo[b].type )
  1653. {
  1654. case asBCTYPE_NO_ARG:
  1655. {
  1656. *(asBYTE*)(bc) = b;
  1657. bc++;
  1658. }
  1659. break;
  1660. case asBCTYPE_W_ARG:
  1661. case asBCTYPE_wW_ARG:
  1662. case asBCTYPE_rW_ARG:
  1663. {
  1664. *(asBYTE*)(bc) = b;
  1665. // Read the argument
  1666. asWORD w;
  1667. READ_NUM(w);
  1668. *(((asWORD*)bc)+1) = w;
  1669. bc++;
  1670. }
  1671. break;
  1672. case asBCTYPE_rW_DW_ARG:
  1673. case asBCTYPE_wW_DW_ARG:
  1674. case asBCTYPE_W_DW_ARG:
  1675. {
  1676. *(asBYTE*)(bc) = b;
  1677. // Read the word argument
  1678. asWORD w;
  1679. READ_NUM(w);
  1680. *(((asWORD*)bc)+1) = w;
  1681. bc++;
  1682. // Read the dword argument
  1683. // TODO: Should be ReadEncodedInt() since we do not know if it is a signed value or not
  1684. *bc++ = ReadEncodedUInt();
  1685. }
  1686. break;
  1687. case asBCTYPE_DW_ARG:
  1688. {
  1689. *(asBYTE*)(bc) = b;
  1690. bc++;
  1691. // Read the argument
  1692. // TODO: Should be ReadEncodedInt() since we do not know if it is a signed value or not
  1693. *bc++ = ReadEncodedUInt();
  1694. }
  1695. break;
  1696. case asBCTYPE_DW_DW_ARG:
  1697. {
  1698. *(asBYTE*)(bc) = b;
  1699. bc++;
  1700. // Read the first argument
  1701. // TODO: Should be ReadEncodedInt() since we do not know if it is a signed value or not
  1702. *bc++ = ReadEncodedUInt();
  1703. // Read the second argument
  1704. // TODO: Should be ReadEncodedInt() since we do not know if it is a signed value or not
  1705. *bc++ = ReadEncodedUInt();
  1706. }
  1707. break;
  1708. case asBCTYPE_wW_rW_rW_ARG:
  1709. {
  1710. *(asBYTE*)(bc) = b;
  1711. // Read the first argument
  1712. asWORD w;
  1713. READ_NUM(w);
  1714. *(((asWORD*)bc)+1) = w;
  1715. bc++;
  1716. // Read the second argument
  1717. READ_NUM(w);
  1718. *(asWORD*)bc = w;
  1719. // Read the third argument
  1720. READ_NUM(w);
  1721. *(((asWORD*)bc)+1) = w;
  1722. bc++;
  1723. }
  1724. break;
  1725. case asBCTYPE_wW_rW_ARG:
  1726. case asBCTYPE_rW_rW_ARG:
  1727. case asBCTYPE_wW_W_ARG:
  1728. {
  1729. *(asBYTE*)(bc) = b;
  1730. // Read the first argument
  1731. asWORD w;
  1732. READ_NUM(w);
  1733. *(((asWORD*)bc)+1) = w;
  1734. bc++;
  1735. // Read the second argument
  1736. READ_NUM(w);
  1737. *(asWORD*)bc = w;
  1738. bc++;
  1739. }
  1740. break;
  1741. case asBCTYPE_wW_rW_DW_ARG:
  1742. case asBCTYPE_rW_W_DW_ARG:
  1743. {
  1744. *(asBYTE*)(bc) = b;
  1745. // Read the first argument
  1746. asWORD w;
  1747. READ_NUM(w);
  1748. *(((asWORD*)bc)+1) = w;
  1749. bc++;
  1750. // Read the second argument
  1751. READ_NUM(w);
  1752. *(asWORD*)bc = w;
  1753. bc++;
  1754. // Read the third argument
  1755. asDWORD dw;
  1756. READ_NUM(dw);
  1757. *bc++ = dw;
  1758. }
  1759. break;
  1760. case asBCTYPE_QW_ARG:
  1761. {
  1762. *(asBYTE*)(bc) = b;
  1763. bc++;
  1764. // Read the argument
  1765. asQWORD qw;
  1766. READ_NUM(qw);
  1767. *(asQWORD*)bc = qw;
  1768. bc += 2;
  1769. }
  1770. break;
  1771. case asBCTYPE_QW_DW_ARG:
  1772. {
  1773. *(asBYTE*)(bc) = b;
  1774. bc++;
  1775. // Read the first argument
  1776. asQWORD qw;
  1777. READ_NUM(qw);
  1778. *(asQWORD*)bc = qw;
  1779. bc += 2;
  1780. // Read the second argument
  1781. asDWORD dw;
  1782. READ_NUM(dw);
  1783. *bc++ = dw;
  1784. }
  1785. break;
  1786. case asBCTYPE_rW_QW_ARG:
  1787. case asBCTYPE_wW_QW_ARG:
  1788. {
  1789. *(asBYTE*)(bc) = b;
  1790. // Read the first argument
  1791. asWORD w;
  1792. READ_NUM(w);
  1793. *(((asWORD*)bc)+1) = w;
  1794. bc++;
  1795. // Read the argument
  1796. asQWORD qw;
  1797. READ_NUM(qw);
  1798. *(asQWORD*)bc = qw;
  1799. bc += 2;
  1800. }
  1801. break;
  1802. default:
  1803. {
  1804. // This should never happen
  1805. asASSERT(false);
  1806. // Read the next 3 bytes
  1807. asDWORD c; asBYTE t;
  1808. #if defined(AS_BIG_ENDIAN)
  1809. c = b << 24;
  1810. READ_NUM(t); c += t << 16;
  1811. READ_NUM(t); c += t << 8;
  1812. READ_NUM(t); c += t;
  1813. #else
  1814. c = b;
  1815. READ_NUM(t); c += t << 8;
  1816. READ_NUM(t); c += t << 16;
  1817. READ_NUM(t); c += t << 24;
  1818. #endif
  1819. *bc++ = c;
  1820. c = *(asBYTE*)&c;
  1821. // Read the bc as is
  1822. for( int n = 1; n < asBCTypeSize[asBCInfo[c].type]; n++ )
  1823. READ_NUM(*bc++);
  1824. }
  1825. }
  1826. length -= asBCTypeSize[asBCInfo[b].type];
  1827. }
  1828. }
  1829. void asCRestore::WriteUsedTypeIds()
  1830. {
  1831. asUINT count = (asUINT)usedTypeIds.GetLength();
  1832. WriteEncodedUInt(count);
  1833. for( asUINT n = 0; n < count; n++ )
  1834. WriteDataType(engine->GetDataTypeFromTypeId(usedTypeIds[n]));
  1835. }
  1836. void asCRestore::ReadUsedTypeIds()
  1837. {
  1838. asUINT count = ReadEncodedUInt();
  1839. usedTypeIds.SetLength(count);
  1840. for( asUINT n = 0; n < count; n++ )
  1841. {
  1842. asCDataType dt;
  1843. ReadDataType(&dt);
  1844. usedTypeIds[n] = engine->GetTypeIdFromDataType(dt);
  1845. }
  1846. }
  1847. int asCRestore::FindGlobalPropPtrIndex(void *ptr)
  1848. {
  1849. int i = usedGlobalProperties.IndexOf(ptr);
  1850. if( i >= 0 ) return i;
  1851. usedGlobalProperties.PushLast(ptr);
  1852. return (int)usedGlobalProperties.GetLength()-1;
  1853. }
  1854. void asCRestore::WriteUsedGlobalProps()
  1855. {
  1856. int c = (int)usedGlobalProperties.GetLength();
  1857. WriteEncodedUInt(c);
  1858. for( int n = 0; n < c; n++ )
  1859. {
  1860. size_t *p = (size_t*)usedGlobalProperties[n];
  1861. // First search for the global in the module
  1862. char moduleProp = 0;
  1863. asCGlobalProperty *prop = 0;
  1864. for( int i = 0; i < (signed)module->scriptGlobals.GetLength(); i++ )
  1865. {
  1866. if( p == module->scriptGlobals[i]->GetAddressOfValue() )
  1867. {
  1868. prop = module->scriptGlobals[i];
  1869. moduleProp = 1;
  1870. break;
  1871. }
  1872. }
  1873. // If it is not in the module, it must be an application registered property
  1874. if( !prop )
  1875. {
  1876. for( int i = 0; i < (signed)engine->registeredGlobalProps.GetLength(); i++ )
  1877. {
  1878. if( engine->registeredGlobalProps[i]->GetAddressOfValue() == p )
  1879. {
  1880. prop = engine->registeredGlobalProps[i];
  1881. break;
  1882. }
  1883. }
  1884. }
  1885. asASSERT(prop);
  1886. // Store the name and type of the property so we can find it again on loading
  1887. WriteString(&prop->name);
  1888. WriteDataType(&prop->type);
  1889. // Also store whether the property is a module property or a registered property
  1890. WRITE_NUM(moduleProp);
  1891. }
  1892. }
  1893. void asCRestore::ReadUsedGlobalProps()
  1894. {
  1895. int c = ReadEncodedUInt();
  1896. usedGlobalProperties.SetLength(c);
  1897. for( int n = 0; n < c; n++ )
  1898. {
  1899. asCString name;
  1900. asCDataType type;
  1901. char moduleProp;
  1902. ReadString(&name);
  1903. ReadDataType(&type);
  1904. READ_NUM(moduleProp);
  1905. // Find the real property
  1906. void *prop = 0;
  1907. if( moduleProp )
  1908. {
  1909. for( asUINT p = 0; p < module->scriptGlobals.GetLength(); p++ )
  1910. {
  1911. if( module->scriptGlobals[p]->name == name &&
  1912. module->scriptGlobals[p]->type == type )
  1913. {
  1914. prop = module->scriptGlobals[p]->GetAddressOfValue();
  1915. break;
  1916. }
  1917. }
  1918. }
  1919. else
  1920. {
  1921. for( asUINT p = 0; p < engine->registeredGlobalProps.GetLength(); p++ )
  1922. {
  1923. if( engine->registeredGlobalProps[p] &&
  1924. engine->registeredGlobalProps[p]->name == name &&
  1925. engine->registeredGlobalProps[p]->type == type )
  1926. {
  1927. prop = engine->registeredGlobalProps[p]->GetAddressOfValue();
  1928. break;
  1929. }
  1930. }
  1931. }
  1932. usedGlobalProperties[n] = prop;
  1933. if( prop == 0 )
  1934. {
  1935. // TODO: Write error message to the callback
  1936. error = true;
  1937. }
  1938. }
  1939. }
  1940. void asCRestore::WriteUsedObjectProps()
  1941. {
  1942. int c = (int)usedObjectProperties.GetLength();
  1943. WriteEncodedUInt(c);
  1944. for( asUINT n = 0; n < usedObjectProperties.GetLength(); n++ )
  1945. {
  1946. asCObjectType *objType = usedObjectProperties[n].objType;
  1947. WriteObjectType(objType);
  1948. // Find the property name
  1949. for( asUINT p = 0; p < objType->properties.GetLength(); p++ )
  1950. {
  1951. if( objType->properties[p]->byteOffset == usedObjectProperties[n].offset )
  1952. {
  1953. WriteString(&objType->properties[p]->name);
  1954. break;
  1955. }
  1956. }
  1957. }
  1958. }
  1959. void asCRestore::ReadUsedObjectProps()
  1960. {
  1961. asUINT c = ReadEncodedUInt();
  1962. usedObjectProperties.SetLength(c);
  1963. for( asUINT n = 0; n < c; n++ )
  1964. {
  1965. asCObjectType *objType = ReadObjectType();
  1966. if( objType == 0 )
  1967. {
  1968. // TODO: Write error message to callback
  1969. error = true;
  1970. break;
  1971. }
  1972. asCString name;
  1973. ReadString(&name);
  1974. // Find the property offset
  1975. bool found = false;
  1976. for( asUINT p = 0; p < objType->properties.GetLength(); p++ )
  1977. {
  1978. if( objType->properties[p]->name == name )
  1979. {
  1980. usedObjectProperties[n].objType = objType;
  1981. usedObjectProperties[n].offset = objType->properties[p]->byteOffset;
  1982. found = true;
  1983. break;
  1984. }
  1985. }
  1986. if( !found )
  1987. {
  1988. // TODO: Write error message to callback
  1989. error = true;
  1990. return;
  1991. }
  1992. }
  1993. }
  1994. //---------------------------------------------------------------------------------------------------
  1995. // Miscellaneous
  1996. //---------------------------------------------------------------------------------------------------
  1997. int asCRestore::FindObjectPropIndex(short offset, int typeId)
  1998. {
  1999. asCObjectType *objType = engine->GetObjectTypeFromTypeId(typeId);
  2000. for( asUINT n = 0; n < usedObjectProperties.GetLength(); n++ )
  2001. {
  2002. if( usedObjectProperties[n].objType == objType &&
  2003. usedObjectProperties[n].offset == offset )
  2004. return n;
  2005. }
  2006. SObjProp prop = {objType, offset};
  2007. usedObjectProperties.PushLast(prop);
  2008. return (int)usedObjectProperties.GetLength() - 1;
  2009. }
  2010. short asCRestore::FindObjectPropOffset(asWORD index)
  2011. {
  2012. if( index >= usedObjectProperties.GetLength() )
  2013. {
  2014. // TODO: Write to message callback
  2015. asASSERT(false);
  2016. error = true;
  2017. return 0;
  2018. }
  2019. return (short)usedObjectProperties[index].offset;
  2020. }
  2021. int asCRestore::FindFunctionIndex(asCScriptFunction *func)
  2022. {
  2023. for( asUINT n = 0; n < usedFunctions.GetLength(); n++ )
  2024. {
  2025. if( usedFunctions[n] == func )
  2026. return n;
  2027. }
  2028. usedFunctions.PushLast(func);
  2029. return (int)usedFunctions.GetLength() - 1;
  2030. }
  2031. asCScriptFunction *asCRestore::FindFunction(int idx)
  2032. {
  2033. if( idx >= 0 && idx < (int)usedFunctions.GetLength() )
  2034. return usedFunctions[idx];
  2035. else
  2036. {
  2037. // TODO: Write to message callback
  2038. error = true;
  2039. return 0;
  2040. }
  2041. }
  2042. void asCRestore::TranslateFunction(asCScriptFunction *func)
  2043. {
  2044. asUINT n;
  2045. asDWORD *bc = func->byteCode.AddressOf();
  2046. for( n = 0; n < func->byteCode.GetLength(); )
  2047. {
  2048. int c = *(asBYTE*)&bc[n];
  2049. if( c == asBC_FREE ||
  2050. c == asBC_REFCPY || c == asBC_OBJTYPE )
  2051. {
  2052. // Translate the index to the true object type
  2053. asPTRWORD *ot = (asPTRWORD*)&bc[n+1];
  2054. *(asCObjectType**)ot = FindObjectType(*(int*)ot);
  2055. }
  2056. else if( c == asBC_TYPEID ||
  2057. c == asBC_Cast )
  2058. {
  2059. // Translate the index to the type id
  2060. int *tid = (int*)&bc[n+1];
  2061. *tid = FindTypeId(*tid);
  2062. }
  2063. else if( c == asBC_ADDSi ||
  2064. c == asBC_LoadThisR )
  2065. {
  2066. // Translate the index to the type id
  2067. int *tid = (int*)&bc[n+1];
  2068. *tid = FindTypeId(*tid);
  2069. // Translate the prop index into the property offset
  2070. *(((short*)&bc[n])+1) = FindObjectPropOffset(*(((short*)&bc[n])+1));
  2071. }
  2072. else if( c == asBC_LoadRObjR ||
  2073. c == asBC_LoadVObjR )
  2074. {
  2075. // Translate the index to the type id
  2076. int *tid = (int*)&bc[n+2];
  2077. *tid = FindTypeId(*tid);
  2078. // Translate the prop index into the property offset
  2079. *(((short*)&bc[n])+2) = FindObjectPropOffset(*(((short*)&bc[n])+2));
  2080. }
  2081. else if( c == asBC_COPY )
  2082. {
  2083. // Translate the index to the type id
  2084. int *tid = (int*)&bc[n+1];
  2085. *tid = FindTypeId(*tid);
  2086. // COPY is used to copy POD types that don't have the opAssign method
  2087. // Update the number of dwords to copy as it may be different on the target platform
  2088. const asCDataType *dt = engine->GetDataTypeFromTypeId(*tid);
  2089. if( dt == 0 )
  2090. {
  2091. // TODO: Write error to message
  2092. error = true;
  2093. }
  2094. else
  2095. asBC_SWORDARG0(&bc[n]) = (short)dt->GetSizeInMemoryDWords();
  2096. }
  2097. else if( c == asBC_CALL ||
  2098. c == asBC_CALLINTF ||
  2099. c == asBC_CALLSYS )
  2100. {
  2101. // Translate the index to the func id
  2102. int *fid = (int*)&bc[n+1];
  2103. asCScriptFunction *f = FindFunction(*fid);
  2104. if( f )
  2105. *fid = f->id;
  2106. else
  2107. {
  2108. // TODO: Write to message callback
  2109. error = true;
  2110. return;
  2111. }
  2112. }
  2113. else if( c == asBC_FuncPtr )
  2114. {
  2115. // Translate the index to the func pointer
  2116. asPTRWORD *fid = (asPTRWORD*)&bc[n+1];
  2117. *fid = (asPTRWORD)(size_t)FindFunction((int)*fid);
  2118. }
  2119. else if( c == asBC_ALLOC )
  2120. {
  2121. // Translate the index to the true object type
  2122. asPTRWORD *arg = (asPTRWORD*)&bc[n+1];
  2123. *(asCObjectType**)arg = FindObjectType(*(int*)arg);
  2124. // If the object type is a script class then the constructor id must be translated
  2125. asCObjectType *ot = *(asCObjectType**)arg;
  2126. if( ot && (ot->flags & asOBJ_SCRIPT_OBJECT) )
  2127. {
  2128. int *fid = (int*)&bc[n+1+AS_PTR_SIZE];
  2129. asCScriptFunction *f = FindFunction(*fid);
  2130. if( f )
  2131. *fid = f->id;
  2132. else
  2133. {
  2134. // TODO: Write to message callback
  2135. error = true;
  2136. return;
  2137. }
  2138. }
  2139. }
  2140. else if( c == asBC_STR )
  2141. {
  2142. // Translate the index to the true string id
  2143. asWORD *arg = ((asWORD*)&bc[n])+1;
  2144. if( *arg < usedStringConstants.GetLength() )
  2145. *arg = (asWORD)usedStringConstants[*arg];
  2146. else
  2147. {
  2148. // TODO: Write to message callback
  2149. error = true;
  2150. return;
  2151. }
  2152. }
  2153. else if( c == asBC_CALLBND )
  2154. {
  2155. // Translate the function id
  2156. asUINT *fid = (asUINT*)&bc[n+1];
  2157. if( *fid < module->bindInformations.GetLength() )
  2158. {
  2159. sBindInfo *bi = module->bindInformations[*fid];
  2160. if( bi )
  2161. *fid = bi->importedFunctionSignature->id;
  2162. else
  2163. {
  2164. // TODO: Write to message callback
  2165. error = true;
  2166. return;
  2167. }
  2168. }
  2169. else
  2170. {
  2171. // TODO: Write to message callback
  2172. error = true;
  2173. return;
  2174. }
  2175. }
  2176. else if( c == asBC_PGA ||
  2177. c == asBC_LDG ||
  2178. c == asBC_PshG4 ||
  2179. c == asBC_LdGRdR4 ||
  2180. c == asBC_CpyGtoV4 ||
  2181. c == asBC_CpyVtoG4 ||
  2182. c == asBC_SetG4 )
  2183. {
  2184. // Translate the global var index to pointer
  2185. asPTRWORD *index = (asPTRWORD*)&bc[n+1];
  2186. if( *(asUINT*)index < usedGlobalProperties.GetLength() )
  2187. *(void**)index = usedGlobalProperties[*(asUINT*)index];
  2188. else
  2189. {
  2190. // TODO: Write to message callback
  2191. error = true;
  2192. return;
  2193. }
  2194. }
  2195. n += asBCTypeSize[asBCInfo[c].type];
  2196. }
  2197. // As the bytecode may have been generated on a different platform it is necessary
  2198. // to adjust the bytecode in case any of the value types allocated on the stack has
  2199. // a different size on this platform.
  2200. asCArray<int> adjustments;
  2201. for( n = 0; n < func->objVariableTypes.GetLength(); n++ )
  2202. {
  2203. if( func->objVariableTypes[n] &&
  2204. (func->objVariableTypes[n]->GetFlags() & asOBJ_VALUE) &&
  2205. !func->objVariableIsOnHeap[n] )
  2206. {
  2207. // Check if type has a different size than originally
  2208. for( asUINT s = 0; s < oldObjectSizes.GetLength(); s++ )
  2209. {
  2210. if( oldObjectSizes[s].objType == func->objVariableTypes[n] &&
  2211. oldObjectSizes[s].oldSize != func->objVariableTypes[n]->GetSize() )
  2212. {
  2213. // How much needs to be adjusted?
  2214. int newSize = func->objVariableTypes[n]->GetSize();
  2215. newSize = newSize < 4 ? 1 : newSize/4;
  2216. int oldSize = oldObjectSizes[s].oldSize;
  2217. oldSize = oldSize < 4 ? 1 : oldSize/4;
  2218. int adjust = newSize - oldSize;
  2219. if( adjust != 0 )
  2220. {
  2221. adjustments.PushLast(func->objVariablePos[n]);
  2222. adjustments.PushLast(adjust);
  2223. }
  2224. }
  2225. }
  2226. }
  2227. }
  2228. asCArray<int> adjustByPos(func->stackNeeded);
  2229. if( adjustments.GetLength() )
  2230. {
  2231. adjustByPos.SetLength(func->stackNeeded);
  2232. memset(adjustByPos.AddressOf(), 0, adjustByPos.GetLength()*sizeof(int));
  2233. // Build look-up table with the adjustments for each stack position
  2234. for( n = 0; n < adjustments.GetLength(); n+=2 )
  2235. {
  2236. int pos = adjustments[n];
  2237. int adjust = adjustments[n+1];
  2238. for( asUINT i = pos; i < adjustByPos.GetLength(); i++ )
  2239. adjustByPos[i] += adjust;
  2240. }
  2241. // Adjust all variable positions
  2242. asDWORD *bc = func->byteCode.AddressOf();
  2243. for( n = 0; n < func->byteCode.GetLength(); )
  2244. {
  2245. int c = *(asBYTE*)&bc[n];
  2246. switch( asBCInfo[c].type )
  2247. {
  2248. case asBCTYPE_wW_ARG:
  2249. case asBCTYPE_rW_DW_ARG:
  2250. case asBCTYPE_wW_QW_ARG:
  2251. case asBCTYPE_rW_ARG:
  2252. case asBCTYPE_wW_DW_ARG:
  2253. case asBCTYPE_wW_W_ARG:
  2254. case asBCTYPE_rW_QW_ARG:
  2255. case asBCTYPE_rW_W_DW_ARG:
  2256. {
  2257. short var = asBC_SWORDARG0(&bc[n]);
  2258. if( var >= (int)adjustByPos.GetLength() )
  2259. error = true;
  2260. else if( var >= 0 )
  2261. asBC_SWORDARG0(&bc[n]) += (short)adjustByPos[var];
  2262. }
  2263. break;
  2264. case asBCTYPE_wW_rW_ARG:
  2265. case asBCTYPE_wW_rW_DW_ARG:
  2266. case asBCTYPE_rW_rW_ARG:
  2267. {
  2268. short var = asBC_SWORDARG0(&bc[n]);
  2269. if( var >= (int)adjustByPos.GetLength() )
  2270. error = true;
  2271. else if( var >= 0 )
  2272. asBC_SWORDARG0(&bc[n]) += (short)adjustByPos[var];
  2273. var = asBC_SWORDARG1(&bc[n]);
  2274. if( var >= (int)adjustByPos.GetLength() )
  2275. error = true;
  2276. else if( var >= 0 )
  2277. asBC_SWORDARG1(&bc[n]) += (short)adjustByPos[var];
  2278. }
  2279. break;
  2280. case asBCTYPE_wW_rW_rW_ARG:
  2281. {
  2282. short var = asBC_SWORDARG0(&bc[n]);
  2283. if( var >= (int)adjustByPos.GetLength() )
  2284. error = true;
  2285. else if( var >= 0 )
  2286. asBC_SWORDARG0(&bc[n]) += (short)adjustByPos[var];
  2287. var = asBC_SWORDARG1(&bc[n]);
  2288. if( var >= (int)adjustByPos.GetLength() )
  2289. error = true;
  2290. else if( var >= 0 )
  2291. asBC_SWORDARG1(&bc[n]) += (short)adjustByPos[var];
  2292. var = asBC_SWORDARG2(&bc[n]);
  2293. if( var >= (int)adjustByPos.GetLength() )
  2294. error = true;
  2295. else if( var >= 0 )
  2296. asBC_SWORDARG2(&bc[n]) += (short)adjustByPos[var];
  2297. }
  2298. break;
  2299. default:
  2300. // The other types don't treat variables so won't be modified
  2301. break;
  2302. }
  2303. if( c == asBC_PUSH )
  2304. {
  2305. // TODO: Maybe the push instruction should be removed, and be kept in
  2306. // the asCScriptFunction as a property instead. CallScriptFunction
  2307. // can immediately reserve the space
  2308. // PUSH is only used to reserve stack space for variables
  2309. asBC_WORDARG0(&bc[n]) += (asWORD)adjustByPos[adjustByPos.GetLength()-1];
  2310. }
  2311. n += asBCTypeSize[asBCInfo[c].type];
  2312. }
  2313. // objVariablePos
  2314. for( n = 0; n < func->objVariablePos.GetLength(); n++ )
  2315. {
  2316. if( func->objVariablePos[n] >= (int)adjustByPos.GetLength() )
  2317. error = true;
  2318. else if( func->objVariablePos[n] >= 0 )
  2319. func->objVariablePos[n] += adjustByPos[func->objVariablePos[n]];
  2320. }
  2321. // objVariableInfo[x].variableOffset // TODO: should be an index into the objVariablePos array
  2322. for( n = 0; n < func->objVariableInfo.GetLength(); n++ )
  2323. {
  2324. if( func->objVariableInfo[n].variableOffset >= (int)adjustByPos.GetLength() )
  2325. error = true;
  2326. else if( func->objVariableInfo[n].variableOffset >= 0 )
  2327. func->objVariableInfo[n].variableOffset += adjustByPos[func->objVariableInfo[n].variableOffset];
  2328. }
  2329. // variables[x].stackOffset
  2330. for( n = 0; n < func->variables.GetLength(); n++ )
  2331. {
  2332. if( func->variables[n]->stackOffset >= (int)adjustByPos.GetLength() )
  2333. error = true;
  2334. else if( func->variables[n]->stackOffset >= 0 )
  2335. func->variables[n]->stackOffset += adjustByPos[func->variables[n]->stackOffset];
  2336. }
  2337. // The stack needed by the function will be adjusted by the highest variable shift
  2338. // TODO: When bytecode is adjusted for 32/64bit it is necessary to adjust
  2339. // also for pointers pushed on the stack as function arguments
  2340. func->stackNeeded += adjustByPos[adjustByPos.GetLength()-1];
  2341. }
  2342. }
  2343. int asCRestore::FindTypeIdIdx(int typeId)
  2344. {
  2345. asUINT n;
  2346. for( n = 0; n < usedTypeIds.GetLength(); n++ )
  2347. {
  2348. if( usedTypeIds[n] == typeId )
  2349. return n;
  2350. }
  2351. usedTypeIds.PushLast(typeId);
  2352. return (int)usedTypeIds.GetLength() - 1;
  2353. }
  2354. int asCRestore::FindTypeId(int idx)
  2355. {
  2356. if( idx >= 0 && idx < (int)usedTypeIds.GetLength() )
  2357. return usedTypeIds[idx];
  2358. else
  2359. {
  2360. // TODO: Write to message callback
  2361. error = true;
  2362. return 0;
  2363. }
  2364. }
  2365. int asCRestore::FindObjectTypeIdx(asCObjectType *obj)
  2366. {
  2367. asUINT n;
  2368. for( n = 0; n < usedTypes.GetLength(); n++ )
  2369. {
  2370. if( usedTypes[n] == obj )
  2371. return n;
  2372. }
  2373. usedTypes.PushLast(obj);
  2374. return (int)usedTypes.GetLength() - 1;
  2375. }
  2376. asCObjectType *asCRestore::FindObjectType(int idx)
  2377. {
  2378. if( idx < 0 || idx >= (int)usedTypes.GetLength() )
  2379. {
  2380. // TODO: Write to message callback
  2381. error = true;
  2382. return 0;
  2383. }
  2384. return usedTypes[idx];
  2385. }
  2386. END_AS_NAMESPACE