as_module.cpp 36 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430
  1. /*
  2. AngelCode Scripting Library
  3. Copyright (c) 2003-2014 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_module.cpp
  25. //
  26. // A class that holds a script module
  27. //
  28. #include "as_config.h"
  29. #include "as_module.h"
  30. #include "as_builder.h"
  31. #include "as_context.h"
  32. #include "as_texts.h"
  33. #include "as_debug.h"
  34. #include "as_restore.h"
  35. BEGIN_AS_NAMESPACE
  36. // internal
  37. asCModule::asCModule(const char *name, asCScriptEngine *engine)
  38. {
  39. this->name = name;
  40. this->engine = engine;
  41. userData = 0;
  42. builder = 0;
  43. isGlobalVarInitialized = false;
  44. accessMask = 1;
  45. defaultNamespace = engine->nameSpaces[0];
  46. }
  47. // internal
  48. asCModule::~asCModule()
  49. {
  50. InternalReset();
  51. if( builder )
  52. {
  53. asDELETE(builder,asCBuilder);
  54. builder = 0;
  55. }
  56. if( engine )
  57. {
  58. // Clean the user data
  59. for( asUINT n = 0; n < userData.GetLength(); n += 2 )
  60. {
  61. if( userData[n+1] )
  62. {
  63. for( asUINT c = 0; c < engine->cleanModuleFuncs.GetLength(); c++ )
  64. if( engine->cleanModuleFuncs[c].type == userData[n] )
  65. engine->cleanModuleFuncs[c].cleanFunc(this);
  66. }
  67. }
  68. // Remove the module from the engine
  69. if( engine->lastModule == this )
  70. engine->lastModule = 0;
  71. engine->scriptModules.RemoveValue(this);
  72. }
  73. }
  74. // interface
  75. void asCModule::Discard()
  76. {
  77. asDELETE(this,asCModule);
  78. }
  79. // interface
  80. void *asCModule::SetUserData(void *data, asPWORD type)
  81. {
  82. // As a thread might add a new new user data at the same time as another
  83. // it is necessary to protect both read and write access to the userData member
  84. ACQUIREEXCLUSIVE(engine->engineRWLock);
  85. // It is not intended to store a lot of different types of userdata,
  86. // so a more complex structure like a associative map would just have
  87. // more overhead than a simple array.
  88. for( asUINT n = 0; n < userData.GetLength(); n += 2 )
  89. {
  90. if( userData[n] == type )
  91. {
  92. void *oldData = reinterpret_cast<void*>(userData[n+1]);
  93. userData[n+1] = reinterpret_cast<asPWORD>(data);
  94. RELEASEEXCLUSIVE(engine->engineRWLock);
  95. return oldData;
  96. }
  97. }
  98. userData.PushLast(type);
  99. userData.PushLast(reinterpret_cast<asPWORD>(data));
  100. RELEASEEXCLUSIVE(engine->engineRWLock);
  101. return 0;
  102. }
  103. // interface
  104. void *asCModule::GetUserData(asPWORD type) const
  105. {
  106. // There may be multiple threads reading, but when
  107. // setting the user data nobody must be reading.
  108. ACQUIRESHARED(engine->engineRWLock);
  109. for( asUINT n = 0; n < userData.GetLength(); n += 2 )
  110. {
  111. if( userData[n] == type )
  112. {
  113. RELEASESHARED(engine->engineRWLock);
  114. return reinterpret_cast<void*>(userData[n+1]);
  115. }
  116. }
  117. RELEASESHARED(engine->engineRWLock);
  118. return 0;
  119. }
  120. // interface
  121. asIScriptEngine *asCModule::GetEngine() const
  122. {
  123. return engine;
  124. }
  125. // interface
  126. void asCModule::SetName(const char *name)
  127. {
  128. this->name = name;
  129. }
  130. // interface
  131. const char *asCModule::GetName() const
  132. {
  133. return name.AddressOf();
  134. }
  135. // interface
  136. const char *asCModule::GetDefaultNamespace() const
  137. {
  138. return defaultNamespace->name.AddressOf();
  139. }
  140. // interface
  141. int asCModule::SetDefaultNamespace(const char *nameSpace)
  142. {
  143. // TODO: cleanup: This function is similar to asCScriptEngine::SetDefaultNamespace. Can we reuse the code?
  144. if( nameSpace == 0 )
  145. return asINVALID_ARG;
  146. asCString ns = nameSpace;
  147. if( ns != "" )
  148. {
  149. // Make sure the namespace is composed of alternating identifier and ::
  150. size_t pos = 0;
  151. bool expectIdentifier = true;
  152. size_t len;
  153. eTokenType t = ttIdentifier;
  154. for( ; pos < ns.GetLength(); pos += len )
  155. {
  156. t = engine->tok.GetToken(ns.AddressOf() + pos, ns.GetLength() - pos, &len);
  157. if( (expectIdentifier && t != ttIdentifier) || (!expectIdentifier && t != ttScope) )
  158. return asINVALID_DECLARATION;
  159. expectIdentifier = !expectIdentifier;
  160. }
  161. // If the namespace ends with :: then strip it off
  162. if( t == ttScope )
  163. ns.SetLength(ns.GetLength()-2);
  164. }
  165. defaultNamespace = engine->AddNameSpace(ns.AddressOf());
  166. return 0;
  167. }
  168. // interface
  169. int asCModule::AddScriptSection(const char *name, const char *code, size_t codeLength, int lineOffset)
  170. {
  171. #ifdef AS_NO_COMPILER
  172. UNUSED_VAR(name);
  173. UNUSED_VAR(code);
  174. UNUSED_VAR(codeLength);
  175. UNUSED_VAR(lineOffset);
  176. return asNOT_SUPPORTED;
  177. #else
  178. if( !builder )
  179. {
  180. builder = asNEW(asCBuilder)(engine, this);
  181. if( builder == 0 )
  182. return asOUT_OF_MEMORY;
  183. }
  184. return builder->AddCode(name, code, (int)codeLength, lineOffset, (int)engine->GetScriptSectionNameIndex(name ? name : ""), engine->ep.copyScriptSections);
  185. #endif
  186. }
  187. // internal
  188. void asCModule::JITCompile()
  189. {
  190. asIJITCompiler *jit = engine->GetJITCompiler();
  191. if( !jit )
  192. return;
  193. for (unsigned int i = 0; i < scriptFunctions.GetLength(); i++)
  194. scriptFunctions[i]->JITCompile();
  195. }
  196. // interface
  197. int asCModule::Build()
  198. {
  199. #ifdef AS_NO_COMPILER
  200. return asNOT_SUPPORTED;
  201. #else
  202. TimeIt("asCModule::Build");
  203. // Only one thread may build at one time
  204. // TODO: It should be possible to have multiple threads perform compilations
  205. int r = engine->RequestBuild();
  206. if( r < 0 )
  207. return r;
  208. engine->PrepareEngine();
  209. if( engine->configFailed )
  210. {
  211. engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, TXT_INVALID_CONFIGURATION);
  212. engine->BuildCompleted();
  213. return asINVALID_CONFIGURATION;
  214. }
  215. InternalReset();
  216. if( !builder )
  217. {
  218. engine->BuildCompleted();
  219. return asSUCCESS;
  220. }
  221. // Compile the script
  222. r = builder->Build();
  223. asDELETE(builder,asCBuilder);
  224. builder = 0;
  225. if( r < 0 )
  226. {
  227. // Reset module again
  228. InternalReset();
  229. engine->BuildCompleted();
  230. return r;
  231. }
  232. JITCompile();
  233. engine->PrepareEngine();
  234. #ifdef AS_DEBUG
  235. // Verify that there are no unwanted gaps in the scriptFunctions array.
  236. for( asUINT n = 1; n < engine->scriptFunctions.GetLength(); n++ )
  237. {
  238. int id = n;
  239. if( engine->scriptFunctions[n] == 0 && !engine->freeScriptFunctionIds.Exists(id) )
  240. asASSERT( false );
  241. }
  242. #endif
  243. engine->BuildCompleted();
  244. // Initialize global variables
  245. if( r >= 0 && engine->ep.initGlobalVarsAfterBuild )
  246. r = ResetGlobalVars(0);
  247. return r;
  248. #endif
  249. }
  250. // interface
  251. int asCModule::ResetGlobalVars(asIScriptContext *ctx)
  252. {
  253. if( isGlobalVarInitialized )
  254. CallExit();
  255. return CallInit(ctx);
  256. }
  257. // interface
  258. asIScriptFunction *asCModule::GetFunctionByIndex(asUINT index) const
  259. {
  260. return const_cast<asCScriptFunction*>(globalFunctions.Get(index));
  261. }
  262. // internal
  263. int asCModule::CallInit(asIScriptContext *myCtx)
  264. {
  265. if( isGlobalVarInitialized )
  266. return asERROR;
  267. // Each global variable needs to be cleared individually
  268. asCSymbolTableIterator<asCGlobalProperty> it = scriptGlobals.List();
  269. while( it )
  270. {
  271. asCGlobalProperty *desc = *it;
  272. memset(desc->GetAddressOfValue(), 0, sizeof(asDWORD)*desc->type.GetSizeOnStackDWords());
  273. it++;
  274. }
  275. // Call the init function for each of the global variables
  276. asIScriptContext *ctx = myCtx;
  277. int r = asEXECUTION_FINISHED;
  278. it = scriptGlobals.List();
  279. while( it && r == asEXECUTION_FINISHED )
  280. {
  281. asCGlobalProperty *desc = *it;
  282. it++;
  283. if( desc->GetInitFunc() )
  284. {
  285. if( ctx == 0 )
  286. {
  287. r = engine->CreateContext(&ctx, true);
  288. if( r < 0 )
  289. break;
  290. }
  291. r = ctx->Prepare(desc->GetInitFunc());
  292. if( r >= 0 )
  293. {
  294. r = ctx->Execute();
  295. if( r != asEXECUTION_FINISHED )
  296. {
  297. asCString msg;
  298. msg.Format(TXT_FAILED_TO_INITIALIZE_s, desc->name.AddressOf());
  299. asCScriptFunction *func = desc->GetInitFunc();
  300. engine->WriteMessage(func->scriptData->scriptSectionIdx >= 0 ? engine->scriptSectionNames[func->scriptData->scriptSectionIdx]->AddressOf() : "",
  301. func->GetLineNumber(0, 0) & 0xFFFFF,
  302. func->GetLineNumber(0, 0) >> 20,
  303. asMSGTYPE_ERROR,
  304. msg.AddressOf());
  305. if( r == asEXECUTION_EXCEPTION )
  306. {
  307. const asIScriptFunction *function = ctx->GetExceptionFunction();
  308. msg.Format(TXT_EXCEPTION_s_IN_s, ctx->GetExceptionString(), function->GetDeclaration());
  309. engine->WriteMessage(function->GetScriptSectionName(),
  310. ctx->GetExceptionLineNumber(),
  311. 0,
  312. asMSGTYPE_INFORMATION,
  313. msg.AddressOf());
  314. }
  315. }
  316. }
  317. }
  318. }
  319. if( ctx && !myCtx )
  320. {
  321. ctx->Release();
  322. ctx = 0;
  323. }
  324. // Even if the initialization failed we need to set the
  325. // flag that the variables have been initialized, otherwise
  326. // the module won't free those variables that really were
  327. // initialized.
  328. isGlobalVarInitialized = true;
  329. if( r != asEXECUTION_FINISHED )
  330. return asINIT_GLOBAL_VARS_FAILED;
  331. return asSUCCESS;
  332. }
  333. // internal
  334. void asCModule::CallExit()
  335. {
  336. if( !isGlobalVarInitialized ) return;
  337. asCSymbolTableIterator<asCGlobalProperty> it = scriptGlobals.List();
  338. while( it )
  339. {
  340. if( (*it)->type.IsObject() )
  341. {
  342. void **obj = (void**)(*it)->GetAddressOfValue();
  343. if( *obj )
  344. {
  345. asCObjectType *ot = (*it)->type.GetObjectType();
  346. if( ot->flags & asOBJ_REF )
  347. {
  348. asASSERT( (ot->flags & asOBJ_NOCOUNT) || ot->beh.release );
  349. if( ot->beh.release )
  350. engine->CallObjectMethod(*obj, ot->beh.release);
  351. }
  352. else
  353. {
  354. if( ot->beh.destruct )
  355. engine->CallObjectMethod(*obj, ot->beh.destruct);
  356. engine->CallFree(*obj);
  357. }
  358. // Set the address to 0 as someone might try to access the variable afterwards
  359. *obj = 0;
  360. }
  361. }
  362. it++;
  363. }
  364. isGlobalVarInitialized = false;
  365. }
  366. // internal
  367. void asCModule::InternalReset()
  368. {
  369. CallExit();
  370. size_t n;
  371. // Release all global functions
  372. asCSymbolTable<asCScriptFunction>::iterator funcIt = globalFunctions.List();
  373. for( ; funcIt; funcIt++ )
  374. (*funcIt)->Release();
  375. globalFunctions.Clear();
  376. // First release all compiled functions
  377. for( n = 0; n < scriptFunctions.GetLength(); n++ )
  378. if( scriptFunctions[n] )
  379. scriptFunctions[n]->Orphan(this);
  380. scriptFunctions.SetLength(0);
  381. // Release the global properties declared in the module
  382. asCSymbolTableIterator<asCGlobalProperty> globIt = scriptGlobals.List();
  383. while( globIt )
  384. {
  385. (*globIt)->Orphan(this);
  386. globIt++;
  387. }
  388. scriptGlobals.Clear();
  389. UnbindAllImportedFunctions();
  390. // Free bind information
  391. for( n = 0; n < bindInformations.GetLength(); n++ )
  392. {
  393. if( bindInformations[n] )
  394. {
  395. asUINT id = bindInformations[n]->importedFunctionSignature->id & ~FUNC_IMPORTED;
  396. engine->importedFunctions[id] = 0;
  397. engine->freeImportedFunctionIdxs.PushLast(id);
  398. asDELETE(bindInformations[n]->importedFunctionSignature, asCScriptFunction);
  399. asDELETE(bindInformations[n], sBindInfo);
  400. }
  401. }
  402. bindInformations.SetLength(0);
  403. // Free declared types, including classes, typedefs, and enums
  404. // TODO: optimize: Check if it is possible to destroy the object directly without notifying the GC
  405. for( n = 0; n < classTypes.GetLength(); n++ )
  406. classTypes[n]->Orphan(this);
  407. classTypes.SetLength(0);
  408. for( n = 0; n < enumTypes.GetLength(); n++ )
  409. enumTypes[n]->Release();
  410. enumTypes.SetLength(0);
  411. for( n = 0; n < typeDefs.GetLength(); n++ )
  412. typeDefs[n]->Release();
  413. typeDefs.SetLength(0);
  414. // Free funcdefs
  415. for( n = 0; n < funcDefs.GetLength(); n++ )
  416. {
  417. // The funcdefs are not removed from the engine at this moment as they may still be referred
  418. // to by other types. The engine's ClearUnusedTypes will take care of the clean up.
  419. funcDefs[n]->Release();
  420. }
  421. funcDefs.SetLength(0);
  422. // Allow the engine to clean up what is not used
  423. engine->CleanupAfterDiscardModule();
  424. asASSERT( IsEmpty() );
  425. }
  426. // interface
  427. asIScriptFunction *asCModule::GetFunctionByName(const char *name) const
  428. {
  429. const asCArray<unsigned int> &idxs = globalFunctions.GetIndexes(defaultNamespace, name);
  430. if( idxs.GetLength() != 1 )
  431. return 0;
  432. const asIScriptFunction *func = globalFunctions.Get(idxs[0]);
  433. return const_cast<asIScriptFunction*>(func);
  434. }
  435. // interface
  436. asUINT asCModule::GetImportedFunctionCount() const
  437. {
  438. return (asUINT)bindInformations.GetLength();
  439. }
  440. // interface
  441. int asCModule::GetImportedFunctionIndexByDecl(const char *decl) const
  442. {
  443. asCBuilder bld(engine, const_cast<asCModule*>(this));
  444. // Don't write parser errors to the message callback
  445. bld.silent = true;
  446. asCScriptFunction func(engine, const_cast<asCModule*>(this), asFUNC_DUMMY);
  447. bld.ParseFunctionDeclaration(0, decl, &func, false, 0, 0, defaultNamespace);
  448. // TODO: optimize: Improve linear search
  449. // Search script functions for matching interface
  450. int id = -1;
  451. for( asUINT n = 0; n < bindInformations.GetLength(); ++n )
  452. {
  453. if( func.name == bindInformations[n]->importedFunctionSignature->name &&
  454. func.returnType == bindInformations[n]->importedFunctionSignature->returnType &&
  455. func.parameterTypes.GetLength() == bindInformations[n]->importedFunctionSignature->parameterTypes.GetLength() )
  456. {
  457. bool match = true;
  458. for( asUINT p = 0; p < func.parameterTypes.GetLength(); ++p )
  459. {
  460. if( func.parameterTypes[p] != bindInformations[n]->importedFunctionSignature->parameterTypes[p] )
  461. {
  462. match = false;
  463. break;
  464. }
  465. }
  466. if( match )
  467. {
  468. if( id == -1 )
  469. id = n;
  470. else
  471. return asMULTIPLE_FUNCTIONS;
  472. }
  473. }
  474. }
  475. if( id == -1 ) return asNO_FUNCTION;
  476. return id;
  477. }
  478. // interface
  479. asUINT asCModule::GetFunctionCount() const
  480. {
  481. return (asUINT)globalFunctions.GetSize();
  482. }
  483. // interface
  484. asIScriptFunction *asCModule::GetFunctionByDecl(const char *decl) const
  485. {
  486. asCBuilder bld(engine, const_cast<asCModule*>(this));
  487. // Don't write parser errors to the message callback
  488. bld.silent = true;
  489. asCScriptFunction func(engine, const_cast<asCModule*>(this), asFUNC_DUMMY);
  490. int r = bld.ParseFunctionDeclaration(0, decl, &func, false, 0, 0, defaultNamespace);
  491. if( r < 0 )
  492. {
  493. // Invalid declaration
  494. // TODO: Write error to message stream
  495. return 0;
  496. }
  497. // Use the defaultNamespace implicitly unless an explicit namespace has been provided
  498. asSNameSpace *ns = func.nameSpace == engine->nameSpaces[0] ? defaultNamespace : func.nameSpace;
  499. // Search script functions for matching interface
  500. asIScriptFunction *f = 0;
  501. const asCArray<unsigned int> &idxs = globalFunctions.GetIndexes(ns, func.name);
  502. for( unsigned int n = 0; n < idxs.GetLength(); n++ )
  503. {
  504. const asCScriptFunction *funcPtr = globalFunctions.Get(idxs[n]);
  505. if( funcPtr->objectType == 0 &&
  506. func.returnType == funcPtr->returnType &&
  507. func.parameterTypes.GetLength() == funcPtr->parameterTypes.GetLength()
  508. )
  509. {
  510. bool match = true;
  511. for( size_t p = 0; p < func.parameterTypes.GetLength(); ++p )
  512. {
  513. if( func.parameterTypes[p] != funcPtr->parameterTypes[p] )
  514. {
  515. match = false;
  516. break;
  517. }
  518. }
  519. if( match )
  520. {
  521. if( f == 0 )
  522. f = const_cast<asCScriptFunction*>(funcPtr);
  523. else
  524. // Multiple functions
  525. return 0;
  526. }
  527. }
  528. }
  529. return f;
  530. }
  531. // interface
  532. asUINT asCModule::GetGlobalVarCount() const
  533. {
  534. return (asUINT)scriptGlobals.GetSize();
  535. }
  536. // interface
  537. int asCModule::GetGlobalVarIndexByName(const char *name) const
  538. {
  539. // Find the global var id
  540. int id = scriptGlobals.GetFirstIndex(defaultNamespace, name);
  541. if( id == -1 ) return asNO_GLOBAL_VAR;
  542. return id;
  543. }
  544. // interface
  545. int asCModule::RemoveGlobalVar(asUINT index)
  546. {
  547. asCGlobalProperty *prop = scriptGlobals.Get(index);
  548. if( !prop )
  549. return asINVALID_ARG;
  550. prop->Orphan(this);
  551. scriptGlobals.Erase(index);
  552. return 0;
  553. }
  554. // interface
  555. int asCModule::GetGlobalVarIndexByDecl(const char *decl) const
  556. {
  557. asCBuilder bld(engine, const_cast<asCModule*>(this));
  558. // Don't write parser errors to the message callback
  559. bld.silent = true;
  560. asCString name;
  561. asSNameSpace *nameSpace;
  562. asCDataType dt;
  563. int r = bld.ParseVariableDeclaration(decl, defaultNamespace, name, nameSpace, dt);
  564. if( r < 0 )
  565. return r;
  566. // Search global variables for a match
  567. int id = scriptGlobals.GetFirstIndex(nameSpace, name, asCCompGlobPropType(dt));
  568. if( id != -1 )
  569. return id;
  570. return asNO_GLOBAL_VAR;
  571. }
  572. // interface
  573. void *asCModule::GetAddressOfGlobalVar(asUINT index)
  574. {
  575. asCGlobalProperty *prop = scriptGlobals.Get(index);
  576. if( !prop )
  577. return 0;
  578. // For object variables it's necessary to dereference the pointer to get the address of the value
  579. if( prop->type.IsObject() &&
  580. !prop->type.IsObjectHandle() )
  581. return *(void**)(prop->GetAddressOfValue());
  582. return (void*)(prop->GetAddressOfValue());
  583. }
  584. // interface
  585. const char *asCModule::GetGlobalVarDeclaration(asUINT index, bool includeNamespace) const
  586. {
  587. const asCGlobalProperty *prop = scriptGlobals.Get(index);
  588. if (!prop) return 0;
  589. asCString *tempString = &asCThreadManager::GetLocalData()->string;
  590. *tempString = prop->type.Format();
  591. *tempString += " ";
  592. if( includeNamespace )
  593. *tempString += prop->nameSpace->name + "::";
  594. *tempString += prop->name;
  595. return tempString->AddressOf();
  596. }
  597. // interface
  598. int asCModule::GetGlobalVar(asUINT index, const char **name, const char **nameSpace, int *typeId, bool *isConst) const
  599. {
  600. const asCGlobalProperty *prop = scriptGlobals.Get(index);
  601. if (!prop) return 0;
  602. if( name )
  603. *name = prop->name.AddressOf();
  604. if( nameSpace )
  605. *nameSpace = prop->nameSpace->name.AddressOf();
  606. if( typeId )
  607. *typeId = engine->GetTypeIdFromDataType(prop->type);
  608. if( isConst )
  609. *isConst = prop->type.IsReadOnly();
  610. return asSUCCESS;
  611. }
  612. // interface
  613. asUINT asCModule::GetObjectTypeCount() const
  614. {
  615. return (asUINT)classTypes.GetLength();
  616. }
  617. // interface
  618. asIObjectType *asCModule::GetObjectTypeByIndex(asUINT index) const
  619. {
  620. if( index >= classTypes.GetLength() )
  621. return 0;
  622. return classTypes[index];
  623. }
  624. // interface
  625. asIObjectType *asCModule::GetObjectTypeByName(const char *name) const
  626. {
  627. for( asUINT n = 0; n < classTypes.GetLength(); n++ )
  628. {
  629. if( classTypes[n] &&
  630. classTypes[n]->name == name &&
  631. classTypes[n]->nameSpace == defaultNamespace )
  632. return classTypes[n];
  633. }
  634. return 0;
  635. }
  636. // interface
  637. int asCModule::GetTypeIdByDecl(const char *decl) const
  638. {
  639. asCDataType dt;
  640. // This const cast is safe since we know the engine won't be modified
  641. asCBuilder bld(engine, const_cast<asCModule*>(this));
  642. // Don't write parser errors to the message callback
  643. bld.silent = true;
  644. int r = bld.ParseDataType(decl, &dt, defaultNamespace);
  645. if( r < 0 )
  646. return asINVALID_TYPE;
  647. return engine->GetTypeIdFromDataType(dt);
  648. }
  649. // interface
  650. asIObjectType *asCModule::GetObjectTypeByDecl(const char *decl) const
  651. {
  652. asCDataType dt;
  653. // This const cast is safe since we know the engine won't be modified
  654. asCBuilder bld(engine, const_cast<asCModule*>(this));
  655. // Don't write parser errors to the message callback
  656. bld.silent = true;
  657. int r = bld.ParseDataType(decl, &dt, defaultNamespace);
  658. if( r < 0 )
  659. return 0;
  660. return dt.GetObjectType();
  661. }
  662. // interface
  663. asUINT asCModule::GetEnumCount() const
  664. {
  665. return (asUINT)enumTypes.GetLength();
  666. }
  667. // interface
  668. const char *asCModule::GetEnumByIndex(asUINT index, int *enumTypeId, const char **nameSpace) const
  669. {
  670. if( index >= enumTypes.GetLength() )
  671. return 0;
  672. if( enumTypeId )
  673. *enumTypeId = engine->GetTypeIdFromDataType(asCDataType::CreateObject(enumTypes[index], false));
  674. if( nameSpace )
  675. *nameSpace = enumTypes[index]->nameSpace->name.AddressOf();
  676. return enumTypes[index]->name.AddressOf();
  677. }
  678. // interface
  679. int asCModule::GetEnumValueCount(int enumTypeId) const
  680. {
  681. asCDataType dt = engine->GetDataTypeFromTypeId(enumTypeId);
  682. asCObjectType *t = dt.GetObjectType();
  683. if( t == 0 || !(t->GetFlags() & asOBJ_ENUM) )
  684. return asINVALID_TYPE;
  685. return (int)t->enumValues.GetLength();
  686. }
  687. // interface
  688. const char *asCModule::GetEnumValueByIndex(int enumTypeId, asUINT index, int *outValue) const
  689. {
  690. asCDataType dt = engine->GetDataTypeFromTypeId(enumTypeId);
  691. asCObjectType *t = dt.GetObjectType();
  692. if( t == 0 || !(t->GetFlags() & asOBJ_ENUM) )
  693. return 0;
  694. if( index >= t->enumValues.GetLength() )
  695. return 0;
  696. if( outValue )
  697. *outValue = t->enumValues[index]->value;
  698. return t->enumValues[index]->name.AddressOf();
  699. }
  700. // interface
  701. asUINT asCModule::GetTypedefCount() const
  702. {
  703. return (asUINT)typeDefs.GetLength();
  704. }
  705. // interface
  706. const char *asCModule::GetTypedefByIndex(asUINT index, int *typeId, const char **nameSpace) const
  707. {
  708. if( index >= typeDefs.GetLength() )
  709. return 0;
  710. if( typeId )
  711. *typeId = engine->GetTypeIdFromDataType(typeDefs[index]->templateSubTypes[0]);
  712. if( nameSpace )
  713. *nameSpace = typeDefs[index]->nameSpace->name.AddressOf();
  714. return typeDefs[index]->name.AddressOf();
  715. }
  716. // internal
  717. int asCModule::GetNextImportedFunctionId()
  718. {
  719. // TODO: multithread: This will break if one thread if freeing a module, while another is being compiled
  720. if( engine->freeImportedFunctionIdxs.GetLength() )
  721. return FUNC_IMPORTED | (asUINT)engine->freeImportedFunctionIdxs[engine->freeImportedFunctionIdxs.GetLength()-1];
  722. return FUNC_IMPORTED | (asUINT)engine->importedFunctions.GetLength();
  723. }
  724. #ifndef AS_NO_COMPILER
  725. // internal
  726. int asCModule::AddScriptFunction(int sectionIdx, int declaredAt, int id, const asCString &name, const asCDataType &returnType, const asCArray<asCDataType> &params, const asCArray<asCString> &paramNames, const asCArray<asETypeModifiers> &inOutFlags, const asCArray<asCString *> &defaultArgs, bool isInterface, asCObjectType *objType, bool isConstMethod, bool isGlobalFunction, bool isPrivate, bool isFinal, bool isOverride, bool isShared, asSNameSpace *ns)
  727. {
  728. asASSERT(id >= 0);
  729. // Store the function information
  730. asCScriptFunction *func = asNEW(asCScriptFunction)(engine, this, isInterface ? asFUNC_INTERFACE : asFUNC_SCRIPT);
  731. if( func == 0 )
  732. {
  733. // Free the default args
  734. for( asUINT n = 0; n < defaultArgs.GetLength(); n++ )
  735. if( defaultArgs[n] )
  736. asDELETE(defaultArgs[n], asCString);
  737. return asOUT_OF_MEMORY;
  738. }
  739. if( ns == 0 )
  740. ns = engine->nameSpaces[0];
  741. // All methods of shared objects are also shared
  742. if( objType && objType->IsShared() )
  743. isShared = true;
  744. func->name = name;
  745. func->nameSpace = ns;
  746. func->id = id;
  747. func->returnType = returnType;
  748. if( func->funcType == asFUNC_SCRIPT )
  749. {
  750. func->scriptData->scriptSectionIdx = sectionIdx;
  751. func->scriptData->declaredAt = declaredAt;
  752. }
  753. func->parameterTypes = params;
  754. func->parameterNames = paramNames;
  755. func->inOutFlags = inOutFlags;
  756. func->defaultArgs = defaultArgs;
  757. func->objectType = objType;
  758. func->isReadOnly = isConstMethod;
  759. func->isPrivate = isPrivate;
  760. func->isFinal = isFinal;
  761. func->isOverride = isOverride;
  762. func->isShared = isShared;
  763. asASSERT( params.GetLength() == inOutFlags.GetLength() && params.GetLength() == defaultArgs.GetLength() );
  764. // Verify that we are not assigning either the final or override specifier(s) if we are registering a non-member function
  765. asASSERT( !(!objType && isFinal) );
  766. asASSERT( !(!objType && isOverride) );
  767. // The script function's refCount was initialized to 1
  768. scriptFunctions.PushLast(func);
  769. engine->SetScriptFunction(func);
  770. // Compute the signature id
  771. if( objType )
  772. func->ComputeSignatureId();
  773. // Add reference
  774. if( isGlobalFunction )
  775. {
  776. globalFunctions.Put(func);
  777. func->AddRef();
  778. }
  779. return 0;
  780. }
  781. // internal
  782. int asCModule::AddScriptFunction(asCScriptFunction *func)
  783. {
  784. scriptFunctions.PushLast(func);
  785. func->AddRef();
  786. engine->SetScriptFunction(func);
  787. return 0;
  788. }
  789. // internal
  790. int asCModule::AddImportedFunction(int id, const asCString &name, const asCDataType &returnType, const asCArray<asCDataType> &params, const asCArray<asETypeModifiers> &inOutFlags, const asCArray<asCString *> &defaultArgs, asSNameSpace *ns, const asCString &moduleName)
  791. {
  792. asASSERT(id >= 0);
  793. // Store the function information
  794. asCScriptFunction *func = asNEW(asCScriptFunction)(engine, this, asFUNC_IMPORTED);
  795. if( func == 0 )
  796. {
  797. // Free the default args
  798. for( asUINT n = 0; n < defaultArgs.GetLength(); n++ )
  799. if( defaultArgs[n] )
  800. asDELETE(defaultArgs[n], asCString);
  801. return asOUT_OF_MEMORY;
  802. }
  803. func->name = name;
  804. func->id = id;
  805. func->returnType = returnType;
  806. func->nameSpace = ns;
  807. func->parameterTypes = params;
  808. func->inOutFlags = inOutFlags;
  809. func->defaultArgs = defaultArgs;
  810. func->objectType = 0;
  811. sBindInfo *info = asNEW(sBindInfo);
  812. if( info == 0 )
  813. {
  814. asDELETE(func, asCScriptFunction);
  815. return asOUT_OF_MEMORY;
  816. }
  817. info->importedFunctionSignature = func;
  818. info->boundFunctionId = -1;
  819. info->importFromModule = moduleName;
  820. bindInformations.PushLast(info);
  821. // Add the info to the array in the engine
  822. if( engine->freeImportedFunctionIdxs.GetLength() )
  823. engine->importedFunctions[engine->freeImportedFunctionIdxs.PopLast()] = info;
  824. else
  825. engine->importedFunctions.PushLast(info);
  826. return 0;
  827. }
  828. #endif
  829. // internal
  830. asCScriptFunction *asCModule::GetImportedFunction(int index) const
  831. {
  832. return bindInformations[index]->importedFunctionSignature;
  833. }
  834. // interface
  835. int asCModule::BindImportedFunction(asUINT index, asIScriptFunction *func)
  836. {
  837. // First unbind the old function
  838. int r = UnbindImportedFunction(index);
  839. if( r < 0 ) return r;
  840. // Must verify that the interfaces are equal
  841. asCScriptFunction *dst = GetImportedFunction(index);
  842. if( dst == 0 ) return asNO_FUNCTION;
  843. if( func == 0 )
  844. return asINVALID_ARG;
  845. asCScriptFunction *src = engine->GetScriptFunction(func->GetId());
  846. if( src == 0 )
  847. return asNO_FUNCTION;
  848. // Verify return type
  849. if( dst->returnType != src->returnType )
  850. return asINVALID_INTERFACE;
  851. if( dst->parameterTypes.GetLength() != src->parameterTypes.GetLength() )
  852. return asINVALID_INTERFACE;
  853. for( size_t n = 0; n < dst->parameterTypes.GetLength(); ++n )
  854. {
  855. if( dst->parameterTypes[n] != src->parameterTypes[n] )
  856. return asINVALID_INTERFACE;
  857. }
  858. bindInformations[index]->boundFunctionId = src->GetId();
  859. src->AddRef();
  860. return asSUCCESS;
  861. }
  862. // interface
  863. int asCModule::UnbindImportedFunction(asUINT index)
  864. {
  865. if( index >= bindInformations.GetLength() )
  866. return asINVALID_ARG;
  867. // Remove reference to old module
  868. if( bindInformations[index] )
  869. {
  870. int oldFuncID = bindInformations[index]->boundFunctionId;
  871. if( oldFuncID != -1 )
  872. {
  873. bindInformations[index]->boundFunctionId = -1;
  874. engine->scriptFunctions[oldFuncID]->Release();
  875. }
  876. }
  877. return asSUCCESS;
  878. }
  879. // interface
  880. const char *asCModule::GetImportedFunctionDeclaration(asUINT index) const
  881. {
  882. asCScriptFunction *func = GetImportedFunction(index);
  883. if( func == 0 ) return 0;
  884. asCString *tempString = &asCThreadManager::GetLocalData()->string;
  885. *tempString = func->GetDeclarationStr();
  886. return tempString->AddressOf();
  887. }
  888. // interface
  889. const char *asCModule::GetImportedFunctionSourceModule(asUINT index) const
  890. {
  891. if( index >= bindInformations.GetLength() )
  892. return 0;
  893. return bindInformations[index]->importFromModule.AddressOf();
  894. }
  895. // inteface
  896. int asCModule::BindAllImportedFunctions()
  897. {
  898. bool notAllFunctionsWereBound = false;
  899. // Bind imported functions
  900. int c = GetImportedFunctionCount();
  901. for( int n = 0; n < c; ++n )
  902. {
  903. asCScriptFunction *importFunc = GetImportedFunction(n);
  904. if( importFunc == 0 ) return asERROR;
  905. asCString str = importFunc->GetDeclarationStr();
  906. // Get module name from where the function should be imported
  907. const char *moduleName = GetImportedFunctionSourceModule(n);
  908. if( moduleName == 0 ) return asERROR;
  909. asCModule *srcMod = engine->GetModule(moduleName, false);
  910. asIScriptFunction *func = 0;
  911. if( srcMod )
  912. func = srcMod->GetFunctionByDecl(str.AddressOf());
  913. if( func == 0 )
  914. notAllFunctionsWereBound = true;
  915. else
  916. {
  917. if( BindImportedFunction(n, func) < 0 )
  918. notAllFunctionsWereBound = true;
  919. }
  920. }
  921. if( notAllFunctionsWereBound )
  922. return asCANT_BIND_ALL_FUNCTIONS;
  923. return asSUCCESS;
  924. }
  925. // interface
  926. int asCModule::UnbindAllImportedFunctions()
  927. {
  928. asUINT c = GetImportedFunctionCount();
  929. for( asUINT n = 0; n < c; ++n )
  930. UnbindImportedFunction(n);
  931. return asSUCCESS;
  932. }
  933. // internal
  934. asCObjectType *asCModule::GetObjectType(const char *type, asSNameSpace *ns)
  935. {
  936. size_t n;
  937. // TODO: optimize: Improve linear search
  938. for( n = 0; n < classTypes.GetLength(); n++ )
  939. if( classTypes[n]->name == type &&
  940. classTypes[n]->nameSpace == ns )
  941. return classTypes[n];
  942. for( n = 0; n < enumTypes.GetLength(); n++ )
  943. if( enumTypes[n]->name == type &&
  944. enumTypes[n]->nameSpace == ns )
  945. return enumTypes[n];
  946. for( n = 0; n < typeDefs.GetLength(); n++ )
  947. if( typeDefs[n]->name == type &&
  948. typeDefs[n]->nameSpace == ns )
  949. return typeDefs[n];
  950. return 0;
  951. }
  952. // internal
  953. asCGlobalProperty *asCModule::AllocateGlobalProperty(const char *name, const asCDataType &dt, asSNameSpace *ns)
  954. {
  955. asCGlobalProperty *prop = engine->AllocateGlobalProperty();
  956. prop->name = name;
  957. prop->nameSpace = ns;
  958. // Allocate the memory for this property based on its type
  959. prop->type = dt;
  960. prop->AllocateMemory();
  961. // Make an entry in the address to variable map
  962. engine->varAddressMap.Insert(prop->GetAddressOfValue(), prop);
  963. // Store the variable in the module scope (the reference count is already set to 1)
  964. scriptGlobals.Put(prop);
  965. return prop;
  966. }
  967. // internal
  968. bool asCModule::IsEmpty() const
  969. {
  970. if( scriptFunctions.GetLength() ) return false;
  971. if( globalFunctions.GetSize() ) return false;
  972. if( bindInformations.GetLength() ) return false;
  973. if( scriptGlobals.GetSize() ) return false;
  974. if( classTypes.GetLength() ) return false;
  975. if( enumTypes.GetLength() ) return false;
  976. if( typeDefs.GetLength() ) return false;
  977. if( funcDefs.GetLength() ) return false;
  978. return true;
  979. }
  980. // interface
  981. int asCModule::SaveByteCode(asIBinaryStream *out, bool stripDebugInfo) const
  982. {
  983. #ifdef AS_NO_COMPILER
  984. UNUSED_VAR(out);
  985. UNUSED_VAR(stripDebugInfo);
  986. return asNOT_SUPPORTED;
  987. #else
  988. if( out == 0 ) return asINVALID_ARG;
  989. // Make sure there is actually something to save
  990. if( IsEmpty() )
  991. return asERROR;
  992. asCWriter write(const_cast<asCModule*>(this), out, engine, stripDebugInfo);
  993. return write.Write();
  994. #endif
  995. }
  996. // interface
  997. int asCModule::LoadByteCode(asIBinaryStream *in, bool *wasDebugInfoStripped)
  998. {
  999. if( in == 0 ) return asINVALID_ARG;
  1000. // Only permit loading bytecode if no other thread is currently compiling
  1001. // TODO: It should be possible to have multiple threads perform compilations
  1002. int r = engine->RequestBuild();
  1003. if( r < 0 )
  1004. return r;
  1005. asCReader read(this, in, engine);
  1006. r = read.Read(wasDebugInfoStripped);
  1007. JITCompile();
  1008. #ifdef AS_DEBUG
  1009. // Verify that there are no unwanted gaps in the scriptFunctions array.
  1010. for( asUINT n = 1; n < engine->scriptFunctions.GetLength(); n++ )
  1011. {
  1012. int id = n;
  1013. if( engine->scriptFunctions[n] == 0 && !engine->freeScriptFunctionIds.Exists(id) )
  1014. asASSERT( false );
  1015. }
  1016. #endif
  1017. engine->BuildCompleted();
  1018. return r;
  1019. }
  1020. // interface
  1021. int asCModule::CompileGlobalVar(const char *sectionName, const char *code, int lineOffset)
  1022. {
  1023. #ifdef AS_NO_COMPILER
  1024. UNUSED_VAR(sectionName);
  1025. UNUSED_VAR(code);
  1026. UNUSED_VAR(lineOffset);
  1027. return asNOT_SUPPORTED;
  1028. #else
  1029. // Validate arguments
  1030. if( code == 0 )
  1031. return asINVALID_ARG;
  1032. // Only one thread may build at one time
  1033. // TODO: It should be possible to have multiple threads perform compilations
  1034. int r = engine->RequestBuild();
  1035. if( r < 0 )
  1036. return r;
  1037. // Prepare the engine
  1038. engine->PrepareEngine();
  1039. if( engine->configFailed )
  1040. {
  1041. engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, TXT_INVALID_CONFIGURATION);
  1042. engine->BuildCompleted();
  1043. return asINVALID_CONFIGURATION;
  1044. }
  1045. // Compile the global variable and add it to the module scope
  1046. asCBuilder builder(engine, this);
  1047. asCString str = code;
  1048. r = builder.CompileGlobalVar(sectionName, str.AddressOf(), lineOffset);
  1049. engine->BuildCompleted();
  1050. // Initialize the variable
  1051. if( r >= 0 && engine->ep.initGlobalVarsAfterBuild )
  1052. {
  1053. // Clear the memory
  1054. asCGlobalProperty *prop = scriptGlobals.GetLast();
  1055. if( prop )
  1056. {
  1057. memset(prop->GetAddressOfValue(), 0, sizeof(asDWORD)*prop->type.GetSizeOnStackDWords());
  1058. if( prop->GetInitFunc() )
  1059. {
  1060. // Call the init function for the global variable
  1061. asIScriptContext *ctx = 0;
  1062. int r = engine->CreateContext(&ctx, true);
  1063. if( r < 0 )
  1064. return r;
  1065. r = ctx->Prepare(prop->GetInitFunc());
  1066. if( r >= 0 )
  1067. r = ctx->Execute();
  1068. ctx->Release();
  1069. }
  1070. }
  1071. }
  1072. return r;
  1073. #endif
  1074. }
  1075. // interface
  1076. int asCModule::CompileFunction(const char *sectionName, const char *code, int lineOffset, asDWORD compileFlags, asIScriptFunction **outFunc)
  1077. {
  1078. // Make sure the outFunc is null if the function fails, so the
  1079. // application doesn't attempt to release a non-existent function
  1080. if( outFunc )
  1081. *outFunc = 0;
  1082. #ifdef AS_NO_COMPILER
  1083. UNUSED_VAR(sectionName);
  1084. UNUSED_VAR(code);
  1085. UNUSED_VAR(lineOffset);
  1086. UNUSED_VAR(compileFlags);
  1087. return asNOT_SUPPORTED;
  1088. #else
  1089. // Validate arguments
  1090. if( code == 0 ||
  1091. (compileFlags != 0 && compileFlags != asCOMP_ADD_TO_MODULE) )
  1092. return asINVALID_ARG;
  1093. // Only one thread may build at one time
  1094. // TODO: It should be possible to have multiple threads perform compilations
  1095. int r = engine->RequestBuild();
  1096. if( r < 0 )
  1097. return r;
  1098. // Prepare the engine
  1099. engine->PrepareEngine();
  1100. if( engine->configFailed )
  1101. {
  1102. engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, TXT_INVALID_CONFIGURATION);
  1103. engine->BuildCompleted();
  1104. return asINVALID_CONFIGURATION;
  1105. }
  1106. // Compile the single function
  1107. asCBuilder builder(engine, this);
  1108. asCString str = code;
  1109. asCScriptFunction *func = 0;
  1110. r = builder.CompileFunction(sectionName, str.AddressOf(), lineOffset, compileFlags, &func);
  1111. engine->BuildCompleted();
  1112. if( r >= 0 && outFunc && func )
  1113. {
  1114. // Return the function to the caller
  1115. *outFunc = func;
  1116. func->AddRef();
  1117. }
  1118. // Release our reference to the function
  1119. if( func )
  1120. func->Release();
  1121. return r;
  1122. #endif
  1123. }
  1124. // interface
  1125. int asCModule::RemoveFunction(asIScriptFunction *func)
  1126. {
  1127. // Find the global function
  1128. asCScriptFunction *f = static_cast<asCScriptFunction*>(func);
  1129. int idx = globalFunctions.GetIndex(f);
  1130. if( idx >= 0 )
  1131. {
  1132. globalFunctions.Erase(idx);
  1133. f->Release();
  1134. scriptFunctions.RemoveValue(f);
  1135. f->Orphan(this);
  1136. return 0;
  1137. }
  1138. return asNO_FUNCTION;
  1139. }
  1140. #ifndef AS_NO_COMPILER
  1141. // internal
  1142. int asCModule::AddFuncDef(const asCString &name, asSNameSpace *ns)
  1143. {
  1144. asCScriptFunction *func = asNEW(asCScriptFunction)(engine, 0, asFUNC_FUNCDEF);
  1145. if( func == 0 )
  1146. return asOUT_OF_MEMORY;
  1147. func->name = name;
  1148. func->nameSpace = ns;
  1149. funcDefs.PushLast(func);
  1150. engine->funcDefs.PushLast(func);
  1151. func->id = engine->GetNextScriptFunctionId();
  1152. engine->SetScriptFunction(func);
  1153. return (int)funcDefs.GetLength()-1;
  1154. }
  1155. #endif
  1156. // interface
  1157. asDWORD asCModule::SetAccessMask(asDWORD mask)
  1158. {
  1159. asDWORD old = accessMask;
  1160. accessMask = mask;
  1161. return old;
  1162. }
  1163. END_AS_NAMESPACE