as_restore.cpp 65 KB

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