PageRenderTime 20ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/indra/lscript/lscript_compile/lscript_scope.h

https://bitbucket.org/lindenlab/viewer-beta/
C++ Header | 406 lines | 338 code | 38 blank | 30 comment | 25 complexity | d9c2087d09a798f6b9a356647c1cd706 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file lscript_scope.h
  3. * @brief builds nametable and checks scope
  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. #ifndef LL_LSCRIPT_SCOPE_H
  27. #define LL_LSCRIPT_SCOPE_H
  28. #include "string_table.h"
  29. #include "llmap.h"
  30. #include "lscript_byteformat.h"
  31. typedef enum e_lscript_identifier_type
  32. {
  33. LIT_INVALID,
  34. LIT_GLOBAL,
  35. LIT_VARIABLE,
  36. LIT_FUNCTION,
  37. LIT_LABEL,
  38. LIT_STATE,
  39. LIT_HANDLER,
  40. LIT_LIBRARY_FUNCTION,
  41. LIT_EOF
  42. } LSCRIPTIdentifierType;
  43. const char LSCRIPTFunctionTypeStrings[LST_EOF] = /*Flawfinder: ignore*/
  44. {
  45. '0',
  46. 'i',
  47. 'f',
  48. 's',
  49. 'k',
  50. 'v',
  51. 'q',
  52. 'l',
  53. '0'
  54. };
  55. const char * const LSCRIPTListDescription[LST_EOF] = /*Flawfinder: ignore*/
  56. {
  57. "PUSHARGB 0",
  58. "PUSHARGB 1",
  59. "PUSHARGB 2",
  60. "PUSHARGB 3",
  61. "PUSHARGB 4",
  62. "PUSHARGB 5",
  63. "PUSHARGB 6",
  64. "PUSHARGB 7",
  65. "PUSHARGB 0"
  66. };
  67. const char * const LSCRIPTTypePush[LST_EOF] = /*Flawfinder: ignore*/
  68. {
  69. "INVALID",
  70. "PUSHE",
  71. "PUSHE",
  72. "PUSHE",
  73. "PUSHE",
  74. "PUSHEV",
  75. "PUSHEQ",
  76. "PUSHE",
  77. "undefined"
  78. };
  79. const char * const LSCRIPTTypeReturn[LST_EOF] = /*Flawfinder: ignore*/
  80. {
  81. "INVALID",
  82. "LOADP -12",
  83. "LOADP -12",
  84. "STORES -12\nPOP",
  85. "STORES -12\nPOP",
  86. "LOADVP -20",
  87. "LOADQP -24",
  88. "LOADLP -12",
  89. "undefined"
  90. };
  91. const char * const LSCRIPTTypePop[LST_EOF] = /*Flawfinder: ignore*/
  92. {
  93. "INVALID",
  94. "POP",
  95. "POP",
  96. "POPS",
  97. "POPS",
  98. "POPV",
  99. "POPQ",
  100. "POPL",
  101. "undefined"
  102. };
  103. const char * const LSCRIPTTypeDuplicate[LST_EOF] = /*Flawfinder: ignore*/
  104. {
  105. "INVALID",
  106. "DUP",
  107. "DUP",
  108. "DUPS",
  109. "DUPS",
  110. "DUPV",
  111. "DUPQ",
  112. "DUPL",
  113. "undefined"
  114. };
  115. const char * const LSCRIPTTypeLocalStore[LST_EOF] = /*Flawfinder: ignore*/
  116. {
  117. "INVALID",
  118. "STORE ",
  119. "STORE ",
  120. "STORES ",
  121. "STORES ",
  122. "STOREV ",
  123. "STOREQ ",
  124. "STOREL ",
  125. "undefined"
  126. };
  127. const char * const LSCRIPTTypeLocalDeclaration[LST_EOF] = /*Flawfinder: ignore*/
  128. {
  129. "INVALID",
  130. "STOREP ",
  131. "STOREP ",
  132. "STORESP ",
  133. "STORESP ",
  134. "STOREVP ",
  135. "STOREQP ",
  136. "STORELP ",
  137. "undefined"
  138. };
  139. const char * const LSCRIPTTypeGlobalStore[LST_EOF] = /*Flawfinder: ignore*/
  140. {
  141. "INVALID",
  142. "STOREG ",
  143. "STOREG ",
  144. "STORESG ",
  145. "STORESG ",
  146. "STOREGV ",
  147. "STOREGQ ",
  148. "STORELG ",
  149. "undefined"
  150. };
  151. const char * const LSCRIPTTypeLocalPush[LST_EOF] = /*Flawfinder: ignore*/
  152. {
  153. "INVALID",
  154. "PUSH ",
  155. "PUSH ",
  156. "PUSHS ",
  157. "PUSHS ",
  158. "PUSHV ",
  159. "PUSHQ ",
  160. "PUSHL ",
  161. "undefined"
  162. };
  163. const char * const LSCRIPTTypeLocalPush1[LST_EOF] = /*Flawfinder: ignore*/
  164. {
  165. "INVALID",
  166. "PUSHARGI 1",
  167. "PUSHARGF 1",
  168. "undefined",
  169. "undefined",
  170. "undefined",
  171. "undefined",
  172. "undefined",
  173. "undefined"
  174. };
  175. const char * const LSCRIPTTypeGlobalPush[LST_EOF] = /*Flawfinder: ignore*/
  176. {
  177. "INVALID",
  178. "PUSHG ",
  179. "PUSHG ",
  180. "PUSHGS ",
  181. "PUSHGS ",
  182. "PUSHGV ",
  183. "PUSHGQ ",
  184. "PUSHGL ",
  185. "undefined"
  186. };
  187. class LLScriptSimpleAssignable;
  188. class LLScriptArgString
  189. {
  190. public:
  191. LLScriptArgString() : mString(NULL) {}
  192. ~LLScriptArgString() { delete [] mString; }
  193. LSCRIPTType getType(S32 count)
  194. {
  195. if (!mString)
  196. return LST_NULL;
  197. S32 length = (S32)strlen(mString); /*Flawfinder: ignore*/
  198. if (count >= length)
  199. {
  200. return LST_NULL;
  201. }
  202. switch(mString[count])
  203. {
  204. case 'i':
  205. return LST_INTEGER;
  206. case 'f':
  207. return LST_FLOATINGPOINT;
  208. case 's':
  209. return LST_STRING;
  210. case 'k':
  211. return LST_KEY;
  212. case 'v':
  213. return LST_VECTOR;
  214. case 'q':
  215. return LST_QUATERNION;
  216. case 'l':
  217. return LST_LIST;
  218. default:
  219. return LST_NULL;
  220. }
  221. }
  222. void addType(LSCRIPTType type)
  223. {
  224. S32 count = 0;
  225. if (mString)
  226. {
  227. count = (S32)strlen(mString); /*Flawfinder: ignore*/
  228. char *temp = new char[count + 2];
  229. memcpy(temp, mString, count); /*Flawfinder: ignore*/
  230. delete [] mString;
  231. mString = temp;
  232. mString[count + 1] = 0;
  233. }
  234. else
  235. {
  236. mString = new char[count + 2];
  237. mString[count + 1] = 0;
  238. }
  239. mString[count++] = LSCRIPTFunctionTypeStrings[type];
  240. }
  241. S32 getNumber()
  242. {
  243. if (mString)
  244. return (S32)strlen(mString); /*Flawfinder: ignore*/
  245. else
  246. return 0;
  247. }
  248. char *mString;
  249. };
  250. class LLScriptScopeEntry
  251. {
  252. public:
  253. LLScriptScopeEntry(const char *identifier, LSCRIPTIdentifierType idtype, LSCRIPTType type, S32 count = 0)
  254. : mIdentifier(identifier), mIDType(idtype), mType(type), mOffset(0), mSize(0), mAssignable(NULL), mCount(count), mLibraryNumber(0)
  255. {
  256. }
  257. ~LLScriptScopeEntry() {}
  258. const char *mIdentifier;
  259. LSCRIPTIdentifierType mIDType;
  260. LSCRIPTType mType;
  261. S32 mOffset;
  262. S32 mSize;
  263. LLScriptSimpleAssignable *mAssignable;
  264. S32 mCount; // NOTE: Index for locals in CIL.
  265. U16 mLibraryNumber;
  266. LLScriptArgString mFunctionArgs;
  267. LLScriptArgString mLocals;
  268. };
  269. class LLScriptScope
  270. {
  271. public:
  272. LLScriptScope(LLStringTable *stable)
  273. : mParentScope(NULL), mSTable(stable), mFunctionCount(0), mStateCount(0)
  274. {
  275. }
  276. ~LLScriptScope()
  277. {
  278. mEntryMap.deleteAllData();
  279. }
  280. LLScriptScopeEntry *addEntry(const char *identifier, LSCRIPTIdentifierType idtype, LSCRIPTType type)
  281. {
  282. const char *name = mSTable->addString(identifier);
  283. if (!mEntryMap.checkData(name))
  284. {
  285. if (idtype == LIT_FUNCTION)
  286. mEntryMap[name] = new LLScriptScopeEntry(name, idtype, type, mFunctionCount++);
  287. else if (idtype == LIT_STATE)
  288. mEntryMap[name] = new LLScriptScopeEntry(name, idtype, type, mStateCount++);
  289. else
  290. mEntryMap[name] = new LLScriptScopeEntry(name, idtype, type);
  291. return mEntryMap[name];
  292. }
  293. else
  294. {
  295. // identifier already exists at this scope
  296. return NULL;
  297. }
  298. }
  299. BOOL checkEntry(const char *identifier)
  300. {
  301. const char *name = mSTable->addString(identifier);
  302. if (mEntryMap.checkData(name))
  303. {
  304. return TRUE;
  305. }
  306. else
  307. {
  308. // identifier already exists at this scope
  309. return FALSE;
  310. }
  311. }
  312. LLScriptScopeEntry *findEntry(const char *identifier)
  313. {
  314. const char *name = mSTable->addString(identifier);
  315. LLScriptScope *scope = this;
  316. while (scope)
  317. {
  318. if (scope->mEntryMap.checkData(name))
  319. {
  320. // cool, we found it at this scope
  321. return scope->mEntryMap[name];
  322. }
  323. scope = scope->mParentScope;
  324. }
  325. return NULL;
  326. }
  327. LLScriptScopeEntry *findEntryTyped(const char *identifier, LSCRIPTIdentifierType idtype)
  328. {
  329. const char *name = mSTable->addString(identifier);
  330. LLScriptScope *scope = this;
  331. while (scope)
  332. {
  333. if (scope->mEntryMap.checkData(name))
  334. {
  335. // need to check type, and if type is function we need to check both types
  336. if (idtype == LIT_FUNCTION)
  337. {
  338. if (scope->mEntryMap[name]->mIDType == LIT_FUNCTION)
  339. {
  340. return scope->mEntryMap[name];
  341. }
  342. else if (scope->mEntryMap[name]->mIDType == LIT_LIBRARY_FUNCTION)
  343. {
  344. return scope->mEntryMap[name];
  345. }
  346. }
  347. else if (scope->mEntryMap[name]->mIDType == idtype)
  348. {
  349. // cool, we found it at this scope
  350. return scope->mEntryMap[name];
  351. }
  352. }
  353. scope = scope->mParentScope;
  354. }
  355. return NULL;
  356. }
  357. void addParentScope(LLScriptScope *scope)
  358. {
  359. mParentScope = scope;
  360. }
  361. LLMap<const char *, LLScriptScopeEntry *> mEntryMap;
  362. LLScriptScope *mParentScope;
  363. LLStringTable *mSTable;
  364. S32 mFunctionCount;
  365. S32 mStateCount;
  366. };
  367. extern LLStringTable *gScopeStringTable;
  368. #endif