Script_Program.cpp 49 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147
  1. /*
  2. ===========================================================================
  3. Doom 3 GPL Source Code
  4. Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
  5. This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
  6. Doom 3 Source Code is free software: you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation, either version 3 of the License, or
  9. (at your option) any later version.
  10. Doom 3 Source Code is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
  16. In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
  17. If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
  18. ===========================================================================
  19. */
  20. #include "../../idlib/precompiled.h"
  21. #pragma hdrstop
  22. #include "../Game_local.h"
  23. // simple types. function types are dynamically allocated
  24. idTypeDef type_void( ev_void, &def_void, "void", 0, NULL );
  25. idTypeDef type_scriptevent( ev_scriptevent, &def_scriptevent, "scriptevent", sizeof( void * ), NULL );
  26. idTypeDef type_namespace( ev_namespace, &def_namespace, "namespace", sizeof( void * ), NULL );
  27. idTypeDef type_string( ev_string, &def_string, "string", MAX_STRING_LEN, NULL );
  28. idTypeDef type_float( ev_float, &def_float, "float", sizeof( float ), NULL );
  29. idTypeDef type_vector( ev_vector, &def_vector, "vector", sizeof( idVec3 ), NULL );
  30. idTypeDef type_entity( ev_entity, &def_entity, "entity", sizeof( int * ), NULL ); // stored as entity number pointer
  31. idTypeDef type_field( ev_field, &def_field, "field", sizeof( void * ), NULL );
  32. idTypeDef type_function( ev_function, &def_function, "function", sizeof( void * ), &type_void );
  33. idTypeDef type_virtualfunction( ev_virtualfunction, &def_virtualfunction, "virtual function", sizeof( int ), NULL );
  34. idTypeDef type_pointer( ev_pointer, &def_pointer, "pointer", sizeof( void * ), NULL );
  35. idTypeDef type_object( ev_object, &def_object, "object", sizeof( int * ), NULL ); // stored as entity number pointer
  36. idTypeDef type_jumpoffset( ev_jumpoffset, &def_jumpoffset, "<jump>", sizeof( int ), NULL ); // only used for jump opcodes
  37. idTypeDef type_argsize( ev_argsize, &def_argsize, "<argsize>", sizeof( int ), NULL ); // only used for function call and thread opcodes
  38. idTypeDef type_boolean( ev_boolean, &def_boolean, "boolean", sizeof( int ), NULL );
  39. idVarDef def_void( &type_void );
  40. idVarDef def_scriptevent( &type_scriptevent );
  41. idVarDef def_namespace( &type_namespace );
  42. idVarDef def_string( &type_string );
  43. idVarDef def_float( &type_float );
  44. idVarDef def_vector( &type_vector );
  45. idVarDef def_entity( &type_entity );
  46. idVarDef def_field( &type_field );
  47. idVarDef def_function( &type_function );
  48. idVarDef def_virtualfunction( &type_virtualfunction );
  49. idVarDef def_pointer( &type_pointer );
  50. idVarDef def_object( &type_object );
  51. idVarDef def_jumpoffset( &type_jumpoffset ); // only used for jump opcodes
  52. idVarDef def_argsize( &type_argsize );
  53. idVarDef def_boolean( &type_boolean );
  54. /***********************************************************************
  55. function_t
  56. ***********************************************************************/
  57. /*
  58. ================
  59. function_t::function_t
  60. ================
  61. */
  62. function_t::function_t() {
  63. Clear();
  64. }
  65. /*
  66. ================
  67. function_t::Allocated
  68. ================
  69. */
  70. size_t function_t::Allocated( void ) const {
  71. return name.Allocated() + parmSize.Allocated();
  72. }
  73. /*
  74. ================
  75. function_t::SetName
  76. ================
  77. */
  78. void function_t::SetName( const char *name ) {
  79. this->name = name;
  80. }
  81. /*
  82. ================
  83. function_t::Name
  84. ================
  85. */
  86. const char *function_t::Name( void ) const {
  87. return name;
  88. }
  89. /*
  90. ================
  91. function_t::Clear
  92. ================
  93. */
  94. void function_t::Clear( void ) {
  95. eventdef = NULL;
  96. def = NULL;
  97. type = NULL;
  98. firstStatement = 0;
  99. numStatements = 0;
  100. parmTotal = 0;
  101. locals = 0;
  102. filenum = 0;
  103. name.Clear();
  104. parmSize.Clear();
  105. }
  106. /***********************************************************************
  107. idTypeDef
  108. ***********************************************************************/
  109. /*
  110. ================
  111. idTypeDef::idTypeDef
  112. ================
  113. */
  114. idTypeDef::idTypeDef( etype_t etype, idVarDef *edef, const char *ename, int esize, idTypeDef *aux ) {
  115. name = ename;
  116. type = etype;
  117. def = edef;
  118. size = esize;
  119. auxType = aux;
  120. parmTypes.SetGranularity( 1 );
  121. parmNames.SetGranularity( 1 );
  122. functions.SetGranularity( 1 );
  123. }
  124. /*
  125. ================
  126. idTypeDef::idTypeDef
  127. ================
  128. */
  129. idTypeDef::idTypeDef( const idTypeDef &other ) {
  130. *this = other;
  131. }
  132. /*
  133. ================
  134. idTypeDef::operator=
  135. ================
  136. */
  137. void idTypeDef::operator=( const idTypeDef& other ) {
  138. type = other.type;
  139. def = other.def;
  140. name = other.name;
  141. size = other.size;
  142. auxType = other.auxType;
  143. parmTypes = other.parmTypes;
  144. parmNames = other.parmNames;
  145. functions = other.functions;
  146. }
  147. /*
  148. ================
  149. idTypeDef::Allocated
  150. ================
  151. */
  152. size_t idTypeDef::Allocated( void ) const {
  153. size_t memsize;
  154. int i;
  155. memsize = name.Allocated() + parmTypes.Allocated() + parmNames.Allocated() + functions.Allocated();
  156. for( i = 0; i < parmTypes.Num(); i++ ) {
  157. memsize += parmNames[ i ].Allocated();
  158. }
  159. return memsize;
  160. }
  161. /*
  162. ================
  163. idTypeDef::Inherits
  164. Returns true if basetype is an ancestor of this type.
  165. ================
  166. */
  167. bool idTypeDef::Inherits( const idTypeDef *basetype ) const {
  168. idTypeDef *superType;
  169. if ( type != ev_object ) {
  170. return false;
  171. }
  172. if ( this == basetype ) {
  173. return true;
  174. }
  175. for( superType = auxType; superType != NULL; superType = superType->auxType ) {
  176. if ( superType == basetype ) {
  177. return true;
  178. }
  179. }
  180. return false;
  181. }
  182. /*
  183. ================
  184. idTypeDef::MatchesType
  185. Returns true if both types' base types and parameters match
  186. ================
  187. */
  188. bool idTypeDef::MatchesType( const idTypeDef &matchtype ) const {
  189. int i;
  190. if ( this == &matchtype ) {
  191. return true;
  192. }
  193. if ( ( type != matchtype.type ) || ( auxType != matchtype.auxType ) ) {
  194. return false;
  195. }
  196. if ( parmTypes.Num() != matchtype.parmTypes.Num() ) {
  197. return false;
  198. }
  199. for( i = 0; i < matchtype.parmTypes.Num(); i++ ) {
  200. if ( parmTypes[ i ] != matchtype.parmTypes[ i ] ) {
  201. return false;
  202. }
  203. }
  204. return true;
  205. }
  206. /*
  207. ================
  208. idTypeDef::MatchesVirtualFunction
  209. Returns true if both functions' base types and parameters match
  210. ================
  211. */
  212. bool idTypeDef::MatchesVirtualFunction( const idTypeDef &matchfunc ) const {
  213. int i;
  214. if ( this == &matchfunc ) {
  215. return true;
  216. }
  217. if ( ( type != matchfunc.type ) || ( auxType != matchfunc.auxType ) ) {
  218. return false;
  219. }
  220. if ( parmTypes.Num() != matchfunc.parmTypes.Num() ) {
  221. return false;
  222. }
  223. if ( parmTypes.Num() > 0 ) {
  224. if ( !parmTypes[ 0 ]->Inherits( matchfunc.parmTypes[ 0 ] ) ) {
  225. return false;
  226. }
  227. }
  228. for( i = 1; i < matchfunc.parmTypes.Num(); i++ ) {
  229. if ( parmTypes[ i ] != matchfunc.parmTypes[ i ] ) {
  230. return false;
  231. }
  232. }
  233. return true;
  234. }
  235. /*
  236. ================
  237. idTypeDef::AddFunctionParm
  238. Adds a new parameter for a function type.
  239. ================
  240. */
  241. void idTypeDef::AddFunctionParm( idTypeDef *parmtype, const char *name ) {
  242. if ( type != ev_function ) {
  243. throw idCompileError( "idTypeDef::AddFunctionParm : tried to add parameter on non-function type" );
  244. }
  245. parmTypes.Append( parmtype );
  246. idStr &parmName = parmNames.Alloc();
  247. parmName = name;
  248. }
  249. /*
  250. ================
  251. idTypeDef::AddField
  252. Adds a new field to an object type.
  253. ================
  254. */
  255. void idTypeDef::AddField( idTypeDef *fieldtype, const char *name ) {
  256. if ( type != ev_object ) {
  257. throw idCompileError( "idTypeDef::AddField : tried to add field to non-object type" );
  258. }
  259. parmTypes.Append( fieldtype );
  260. idStr &parmName = parmNames.Alloc();
  261. parmName = name;
  262. if ( fieldtype->FieldType()->Inherits( &type_object ) ) {
  263. size += type_object.Size();
  264. } else {
  265. size += fieldtype->FieldType()->Size();
  266. }
  267. }
  268. /*
  269. ================
  270. idTypeDef::SetName
  271. ================
  272. */
  273. void idTypeDef::SetName( const char *newname ) {
  274. name = newname;
  275. }
  276. /*
  277. ================
  278. idTypeDef::Name
  279. ================
  280. */
  281. const char *idTypeDef::Name( void ) const {
  282. return name;
  283. }
  284. /*
  285. ================
  286. idTypeDef::Type
  287. ================
  288. */
  289. etype_t idTypeDef::Type( void ) const {
  290. return type;
  291. }
  292. /*
  293. ================
  294. idTypeDef::Size
  295. ================
  296. */
  297. int idTypeDef::Size( void ) const {
  298. return size;
  299. }
  300. /*
  301. ================
  302. idTypeDef::SuperClass
  303. If type is an object, then returns the object's superclass
  304. ================
  305. */
  306. idTypeDef *idTypeDef::SuperClass( void ) const {
  307. if ( type != ev_object ) {
  308. throw idCompileError( "idTypeDef::SuperClass : tried to get superclass of a non-object type" );
  309. }
  310. return auxType;
  311. }
  312. /*
  313. ================
  314. idTypeDef::ReturnType
  315. If type is a function, then returns the function's return type
  316. ================
  317. */
  318. idTypeDef *idTypeDef::ReturnType( void ) const {
  319. if ( type != ev_function ) {
  320. throw idCompileError( "idTypeDef::ReturnType: tried to get return type on non-function type" );
  321. }
  322. return auxType;
  323. }
  324. /*
  325. ================
  326. idTypeDef::SetReturnType
  327. If type is a function, then sets the function's return type
  328. ================
  329. */
  330. void idTypeDef::SetReturnType( idTypeDef *returntype ) {
  331. if ( type != ev_function ) {
  332. throw idCompileError( "idTypeDef::SetReturnType: tried to set return type on non-function type" );
  333. }
  334. auxType = returntype;
  335. }
  336. /*
  337. ================
  338. idTypeDef::FieldType
  339. If type is a field, then returns it's type
  340. ================
  341. */
  342. idTypeDef *idTypeDef::FieldType( void ) const {
  343. if ( type != ev_field ) {
  344. throw idCompileError( "idTypeDef::FieldType: tried to get field type on non-field type" );
  345. }
  346. return auxType;
  347. }
  348. /*
  349. ================
  350. idTypeDef::SetFieldType
  351. If type is a field, then sets the function's return type
  352. ================
  353. */
  354. void idTypeDef::SetFieldType( idTypeDef *fieldtype ) {
  355. if ( type != ev_field ) {
  356. throw idCompileError( "idTypeDef::SetFieldType: tried to set return type on non-function type" );
  357. }
  358. auxType = fieldtype;
  359. }
  360. /*
  361. ================
  362. idTypeDef::PointerType
  363. If type is a pointer, then returns the type it points to
  364. ================
  365. */
  366. idTypeDef *idTypeDef::PointerType( void ) const {
  367. if ( type != ev_pointer ) {
  368. throw idCompileError( "idTypeDef::PointerType: tried to get pointer type on non-pointer" );
  369. }
  370. return auxType;
  371. }
  372. /*
  373. ================
  374. idTypeDef::SetPointerType
  375. If type is a pointer, then sets the pointer's type
  376. ================
  377. */
  378. void idTypeDef::SetPointerType( idTypeDef *pointertype ) {
  379. if ( type != ev_pointer ) {
  380. throw idCompileError( "idTypeDef::SetPointerType: tried to set type on non-pointer" );
  381. }
  382. auxType = pointertype;
  383. }
  384. /*
  385. ================
  386. idTypeDef::NumParameters
  387. ================
  388. */
  389. int idTypeDef::NumParameters( void ) const {
  390. return parmTypes.Num();
  391. }
  392. /*
  393. ================
  394. idTypeDef::GetParmType
  395. ================
  396. */
  397. idTypeDef *idTypeDef::GetParmType( int parmNumber ) const {
  398. assert( parmNumber >= 0 );
  399. assert( parmNumber < parmTypes.Num() );
  400. return parmTypes[ parmNumber ];
  401. }
  402. /*
  403. ================
  404. idTypeDef::GetParmName
  405. ================
  406. */
  407. const char *idTypeDef::GetParmName( int parmNumber ) const {
  408. assert( parmNumber >= 0 );
  409. assert( parmNumber < parmTypes.Num() );
  410. return parmNames[ parmNumber ];
  411. }
  412. /*
  413. ================
  414. idTypeDef::NumFunctions
  415. ================
  416. */
  417. int idTypeDef::NumFunctions( void ) const {
  418. return functions.Num();
  419. }
  420. /*
  421. ================
  422. idTypeDef::GetFunctionNumber
  423. ================
  424. */
  425. int idTypeDef::GetFunctionNumber( const function_t *func ) const {
  426. int i;
  427. for( i = 0; i < functions.Num(); i++ ) {
  428. if ( functions[ i ] == func ) {
  429. return i;
  430. }
  431. }
  432. return -1;
  433. }
  434. /*
  435. ================
  436. idTypeDef::GetFunction
  437. ================
  438. */
  439. const function_t *idTypeDef::GetFunction( int funcNumber ) const {
  440. assert( funcNumber >= 0 );
  441. assert( funcNumber < functions.Num() );
  442. return functions[ funcNumber ];
  443. }
  444. /*
  445. ================
  446. idTypeDef::AddFunction
  447. ================
  448. */
  449. void idTypeDef::AddFunction( const function_t *func ) {
  450. int i;
  451. for( i = 0; i < functions.Num(); i++ ) {
  452. if ( !strcmp( functions[ i ]->def->Name(), func->def->Name() ) ) {
  453. if ( func->def->TypeDef()->MatchesVirtualFunction( *functions[ i ]->def->TypeDef() ) ) {
  454. functions[ i ] = func;
  455. return;
  456. }
  457. }
  458. }
  459. functions.Append( func );
  460. }
  461. /***********************************************************************
  462. idVarDef
  463. ***********************************************************************/
  464. /*
  465. ================
  466. idVarDef::idVarDef()
  467. ================
  468. */
  469. idVarDef::idVarDef( idTypeDef *typeptr ) {
  470. typeDef = typeptr;
  471. num = 0;
  472. scope = NULL;
  473. numUsers = 0;
  474. initialized = idVarDef::uninitialized;
  475. memset( &value, 0, sizeof( value ) );
  476. name = NULL;
  477. next = NULL;
  478. }
  479. /*
  480. ============
  481. idVarDef::~idVarDef
  482. ============
  483. */
  484. idVarDef::~idVarDef() {
  485. if ( name ) {
  486. name->RemoveDef( this );
  487. }
  488. }
  489. /*
  490. ============
  491. idVarDef::Name
  492. ============
  493. */
  494. const char *idVarDef::Name( void ) const {
  495. return name->Name();
  496. }
  497. /*
  498. ============
  499. idVarDef::GlobalName
  500. ============
  501. */
  502. const char *idVarDef::GlobalName( void ) const {
  503. if ( scope != &def_namespace ) {
  504. return va( "%s::%s", scope->GlobalName(), name->Name() );
  505. } else {
  506. return name->Name();
  507. }
  508. }
  509. /*
  510. ============
  511. idVarDef::DepthOfScope
  512. ============
  513. */
  514. int idVarDef::DepthOfScope( const idVarDef *otherScope ) const {
  515. const idVarDef *def;
  516. int depth;
  517. depth = 1;
  518. for( def = otherScope; def != NULL; def = def->scope ) {
  519. if ( def == scope ) {
  520. return depth;
  521. }
  522. depth++;
  523. }
  524. return 0;
  525. }
  526. /*
  527. ============
  528. idVarDef::SetFunction
  529. ============
  530. */
  531. void idVarDef::SetFunction( function_t *func ) {
  532. assert( typeDef );
  533. initialized = initializedConstant;
  534. assert( typeDef->Type() == ev_function );
  535. value.functionPtr = func;
  536. }
  537. /*
  538. ============
  539. idVarDef::SetObject
  540. ============
  541. */
  542. void idVarDef::SetObject( idScriptObject *object ) {
  543. assert( typeDef );
  544. initialized = initialized;
  545. assert( typeDef->Inherits( &type_object ) );
  546. *value.objectPtrPtr = object;
  547. }
  548. /*
  549. ============
  550. idVarDef::SetValue
  551. ============
  552. */
  553. void idVarDef::SetValue( const eval_t &_value, bool constant ) {
  554. assert( typeDef );
  555. if ( constant ) {
  556. initialized = initializedConstant;
  557. } else {
  558. initialized = initializedVariable;
  559. }
  560. switch( typeDef->Type() ) {
  561. case ev_pointer :
  562. case ev_boolean :
  563. case ev_field :
  564. *value.intPtr = _value._int;
  565. break;
  566. case ev_jumpoffset :
  567. value.jumpOffset = _value._int;
  568. break;
  569. case ev_argsize :
  570. value.argSize = _value._int;
  571. break;
  572. case ev_entity :
  573. *value.entityNumberPtr = _value.entity;
  574. break;
  575. case ev_string :
  576. idStr::Copynz( value.stringPtr, _value.stringPtr, MAX_STRING_LEN );
  577. break;
  578. case ev_float :
  579. *value.floatPtr = _value._float;
  580. break;
  581. case ev_vector :
  582. value.vectorPtr->x = _value.vector[ 0 ];
  583. value.vectorPtr->y = _value.vector[ 1 ];
  584. value.vectorPtr->z = _value.vector[ 2 ];
  585. break;
  586. case ev_function :
  587. value.functionPtr = _value.function;
  588. break;
  589. case ev_virtualfunction :
  590. value.virtualFunction = _value._int;
  591. break;
  592. case ev_object :
  593. *value.entityNumberPtr = _value.entity;
  594. break;
  595. default :
  596. throw idCompileError( va( "weird type on '%s'", Name() ) );
  597. break;
  598. }
  599. }
  600. /*
  601. ============
  602. idVarDef::SetString
  603. ============
  604. */
  605. void idVarDef::SetString( const char *string, bool constant ) {
  606. if ( constant ) {
  607. initialized = initializedConstant;
  608. } else {
  609. initialized = initializedVariable;
  610. }
  611. assert( typeDef && ( typeDef->Type() == ev_string ) );
  612. idStr::Copynz( value.stringPtr, string, MAX_STRING_LEN );
  613. }
  614. /*
  615. ============
  616. idVarDef::PrintInfo
  617. ============
  618. */
  619. void idVarDef::PrintInfo( idFile *file, int instructionPointer ) const {
  620. statement_t *jumpst;
  621. int jumpto;
  622. etype_t etype;
  623. int i;
  624. int len;
  625. const char *ch;
  626. if ( initialized == initializedConstant ) {
  627. file->Printf( "const " );
  628. }
  629. etype = typeDef->Type();
  630. switch( etype ) {
  631. case ev_jumpoffset :
  632. jumpto = instructionPointer + value.jumpOffset;
  633. jumpst = &gameLocal.program.GetStatement( jumpto );
  634. file->Printf( "address %d [%s(%d)]", jumpto, gameLocal.program.GetFilename( jumpst->file ), jumpst->linenumber );
  635. break;
  636. case ev_function :
  637. if ( value.functionPtr->eventdef ) {
  638. file->Printf( "event %s", GlobalName() );
  639. } else {
  640. file->Printf( "function %s", GlobalName() );
  641. }
  642. break;
  643. case ev_field :
  644. file->Printf( "field %d", value.ptrOffset );
  645. break;
  646. case ev_argsize:
  647. file->Printf( "args %d", value.argSize );
  648. break;
  649. default:
  650. file->Printf( "%s ", typeDef->Name() );
  651. if ( initialized == initializedConstant ) {
  652. switch( etype ) {
  653. case ev_string :
  654. file->Printf( "\"" );
  655. len = strlen( value.stringPtr );
  656. ch = value.stringPtr;
  657. for( i = 0; i < len; i++, ch++ ) {
  658. if ( idStr::CharIsPrintable( *ch ) ) {
  659. file->Printf( "%c", *ch );
  660. } else if ( *ch == '\n' ) {
  661. file->Printf( "\\n" );
  662. } else {
  663. file->Printf( "\\x%.2x", static_cast<int>( *ch ) );
  664. }
  665. }
  666. file->Printf( "\"" );
  667. break;
  668. case ev_vector :
  669. file->Printf( "'%s'", value.vectorPtr->ToString() );
  670. break;
  671. case ev_float :
  672. file->Printf( "%f", *value.floatPtr );
  673. break;
  674. case ev_virtualfunction :
  675. file->Printf( "vtable[ %d ]", value.virtualFunction );
  676. break;
  677. default :
  678. file->Printf( "%d", *value.intPtr );
  679. break;
  680. }
  681. } else if ( initialized == stackVariable ) {
  682. file->Printf( "stack[%d]", value.stackOffset );
  683. } else {
  684. file->Printf( "global[%d]", num );
  685. }
  686. break;
  687. }
  688. }
  689. /***********************************************************************
  690. idVarDef
  691. ***********************************************************************/
  692. /*
  693. ============
  694. idVarDefName::AddDef
  695. ============
  696. */
  697. void idVarDefName::AddDef( idVarDef *def ) {
  698. assert( def->next == NULL );
  699. def->name = this;
  700. def->next = defs;
  701. defs = def;
  702. }
  703. /*
  704. ============
  705. idVarDefName::RemoveDef
  706. ============
  707. */
  708. void idVarDefName::RemoveDef( idVarDef *def ) {
  709. if ( defs == def ) {
  710. defs = def->next;
  711. } else {
  712. for ( idVarDef *d = defs; d->next != NULL; d = d->next ) {
  713. if ( d->next == def ) {
  714. d->next = def->next;
  715. break;
  716. }
  717. }
  718. }
  719. def->next = NULL;
  720. def->name = NULL;
  721. }
  722. /***********************************************************************
  723. idScriptObject
  724. ***********************************************************************/
  725. /*
  726. ============
  727. idScriptObject::idScriptObject
  728. ============
  729. */
  730. idScriptObject::idScriptObject() {
  731. data = NULL;
  732. type = &type_object;
  733. }
  734. /*
  735. ============
  736. idScriptObject::~idScriptObject
  737. ============
  738. */
  739. idScriptObject::~idScriptObject() {
  740. Free();
  741. }
  742. /*
  743. ============
  744. idScriptObject::Free
  745. ============
  746. */
  747. void idScriptObject::Free( void ) {
  748. if ( data ) {
  749. Mem_Free( data );
  750. }
  751. data = NULL;
  752. type = &type_object;
  753. }
  754. /*
  755. ================
  756. idScriptObject::Save
  757. ================
  758. */
  759. void idScriptObject::Save( idSaveGame *savefile ) const {
  760. size_t size;
  761. if ( type == &type_object && data == NULL ) {
  762. // Write empty string for uninitialized object
  763. savefile->WriteString( "" );
  764. } else {
  765. savefile->WriteString( type->Name() );
  766. size = type->Size();
  767. savefile->WriteInt( size );
  768. savefile->Write( data, size );
  769. }
  770. }
  771. /*
  772. ================
  773. idScriptObject::Restore
  774. ================
  775. */
  776. void idScriptObject::Restore( idRestoreGame *savefile ) {
  777. idStr typeName;
  778. size_t size;
  779. savefile->ReadString( typeName );
  780. // Empty string signals uninitialized object
  781. if ( typeName.Length() == 0 ) {
  782. return;
  783. }
  784. if ( !SetType( typeName ) ) {
  785. savefile->Error( "idScriptObject::Restore: failed to restore object of type '%s'.", typeName.c_str() );
  786. }
  787. savefile->ReadInt( (int &)size );
  788. if ( size != type->Size() ) {
  789. savefile->Error( "idScriptObject::Restore: size of object '%s' doesn't match size in save game.", typeName.c_str() );
  790. }
  791. savefile->Read( data, size );
  792. }
  793. /*
  794. ============
  795. idScriptObject::SetType
  796. Allocates an object and initializes memory.
  797. ============
  798. */
  799. bool idScriptObject::SetType( const char *typeName ) {
  800. size_t size;
  801. idTypeDef *newtype;
  802. // lookup the type
  803. newtype = gameLocal.program.FindType( typeName );
  804. // only allocate memory if the object type changes
  805. if ( newtype != type ) {
  806. Free();
  807. if ( !newtype ) {
  808. gameLocal.Warning( "idScriptObject::SetType: Unknown type '%s'", typeName );
  809. return false;
  810. }
  811. if ( !newtype->Inherits( &type_object ) ) {
  812. gameLocal.Warning( "idScriptObject::SetType: Can't create object of type '%s'. Must be an object type.", newtype->Name() );
  813. return false;
  814. }
  815. // set the type
  816. type = newtype;
  817. // allocate the memory
  818. size = type->Size();
  819. data = ( byte * )Mem_Alloc( size );
  820. }
  821. // init object memory
  822. ClearObject();
  823. return true;
  824. }
  825. /*
  826. ============
  827. idScriptObject::ClearObject
  828. Resets the memory for the script object without changing its type.
  829. ============
  830. */
  831. void idScriptObject::ClearObject( void ) {
  832. size_t size;
  833. if ( type != &type_object ) {
  834. // init object memory
  835. size = type->Size();
  836. memset( data, 0, size );
  837. }
  838. }
  839. /*
  840. ============
  841. idScriptObject::HasObject
  842. ============
  843. */
  844. bool idScriptObject::HasObject( void ) const {
  845. return ( type != &type_object );
  846. }
  847. /*
  848. ============
  849. idScriptObject::GetTypeDef
  850. ============
  851. */
  852. idTypeDef *idScriptObject::GetTypeDef( void ) const {
  853. return type;
  854. }
  855. /*
  856. ============
  857. idScriptObject::GetTypeName
  858. ============
  859. */
  860. const char *idScriptObject::GetTypeName( void ) const {
  861. return type->Name();
  862. }
  863. /*
  864. ============
  865. idScriptObject::GetConstructor
  866. ============
  867. */
  868. const function_t *idScriptObject::GetConstructor( void ) const {
  869. const function_t *func;
  870. func = GetFunction( "init" );
  871. return func;
  872. }
  873. /*
  874. ============
  875. idScriptObject::GetDestructor
  876. ============
  877. */
  878. const function_t *idScriptObject::GetDestructor( void ) const {
  879. const function_t *func;
  880. func = GetFunction( "destroy" );
  881. return func;
  882. }
  883. /*
  884. ============
  885. idScriptObject::GetFunction
  886. ============
  887. */
  888. const function_t *idScriptObject::GetFunction( const char *name ) const {
  889. const function_t *func;
  890. if ( type == &type_object ) {
  891. return NULL;
  892. }
  893. func = gameLocal.program.FindFunction( name, type );
  894. return func;
  895. }
  896. /*
  897. ============
  898. idScriptObject::GetVariable
  899. ============
  900. */
  901. byte *idScriptObject::GetVariable( const char *name, etype_t etype ) const {
  902. int i;
  903. int pos;
  904. const idTypeDef *t;
  905. const idTypeDef *parm;
  906. if ( type == &type_object ) {
  907. return NULL;
  908. }
  909. t = type;
  910. do {
  911. if ( t->SuperClass() != &type_object ) {
  912. pos = t->SuperClass()->Size();
  913. } else {
  914. pos = 0;
  915. }
  916. for( i = 0; i < t->NumParameters(); i++ ) {
  917. parm = t->GetParmType( i );
  918. if ( !strcmp( t->GetParmName( i ), name ) ) {
  919. if ( etype != parm->FieldType()->Type() ) {
  920. return NULL;
  921. }
  922. return &data[ pos ];
  923. }
  924. if ( parm->FieldType()->Inherits( &type_object ) ) {
  925. pos += type_object.Size();
  926. } else {
  927. pos += parm->FieldType()->Size();
  928. }
  929. }
  930. t = t->SuperClass();
  931. } while( t && ( t != &type_object ) );
  932. return NULL;
  933. }
  934. /***********************************************************************
  935. idProgram
  936. ***********************************************************************/
  937. /*
  938. ============
  939. idProgram::AllocType
  940. ============
  941. */
  942. idTypeDef *idProgram::AllocType( idTypeDef &type ) {
  943. idTypeDef *newtype;
  944. newtype = new idTypeDef( type );
  945. types.Append( newtype );
  946. return newtype;
  947. }
  948. /*
  949. ============
  950. idProgram::AllocType
  951. ============
  952. */
  953. idTypeDef *idProgram::AllocType( etype_t etype, idVarDef *edef, const char *ename, int esize, idTypeDef *aux ) {
  954. idTypeDef *newtype;
  955. newtype = new idTypeDef( etype, edef, ename, esize, aux );
  956. types.Append( newtype );
  957. return newtype;
  958. }
  959. /*
  960. ============
  961. idProgram::GetType
  962. Returns a preexisting complex type that matches the parm, or allocates
  963. a new one and copies it out.
  964. ============
  965. */
  966. idTypeDef *idProgram::GetType( idTypeDef &type, bool allocate ) {
  967. int i;
  968. //FIXME: linear search == slow
  969. for( i = types.Num() - 1; i >= 0; i-- ) {
  970. if ( types[ i ]->MatchesType( type ) && !strcmp( types[ i ]->Name(), type.Name() ) ) {
  971. return types[ i ];
  972. }
  973. }
  974. if ( !allocate ) {
  975. return NULL;
  976. }
  977. // allocate a new one
  978. return AllocType( type );
  979. }
  980. /*
  981. ============
  982. idProgram::FindType
  983. Returns a preexisting complex type that matches the name, or returns NULL if not found
  984. ============
  985. */
  986. idTypeDef *idProgram::FindType( const char *name ) {
  987. idTypeDef *check;
  988. int i;
  989. for( i = types.Num() - 1; i >= 0; i-- ) {
  990. check = types[ i ];
  991. if ( !strcmp( check->Name(), name ) ) {
  992. return check;
  993. }
  994. }
  995. return NULL;
  996. }
  997. /*
  998. ============
  999. idProgram::GetDefList
  1000. ============
  1001. */
  1002. idVarDef *idProgram::GetDefList( const char *name ) const {
  1003. int i, hash;
  1004. hash = varDefNameHash.GenerateKey( name, true );
  1005. for ( i = varDefNameHash.First( hash ); i != -1; i = varDefNameHash.Next( i ) ) {
  1006. if ( idStr::Cmp( varDefNames[i]->Name(), name ) == 0 ) {
  1007. return varDefNames[i]->GetDefs();
  1008. }
  1009. }
  1010. return NULL;
  1011. }
  1012. /*
  1013. ============
  1014. idProgram::AddDefToNameList
  1015. ============
  1016. */
  1017. void idProgram::AddDefToNameList( idVarDef *def, const char *name ) {
  1018. int i, hash;
  1019. hash = varDefNameHash.GenerateKey( name, true );
  1020. for ( i = varDefNameHash.First( hash ); i != -1; i = varDefNameHash.Next( i ) ) {
  1021. if ( idStr::Cmp( varDefNames[i]->Name(), name ) == 0 ) {
  1022. break;
  1023. }
  1024. }
  1025. if ( i == -1 ) {
  1026. i = varDefNames.Append( new idVarDefName( name ) );
  1027. varDefNameHash.Add( hash, i );
  1028. }
  1029. varDefNames[i]->AddDef( def );
  1030. }
  1031. /*
  1032. ============
  1033. idProgram::AllocDef
  1034. ============
  1035. */
  1036. idVarDef *idProgram::AllocDef( idTypeDef *type, const char *name, idVarDef *scope, bool constant ) {
  1037. idVarDef *def;
  1038. idStr element;
  1039. idVarDef *def_x;
  1040. idVarDef *def_y;
  1041. idVarDef *def_z;
  1042. // allocate a new def
  1043. def = new idVarDef( type );
  1044. def->scope = scope;
  1045. def->numUsers = 1;
  1046. def->num = varDefs.Append( def );
  1047. // add the def to the list with defs with this name and set the name pointer
  1048. AddDefToNameList( def, name );
  1049. if ( ( type->Type() == ev_vector ) || ( ( type->Type() == ev_field ) && ( type->FieldType()->Type() == ev_vector ) ) ) {
  1050. //
  1051. // vector
  1052. //
  1053. if ( !strcmp( name, RESULT_STRING ) ) {
  1054. // <RESULT> vector defs don't need the _x, _y and _z components
  1055. assert( scope->Type() == ev_function );
  1056. def->value.stackOffset = scope->value.functionPtr->locals;
  1057. def->initialized = idVarDef::stackVariable;
  1058. scope->value.functionPtr->locals += type->Size();
  1059. } else if ( scope->TypeDef()->Inherits( &type_object ) ) {
  1060. idTypeDef newtype( ev_field, NULL, "float field", 0, &type_float );
  1061. idTypeDef *type = GetType( newtype, true );
  1062. // set the value to the variable's position in the object
  1063. def->value.ptrOffset = scope->TypeDef()->Size();
  1064. // make automatic defs for the vectors elements
  1065. // origin can be accessed as origin_x, origin_y, and origin_z
  1066. sprintf( element, "%s_x", def->Name() );
  1067. def_x = AllocDef( type, element, scope, constant );
  1068. sprintf( element, "%s_y", def->Name() );
  1069. def_y = AllocDef( type, element, scope, constant );
  1070. def_y->value.ptrOffset = def_x->value.ptrOffset + type_float.Size();
  1071. sprintf( element, "%s_z", def->Name() );
  1072. def_z = AllocDef( type, element, scope, constant );
  1073. def_z->value.ptrOffset = def_y->value.ptrOffset + type_float.Size();
  1074. } else {
  1075. // make automatic defs for the vectors elements
  1076. // origin can be accessed as origin_x, origin_y, and origin_z
  1077. sprintf( element, "%s_x", def->Name() );
  1078. def_x = AllocDef( &type_float, element, scope, constant );
  1079. sprintf( element, "%s_y", def->Name() );
  1080. def_y = AllocDef( &type_float, element, scope, constant );
  1081. sprintf( element, "%s_z", def->Name() );
  1082. def_z = AllocDef( &type_float, element, scope, constant );
  1083. // point the vector def to the x coordinate
  1084. def->value = def_x->value;
  1085. def->initialized = def_x->initialized;
  1086. }
  1087. } else if ( scope->TypeDef()->Inherits( &type_object ) ) {
  1088. //
  1089. // object variable
  1090. //
  1091. // set the value to the variable's position in the object
  1092. def->value.ptrOffset = scope->TypeDef()->Size();
  1093. } else if ( scope->Type() == ev_function ) {
  1094. //
  1095. // stack variable
  1096. //
  1097. // since we don't know how many local variables there are,
  1098. // we have to have them go backwards on the stack
  1099. def->value.stackOffset = scope->value.functionPtr->locals;
  1100. def->initialized = idVarDef::stackVariable;
  1101. if ( type->Inherits( &type_object ) ) {
  1102. // objects only have their entity number on the stack, not the entire object
  1103. scope->value.functionPtr->locals += type_object.Size();
  1104. } else {
  1105. scope->value.functionPtr->locals += type->Size();
  1106. }
  1107. } else {
  1108. //
  1109. // global variable
  1110. //
  1111. def->value.bytePtr = &variables[ numVariables ];
  1112. numVariables += def->TypeDef()->Size();
  1113. if ( numVariables > sizeof( variables ) ) {
  1114. throw idCompileError( va( "Exceeded global memory size (%d bytes)", sizeof( variables ) ) );
  1115. }
  1116. memset( def->value.bytePtr, 0, def->TypeDef()->Size() );
  1117. }
  1118. return def;
  1119. }
  1120. /*
  1121. ============
  1122. idProgram::GetDef
  1123. If type is NULL, it will match any type
  1124. ============
  1125. */
  1126. idVarDef *idProgram::GetDef( const idTypeDef *type, const char *name, const idVarDef *scope ) const {
  1127. idVarDef *def;
  1128. idVarDef *bestDef;
  1129. int bestDepth;
  1130. int depth;
  1131. bestDepth = 0;
  1132. bestDef = NULL;
  1133. for( def = GetDefList( name ); def != NULL; def = def->Next() ) {
  1134. if ( def->scope->Type() == ev_namespace ) {
  1135. depth = def->DepthOfScope( scope );
  1136. if ( !depth ) {
  1137. // not in the same namespace
  1138. continue;
  1139. }
  1140. } else if ( def->scope != scope ) {
  1141. // in a different function
  1142. continue;
  1143. } else {
  1144. depth = 1;
  1145. }
  1146. if ( !bestDef || ( depth < bestDepth ) ) {
  1147. bestDepth = depth;
  1148. bestDef = def;
  1149. }
  1150. }
  1151. // see if the name is already in use for another type
  1152. if ( bestDef && type && ( bestDef->TypeDef() != type ) ) {
  1153. throw idCompileError( va( "Type mismatch on redeclaration of %s", name ) );
  1154. }
  1155. return bestDef;
  1156. }
  1157. /*
  1158. ============
  1159. idProgram::FreeDef
  1160. ============
  1161. */
  1162. void idProgram::FreeDef( idVarDef *def, const idVarDef *scope ) {
  1163. idVarDef *e;
  1164. int i;
  1165. if ( def->Type() == ev_vector ) {
  1166. idStr name;
  1167. sprintf( name, "%s_x", def->Name() );
  1168. e = GetDef( NULL, name, scope );
  1169. if ( e ) {
  1170. FreeDef( e, scope );
  1171. }
  1172. sprintf( name, "%s_y", def->Name() );
  1173. e = GetDef( NULL, name, scope );
  1174. if ( e ) {
  1175. FreeDef( e, scope );
  1176. }
  1177. sprintf( name, "%s_z", def->Name() );
  1178. e = GetDef( NULL, name, scope );
  1179. if ( e ) {
  1180. FreeDef( e, scope );
  1181. }
  1182. }
  1183. varDefs.RemoveIndex( def->num );
  1184. for( i = def->num; i < varDefs.Num(); i++ ) {
  1185. varDefs[ i ]->num = i;
  1186. }
  1187. delete def;
  1188. }
  1189. /*
  1190. ============
  1191. idProgram::FindFreeResultDef
  1192. ============
  1193. */
  1194. idVarDef *idProgram::FindFreeResultDef( idTypeDef *type, const char *name, idVarDef *scope, const idVarDef *a, const idVarDef *b ) {
  1195. idVarDef *def;
  1196. for( def = GetDefList( name ); def != NULL; def = def->Next() ) {
  1197. if ( def == a || def == b ) {
  1198. continue;
  1199. }
  1200. if ( def->TypeDef() != type ) {
  1201. continue;
  1202. }
  1203. if ( def->scope != scope ) {
  1204. continue;
  1205. }
  1206. if ( def->numUsers <= 1 ) {
  1207. continue;
  1208. }
  1209. return def;
  1210. }
  1211. return AllocDef( type, name, scope, false );
  1212. }
  1213. /*
  1214. ================
  1215. idProgram::FindFunction
  1216. Searches for the specified function in the currently loaded script. A full namespace should be
  1217. specified if not in the global namespace.
  1218. Returns 0 if function not found.
  1219. Returns >0 if function found.
  1220. ================
  1221. */
  1222. function_t *idProgram::FindFunction( const char *name ) const {
  1223. int start;
  1224. int pos;
  1225. idVarDef *namespaceDef;
  1226. idVarDef *def;
  1227. assert( name );
  1228. idStr fullname = name;
  1229. start = 0;
  1230. namespaceDef = &def_namespace;
  1231. do {
  1232. pos = fullname.Find( "::", true, start );
  1233. if ( pos < 0 ) {
  1234. break;
  1235. }
  1236. idStr namespaceName = fullname.Mid( start, pos - start );
  1237. def = GetDef( NULL, namespaceName, namespaceDef );
  1238. if ( !def ) {
  1239. // couldn't find namespace
  1240. return NULL;
  1241. }
  1242. namespaceDef = def;
  1243. // skip past the ::
  1244. start = pos + 2;
  1245. } while( def->Type() == ev_namespace );
  1246. idStr funcName = fullname.Right( fullname.Length() - start );
  1247. def = GetDef( NULL, funcName, namespaceDef );
  1248. if ( !def ) {
  1249. // couldn't find function
  1250. return NULL;
  1251. }
  1252. if ( ( def->Type() == ev_function ) && ( def->value.functionPtr->eventdef == NULL ) ) {
  1253. return def->value.functionPtr;
  1254. }
  1255. // is not a function, or is an eventdef
  1256. return NULL;
  1257. }
  1258. /*
  1259. ================
  1260. idProgram::FindFunction
  1261. Searches for the specified object function in the currently loaded script.
  1262. Returns 0 if function not found.
  1263. Returns >0 if function found.
  1264. ================
  1265. */
  1266. function_t *idProgram::FindFunction( const char *name, const idTypeDef *type ) const {
  1267. const idVarDef *tdef;
  1268. const idVarDef *def;
  1269. // look for the function
  1270. def = NULL;
  1271. for( tdef = type->def; tdef != &def_object; tdef = tdef->TypeDef()->SuperClass()->def ) {
  1272. def = GetDef( NULL, name, tdef );
  1273. if ( def ) {
  1274. return def->value.functionPtr;
  1275. }
  1276. }
  1277. return NULL;
  1278. }
  1279. /*
  1280. ================
  1281. idProgram::AllocFunction
  1282. ================
  1283. */
  1284. function_t &idProgram::AllocFunction( idVarDef *def ) {
  1285. if ( functions.Num() >= functions.Max() ) {
  1286. throw idCompileError( va( "Exceeded maximum allowed number of functions (%d)", functions.Max() ) );
  1287. }
  1288. // fill in the dfunction
  1289. function_t &func = *functions.Alloc();
  1290. func.eventdef = NULL;
  1291. func.def = def;
  1292. func.type = def->TypeDef();
  1293. func.firstStatement = 0;
  1294. func.numStatements = 0;
  1295. func.parmTotal = 0;
  1296. func.locals = 0;
  1297. func.filenum = filenum;
  1298. func.parmSize.SetGranularity( 1 );
  1299. func.SetName( def->GlobalName() );
  1300. def->SetFunction( &func );
  1301. return func;
  1302. }
  1303. /*
  1304. ================
  1305. idProgram::SetEntity
  1306. ================
  1307. */
  1308. void idProgram::SetEntity( const char *name, idEntity *ent ) {
  1309. idVarDef *def;
  1310. idStr defName( "$" );
  1311. defName += name;
  1312. def = GetDef( &type_entity, defName, &def_namespace );
  1313. if ( def && ( def->initialized != idVarDef::stackVariable ) ) {
  1314. // 0 is reserved for NULL entity
  1315. if ( !ent ) {
  1316. *def->value.entityNumberPtr = 0;
  1317. } else {
  1318. *def->value.entityNumberPtr = ent->entityNumber + 1;
  1319. }
  1320. }
  1321. }
  1322. /*
  1323. ================
  1324. idProgram::AllocStatement
  1325. ================
  1326. */
  1327. statement_t *idProgram::AllocStatement( void ) {
  1328. if ( statements.Num() >= statements.Max() ) {
  1329. throw idCompileError( va( "Exceeded maximum allowed number of statements (%d)", statements.Max() ) );
  1330. }
  1331. return statements.Alloc();
  1332. }
  1333. /*
  1334. ==============
  1335. idProgram::BeginCompilation
  1336. called before compiling a batch of files, clears the pr struct
  1337. ==============
  1338. */
  1339. void idProgram::BeginCompilation( void ) {
  1340. statement_t *statement;
  1341. FreeData();
  1342. try {
  1343. // make the first statement a return for a "NULL" function
  1344. statement = AllocStatement();
  1345. statement->linenumber = 0;
  1346. statement->file = 0;
  1347. statement->op = OP_RETURN;
  1348. statement->a = NULL;
  1349. statement->b = NULL;
  1350. statement->c = NULL;
  1351. // define NULL
  1352. //AllocDef( &type_void, "<NULL>", &def_namespace, true );
  1353. // define the return def
  1354. returnDef = AllocDef( &type_vector, "<RETURN>", &def_namespace, false );
  1355. // define the return def for strings
  1356. returnStringDef = AllocDef( &type_string, "<RETURN>", &def_namespace, false );
  1357. // define the sys object
  1358. sysDef = AllocDef( &type_void, "sys", &def_namespace, true );
  1359. }
  1360. catch( idCompileError &err ) {
  1361. gameLocal.Error( "%s", err.error );
  1362. }
  1363. }
  1364. /*
  1365. ==============
  1366. idProgram::DisassembleStatement
  1367. ==============
  1368. */
  1369. void idProgram::DisassembleStatement( idFile *file, int instructionPointer ) const {
  1370. opcode_t *op;
  1371. const statement_t *statement;
  1372. statement = &statements[ instructionPointer ];
  1373. op = &idCompiler::opcodes[ statement->op ];
  1374. file->Printf( "%20s(%d):\t%6d: %15s\t", fileList[ statement->file ].c_str(), statement->linenumber, instructionPointer, op->opname );
  1375. if ( statement->a ) {
  1376. file->Printf( "\ta: " );
  1377. statement->a->PrintInfo( file, instructionPointer );
  1378. }
  1379. if ( statement->b ) {
  1380. file->Printf( "\tb: " );
  1381. statement->b->PrintInfo( file, instructionPointer );
  1382. }
  1383. if ( statement->c ) {
  1384. file->Printf( "\tc: " );
  1385. statement->c->PrintInfo( file, instructionPointer );
  1386. }
  1387. file->Printf( "\n" );
  1388. }
  1389. /*
  1390. ==============
  1391. idProgram::Disassemble
  1392. ==============
  1393. */
  1394. void idProgram::Disassemble( void ) const {
  1395. int i;
  1396. int instructionPointer;
  1397. const function_t *func;
  1398. idFile *file;
  1399. file = fileSystem->OpenFileByMode( "script/disasm.txt", FS_WRITE );
  1400. for( i = 0; i < functions.Num(); i++ ) {
  1401. func = &functions[ i ];
  1402. if ( func->eventdef ) {
  1403. // skip eventdefs
  1404. continue;
  1405. }
  1406. file->Printf( "\nfunction %s() %d stack used, %d parms, %d locals {\n", func->Name(), func->locals, func->parmTotal, func->locals - func->parmTotal );
  1407. for( instructionPointer = 0; instructionPointer < func->numStatements; instructionPointer++ ) {
  1408. DisassembleStatement( file, func->firstStatement + instructionPointer );
  1409. }
  1410. file->Printf( "}\n" );
  1411. }
  1412. fileSystem->CloseFile( file );
  1413. }
  1414. /*
  1415. ==============
  1416. idProgram::FinishCompilation
  1417. Called after all files are compiled to check for errors
  1418. ==============
  1419. */
  1420. void idProgram::FinishCompilation( void ) {
  1421. int i;
  1422. top_functions = functions.Num();
  1423. top_statements = statements.Num();
  1424. top_types = types.Num();
  1425. top_defs = varDefs.Num();
  1426. top_files = fileList.Num();
  1427. variableDefaults.Clear();
  1428. variableDefaults.SetNum( numVariables );
  1429. for( i = 0; i < numVariables; i++ ) {
  1430. variableDefaults[ i ] = variables[ i ];
  1431. }
  1432. }
  1433. /*
  1434. ==============
  1435. idProgram::CompileStats
  1436. called after all files are compiled to report memory usage.
  1437. ==============
  1438. */
  1439. void idProgram::CompileStats( void ) {
  1440. int memused;
  1441. int memallocated;
  1442. int numdefs;
  1443. int stringspace;
  1444. int funcMem;
  1445. int i;
  1446. gameLocal.Printf( "---------- Compile stats ----------\n" );
  1447. gameLocal.DPrintf( "Files loaded:\n" );
  1448. stringspace = 0;
  1449. for( i = 0; i < fileList.Num(); i++ ) {
  1450. gameLocal.DPrintf( " %s\n", fileList[ i ].c_str() );
  1451. stringspace += fileList[ i ].Allocated();
  1452. }
  1453. stringspace += fileList.Size();
  1454. numdefs = varDefs.Num();
  1455. memused = varDefs.Num() * sizeof( idVarDef );
  1456. memused += types.Num() * sizeof( idTypeDef );
  1457. memused += stringspace;
  1458. for( i = 0; i < types.Num(); i++ ) {
  1459. memused += types[ i ]->Allocated();
  1460. }
  1461. funcMem = functions.MemoryUsed();
  1462. for( i = 0; i < functions.Num(); i++ ) {
  1463. funcMem += functions[ i ].Allocated();
  1464. }
  1465. memallocated = funcMem + memused + sizeof( idProgram );
  1466. memused += statements.MemoryUsed();
  1467. memused += functions.MemoryUsed(); // name and filename of functions are shared, so no need to include them
  1468. memused += sizeof( variables );
  1469. gameLocal.Printf( "\nMemory usage:\n" );
  1470. gameLocal.Printf( " Strings: %d, %d bytes\n", fileList.Num(), stringspace );
  1471. gameLocal.Printf( " Statements: %d, %d bytes\n", statements.Num(), statements.MemoryUsed() );
  1472. gameLocal.Printf( " Functions: %d, %d bytes\n", functions.Num(), funcMem );
  1473. gameLocal.Printf( " Variables: %d bytes\n", numVariables );
  1474. gameLocal.Printf( " Mem used: %d bytes\n", memused );
  1475. gameLocal.Printf( " Static data: %d bytes\n", sizeof( idProgram ) );
  1476. gameLocal.Printf( " Allocated: %d bytes\n", memallocated );
  1477. gameLocal.Printf( " Thread size: %d bytes\n\n", sizeof( idThread ) );
  1478. }
  1479. /*
  1480. ================
  1481. idProgram::CompileText
  1482. ================
  1483. */
  1484. bool idProgram::CompileText( const char *source, const char *text, bool console ) {
  1485. idCompiler compiler;
  1486. int i;
  1487. idVarDef *def;
  1488. idStr ospath;
  1489. // use a full os path for GetFilenum since it calls OSPathToRelativePath to convert filenames from the parser
  1490. ospath = fileSystem->RelativePathToOSPath( source );
  1491. filenum = GetFilenum( ospath );
  1492. try {
  1493. compiler.CompileFile( text, filename, console );
  1494. // check to make sure all functions prototyped have code
  1495. for( i = 0; i < varDefs.Num(); i++ ) {
  1496. def = varDefs[ i ];
  1497. if ( ( def->Type() == ev_function ) && ( ( def->scope->Type() == ev_namespace ) || def->scope->TypeDef()->Inherits( &type_object ) ) ) {
  1498. if ( !def->value.functionPtr->eventdef && !def->value.functionPtr->firstStatement ) {
  1499. throw idCompileError( va( "function %s was not defined\n", def->GlobalName() ) );
  1500. }
  1501. }
  1502. }
  1503. }
  1504. catch( idCompileError &err ) {
  1505. if ( console ) {
  1506. gameLocal.Printf( "%s\n", err.error );
  1507. return false;
  1508. } else {
  1509. gameLocal.Error( "%s\n", err.error );
  1510. }
  1511. };
  1512. if ( !console ) {
  1513. CompileStats();
  1514. }
  1515. return true;
  1516. }
  1517. /*
  1518. ================
  1519. idProgram::CompileFunction
  1520. ================
  1521. */
  1522. const function_t *idProgram::CompileFunction( const char *functionName, const char *text ) {
  1523. bool result;
  1524. result = CompileText( functionName, text, false );
  1525. if ( g_disasm.GetBool() ) {
  1526. Disassemble();
  1527. }
  1528. if ( !result ) {
  1529. gameLocal.Error( "Compile failed." );
  1530. }
  1531. return FindFunction( functionName );
  1532. }
  1533. /*
  1534. ================
  1535. idProgram::CompileFile
  1536. ================
  1537. */
  1538. void idProgram::CompileFile( const char *filename ) {
  1539. char *src;
  1540. bool result;
  1541. if ( fileSystem->ReadFile( filename, ( void ** )&src, NULL ) < 0 ) {
  1542. gameLocal.Error( "Couldn't load %s\n", filename );
  1543. }
  1544. result = CompileText( filename, src, false );
  1545. fileSystem->FreeFile( src );
  1546. if ( g_disasm.GetBool() ) {
  1547. Disassemble();
  1548. }
  1549. if ( !result ) {
  1550. gameLocal.Error( "Compile failed in file %s.", filename );
  1551. }
  1552. }
  1553. /*
  1554. ================
  1555. idProgram::FreeData
  1556. ================
  1557. */
  1558. void idProgram::FreeData( void ) {
  1559. int i;
  1560. // free the defs
  1561. varDefs.DeleteContents( true );
  1562. varDefNames.DeleteContents( true );
  1563. varDefNameHash.Free();
  1564. returnDef = NULL;
  1565. returnStringDef = NULL;
  1566. sysDef = NULL;
  1567. // free any special types we've created
  1568. types.DeleteContents( true );
  1569. filenum = 0;
  1570. numVariables = 0;
  1571. memset( variables, 0, sizeof( variables ) );
  1572. // clear all the strings in the functions so that it doesn't look like we're leaking memory.
  1573. for( i = 0; i < functions.Num(); i++ ) {
  1574. functions[ i ].Clear();
  1575. }
  1576. filename.Clear();
  1577. fileList.Clear();
  1578. statements.Clear();
  1579. functions.Clear();
  1580. top_functions = 0;
  1581. top_statements = 0;
  1582. top_types = 0;
  1583. top_defs = 0;
  1584. top_files = 0;
  1585. filename = "";
  1586. }
  1587. /*
  1588. ================
  1589. idProgram::Startup
  1590. ================
  1591. */
  1592. void idProgram::Startup( const char *defaultScript ) {
  1593. gameLocal.Printf( "Initializing scripts\n" );
  1594. // make sure all data is freed up
  1595. idThread::Restart();
  1596. // get ready for loading scripts
  1597. BeginCompilation();
  1598. // load the default script
  1599. if ( defaultScript && *defaultScript ) {
  1600. CompileFile( defaultScript );
  1601. }
  1602. FinishCompilation();
  1603. }
  1604. /*
  1605. ================
  1606. idProgram::Save
  1607. ================
  1608. */
  1609. void idProgram::Save( idSaveGame *savefile ) const {
  1610. int i;
  1611. int currentFileNum = top_files;
  1612. savefile->WriteInt( (fileList.Num() - currentFileNum) );
  1613. while ( currentFileNum < fileList.Num() ) {
  1614. savefile->WriteString( fileList[ currentFileNum ] );
  1615. currentFileNum++;
  1616. }
  1617. for ( i = 0; i < variableDefaults.Num(); i++ ) {
  1618. if ( variables[i] != variableDefaults[i] ) {
  1619. savefile->WriteInt( i );
  1620. savefile->WriteByte( variables[i] );
  1621. }
  1622. }
  1623. // Mark the end of the diff with default variables with -1
  1624. savefile->WriteInt( -1 );
  1625. savefile->WriteInt( numVariables );
  1626. for ( i = variableDefaults.Num(); i < numVariables; i++ ) {
  1627. savefile->WriteByte( variables[i] );
  1628. }
  1629. int checksum = CalculateChecksum();
  1630. savefile->WriteInt( checksum );
  1631. }
  1632. /*
  1633. ================
  1634. idProgram::Restore
  1635. ================
  1636. */
  1637. bool idProgram::Restore( idRestoreGame *savefile ) {
  1638. int i, num, index;
  1639. bool result = true;
  1640. idStr scriptname;
  1641. savefile->ReadInt( num );
  1642. for ( i = 0; i < num; i++ ) {
  1643. savefile->ReadString( scriptname );
  1644. CompileFile( scriptname );
  1645. }
  1646. savefile->ReadInt( index );
  1647. while( index >= 0 ) {
  1648. savefile->ReadByte( variables[index] );
  1649. savefile->ReadInt( index );
  1650. }
  1651. savefile->ReadInt( num );
  1652. for ( i = variableDefaults.Num(); i < num; i++ ) {
  1653. savefile->ReadByte( variables[i] );
  1654. }
  1655. int saved_checksum, checksum;
  1656. savefile->ReadInt( saved_checksum );
  1657. checksum = CalculateChecksum();
  1658. if ( saved_checksum != checksum ) {
  1659. result = false;
  1660. }
  1661. return result;
  1662. }
  1663. /*
  1664. ================
  1665. idProgram::CalculateChecksum
  1666. ================
  1667. */
  1668. int idProgram::CalculateChecksum( void ) const {
  1669. int i, result;
  1670. typedef struct {
  1671. unsigned short op;
  1672. int a;
  1673. int b;
  1674. int c;
  1675. unsigned short linenumber;
  1676. unsigned short file;
  1677. } statementBlock_t;
  1678. statementBlock_t *statementList = new statementBlock_t[ statements.Num() ];
  1679. memset( statementList, 0, ( sizeof(statementBlock_t) * statements.Num() ) );
  1680. // Copy info into new list, using the variable numbers instead of a pointer to the variable
  1681. for( i = 0; i < statements.Num(); i++ ) {
  1682. statementList[i].op = statements[i].op;
  1683. if ( statements[i].a ) {
  1684. statementList[i].a = statements[i].a->num;
  1685. } else {
  1686. statementList[i].a = -1;
  1687. }
  1688. if ( statements[i].b ) {
  1689. statementList[i].b = statements[i].b->num;
  1690. } else {
  1691. statementList[i].b = -1;
  1692. }
  1693. if ( statements[i].c ) {
  1694. statementList[i].c = statements[i].c->num;
  1695. } else {
  1696. statementList[i].c = -1;
  1697. }
  1698. statementList[i].linenumber = statements[i].linenumber;
  1699. statementList[i].file = statements[i].file;
  1700. }
  1701. result = MD4_BlockChecksum( statementList, ( sizeof(statementBlock_t) * statements.Num() ) );
  1702. delete [] statementList;
  1703. return result;
  1704. }
  1705. /*
  1706. ==============
  1707. idProgram::Restart
  1708. Restores all variables to their initial value
  1709. ==============
  1710. */
  1711. void idProgram::Restart( void ) {
  1712. int i;
  1713. idThread::Restart();
  1714. //
  1715. // since there may have been a script loaded by the map or the user may
  1716. // have typed "script" from the console, free up any types and vardefs that
  1717. // have been allocated after the initial startup
  1718. //
  1719. for( i = top_types; i < types.Num(); i++ ) {
  1720. delete types[ i ];
  1721. }
  1722. types.SetNum( top_types, false );
  1723. for( i = top_defs; i < varDefs.Num(); i++ ) {
  1724. delete varDefs[ i ];
  1725. }
  1726. varDefs.SetNum( top_defs, false );
  1727. for( i = top_functions; i < functions.Num(); i++ ) {
  1728. functions[ i ].Clear();
  1729. }
  1730. functions.SetNum( top_functions );
  1731. statements.SetNum( top_statements );
  1732. fileList.SetNum( top_files, false );
  1733. filename.Clear();
  1734. // reset the variables to their default values
  1735. numVariables = variableDefaults.Num();
  1736. for( i = 0; i < numVariables; i++ ) {
  1737. variables[ i ] = variableDefaults[ i ];
  1738. }
  1739. }
  1740. /*
  1741. ================
  1742. idProgram::GetFilenum
  1743. ================
  1744. */
  1745. int idProgram::GetFilenum( const char *name ) {
  1746. if ( filename == name ) {
  1747. return filenum;
  1748. }
  1749. idStr strippedName;
  1750. strippedName = fileSystem->OSPathToRelativePath( name );
  1751. if ( !strippedName.Length() ) {
  1752. // not off the base path so just use the full path
  1753. filenum = fileList.AddUnique( name );
  1754. } else {
  1755. filenum = fileList.AddUnique( strippedName );
  1756. }
  1757. // save the unstripped name so that we don't have to strip the incoming name every time we call GetFilenum
  1758. filename = name;
  1759. return filenum;
  1760. }
  1761. /*
  1762. ================
  1763. idProgram::idProgram
  1764. ================
  1765. */
  1766. idProgram::idProgram() {
  1767. FreeData();
  1768. }
  1769. /*
  1770. ================
  1771. idProgram::~idProgram
  1772. ================
  1773. */
  1774. idProgram::~idProgram() {
  1775. FreeData();
  1776. }
  1777. /*
  1778. ================
  1779. idProgram::ReturnEntity
  1780. ================
  1781. */
  1782. void idProgram::ReturnEntity( idEntity *ent ) {
  1783. if ( ent ) {
  1784. *returnDef->value.entityNumberPtr = ent->entityNumber + 1;
  1785. } else {
  1786. *returnDef->value.entityNumberPtr = 0;
  1787. }
  1788. }