as_restore.cpp 72 KB

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