as_restore.cpp 74 KB

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