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