PageRenderTime 37ms CodeModel.GetById 0ms RepoModel.GetById 0ms app.codeStats 0ms

/indra/lscript/lscript_compile/lscript_tree.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 2002 lines | 1954 code | 19 blank | 29 comment | 4 complexity | 9a642e4b3c4c6c134920499e3410d98b MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file lscript_tree.cpp
  3. * @brief implements methods for lscript_tree.h classes
  4. *
  5. * $LicenseInfo:firstyear=2002&license=viewerlgpl$
  6. * Second Life Viewer Source Code
  7. * Copyright (C) 2010, Linden Research, Inc.
  8. *
  9. * This library is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation;
  12. * version 2.1 of the License only.
  13. *
  14. * This library is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with this library; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. *
  23. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  24. * $/LicenseInfo$
  25. */
  26. // TO DO: Move print functionality from .h file to here
  27. #include "linden_common.h"
  28. #include "lscript_tree.h"
  29. #include "lscript_typecheck.h"
  30. #include "lscript_resource.h"
  31. #include "lscript_bytecode.h"
  32. #include "lscript_heap.h"
  33. #include "lscript_library.h"
  34. #include "lscript_alloc.h"
  35. //#define LSL_INCLUDE_DEBUG_INFO
  36. static void print_cil_box(LLFILE* fp, LSCRIPTType type)
  37. {
  38. switch(type)
  39. {
  40. case LST_INTEGER:
  41. fprintf(fp, "box [mscorlib]System.Int32\n");
  42. break;
  43. case LST_FLOATINGPOINT:
  44. fprintf(fp, "box [mscorlib]System.Single\n");
  45. break;
  46. case LST_STRING:
  47. // System.String is not a System.ValueType,
  48. // so does not need to be boxed.
  49. break;
  50. case LST_KEY:
  51. fprintf(fp, "box [ScriptTypes]LindenLab.SecondLife.Key\n");
  52. break;
  53. case LST_VECTOR:
  54. fprintf(fp, "box [ScriptTypes]LindenLab.SecondLife.Vector\n");
  55. break;
  56. case LST_QUATERNION:
  57. fprintf(fp, "box [ScriptTypes]LindenLab.SecondLife.Quaternion\n");
  58. break;
  59. default:
  60. llassert(false);
  61. break;
  62. }
  63. }
  64. static void print_cil_type(LLFILE* fp, LSCRIPTType type)
  65. {
  66. switch(type)
  67. {
  68. case LST_INTEGER:
  69. fprintf(fp, "int32");
  70. break;
  71. case LST_FLOATINGPOINT:
  72. fprintf(fp, "float32");
  73. break;
  74. case LST_STRING:
  75. fprintf(fp, "string");
  76. break;
  77. case LST_KEY:
  78. fprintf(fp, "valuetype [ScriptTypes]LindenLab.SecondLife.Key");
  79. break;
  80. case LST_VECTOR:
  81. fprintf(fp, "class [ScriptTypes]LindenLab.SecondLife.Vector");
  82. break;
  83. case LST_QUATERNION:
  84. fprintf(fp, "class [ScriptTypes]LindenLab.SecondLife.Quaternion");
  85. break;
  86. case LST_LIST:
  87. fprintf(fp, "class [mscorlib]System.Collections.ArrayList");
  88. break;
  89. case LST_NULL:
  90. fprintf(fp, "void");
  91. break;
  92. default:
  93. break;
  94. }
  95. }
  96. void LLScriptType::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
  97. {
  98. if (gErrorToText.getErrors())
  99. {
  100. return;
  101. }
  102. switch(pass)
  103. {
  104. case LSCP_PRETTY_PRINT:
  105. case LSCP_EMIT_ASSEMBLY:
  106. fprintf(fp,"%s",LSCRIPTTypeNames[mType]);
  107. break;
  108. case LSCP_TYPE:
  109. type = mType;
  110. break;
  111. case LSCP_EMIT_CIL_ASSEMBLY:
  112. print_cil_type(fp, mType);
  113. break;
  114. default:
  115. break;
  116. }
  117. }
  118. S32 LLScriptType::getSize()
  119. {
  120. return LSCRIPTDataSize[mType];
  121. }
  122. void LLScriptConstant::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
  123. {
  124. if (gErrorToText.getErrors())
  125. {
  126. return;
  127. }
  128. switch(pass)
  129. {
  130. case LSCP_PRETTY_PRINT:
  131. case LSCP_EMIT_ASSEMBLY:
  132. fprintf(fp,"Script Constant Base class -- should never get here!\n");
  133. break;
  134. default:
  135. break;
  136. }
  137. }
  138. S32 LLScriptConstant::getSize()
  139. {
  140. printf("Script Constant Base class -- should never get here!\n");
  141. return 0;
  142. }
  143. void LLScriptConstantInteger::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
  144. {
  145. if (gErrorToText.getErrors())
  146. {
  147. return;
  148. }
  149. switch(pass)
  150. {
  151. case LSCP_PRETTY_PRINT:
  152. fprintf(fp, "%d", mValue);
  153. break;
  154. case LSCP_EMIT_ASSEMBLY:
  155. fprintf(fp, "PUSHARGI %d\n", mValue);
  156. break;
  157. case LSCP_TYPE:
  158. type = mType;
  159. break;
  160. case LSCP_EMIT_BYTE_CODE:
  161. {
  162. chunk->addInteger(mValue);
  163. type = mType;
  164. }
  165. break;
  166. case LSCP_TO_STACK:
  167. {
  168. chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGI]);
  169. chunk->addInteger(mValue);
  170. type = mType;
  171. }
  172. break;
  173. case LSCP_LIST_BUILD_SIMPLE:
  174. {
  175. *ldata = new LLScriptLibData(mValue);
  176. }
  177. break;
  178. case LSCP_EMIT_CIL_ASSEMBLY:
  179. fprintf(fp, "ldc.i4 %d\n", mValue);
  180. type = mType;
  181. break;
  182. default:
  183. break;
  184. }
  185. }
  186. S32 LLScriptConstantInteger::getSize()
  187. {
  188. return LSCRIPTDataSize[LST_INTEGER];
  189. }
  190. void LLScriptConstantFloat::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
  191. {
  192. if (gErrorToText.getErrors())
  193. {
  194. return;
  195. }
  196. switch(pass)
  197. {
  198. case LSCP_PRETTY_PRINT:
  199. fprintf(fp, "%5.5f", mValue);
  200. break;
  201. case LSCP_EMIT_ASSEMBLY:
  202. fprintf(fp, "PUSHARGF %5.5f\n", mValue);
  203. break;
  204. case LSCP_TYPE:
  205. type = mType;
  206. break;
  207. case LSCP_EMIT_BYTE_CODE:
  208. {
  209. chunk->addFloat(mValue);
  210. type = mType;
  211. }
  212. break;
  213. case LSCP_TO_STACK:
  214. {
  215. chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGF]);
  216. chunk->addFloat(mValue);
  217. type = mType;
  218. }
  219. break;
  220. case LSCP_LIST_BUILD_SIMPLE:
  221. {
  222. *ldata = new LLScriptLibData(mValue);
  223. }
  224. break;
  225. case LSCP_EMIT_CIL_ASSEMBLY:
  226. {
  227. double v = (double)mValue;
  228. U8 * p = (U8 *)&v; // See ECMA-335 Partition VI, Appendix C.4.6 Examples, line 4
  229. fprintf(fp, "ldc.r8 (%02x %02x %02x %02x %02x %02x %02x %02x)\n", p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
  230. type = mType;
  231. }
  232. break;
  233. default:
  234. break;
  235. }
  236. }
  237. S32 LLScriptConstantFloat::getSize()
  238. {
  239. return LSCRIPTDataSize[LST_FLOATINGPOINT];
  240. }
  241. void print_escaped(LLFILE* fp, const char* str)
  242. {
  243. putc('"', fp);
  244. for(const char* c = str; *c != '\0'; ++c)
  245. {
  246. switch(*c)
  247. {
  248. case '"':
  249. putc('\\', fp);
  250. putc(*c, fp);
  251. break;
  252. case '\n':
  253. putc('\\', fp);
  254. putc('n', fp);
  255. break;
  256. case '\t':
  257. putc(' ', fp);
  258. putc(' ', fp);
  259. putc(' ', fp);
  260. putc(' ', fp);
  261. break;
  262. case '\\':
  263. putc('\\', fp);
  264. putc('\\', fp);
  265. break;
  266. default:
  267. putc(*c, fp);
  268. }
  269. }
  270. putc('"', fp);
  271. }
  272. void LLScriptConstantString::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
  273. {
  274. if (gErrorToText.getErrors())
  275. {
  276. return;
  277. }
  278. switch(pass)
  279. {
  280. case LSCP_PRETTY_PRINT:
  281. fprintf(fp, "\"%s\"", mValue);
  282. break;
  283. case LSCP_EMIT_ASSEMBLY:
  284. fprintf(fp, "PUSHARGS \"%s\"\n", mValue);
  285. break;
  286. case LSCP_TYPE:
  287. type = mType;
  288. break;
  289. case LSCP_EMIT_BYTE_CODE:
  290. {
  291. chunk->addInteger(heap->mCurrentOffset + 1);
  292. LLScriptLibData *data = new LLScriptLibData(mValue);
  293. U8 *temp;
  294. S32 size = lsa_create_data_block(&temp, data, heap->mCurrentOffset);
  295. heap->addBytes(temp, size);
  296. delete [] temp;
  297. delete data;
  298. }
  299. break;
  300. case LSCP_TO_STACK:
  301. {
  302. chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGS]);
  303. chunk->addBytes(mValue, (S32)strlen(mValue) + 1);
  304. type = mType;
  305. }
  306. break;
  307. case LSCP_LIST_BUILD_SIMPLE:
  308. {
  309. *ldata = new LLScriptLibData(mValue);
  310. }
  311. break;
  312. case LSCP_EMIT_CIL_ASSEMBLY:
  313. fprintf(fp, "ldstr ");
  314. print_escaped(fp, mValue);
  315. fprintf(fp, "\n");
  316. default:
  317. break;
  318. }
  319. }
  320. S32 LLScriptConstantString::getSize()
  321. {
  322. return (S32)strlen(mValue) + 1;
  323. }
  324. void LLScriptIdentifier::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
  325. {
  326. if (gErrorToText.getErrors())
  327. {
  328. return;
  329. }
  330. switch(pass)
  331. {
  332. case LSCP_PRETTY_PRINT:
  333. fprintf(fp, "%s", mName);
  334. break;
  335. case LSCP_EMIT_ASSEMBLY:
  336. if (mScopeEntry)
  337. {
  338. if (mScopeEntry->mIDType == LIT_VARIABLE)
  339. {
  340. fprintf(fp, "$BP + %d [%s]", mScopeEntry->mOffset, mName);
  341. }
  342. else if (mScopeEntry->mIDType == LIT_GLOBAL)
  343. {
  344. fprintf(fp, "$GVR + %d [%s]", mScopeEntry->mOffset, mName);
  345. }
  346. else
  347. {
  348. fprintf(fp, "%s", mName);
  349. }
  350. }
  351. break;
  352. case LSCP_TYPE:
  353. if (mScopeEntry)
  354. type = mScopeEntry->mType;
  355. else
  356. type = LST_NULL;
  357. break;
  358. case LSCP_RESOURCE:
  359. if (mScopeEntry)
  360. {
  361. if (mScopeEntry->mIDType == LIT_VARIABLE)
  362. {
  363. // fprintf(fp, "LOCAL : %d : %d : %s\n", mScopeEntry->mOffset, mScopeEntry->mSize, mName);
  364. }
  365. else if (mScopeEntry->mIDType == LIT_GLOBAL)
  366. {
  367. // fprintf(fp, "GLOBAL: %d : %d : %s\n", mScopeEntry->mOffset, mScopeEntry->mSize, mName);
  368. }
  369. }
  370. break;
  371. case LSCP_LIST_BUILD_SIMPLE:
  372. {
  373. if (mScopeEntry)
  374. {
  375. if (mScopeEntry->mType == LST_LIST)
  376. {
  377. gErrorToText.writeError(fp, this, LSERROR_NO_LISTS_IN_LISTS);
  378. }
  379. else if (mScopeEntry->mAssignable)
  380. {
  381. mScopeEntry->mAssignable->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, ldata);
  382. }
  383. else
  384. {
  385. gErrorToText.writeError(fp, this, LSERROR_NO_UNITIALIZED_VARIABLES_IN_LISTS);
  386. }
  387. }
  388. else
  389. {
  390. gErrorToText.writeError(fp, this, LSERROR_UNDEFINED_NAME);
  391. }
  392. }
  393. break;
  394. case LSCP_EMIT_CIL_ASSEMBLY:
  395. fprintf(fp, "'%s'", mName);
  396. break;
  397. default:
  398. break;
  399. }
  400. }
  401. S32 LLScriptIdentifier::getSize()
  402. {
  403. return 0;
  404. }
  405. void LLScriptSimpleAssignable::addAssignable(LLScriptSimpleAssignable *assign)
  406. {
  407. if (mNextp)
  408. {
  409. assign->mNextp = mNextp;
  410. }
  411. mNextp = assign;
  412. }
  413. void LLScriptSimpleAssignable::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
  414. {
  415. if (gErrorToText.getErrors())
  416. {
  417. return;
  418. }
  419. fprintf(fp, "Simple Assignable Base Class -- should never get here!\n");
  420. }
  421. S32 LLScriptSimpleAssignable::getSize()
  422. {
  423. printf("Simple Assignable Base Class -- should never get here!\n");
  424. return 0;
  425. }
  426. static void print_cil_member(LLFILE* fp, LLScriptIdentifier *ident)
  427. {
  428. print_cil_type(fp, ident->mScopeEntry->mType);
  429. fprintf(fp, " %s::'%s'\n", gScriptp->getClassName(), ident->mScopeEntry->mIdentifier);
  430. }
  431. void LLScriptSAIdentifier::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
  432. {
  433. if (gErrorToText.getErrors())
  434. {
  435. return;
  436. }
  437. switch(pass)
  438. {
  439. case LSCP_PRETTY_PRINT:
  440. case LSCP_EMIT_ASSEMBLY:
  441. mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  442. if (mNextp)
  443. {
  444. fprintf(fp, ", ");
  445. mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  446. }
  447. break;
  448. case LSCP_SCOPE_PASS1:
  449. {
  450. LLScriptScopeEntry *entry = scope->findEntry(mIdentifier->mName);
  451. if (!entry)
  452. {
  453. gErrorToText.writeError(fp, this, LSERROR_UNDEFINED_NAME);
  454. }
  455. else
  456. {
  457. // if we did find it, make sure this identifier is associated with the correct scope entry
  458. mIdentifier->mScopeEntry = entry;
  459. }
  460. if (mNextp)
  461. {
  462. mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  463. }
  464. }
  465. break;
  466. case LSCP_EMIT_BYTE_CODE:
  467. {
  468. if (mIdentifier->mScopeEntry)
  469. {
  470. if(mIdentifier->mScopeEntry->mAssignable)
  471. {
  472. mIdentifier->mScopeEntry->mAssignable->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  473. }
  474. else
  475. {
  476. // Babbage: 29/8/06: If the scope entry has no mAssignable,
  477. // set the default type and add the default 0 value to the
  478. // chunk. Without this SAVectors and SAQuaternions will
  479. // assume the arbitrary current type is the assignable type
  480. // and may attempt to access a null chunk. (SL-20156)
  481. type = mIdentifier->mScopeEntry->mType;
  482. chunk->addBytes(LSCRIPTDataSize[type]);
  483. }
  484. }
  485. if (mNextp)
  486. {
  487. mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  488. }
  489. }
  490. break;
  491. case LSCP_LIST_BUILD_SIMPLE:
  492. {
  493. mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, ldata);
  494. if (mNextp)
  495. {
  496. mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, &(*ldata)->mListp);
  497. }
  498. }
  499. break;
  500. case LSCP_EMIT_CIL_ASSEMBLY:
  501. {
  502. fprintf(fp, "ldarg.0\n");
  503. fprintf(fp, "ldfld ");
  504. print_cil_member(fp, mIdentifier);
  505. fprintf(fp, "\n");
  506. if (mNextp)
  507. {
  508. mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  509. }
  510. break;
  511. }
  512. default:
  513. mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  514. if (mNextp)
  515. {
  516. mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  517. }
  518. break;
  519. }
  520. }
  521. S32 LLScriptSAIdentifier::getSize()
  522. {
  523. return mIdentifier->getSize();
  524. }
  525. void LLScriptSAConstant::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
  526. {
  527. if (gErrorToText.getErrors())
  528. {
  529. return;
  530. }
  531. switch(pass)
  532. {
  533. case LSCP_PRETTY_PRINT:
  534. case LSCP_EMIT_ASSEMBLY:
  535. mConstant->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  536. if (mNextp)
  537. {
  538. fprintf(fp, ", ");
  539. mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  540. }
  541. break;
  542. case LSCP_LIST_BUILD_SIMPLE:
  543. {
  544. mConstant->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, ldata);
  545. if (mNextp)
  546. {
  547. mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, &(*ldata)->mListp);
  548. }
  549. }
  550. break;
  551. default:
  552. mConstant->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  553. if (mNextp)
  554. {
  555. mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  556. }
  557. break;
  558. }
  559. }
  560. S32 LLScriptSAConstant::getSize()
  561. {
  562. return mConstant->getSize();
  563. }
  564. static void print_cil_cast(LLFILE* fp, LSCRIPTType srcType, LSCRIPTType targetType)
  565. {
  566. switch(srcType)
  567. {
  568. case LST_INTEGER:
  569. switch(targetType)
  570. {
  571. case LST_FLOATINGPOINT:
  572. fprintf(fp, "conv.r8\n");
  573. break;
  574. case LST_STRING:
  575. fprintf(fp, "call string class [mscorlib]System.Convert::ToString(int32)\n");
  576. break;
  577. case LST_LIST:
  578. print_cil_box(fp, LST_INTEGER);
  579. fprintf(fp, "call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::CreateList(object)\n");
  580. break;
  581. default:
  582. break;
  583. }
  584. break;
  585. case LST_FLOATINGPOINT:
  586. switch(targetType)
  587. {
  588. case LST_INTEGER:
  589. fprintf(fp, "call int32 [LslLibrary]LindenLab.SecondLife.LslRunTime::ToInteger(float32)\n");
  590. break;
  591. case LST_STRING:
  592. fprintf(fp, "call string [LslLibrary]LindenLab.SecondLife.LslRunTime::ToString(float32)\n");
  593. break;
  594. case LST_LIST:
  595. print_cil_box(fp, LST_FLOATINGPOINT);
  596. fprintf(fp, "call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::CreateList(object)\n");
  597. break;
  598. default:
  599. break;
  600. }
  601. break;
  602. case LST_STRING:
  603. switch(targetType)
  604. {
  605. case LST_INTEGER:
  606. fprintf(fp, "call int32 [LslLibrary]LindenLab.SecondLife.LslRunTime::StringToInt(string)\n");
  607. break;
  608. case LST_FLOATINGPOINT:
  609. fprintf(fp, "call float32 [LslLibrary]LindenLab.SecondLife.LslRunTime::StringToFloat(string)\n");
  610. break;
  611. case LST_KEY:
  612. fprintf(fp, "call valuetype [ScriptTypes]LindenLab.SecondLife.Key class [LslUserScript]LindenLab.SecondLife.LslUserScript::'CreateKey'(string)\n");
  613. break;
  614. case LST_LIST:
  615. fprintf(fp, "call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::CreateList(object)\n");
  616. break;
  617. case LST_VECTOR:
  618. fprintf(fp, "call class [ScriptTypes]LindenLab.SecondLife.Vector class [LslUserScript]LindenLab.SecondLife.LslUserScript::'ParseVector'(string)\n");
  619. break;
  620. case LST_QUATERNION:
  621. fprintf(fp, "call class [ScriptTypes]LindenLab.SecondLife.Quaternion class [LslUserScript]LindenLab.SecondLife.LslUserScript::'ParseQuaternion'(string)\n");
  622. break;
  623. default:
  624. break;
  625. }
  626. break;
  627. case LST_KEY:
  628. switch(targetType)
  629. {
  630. case LST_KEY:
  631. break;
  632. case LST_STRING:
  633. fprintf(fp, "call string [LslUserScript]LindenLab.SecondLife.LslUserScript::'ToString'(valuetype [ScriptTypes]LindenLab.SecondLife.Key)\n");
  634. break;
  635. case LST_LIST:
  636. print_cil_box(fp, LST_KEY);
  637. fprintf(fp, "call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::CreateList(object)\n");
  638. break;
  639. default:
  640. break;
  641. }
  642. break;
  643. case LST_VECTOR:
  644. switch(targetType)
  645. {
  646. case LST_VECTOR:
  647. break;
  648. case LST_STRING:
  649. fprintf(fp, "call string [LslUserScript]LindenLab.SecondLife.LslUserScript::'ToString'(valuetype [ScriptTypes]LindenLab.SecondLife.Vector)\n");
  650. break;
  651. case LST_LIST:
  652. print_cil_box(fp, LST_VECTOR);
  653. fprintf(fp, "call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::CreateList(object)\n");
  654. break;
  655. default:
  656. break;
  657. }
  658. break;
  659. case LST_QUATERNION:
  660. switch(targetType)
  661. {
  662. case LST_QUATERNION:
  663. break;
  664. case LST_STRING:
  665. fprintf(fp, "call string [LslUserScript]LindenLab.SecondLife.LslUserScript::'ToString'(valuetype [ScriptTypes]LindenLab.SecondLife.Quaternion)\n");
  666. break;
  667. case LST_LIST:
  668. print_cil_box(fp, LST_QUATERNION);
  669. fprintf(fp, "call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::CreateList(object)\n");
  670. break;
  671. default:
  672. break;
  673. }
  674. break;
  675. case LST_LIST:
  676. switch(targetType)
  677. {
  678. case LST_LIST:
  679. break;
  680. case LST_STRING:
  681. fprintf(fp, "call string [LslLibrary]LindenLab.SecondLife.LslRunTime::ListToString(class [mscorlib]System.Collections.ArrayList)\n");
  682. break;
  683. default:
  684. break;
  685. }
  686. break;
  687. default:
  688. break;
  689. }
  690. }
  691. static void print_cil_numeric_cast(LLFILE* fp, LSCRIPTType currentArg, LSCRIPTType otherArg)
  692. {
  693. if((currentArg == LST_INTEGER) && ((otherArg == LST_FLOATINGPOINT) || (otherArg == LST_VECTOR)))
  694. {
  695. print_cil_cast(fp, LST_INTEGER, LST_FLOATINGPOINT);
  696. }
  697. }
  698. static void print_cil_assignment_cast(LLFILE* fp, LSCRIPTType src,
  699. LSCRIPTType dest)
  700. {
  701. if (LST_STRING == src && LST_KEY == dest)
  702. {
  703. print_cil_cast(fp, src, dest);
  704. }
  705. else if(LST_KEY == src && LST_STRING == dest)
  706. {
  707. print_cil_cast(fp, src, dest);
  708. }
  709. else
  710. {
  711. print_cil_numeric_cast(fp, src, dest);
  712. }
  713. }
  714. // HACK! Babbage: should be converted to virtual on LSCRIPTSimpleAssignableType to avoid downcasts.
  715. LSCRIPTType get_type(LLScriptSimpleAssignable* sa)
  716. {
  717. LSCRIPTType result = LST_NULL;
  718. switch(sa->mType)
  719. {
  720. case LSSAT_IDENTIFIER:
  721. result = ((LLScriptSAIdentifier*) sa)->mIdentifier->mScopeEntry->mType;
  722. break;
  723. case LSSAT_CONSTANT:
  724. result = ((LLScriptSAConstant*) sa)->mConstant->mType;
  725. break;
  726. case LSSAT_VECTOR_CONSTANT:
  727. result = LST_VECTOR;
  728. break;
  729. case LSSAT_QUATERNION_CONSTANT:
  730. result = LST_QUATERNION;
  731. break;
  732. case LSSAT_LIST_CONSTANT:
  733. result = LST_LIST;
  734. break;
  735. default:
  736. result = LST_UNDEFINED;
  737. break;
  738. }
  739. return result;
  740. }
  741. void LLScriptSAVector::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
  742. {
  743. if (gErrorToText.getErrors())
  744. {
  745. return;
  746. }
  747. switch(pass)
  748. {
  749. case LSCP_PRETTY_PRINT:
  750. case LSCP_EMIT_ASSEMBLY:
  751. fprintf(fp, "< ");
  752. mEntry3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  753. fprintf(fp, ", ");
  754. mEntry2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  755. fprintf(fp, ", ");
  756. mEntry1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  757. fprintf(fp, " >");
  758. if (mNextp)
  759. {
  760. fprintf(fp, ", ");
  761. mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  762. }
  763. break;
  764. case LSCP_TYPE:
  765. // vector's take floats
  766. mEntry3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  767. if (!legal_assignment(LST_FLOATINGPOINT, type))
  768. {
  769. gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
  770. }
  771. mEntry2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  772. if (!legal_assignment(LST_FLOATINGPOINT, type))
  773. {
  774. gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
  775. }
  776. mEntry1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  777. if (!legal_assignment(LST_FLOATINGPOINT, type))
  778. {
  779. gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
  780. }
  781. type = LST_VECTOR;
  782. if (mNextp)
  783. {
  784. mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  785. }
  786. break;
  787. case LSCP_EMIT_BYTE_CODE:
  788. mEntry3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  789. if (type == LST_INTEGER)
  790. {
  791. S32 offset = chunk->mCurrentOffset - 4;
  792. bytestream_int2float(chunk->mCodeChunk, offset);
  793. }
  794. mEntry2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  795. if (type == LST_INTEGER)
  796. {
  797. S32 offset = chunk->mCurrentOffset - 4;
  798. bytestream_int2float(chunk->mCodeChunk, offset);
  799. }
  800. mEntry1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  801. if (type == LST_INTEGER)
  802. {
  803. S32 offset = chunk->mCurrentOffset - 4;
  804. bytestream_int2float(chunk->mCodeChunk, offset);
  805. }
  806. if (mNextp)
  807. {
  808. mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  809. }
  810. break;
  811. case LSCP_LIST_BUILD_SIMPLE:
  812. {
  813. LLScriptByteCodeChunk *list = new LLScriptByteCodeChunk(FALSE);
  814. mEntry3->recurse(fp, tabs, tabsize, LSCP_EMIT_BYTE_CODE, ptype, prunearg, scope, type, basetype, count, list, heap, stacksize, entry, entrycount, NULL);
  815. if (type == LST_INTEGER)
  816. {
  817. S32 offset = list->mCurrentOffset - 4;
  818. bytestream_int2float(list->mCodeChunk, offset);
  819. }
  820. mEntry2->recurse(fp, tabs, tabsize, LSCP_EMIT_BYTE_CODE, ptype, prunearg, scope, type, basetype, count, list, heap, stacksize, entry, entrycount, NULL);
  821. if (type == LST_INTEGER)
  822. {
  823. S32 offset = list->mCurrentOffset - 4;
  824. bytestream_int2float(list->mCodeChunk, offset);
  825. }
  826. mEntry1->recurse(fp, tabs, tabsize, LSCP_EMIT_BYTE_CODE, ptype, prunearg, scope, type, basetype, count, list, heap, stacksize, entry, entrycount, NULL);
  827. if (type == LST_INTEGER)
  828. {
  829. S32 offset = list->mCurrentOffset - 4;
  830. bytestream_int2float(list->mCodeChunk, offset);
  831. }
  832. LLVector3 vec;
  833. S32 offset = 0;
  834. bytestream2vector(vec, list->mCodeChunk, offset);
  835. *ldata = new LLScriptLibData(vec);
  836. delete list;
  837. if (mNextp)
  838. {
  839. mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, &(*ldata)->mListp);
  840. }
  841. }
  842. break;
  843. case LSCP_EMIT_CIL_ASSEMBLY:
  844. // Load arguments.
  845. mEntry1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  846. if(LST_INTEGER == get_type(mEntry1))
  847. {
  848. print_cil_cast(fp, LST_INTEGER, LST_FLOATINGPOINT);
  849. }
  850. mEntry2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  851. if(LST_INTEGER == get_type(mEntry2))
  852. {
  853. print_cil_cast(fp, LST_INTEGER, LST_FLOATINGPOINT);
  854. }
  855. mEntry3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  856. if(LST_INTEGER == get_type(mEntry3))
  857. {
  858. print_cil_cast(fp, LST_INTEGER, LST_FLOATINGPOINT);
  859. }
  860. // Call named ctor, which leaves new Vector on stack, so it can be saved in to local or argument just like a primitive type.
  861. fprintf(fp, "call class [ScriptTypes]LindenLab.SecondLife.Vector class [LslUserScript]LindenLab.SecondLife.LslUserScript::'CreateVector'(float32, float32, float32)\n");
  862. // Next.
  863. if (mNextp)
  864. {
  865. mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  866. }
  867. break;
  868. default:
  869. mEntry3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  870. mEntry2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  871. mEntry1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  872. if (mNextp)
  873. {
  874. mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  875. }
  876. break;
  877. }
  878. }
  879. S32 LLScriptSAVector::getSize()
  880. {
  881. return mEntry1->getSize() + mEntry2->getSize() + mEntry3->getSize();
  882. }
  883. void LLScriptSAQuaternion::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
  884. {
  885. if (gErrorToText.getErrors())
  886. {
  887. return;
  888. }
  889. switch(pass)
  890. {
  891. case LSCP_PRETTY_PRINT:
  892. case LSCP_EMIT_ASSEMBLY:
  893. fprintf(fp, "< ");
  894. mEntry4->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  895. fprintf(fp, ", ");
  896. mEntry3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  897. fprintf(fp, ", ");
  898. mEntry2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  899. fprintf(fp, ", ");
  900. mEntry1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  901. fprintf(fp, " >");
  902. if (mNextp)
  903. {
  904. fprintf(fp, ", ");
  905. mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  906. }
  907. break;
  908. case LSCP_TYPE:
  909. // vector's take floats
  910. mEntry4->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  911. if (!legal_assignment(LST_FLOATINGPOINT, type))
  912. {
  913. gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
  914. }
  915. mEntry3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  916. if (!legal_assignment(LST_FLOATINGPOINT, type))
  917. {
  918. gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
  919. }
  920. mEntry2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  921. if (!legal_assignment(LST_FLOATINGPOINT, type))
  922. {
  923. gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
  924. }
  925. mEntry1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  926. if (!legal_assignment(LST_FLOATINGPOINT, type))
  927. {
  928. gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
  929. }
  930. type = LST_QUATERNION;
  931. if (mNextp)
  932. {
  933. mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  934. }
  935. break;
  936. case LSCP_EMIT_BYTE_CODE:
  937. mEntry4->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  938. if (type == LST_INTEGER)
  939. {
  940. S32 offset = chunk->mCurrentOffset - 4;
  941. bytestream_int2float(chunk->mCodeChunk, offset);
  942. }
  943. mEntry3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  944. if (type == LST_INTEGER)
  945. {
  946. S32 offset = chunk->mCurrentOffset - 4;
  947. bytestream_int2float(chunk->mCodeChunk, offset);
  948. }
  949. mEntry2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  950. if (type == LST_INTEGER)
  951. {
  952. S32 offset = chunk->mCurrentOffset - 4;
  953. bytestream_int2float(chunk->mCodeChunk, offset);
  954. }
  955. mEntry1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  956. if (type == LST_INTEGER)
  957. {
  958. S32 offset = chunk->mCurrentOffset - 4;
  959. bytestream_int2float(chunk->mCodeChunk, offset);
  960. }
  961. if (mNextp)
  962. {
  963. mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  964. }
  965. break;
  966. case LSCP_LIST_BUILD_SIMPLE:
  967. {
  968. LLScriptByteCodeChunk *list = new LLScriptByteCodeChunk(FALSE);
  969. mEntry4->recurse(fp, tabs, tabsize, LSCP_EMIT_BYTE_CODE, ptype, prunearg, scope, type, basetype, count, list, heap, stacksize, entry, entrycount, NULL);
  970. if (type == LST_INTEGER)
  971. {
  972. S32 offset = list->mCurrentOffset - 4;
  973. bytestream_int2float(list->mCodeChunk, offset);
  974. }
  975. mEntry3->recurse(fp, tabs, tabsize, LSCP_EMIT_BYTE_CODE, ptype, prunearg, scope, type, basetype, count, list, heap, stacksize, entry, entrycount, NULL);
  976. if (type == LST_INTEGER)
  977. {
  978. S32 offset = list->mCurrentOffset - 4;
  979. bytestream_int2float(list->mCodeChunk, offset);
  980. }
  981. mEntry2->recurse(fp, tabs, tabsize, LSCP_EMIT_BYTE_CODE, ptype, prunearg, scope, type, basetype, count, list, heap, stacksize, entry, entrycount, NULL);
  982. if (type == LST_INTEGER)
  983. {
  984. S32 offset = list->mCurrentOffset - 4;
  985. bytestream_int2float(list->mCodeChunk, offset);
  986. }
  987. mEntry1->recurse(fp, tabs, tabsize, LSCP_EMIT_BYTE_CODE, ptype, prunearg, scope, type, basetype, count, list, heap, stacksize, entry, entrycount, NULL);
  988. if (type == LST_INTEGER)
  989. {
  990. S32 offset = list->mCurrentOffset - 4;
  991. bytestream_int2float(list->mCodeChunk, offset);
  992. }
  993. LLQuaternion quat;
  994. S32 offset = 0;
  995. bytestream2quaternion(quat, list->mCodeChunk, offset);
  996. *ldata = new LLScriptLibData(quat);
  997. delete list;
  998. if (mNextp)
  999. {
  1000. mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, &(*ldata)->mListp);
  1001. }
  1002. }
  1003. break;
  1004. case LSCP_EMIT_CIL_ASSEMBLY:
  1005. // Load arguments.
  1006. mEntry1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1007. if(LST_INTEGER == get_type(mEntry1))
  1008. {
  1009. print_cil_cast(fp, LST_INTEGER, LST_FLOATINGPOINT);
  1010. }
  1011. mEntry2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1012. if(LST_INTEGER == get_type(mEntry2))
  1013. {
  1014. print_cil_cast(fp, LST_INTEGER, LST_FLOATINGPOINT);
  1015. }
  1016. mEntry3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1017. if(LST_INTEGER == get_type(mEntry3))
  1018. {
  1019. print_cil_cast(fp, LST_INTEGER, LST_FLOATINGPOINT);
  1020. }
  1021. mEntry4->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1022. if(LST_INTEGER == get_type(mEntry4))
  1023. {
  1024. print_cil_cast(fp, LST_INTEGER, LST_FLOATINGPOINT);
  1025. }
  1026. // Call named ctor, which leaves new Vector on stack, so it can be saved in to local or argument just like a primitive type.
  1027. fprintf(fp, "call class [ScriptTypes]LindenLab.SecondLife.Quaternion class [LslUserScript]LindenLab.SecondLife.LslUserScript::'CreateQuaternion'(float32, float32, float32, float32)\n");
  1028. // Next.
  1029. if (mNextp)
  1030. {
  1031. mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1032. }
  1033. break;
  1034. default:
  1035. mEntry4->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1036. mEntry3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1037. mEntry2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1038. mEntry1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1039. if (mNextp)
  1040. {
  1041. mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1042. }
  1043. break;
  1044. }
  1045. }
  1046. S32 LLScriptSAQuaternion::getSize()
  1047. {
  1048. return mEntry1->getSize() + mEntry2->getSize() + mEntry3->getSize() + mEntry4->getSize();
  1049. }
  1050. void LLScriptSAList::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
  1051. {
  1052. if (gErrorToText.getErrors())
  1053. {
  1054. return;
  1055. }
  1056. switch(pass)
  1057. {
  1058. case LSCP_PRETTY_PRINT:
  1059. case LSCP_EMIT_ASSEMBLY:
  1060. fprintf(fp, "[ ");
  1061. if (mEntryList)
  1062. mEntryList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1063. fprintf(fp, " ]");
  1064. if (mNextp)
  1065. {
  1066. fprintf(fp, ", ");
  1067. mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1068. }
  1069. break;
  1070. case LSCP_TYPE:
  1071. if (mEntryList)
  1072. mEntryList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1073. type = LST_LIST;
  1074. if (mNextp)
  1075. {
  1076. mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1077. }
  1078. break;
  1079. case LSCP_EMIT_BYTE_CODE:
  1080. {
  1081. LLScriptLibData *list_data = new LLScriptLibData;
  1082. list_data->mType = LST_LIST;
  1083. if (mEntryList)
  1084. mEntryList->recurse(fp, tabs, tabsize, LSCP_LIST_BUILD_SIMPLE, ptype, prunearg, scope, type, basetype, count, chunk, NULL, stacksize, entry, entrycount, &(list_data->mListp));
  1085. U8 *temp;
  1086. chunk->addInteger(heap->mCurrentOffset + 1);
  1087. S32 size = lsa_create_data_block(&temp, list_data, heap->mCurrentOffset);
  1088. heap->addBytes(temp, size);
  1089. delete list_data;
  1090. delete [] temp;
  1091. if (mNextp)
  1092. {
  1093. mNextp->recurse(fp, tabs, tabsize, LSCP_EMIT_BYTE_CODE, ptype, prunearg, scope, type, basetype, count, chunk, NULL, stacksize, entry, entrycount, NULL);
  1094. }
  1095. }
  1096. break;
  1097. case LSCP_EMIT_CIL_ASSEMBLY:
  1098. {
  1099. // Create list.
  1100. fprintf(fp, "call class [mscorlib]System.Collections.ArrayList [LslUserScript]LindenLab.SecondLife.LslUserScript::CreateList()\n");
  1101. // Add elements.
  1102. LLScriptSimpleAssignable* current_entry = mEntryList;
  1103. LLScriptSimpleAssignable* next_entry = NULL;
  1104. while(NULL != current_entry)
  1105. {
  1106. next_entry = current_entry->mNextp;
  1107. // Null mNextp pointer, so only current list element is processed.
  1108. current_entry->mNextp = NULL;
  1109. current_entry->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1110. // Restore mNextp pointer.
  1111. current_entry->mNextp = next_entry;
  1112. // Box element and store in list.
  1113. print_cil_box(fp, get_type(current_entry));
  1114. fprintf(fp, "call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::Append(class [mscorlib]System.Collections.ArrayList, object)\n");
  1115. // Process next element.
  1116. current_entry = next_entry;
  1117. }
  1118. // Process next list.
  1119. if (mNextp)
  1120. {
  1121. mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1122. }
  1123. }
  1124. break;
  1125. default:
  1126. if (mEntryList)
  1127. mEntryList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, ldata);
  1128. if (mNextp)
  1129. {
  1130. mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, ldata);
  1131. }
  1132. break;
  1133. }
  1134. }
  1135. S32 LLScriptSAList::getSize()
  1136. {
  1137. return mEntryList->getSize();
  1138. }
  1139. void LLScriptGlobalVariable::addGlobal(LLScriptGlobalVariable *global)
  1140. {
  1141. if (mNextp)
  1142. {
  1143. global->mNextp = mNextp;
  1144. }
  1145. mNextp = global;
  1146. }
  1147. void LLScriptGlobalVariable::gonext(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
  1148. {
  1149. switch(pass)
  1150. {
  1151. case LSCP_PRETTY_PRINT:
  1152. if (mNextp)
  1153. {
  1154. mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1155. }
  1156. break;
  1157. default:
  1158. if (mNextp)
  1159. {
  1160. mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1161. }
  1162. break;
  1163. }
  1164. }
  1165. // Push initialised variable of type on to stack.
  1166. static void print_cil_init_variable(LLFILE* fp, LSCRIPTType type)
  1167. {
  1168. switch(type)
  1169. {
  1170. case LST_INTEGER:
  1171. fprintf(fp, "ldc.i4.0\n");
  1172. break;
  1173. case LST_FLOATINGPOINT:
  1174. fprintf(fp, "ldc.r8 0\n");
  1175. break;
  1176. case LST_STRING:
  1177. fprintf(fp, "ldstr \"\"\n");
  1178. break;
  1179. case LST_KEY:
  1180. fprintf(fp, "ldstr \"\"\n");
  1181. fprintf(fp, "call valuetype [ScriptTypes]LindenLab.SecondLife.Key class [LslUserScript]LindenLab.SecondLife.LslUserScript::'CreateKey'(string)\n");
  1182. break;
  1183. case LST_VECTOR:
  1184. fprintf(fp, "ldc.r8 0\n");
  1185. fprintf(fp, "ldc.r8 0\n");
  1186. fprintf(fp, "ldc.r8 0\n");
  1187. fprintf(fp, "call class [ScriptTypes]LindenLab.SecondLife.Vector class [LslUserScript]LindenLab.SecondLife.LslUserScript::'CreateVector'(float32, float32, float32)\n");
  1188. break;
  1189. case LST_QUATERNION:
  1190. fprintf(fp, "ldc.r8 0\n");
  1191. fprintf(fp, "ldc.r8 0\n");
  1192. fprintf(fp, "ldc.r8 0\n");
  1193. fprintf(fp, "ldc.r8 1\n");
  1194. fprintf(fp, "call class [ScriptTypes]LindenLab.SecondLife.Quaternion class [LslUserScript]LindenLab.SecondLife.LslUserScript::'CreateQuaternion'(float32, float32, float32, float32)\n");
  1195. break;
  1196. case LST_LIST:
  1197. fprintf(fp, "call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::CreateList()\n");
  1198. break;
  1199. default:
  1200. break;
  1201. }
  1202. }
  1203. void LLScriptGlobalVariable::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
  1204. {
  1205. if (gErrorToText.getErrors())
  1206. {
  1207. return;
  1208. }
  1209. switch(pass)
  1210. {
  1211. case LSCP_PRETTY_PRINT:
  1212. mType->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1213. fprintf(fp,"\t");
  1214. mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1215. if (mAssignable)
  1216. {
  1217. fprintf(fp, " = ");
  1218. mAssignable->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1219. }
  1220. fprintf(fp, ";\n");
  1221. break;
  1222. case LSCP_EMIT_ASSEMBLY:
  1223. mType->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1224. fprintf(fp,"\t");
  1225. mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1226. if (mAssignable)
  1227. {
  1228. fprintf(fp, " = ");
  1229. mAssignable->recurse(fp, tabs, tabsize, LSCP_PRETTY_PRINT, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1230. fprintf(fp, "\n");
  1231. fprintf(fp, "Offset: %d Type: %d\n", mIdentifier->mScopeEntry->mOffset, (S32)LSCRIPTTypeByte[mType->mType]);
  1232. }
  1233. else
  1234. {
  1235. fprintf(fp, "\n");
  1236. fprintf(fp, "Offset: %d Type: %d\n", mIdentifier->mScopeEntry->mOffset, (S32)LSCRIPTTypeByte[mType->mType]);
  1237. }
  1238. break;
  1239. case LSCP_SCOPE_PASS1:
  1240. if (scope->checkEntry(mIdentifier->mName))
  1241. {
  1242. gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
  1243. }
  1244. else
  1245. {
  1246. if (mAssignable)
  1247. {
  1248. mAssignable->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1249. }
  1250. // this needs to go after expression decent to make sure that we don't add ourselves or something silly
  1251. mIdentifier->mScopeEntry = scope->addEntry(mIdentifier->mName, LIT_GLOBAL, mType->mType);
  1252. if (mIdentifier->mScopeEntry && mAssignable)
  1253. mIdentifier->mScopeEntry->mAssignable = mAssignable;
  1254. }
  1255. break;
  1256. case LSCP_TYPE:
  1257. // if the variable has an assignable, it must assignable to the variable's type
  1258. if (mAssignable)
  1259. {
  1260. mAssignable->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1261. mAssignableType = type;
  1262. if (!legal_assignment(mType->mType, mAssignableType))
  1263. {
  1264. gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
  1265. }
  1266. }
  1267. break;
  1268. case LSCP_RESOURCE:
  1269. {
  1270. // we're just tryng to determine how much space the variable needs
  1271. // it also includes the name of the variable as well as the type
  1272. // plus 4 bytes of offset from it's apparent address to the actual data
  1273. #ifdef LSL_INCLUDE_DEBUG_INFO
  1274. count += strlen(mIdentifier->mName) + 1 + 1 + 4;
  1275. #else
  1276. count += 1 + 1 + 4;
  1277. #endif
  1278. mIdentifier->mScopeEntry->mOffset = (S32)count;
  1279. mIdentifier->mScopeEntry->mSize = mType->getSize();
  1280. count += mIdentifier->mScopeEntry->mSize;
  1281. mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1282. }
  1283. break;
  1284. case LSCP_EMIT_BYTE_CODE:
  1285. {
  1286. // order for global variables
  1287. // 0 - 4: offset to actual data
  1288. S32 offsetoffset = chunk->mCurrentOffset;
  1289. S32 offsetdelta = 0;
  1290. chunk->addBytes(4);
  1291. // type
  1292. char vtype;
  1293. vtype = LSCRIPTTypeByte[mType->mType];
  1294. chunk->addBytes(&vtype, 1);
  1295. // null terminated name
  1296. #ifdef LSL_INCLUDE_DEBUG_INFO
  1297. chunk->addBytes(mIdentifier->mName, strlen(mIdentifier->mName) + 1);
  1298. #else
  1299. chunk->addBytes(1);
  1300. #endif
  1301. // put correct offset delta in
  1302. offsetdelta = chunk->mCurrentOffset - offsetoffset;
  1303. integer2bytestream(chunk->mCodeChunk, offsetoffset, offsetdelta);
  1304. // now we need space for the variable itself
  1305. LLScriptByteCodeChunk *value = new LLScriptByteCodeChunk(FALSE);
  1306. if (mAssignable)
  1307. {
  1308. mAssignable->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, value, heap, stacksize, entry, entrycount, NULL);
  1309. // need to put sneaky type conversion here
  1310. if (mAssignableType != mType->mType)
  1311. {
  1312. // the only legal case that is a problem is int->float
  1313. if (mType->mType == LST_FLOATINGPOINT && mAssignableType == LST_INTEGER)
  1314. {
  1315. S32 offset = value->mCurrentOffset - 4;
  1316. bytestream_int2float(value->mCodeChunk, offset);
  1317. }
  1318. }
  1319. }
  1320. else
  1321. {
  1322. if ( (mType->mType == LST_STRING)
  1323. ||(mType->mType == LST_KEY))
  1324. {
  1325. // string and keys (even empty ones) need heap entries
  1326. chunk->addInteger(heap->mCurrentOffset + 1);
  1327. LLScriptLibData *data = new LLScriptLibData("");
  1328. U8 *temp;
  1329. S32 size = lsa_create_data_block(&temp, data, heap->mCurrentOffset);
  1330. heap->addBytes(temp, size);
  1331. delete [] temp;
  1332. delete data;
  1333. }
  1334. else if (mType->mType == LST_LIST)
  1335. {
  1336. chunk->addInteger(heap->mCurrentOffset + 1);
  1337. LLScriptLibData *data = new LLScriptLibData;
  1338. data->mType = LST_LIST;
  1339. U8 *temp;
  1340. S32 size = lsa_create_data_block(&temp, data, heap->mCurrentOffset);
  1341. heap->addBytes(temp, size);
  1342. delete [] temp;
  1343. delete data;
  1344. }
  1345. else if (mType->mType == LST_QUATERNION)
  1346. {
  1347. chunk->addFloat(1.f);
  1348. chunk->addFloat(0.f);
  1349. chunk->addFloat(0.f);
  1350. chunk->addFloat(0.f);
  1351. }
  1352. else
  1353. {
  1354. value->addBytes(LSCRIPTDataSize[mType->mType]);
  1355. }
  1356. }
  1357. chunk->addBytes(value->mCodeChunk, value->mCurrentOffset);
  1358. delete value;
  1359. }
  1360. break;
  1361. case LSCP_EMIT_CIL_ASSEMBLY:
  1362. // Initialisation inside ctor.
  1363. fprintf(fp, "ldarg.0\n");
  1364. if (mAssignable)
  1365. {
  1366. // Initialise to value.
  1367. mAssignable->recurse(fp, tabs, tabsize, LSCP_EMIT_CIL_ASSEMBLY,
  1368. ptype, prunearg, scope, type, basetype,
  1369. count, chunk, heap, stacksize, entry,
  1370. entrycount, NULL);
  1371. print_cil_assignment_cast(fp, get_type(mAssignable), mType->mType);
  1372. }
  1373. else
  1374. {
  1375. // Initialise to zero.
  1376. print_cil_init_variable(fp, mType->mType);
  1377. }
  1378. // Store value.
  1379. fprintf(fp, "stfld ");
  1380. mType->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1381. fprintf(fp," %s::", gScriptp->getClassName());
  1382. mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1383. fprintf(fp, "\n");
  1384. break;
  1385. default:
  1386. mType->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1387. mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1388. if (mAssignable)
  1389. {
  1390. mAssignable->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1391. }
  1392. break;
  1393. }
  1394. gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1395. }
  1396. S32 LLScriptGlobalVariable::getSize()
  1397. {
  1398. S32 return_size;
  1399. return_size = mType->getSize();
  1400. return return_size;
  1401. }
  1402. void LLScriptEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
  1403. {
  1404. fprintf(fp, "Event Base Class -- should never get here!\n");
  1405. }
  1406. S32 LLScriptEvent::getSize()
  1407. {
  1408. printf("Event Base Class -- should never get here!\n");
  1409. return 0;
  1410. }
  1411. static void checkForDuplicateHandler(LLFILE *fp, LLScriptFilePosition *pos,
  1412. LLScriptScope *scope,
  1413. const char* name)
  1414. {
  1415. LLScriptScope *parent = scope->mParentScope;
  1416. if (parent->checkEntry((char*)name))
  1417. {
  1418. gErrorToText.writeError(fp, pos, LSERROR_DUPLICATE_NAME);
  1419. }
  1420. else
  1421. {
  1422. parent->addEntry(((char*)name), LIT_HANDLER, LST_NULL);
  1423. }
  1424. }
  1425. void LLScriptStateEntryEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
  1426. {
  1427. if (gErrorToText.getErrors())
  1428. {
  1429. return;
  1430. }
  1431. switch(pass)
  1432. {
  1433. case LSCP_PRETTY_PRINT:
  1434. fdotabs(fp, tabs, tabsize);
  1435. fprintf(fp, "state_entry()\n");
  1436. break;
  1437. case LSCP_EMIT_ASSEMBLY:
  1438. fprintf(fp, "state_entry()\n");
  1439. break;
  1440. case LSCP_SCOPE_PASS1:
  1441. checkForDuplicateHandler(fp, this, scope, "state_entry");
  1442. break;
  1443. case LSCP_EMIT_BYTE_CODE:
  1444. {
  1445. #ifdef LSL_INCLUDE_DEBUG_INFO
  1446. char name[] = "state_entry";
  1447. chunk->addBytes(name, strlen(name) + 1);
  1448. #endif
  1449. }
  1450. break;
  1451. case LSCP_EMIT_CIL_ASSEMBLY:
  1452. fprintf(fp, "state_entry()");
  1453. break;
  1454. default:
  1455. break;
  1456. }
  1457. }
  1458. S32 LLScriptStateEntryEvent::getSize()
  1459. {
  1460. return 0;
  1461. }
  1462. void LLScriptStateExitEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
  1463. {
  1464. if (gErrorToText.getErrors())
  1465. {
  1466. return;
  1467. }
  1468. switch(pass)
  1469. {
  1470. case LSCP_PRETTY_PRINT:
  1471. fdotabs(fp, tabs, tabsize);
  1472. fprintf(fp, "state_exit()\n");
  1473. break;
  1474. case LSCP_SCOPE_PASS1:
  1475. checkForDuplicateHandler(fp, this, scope, "state_exit");
  1476. break;
  1477. case LSCP_EMIT_ASSEMBLY:
  1478. fprintf(fp, "state_exit()\n");
  1479. break;
  1480. case LSCP_EMIT_BYTE_CODE:
  1481. {
  1482. #ifdef LSL_INCLUDE_DEBUG_INFO
  1483. char name[] = "state_exit";
  1484. chunk->addBytes(name, strlen(name) + 1);
  1485. #endif
  1486. }
  1487. break;
  1488. case LSCP_EMIT_CIL_ASSEMBLY:
  1489. fprintf(fp, "state_exit()");
  1490. break;
  1491. default:
  1492. break;
  1493. }
  1494. }
  1495. S32 LLScriptStateExitEvent::getSize()
  1496. {
  1497. return 0;
  1498. }
  1499. void LLScriptTouchStartEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
  1500. {
  1501. if (gErrorToText.getErrors())
  1502. {
  1503. return;
  1504. }
  1505. switch(pass)
  1506. {
  1507. case LSCP_PRETTY_PRINT:
  1508. case LSCP_EMIT_ASSEMBLY:
  1509. fdotabs(fp, tabs, tabsize);
  1510. fprintf(fp, "touch_start( integer ");
  1511. mCount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1512. fprintf(fp, " )\n");
  1513. break;
  1514. break;
  1515. case LSCP_SCOPE_PASS1:
  1516. checkForDuplicateHandler(fp, this, scope, "touch_start");
  1517. if (scope->checkEntry(mCount->mName))
  1518. {
  1519. gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
  1520. }
  1521. else
  1522. {
  1523. mCount->mScopeEntry = scope->addEntry(mCount->mName, LIT_VARIABLE, LST_INTEGER);
  1524. }
  1525. break;
  1526. case LSCP_RESOURCE:
  1527. {
  1528. // we're just tryng to determine how much space the variable needs
  1529. if (mCount->mScopeEntry)
  1530. {
  1531. mCount->mScopeEntry->mOffset = (S32)count;
  1532. mCount->mScopeEntry->mSize = 4;
  1533. count += mCount->mScopeEntry->mSize;
  1534. }
  1535. }
  1536. break;
  1537. case LSCP_EMIT_BYTE_CODE:
  1538. {
  1539. #ifdef LSL_INCLUDE_DEBUG_INFO
  1540. char name[] = "touch_start";
  1541. chunk->addBytes(name, strlen(name) + 1);
  1542. chunk->addBytes(mCount->mName, strlen(mCount->mName) + 1);
  1543. #endif
  1544. }
  1545. break;
  1546. case LSCP_EMIT_CIL_ASSEMBLY:
  1547. fdotabs(fp, tabs, tabsize);
  1548. fprintf(fp, "touch_start( int32 ");
  1549. mCount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1550. fprintf(fp, " )");
  1551. break;
  1552. break;
  1553. default:
  1554. mCount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1555. break;
  1556. }
  1557. }
  1558. S32 LLScriptTouchStartEvent::getSize()
  1559. {
  1560. // integer = 4
  1561. return 4;
  1562. }
  1563. void LLScriptTouchEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
  1564. {
  1565. if (gErrorToText.getErrors())
  1566. {
  1567. return;
  1568. }
  1569. switch(pass)
  1570. {
  1571. case LSCP_PRETTY_PRINT:
  1572. case LSCP_EMIT_ASSEMBLY:
  1573. fdotabs(fp, tabs, tabsize);
  1574. fprintf(fp, "touch( integer ");
  1575. mCount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1576. fprintf(fp, " )\n");
  1577. break;
  1578. break;
  1579. case LSCP_SCOPE_PASS1:
  1580. checkForDuplicateHandler(fp, this, scope, "touch");
  1581. if (scope->checkEntry(mCount->mName))
  1582. {
  1583. gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
  1584. }
  1585. else
  1586. {
  1587. mCount->mScopeEntry = scope->addEntry(mCount->mName, LIT_VARIABLE, LST_INTEGER);
  1588. }
  1589. break;
  1590. case LSCP_RESOURCE:
  1591. {
  1592. // we're just tryng to determine how much space the variable needs
  1593. if (mCount->mScopeEntry)
  1594. {
  1595. mCount->mScopeEntry->mOffset = (S32)count;
  1596. mCount->mScopeEntry->mSize = 4;
  1597. count += mCount->mScopeEntry->mSize;
  1598. }
  1599. }
  1600. break;
  1601. case LSCP_EMIT_BYTE_CODE:
  1602. {
  1603. #ifdef LSL_INCLUDE_DEBUG_INFO
  1604. char name[] = "touch";
  1605. chunk->addBytes(name, strlen(name) + 1);
  1606. chunk->addBytes(mCount->mName, strlen(mCount->mName) + 1);
  1607. #endif
  1608. }
  1609. break;
  1610. case LSCP_EMIT_CIL_ASSEMBLY:
  1611. fdotabs(fp, tabs, tabsize);
  1612. fprintf(fp, "touch( int32 ");
  1613. mCount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1614. fprintf(fp, " )");
  1615. break;
  1616. break;
  1617. default:
  1618. mCount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1619. break;
  1620. }
  1621. }
  1622. S32 LLScriptTouchEvent::getSize()
  1623. {
  1624. // integer = 4
  1625. return 4;
  1626. }
  1627. void LLScriptTouchEndEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
  1628. {
  1629. if (gErrorToText.getErrors())
  1630. {
  1631. return;
  1632. }
  1633. switch(pass)
  1634. {
  1635. case LSCP_PRETTY_PRINT:
  1636. case LSCP_EMIT_ASSEMBLY:
  1637. fdotabs(fp, tabs, tabsize);
  1638. fprintf(fp, "touch_end( integer ");
  1639. mCount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1640. fprintf(fp, " )\n");
  1641. break;
  1642. break;
  1643. case LSCP_SCOPE_PASS1:
  1644. checkForDuplicateHandler(fp, this, scope, "touch_end");
  1645. if (scope->checkEntry(mCount->mName))
  1646. {
  1647. gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
  1648. }
  1649. else
  1650. {
  1651. mCount->mScopeEntry = scope->addEntry(mCount->mName, LIT_VARIABLE, LST_INTEGER);
  1652. }
  1653. break;
  1654. case LSCP_RESOURCE:
  1655. {
  1656. // we're just tryng to determine how much space the variable needs
  1657. if (mCount->mScopeEntry)
  1658. {
  1659. mCount->mScopeEntry->mOffset = (S32)count;
  1660. mCount->mScopeEntry->mSize = 4;
  1661. count += mCount->mScopeEntry->mSize;
  1662. }
  1663. }
  1664. break;
  1665. case LSCP_EMIT_BYTE_CODE:
  1666. {
  1667. #ifdef LSL_INCLUDE_DEBUG_INFO
  1668. char name[] = "touch_end";
  1669. chunk->addBytes(name, strlen(name) + 1);
  1670. chunk->addBytes(mCount->mName, strlen(mCount->mName) + 1);
  1671. #endif
  1672. }
  1673. break;
  1674. case LSCP_EMIT_CIL_ASSEMBLY:
  1675. fdotabs(fp, tabs, tabsize);
  1676. fprintf(fp, "touch_end( int32 ");
  1677. mCount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1678. fprintf(fp, " )");
  1679. break;
  1680. break;
  1681. default:
  1682. mCount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1683. break;
  1684. }
  1685. }
  1686. S32 LLScriptTouchEndEvent::getSize()
  1687. {
  1688. // integer = 4
  1689. return 4;
  1690. }
  1691. void LLScriptCollisionStartEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
  1692. {
  1693. if (gErrorToText.getErrors())
  1694. {
  1695. return;
  1696. }
  1697. switch(pass)
  1698. {
  1699. case LSCP_PRETTY_PRINT:
  1700. case LSCP_EMIT_ASSEMBLY:
  1701. fdotabs(fp, tabs, tabsize);
  1702. fprintf(fp, "collision_start( integer ");
  1703. mCount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1704. fprintf(fp, " )\n");
  1705. break;
  1706. break;
  1707. case LSCP_SCOPE_PASS1:
  1708. checkForDuplicateHandler(fp, this, scope, "collision_start");
  1709. if (scope->checkEntry(mCount->mName))
  1710. {
  1711. gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
  1712. }
  1713. else
  1714. {
  1715. mCount->mScopeEntry = scope->addEntry(mCount->mName, LIT_VARIABLE, LST_INTEGER);
  1716. }
  1717. break;
  1718. case LSCP_RESOURCE:
  1719. {
  1720. // we're just tryng to determine how much space the variable needs
  1721. if (mCount->mScopeEntry)
  1722. {
  1723. mCount->mScopeEntry->mOffset = (S32)count;
  1724. mCount->mScopeEntry->mSize = 4;
  1725. count += mCount->mScopeEntry->mSize;
  1726. }
  1727. }
  1728. break;
  1729. case LSCP_EMIT_BYTE_CODE:
  1730. {
  1731. #ifdef LSL_INCLUDE_DEBUG_INFO
  1732. char name[] = "collision_start";
  1733. chunk->addBytes(name, (S32)strlen(name) + 1);
  1734. chunk->addBytes(mCount->mName, (S32)strlen(mCount->mName) + 1);
  1735. #endif
  1736. }
  1737. break;
  1738. case LSCP_EMIT_CIL_ASSEMBLY:
  1739. fdotabs(fp, tabs, tabsize);
  1740. fprintf(fp, "collision_start( int32 ");
  1741. mCount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1742. fprintf(fp, " )");
  1743. break;
  1744. default:
  1745. mCount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1746. break;
  1747. }
  1748. }
  1749. S32 LLScriptCollisionStartEvent::getSize()
  1750. {
  1751. // integer = 4
  1752. return 4;
  1753. }
  1754. void LLScriptCollisionEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
  1755. {
  1756. if (gErrorToText.getErrors())
  1757. {
  1758. return;
  1759. }
  1760. switch(pass)
  1761. {
  1762. case LSCP_PRETTY_PRINT:
  1763. case LSCP_EMIT_ASSEMBLY:
  1764. fdotabs(fp, tabs, tabsize);
  1765. fprintf(fp, "collision( integer ");
  1766. mCount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1767. fprintf(fp, " )\n");
  1768. break;
  1769. break;
  1770. case LSCP_SCOPE_PASS1:
  1771. checkForDuplicateHandler(fp, this, scope, "collision");
  1772. if (scope->checkEntry(mCount->mName))
  1773. {
  1774. gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
  1775. }
  1776. else
  1777. {
  1778. mCount->mScopeEntry = scope->addEntry(mCount->mName, LIT_VARIABLE, LST_INTEGER);
  1779. }
  1780. break;
  1781. case LSCP_RESOURCE:
  1782. {
  1783. // we're just tryng to determine how much space the variable needs
  1784. if (mCount->mScopeEntry)
  1785. {
  1786. mCount->mScopeEntry->mOffset = (S32)count;
  1787. mCount->mScopeEntry->mSize = 4;
  1788. count += mCount->mScopeEntry->mSize;
  1789. }
  1790. }
  1791. break;
  1792. case LSCP_EMIT_BYTE_CODE:
  1793. {
  1794. #ifdef LSL_INCLUDE_DEBUG_INFO
  1795. char name[] = "collision";
  1796. chunk->addBytes(name, strlen(name) + 1);
  1797. chunk->addBytes(mCount->mName, strlen(mCount->mName) + 1);
  1798. #endif
  1799. }
  1800. break;
  1801. case LSCP_EMIT_CIL_ASSEMBLY:
  1802. fprintf(fp, "collision( int32 ");
  1803. mCount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1804. fprintf(fp, " )");
  1805. break;
  1806. default:
  1807. mCount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1808. break;
  1809. }
  1810. }
  1811. S32 LLScriptCollisionEvent::getSize()
  1812. {
  1813. // integer = 4
  1814. return 4;
  1815. }
  1816. void LLScriptCollisionEndEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
  1817. {
  1818. if (gErrorToText.getErrors())
  1819. {
  1820. return;
  1821. }
  1822. switch(pass)
  1823. {
  1824. case LSCP_PRETTY_PRINT:
  1825. case LSCP_EMIT_ASSEMBLY:
  1826. fdotabs(fp, tabs, tabsize);
  1827. fprintf(fp, "collision_end( integer ");
  1828. mCount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1829. fprintf(fp, " )\n");
  1830. break;
  1831. break;
  1832. case LSCP_SCOPE_PASS1:
  1833. checkForDuplicateHandler(fp, this, scope, "collision_end");
  1834. if (scope->checkEntry(mCount->mName))
  1835. {
  1836. gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
  1837. }
  1838. else
  1839. {
  1840. mCount->mScopeEntry = scope->addEntry(mCount->mName, LIT_VARIABLE, LST_INTEGER);
  1841. }
  1842. break;
  1843. case LSCP_RESOURCE:
  1844. {
  1845. // we're just tryng to determine how much space the variable needs
  1846. if (mCount->mScopeEntry)
  1847. {
  1848. mCount->mScopeEntry->mOffset = (S32)count;
  1849. mCount->mScopeEntry->mSize = 4;
  1850. count += mCount->mScopeEntry->mSize;
  1851. }
  1852. }
  1853. break;
  1854. case LSCP_EMIT_BYTE_CODE:
  1855. {
  1856. #ifdef LSL_INCLUDE_DEBUG_INFO
  1857. char name[] = "collision_end";
  1858. chunk->addBytes(name, strlen(name) + 1);
  1859. chunk->addBytes(mCount->mName, strlen(mCount->mName) + 1);
  1860. #endif
  1861. }
  1862. break;
  1863. case LSCP_EMIT_CIL_ASSEMBLY:
  1864. fdotabs(fp, tabs, tabsize);
  1865. fprintf(fp, "collision_end( int32 ");
  1866. mCount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1867. fprintf(fp, " )");
  1868. break;
  1869. default:
  1870. mCount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1871. break;
  1872. }
  1873. }
  1874. S32 LLScriptCollisionEndEvent::getSize()
  1875. {
  1876. // integer = 4
  1877. return 4;
  1878. }
  1879. void LLScriptLandCollisionStartEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
  1880. {
  1881. if (gErrorToText.getErrors())
  1882. {
  1883. return;
  1884. }
  1885. switch(pass)
  1886. {
  1887. case LSCP_PRETTY_PRINT:
  1888. case LSCP_EMIT_ASSEMBLY:
  1889. fdotabs(fp, tabs, tabsize);
  1890. fprintf(fp, "land_collision_start( vector ");
  1891. mPosition->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1892. fprintf(fp, " )\n");
  1893. break;
  1894. case LSCP_SCOPE_PASS1:
  1895. checkForDuplicateHandler(fp, this, scope, "land_collision_start");
  1896. if (scope->checkEntry(mPosition->mName))
  1897. {
  1898. gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
  1899. }
  1900. else
  1901. {
  1902. mPosition->mScopeEntry = scope->addEntry(mPosition->mName, LIT_VARIABLE, LST_VECTOR);
  1903. }
  1904. break;
  1905. case LSCP_RESOURCE:
  1906. {
  1907. // we're just tryng to determine how much space the variable needs
  1908. if (mPosition->mScopeEntry)
  1909. {
  1910. mPosition->m