aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/lscript
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:44:46 -0500
committerJacek Antonelli2008-08-15 23:44:46 -0500
commit38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch)
treeadca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/lscript
parentREADME.txt (diff)
downloadmeta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.zip
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.gz
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.bz2
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.xz
Second Life viewer sources 1.13.2.12
Diffstat (limited to 'linden/indra/lscript')
-rw-r--r--linden/indra/lscript/files.lst16
-rw-r--r--linden/indra/lscript/lscript_alloc.h363
-rw-r--r--linden/indra/lscript/lscript_byteconvert.h1106
-rw-r--r--linden/indra/lscript/lscript_byteformat.h563
-rw-r--r--linden/indra/lscript/lscript_compile/indra.l834
-rw-r--r--linden/indra/lscript/lscript_compile/indra.y1680
-rw-r--r--linden/indra/lscript/lscript_compile/lscript_alloc.cpp27
-rw-r--r--linden/indra/lscript/lscript_compile/lscript_bytecode.cpp318
-rw-r--r--linden/indra/lscript/lscript_compile/lscript_bytecode.h90
-rw-r--r--linden/indra/lscript/lscript_compile/lscript_compile.vcproj222
-rwxr-xr-xlinden/indra/lscript/lscript_compile/lscript_compile_fb.vcproj106
-rw-r--r--linden/indra/lscript/lscript_compile/lscript_error.cpp96
-rw-r--r--linden/indra/lscript/lscript_compile/lscript_error.h151
-rw-r--r--linden/indra/lscript/lscript_compile/lscript_heap.cpp68
-rw-r--r--linden/indra/lscript/lscript_compile/lscript_heap.h59
-rw-r--r--linden/indra/lscript/lscript_compile/lscript_resource.cpp37
-rw-r--r--linden/indra/lscript/lscript_compile/lscript_resource.h40
-rw-r--r--linden/indra/lscript/lscript_compile/lscript_scope.cpp32
-rw-r--r--linden/indra/lscript/lscript_compile/lscript_scope.h407
-rw-r--r--linden/indra/lscript/lscript_compile/lscript_tree.cpp10017
-rw-r--r--linden/indra/lscript/lscript_compile/lscript_tree.h2298
-rw-r--r--linden/indra/lscript/lscript_compile/lscript_typecheck.cpp581
-rw-r--r--linden/indra/lscript/lscript_compile/lscript_typecheck.h119
-rw-r--r--linden/indra/lscript/lscript_execute.h383
-rw-r--r--linden/indra/lscript/lscript_execute/lscript_execute.cpp3929
-rw-r--r--linden/indra/lscript/lscript_execute/lscript_execute.vcproj189
-rw-r--r--linden/indra/lscript/lscript_execute/lscript_heapruntime.cpp520
-rw-r--r--linden/indra/lscript/lscript_execute/lscript_heapruntime.h41
-rw-r--r--linden/indra/lscript/lscript_execute/lscript_readlso.cpp1572
-rw-r--r--linden/indra/lscript/lscript_execute/lscript_readlso.h166
-rw-r--r--linden/indra/lscript/lscript_export.h35
-rw-r--r--linden/indra/lscript/lscript_http.h46
-rw-r--r--linden/indra/lscript/lscript_library.h401
-rw-r--r--linden/indra/lscript/lscript_library/lscript_alloc.cpp1121
-rw-r--r--linden/indra/lscript/lscript_library/lscript_export.cpp27
-rw-r--r--linden/indra/lscript/lscript_library/lscript_library.cpp576
-rw-r--r--linden/indra/lscript/lscript_library/lscript_library.vcproj183
-rw-r--r--linden/indra/lscript/lscript_rt_interface.h37
38 files changed, 28456 insertions, 0 deletions
diff --git a/linden/indra/lscript/files.lst b/linden/indra/lscript/files.lst
new file mode 100644
index 0000000..3413b4e
--- /dev/null
+++ b/linden/indra/lscript/files.lst
@@ -0,0 +1,16 @@
1lscript/lscript_compile/indra.l.cpp
2lscript/lscript_compile/indra.y.cpp
3lscript/lscript_compile/lscript_alloc.cpp
4lscript/lscript_compile/lscript_bytecode.cpp
5lscript/lscript_compile/lscript_error.cpp
6lscript/lscript_compile/lscript_heap.cpp
7lscript/lscript_compile/lscript_resource.cpp
8lscript/lscript_compile/lscript_scope.cpp
9lscript/lscript_compile/lscript_tree.cpp
10lscript/lscript_compile/lscript_typecheck.cpp
11lscript/lscript_execute/lscript_execute.cpp
12lscript/lscript_execute/lscript_heapruntime.cpp
13lscript/lscript_execute/lscript_readlso.cpp
14lscript/lscript_library/lscript_alloc.cpp
15lscript/lscript_library/lscript_library.cpp
16lscript/lscript_library/lscript_export.cpp
diff --git a/linden/indra/lscript/lscript_alloc.h b/linden/indra/lscript/lscript_alloc.h
new file mode 100644
index 0000000..67e3dc0
--- /dev/null
+++ b/linden/indra/lscript/lscript_alloc.h
@@ -0,0 +1,363 @@
1/**
2 * @file lscript_alloc.h
3 * @brief General heap management for scripting system
4 *
5 * Copyright (c) 2002-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28#ifndef LL_LSCRIPT_ALLOC_H
29#define LL_LSCRIPT_ALLOC_H
30// #define at top of file accelerates gcc compiles
31// Under gcc 2.9, the manual is unclear if comments can appear above #ifndef
32// Under gcc 3, the manual explicitly states comments can appear above the #ifndef
33
34#include "stdtypes.h"
35#include "lscript_byteconvert.h"
36#include "lscript_library.h"
37#include "llrand.h"
38#include <stdio.h>
39
40void reset_hp_to_safe_spot(const U8 *buffer);
41
42
43// supported data types
44
45// basic types
46// integer 4 bytes of integer data
47// float 4 bytes of float data
48// string data null terminated 1 byte string
49// key data null terminated 1 byte string
50// vector data 12 bytes of 3 floats
51// quaternion data 16 bytes of 4 floats
52
53// list type
54// list data 4 bytes of number of entries followed by followed by pointer
55
56// string pointer 4 bytes of address of string data on the heap (only used in list data)
57// key pointer 4 bytes of address of key data on the heap (only used in list data)
58
59// heap format
60//
61// 4 byte offset to next block (in bytes)
62// 1 byte of type of variable or empty
63// 2 bytes of reference count
64// nn bytes of data
65
66const S32 MAX_HEAP_SIZE = TOP_OF_MEMORY;
67
68class LLScriptAllocEntry
69{
70public:
71 LLScriptAllocEntry() : mSize(0), mType(LST_NULL), mReferenceCount(0) {}
72 LLScriptAllocEntry(S32 offset, U8 type) : mSize(offset), mType(type), mReferenceCount(1) {}
73 friend std::ostream& operator<<(std::ostream& s, const LLScriptAllocEntry &a)
74 {
75 s << "Size: " << a.mSize << " Type: " << LSCRIPTTypeNames[a.mType] << " Count: " << a.mReferenceCount;
76 return s;
77 }
78
79 S32 mSize;
80 U8 mType;
81 S16 mReferenceCount;
82};
83
84// this is only OK because we only load/save via accessors below
85const S32 SIZEOF_SCRIPT_ALLOC_ENTRY = 7;
86
87inline void alloc_entry2bytestream(U8 *buffer, S32 &offset, const LLScriptAllocEntry &entry)
88{
89 if ( (offset < 0)
90 ||(offset > MAX_HEAP_SIZE))
91 {
92 set_fault(buffer, LSRF_BOUND_CHECK_ERROR);
93 }
94 else
95 {
96 integer2bytestream(buffer, offset, entry.mSize);
97 byte2bytestream(buffer, offset, entry.mType);
98 s162bytestream(buffer, offset, entry.mReferenceCount);
99 }
100}
101
102inline void bytestream2alloc_entry(LLScriptAllocEntry &entry, U8 *buffer, S32 &offset)
103{
104 if ( (offset < 0)
105 ||(offset > MAX_HEAP_SIZE))
106 {
107 set_fault(buffer, LSRF_BOUND_CHECK_ERROR);
108 reset_hp_to_safe_spot(buffer);
109 }
110 else
111 {
112 entry.mSize = bytestream2integer(buffer, offset);
113 entry.mType = bytestream2byte(buffer, offset);
114 entry.mReferenceCount = bytestream2s16(buffer, offset);
115 }
116}
117
118// create a heap from the HR to TM
119BOOL lsa_create_heap(U8 *heap_start, S32 size);
120void lsa_fprint_heap(U8 *buffer, FILE *fp);
121
122void lsa_print_heap(U8 *buffer);
123
124// adding to heap
125// if block is empty
126// if block is at least block size + 4 larger than data
127// split block
128// insert data into first part
129// return address
130// else
131// insert data into block
132// return address
133// else
134// if next block is >= SP
135// set Stack-Heap collision
136// return NULL
137// if next block is empty
138// merge next block with current block
139// go to start of algorithm
140// else
141// move to next block
142// go to start of algorithm
143
144S32 lsa_heap_add_data(U8 *buffer, LLScriptLibData *data, S32 heapsize, BOOL b_delete);
145
146S32 lsa_heap_top(U8 *heap_start, S32 maxsize);
147
148// split block
149// set offset to point to new block
150// set offset of new block to point to original offset - block size - data size
151// set new block to empty
152// set new block reference count to 0
153void lsa_split_block(U8 *buffer, S32 &offset, S32 size, LLScriptAllocEntry &entry);
154
155// insert data
156// if data is non-list type
157// set type to basic type, set reference count to 1, copy data, return address
158// else
159// set type to list data type, set reference count to 1
160// for each list entry
161// insert data
162// return address
163
164void lsa_insert_data(U8 *buffer, S32 &offset, LLScriptLibData *data, LLScriptAllocEntry &entry, S32 heapsize);
165
166S32 lsa_create_data_block(U8 **buffer, LLScriptLibData *data, S32 base_offset);
167
168// increase reference count
169// increase reference count by 1
170
171void lsa_increase_ref_count(U8 *buffer, S32 offset);
172
173// decrease reference count
174// decrease reference count by 1
175// if reference count == 0
176// set type to empty
177
178void lsa_decrease_ref_count(U8 *buffer, S32 offset);
179
180inline S32 get_max_heap_size(U8 *buffer)
181{
182 return get_register(buffer, LREG_SP) - get_register(buffer, LREG_HR);
183}
184
185
186LLScriptLibData *lsa_get_data(U8 *buffer, S32 &offset, BOOL b_dec_ref);
187LLScriptLibData *lsa_get_list_ptr(U8 *buffer, S32 &offset, BOOL b_dec_ref);
188
189S32 lsa_cat_strings(U8 *buffer, S32 offset1, S32 offset2, S32 heapsize);
190S32 lsa_cmp_strings(U8 *buffer, S32 offset1, S32 offset2);
191
192S32 lsa_cat_lists(U8 *buffer, S32 offset1, S32 offset2, S32 heapsize);
193S32 lsa_cmp_lists(U8 *buffer, S32 offset1, S32 offset2);
194S32 lsa_preadd_lists(U8 *buffer, LLScriptLibData *data, S32 offset2, S32 heapsize);
195S32 lsa_postadd_lists(U8 *buffer, S32 offset1, LLScriptLibData *data, S32 heapsize);
196
197// modifying a list
198// insert new list that is modified
199// store returned address in original list's variable
200// decrease reference count on old list
201
202// list l1 = [10];
203// list l2 = l1;
204// l1 = [11];
205
206// we want l2 == [10];
207
208// more complicated example:
209// list l1 = [10, 11];
210// list l2 = l1;
211// l1[0] = 12
212
213// I think that we want l2 = [10, 11];
214
215// one option would be to use syntax like:
216// l1 = llSetList(l1, 0, 12);
217// but this would require variable argument list matching
218// which maybe is ok, but would be work
219// the other option would be changes to lists that have multiple references causes a copy to occur
220
221// popl @l1, 0, integer, 12
222//
223// would cause l1 to be copied, 12 to replace the 0th entry, and the address of the new list to be saved in l1
224//
225
226inline LLScriptLibData *lsa_bubble_sort(LLScriptLibData *src, S32 stride, S32 ascending)
227{
228 S32 number = src->getListLength();
229
230 if (number <= 0)
231 {
232 return NULL;
233 }
234
235 if (stride <= 0)
236 {
237 stride = 1;
238 }
239
240 S32 i = 0;
241
242 if (number % stride)
243 {
244 LLScriptLibData *retval = src->mListp;
245 src->mListp = NULL;
246 return retval;
247 }
248
249 LLScriptLibData **sortarray = (LLScriptLibData **)new U32[number];
250
251 LLScriptLibData *temp = src->mListp;
252 while (temp)
253 {
254 sortarray[i] = temp;
255 i++;
256 temp = temp->mListp;
257 }
258
259 S32 j, s;
260
261 for (i = 0; i < number; i += stride)
262 {
263 for (j = i; j < number; j += stride)
264 {
265 if ( ((*sortarray[i]) <= (*sortarray[j]))
266 != (ascending == TRUE))
267 {
268 for (s = 0; s < stride; s++)
269 {
270 temp = sortarray[i + s];
271 sortarray[i + s] = sortarray[j + s];
272 sortarray[j + s] = temp;
273 }
274 }
275 }
276 }
277
278 i = 1;
279 temp = sortarray[0];
280 while (i < number)
281 {
282 temp->mListp = sortarray[i++];
283 temp = temp->mListp;
284 }
285 temp->mListp = NULL;
286
287 src->mListp = NULL;
288
289 return sortarray[0];
290}
291
292
293inline LLScriptLibData *lsa_randomize(LLScriptLibData *src, S32 stride)
294{
295 S32 number = src->getListLength();
296
297 if (number <= 0)
298 {
299 return NULL;
300 }
301
302 if (stride <= 0)
303 {
304 stride = 1;
305 }
306
307 if (number % stride)
308 {
309 LLScriptLibData *retval = src->mListp;
310 src->mListp = NULL;
311 return retval;
312 }
313
314 LLScriptLibData **sortarray = (LLScriptLibData **)new U32[number];
315
316 LLScriptLibData *temp = src->mListp;
317 S32 i = 0;
318 while (temp)
319 {
320 sortarray[i] = temp;
321 i++;
322 temp = temp->mListp;
323 }
324
325 S32 k, j, s;
326
327 for (k = 0; k < 20; k++)
328 {
329 for (i = 0; i < number; i += stride)
330 {
331 for (j = i; j < number; j += stride)
332 {
333 if (frand(1.f) > 0.5)
334 {
335 for (s = 0; s < stride; s++)
336 {
337 temp = sortarray[i + s];
338 sortarray[i + s] = sortarray[j + s];
339 sortarray[j + s] = temp;
340 }
341 }
342 }
343 }
344 }
345
346 i = 1;
347 temp = sortarray[0];
348 while (i < number)
349 {
350 temp->mListp = sortarray[i++];
351 temp = temp->mListp;
352 }
353 temp->mListp = NULL;
354
355 src->mListp = NULL;
356
357 LLScriptLibData *ret_value = sortarray[0];
358 delete [] sortarray;
359
360 return ret_value;
361}
362
363#endif
diff --git a/linden/indra/lscript/lscript_byteconvert.h b/linden/indra/lscript/lscript_byteconvert.h
new file mode 100644
index 0000000..de81fd7
--- /dev/null
+++ b/linden/indra/lscript/lscript_byteconvert.h
@@ -0,0 +1,1106 @@
1/**
2 * @file lscript_byteconvert.h
3 * @brief Shared code for compiler and assembler for LSL
4 *
5 * Copyright (c) 2002-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28// data shared between compiler/assembler
29// used to convert data between byte stream and outside data types
30
31#ifndef LL_LSCRIPT_BYTECONVERT_H
32#define LL_LSCRIPT_BYTECONVERT_H
33
34#include "stdtypes.h"
35#include "v3math.h"
36#include "llquaternion.h"
37#include "lscript_byteformat.h"
38#include "lluuid.h"
39
40void reset_hp_to_safe_spot(const U8 *buffer);
41
42// remember that LScript byte stream is BigEndian
43void set_fault(const U8 *stream, LSCRIPTRunTimeFaults fault);
44
45inline S32 bytestream2integer(const U8 *stream, S32 &offset)
46{
47 stream += offset;
48 offset += 4;
49 return (*stream<<24) | (*(stream + 1)<<16) | (*(stream + 2)<<8) | *(stream + 3);
50}
51
52inline U32 bytestream2unsigned_integer(const U8 *stream, S32 &offset)
53{
54 stream += offset;
55 offset += 4;
56 return (*stream<<24) | (*(stream + 1)<<16) | (*(stream + 2)<<8) | *(stream + 3);
57}
58
59inline U64 bytestream2u64(const U8 *stream, S32 &offset)
60{
61 stream += offset;
62 offset += 8;
63 return ((U64)(*stream)<<56)| ((U64)(*(stream + 1))<<48) | ((U64)(*(stream + 2))<<40) | ((U64)(*(stream + 3))<<32) |
64 ((U64)(*(stream + 4))<<24) | ((U64)(*(stream + 5))<<16) | ((U64)(*(stream + 6))<<8) | (U64)(*(stream + 7));
65}
66
67inline void integer2bytestream(U8 *stream, S32 &offset, S32 integer)
68{
69 stream += offset;
70 offset += 4;
71 *(stream) = (integer >> 24);
72 *(stream + 1) = (integer >> 16) & 0xff;
73 *(stream + 2) = (integer >> 8) & 0xff;
74 *(stream + 3) = (integer) & 0xff;
75}
76
77inline void unsigned_integer2bytestream(U8 *stream, S32 &offset, U32 integer)
78{
79 stream += offset;
80 offset += 4;
81 *(stream) = (integer >> 24);
82 *(stream + 1) = (integer >> 16) & 0xff;
83 *(stream + 2) = (integer >> 8) & 0xff;
84 *(stream + 3) = (integer) & 0xff;
85}
86inline void u642bytestream(U8 *stream, S32 &offset, U64 integer)
87{
88 stream += offset;
89 offset += 8;
90 *(stream) = (U8)(integer >> 56);
91 *(stream + 1) = (U8)((integer >> 48) & 0xff);
92 *(stream + 2) = (U8)((integer >> 40) & 0xff);
93 *(stream + 3) = (U8)((integer >> 32) & 0xff);
94 *(stream + 4) = (U8)((integer >> 24) & 0xff);
95 *(stream + 5) = (U8)((integer >> 16) & 0xff);
96 *(stream + 6) = (U8)((integer >> 8) & 0xff);
97 *(stream + 7) = (U8)((integer) & 0xff);
98}
99
100inline S16 bytestream2s16(const U8 *stream, S32 &offset)
101{
102 stream += offset;
103 offset += 2;
104 return (*stream<<8) | *(stream + 1);
105}
106
107inline void s162bytestream(U8 *stream, S32 &offset, S16 integer)
108{
109 stream += offset;
110 offset += 2;
111 *(stream) = (integer >> 8);
112 *(stream + 1) = (integer) & 0xff;
113}
114
115inline U16 bytestream2u16(const U8 *stream, S32 &offset)
116{
117 stream += offset;
118 offset += 2;
119 return (*stream<<8) | *(stream + 1);
120}
121
122inline void u162bytestream(U8 *stream, S32 &offset, U16 integer)
123{
124 stream += offset;
125 offset += 2;
126 *(stream) = (integer >> 8);
127 *(stream + 1) = (integer) & 0xff;
128}
129
130inline F32 bytestream2float(const U8 *stream, S32 &offset)
131{
132 S32 value = bytestream2integer(stream, offset);
133 F32 fpvalue = *(F32 *)&value;
134 if (!llfinite(fpvalue))
135 {
136 fpvalue = 0;
137 set_fault(stream, LSRF_MATH);
138 }
139 return fpvalue;
140}
141
142inline void float2bytestream(U8 *stream, S32 &offset, F32 floatingpoint)
143{
144 S32 value = *(S32 *)&floatingpoint;
145 integer2bytestream(stream, offset, value);
146}
147
148inline void bytestream_int2float(U8 *stream, S32 &offset)
149{
150 S32 value = bytestream2integer(stream, offset);
151 offset -= 4;
152 F32 fpvalue = (F32)value;
153 if (!llfinite(fpvalue))
154 {
155 fpvalue = 0;
156 set_fault(stream, LSRF_MATH);
157 }
158 float2bytestream(stream, offset, fpvalue);
159}
160
161inline void bytestream2char(char *buffer, const U8 *stream, S32 &offset)
162{
163 while ((*buffer++ = *(stream + offset++)))
164 ;
165}
166
167inline void char2bytestream(U8 *stream, S32 &offset, char *buffer)
168{
169 while ((*(stream + offset++) = *buffer++))
170 ;
171}
172
173inline U8 bytestream2byte(const U8 *stream, S32 &offset)
174{
175 return *(stream + offset++);
176}
177
178inline void byte2bytestream(U8 *stream, S32 &offset, U8 byte)
179{
180 *(stream + offset++) = byte;
181}
182
183inline void bytestream2bytestream(U8 *dest, S32 &dest_offset, const U8 *src, S32 &src_offset, S32 count)
184{
185 while (count)
186 {
187 (*(dest + dest_offset++)) = (*(src + src_offset++));
188 count--;
189 }
190}
191
192inline void uuid2bytestream(U8 *stream, S32 &offset, const LLUUID &uuid)
193{
194 S32 i;
195 for (i = 0; i < UUID_BYTES; i++)
196 {
197 *(stream + offset++) = uuid.mData[i];
198 }
199}
200
201inline void bytestream2uuid(U8 *stream, S32 &offset, LLUUID &uuid)
202{
203 S32 i;
204 for (i = 0; i < UUID_BYTES; i++)
205 {
206 uuid.mData[i] = *(stream + offset++);
207 }
208}
209
210// vectors and quaternions and encoded in backwards order to match the way in which they are stored on the stack
211inline void bytestream2vector(LLVector3 &vector, const U8 *stream, S32 &offset)
212{
213 S32 value = bytestream2integer(stream, offset);
214 vector.mV[VZ] = *(F32 *)&value;
215 if (!llfinite(vector.mV[VZ]))
216 {
217 vector.mV[VZ] = 0;
218 set_fault(stream, LSRF_MATH);
219 }
220 value = bytestream2integer(stream, offset);
221 vector.mV[VY] = *(F32 *)&value;
222 if (!llfinite(vector.mV[VY]))
223 {
224 vector.mV[VY] = 0;
225 set_fault(stream, LSRF_MATH);
226 }
227 value = bytestream2integer(stream, offset);
228 vector.mV[VX] = *(F32 *)&value;
229 if (!llfinite(vector.mV[VX]))
230 {
231 vector.mV[VX] = 0;
232 set_fault(stream, LSRF_MATH);
233 }
234}
235
236inline void vector2bytestream(U8 *stream, S32 &offset, LLVector3 &vector)
237{
238 S32 value = *(S32 *)&vector.mV[VZ];
239 integer2bytestream(stream, offset, value);
240 value = *(S32 *)&vector.mV[VY];
241 integer2bytestream(stream, offset, value);
242 value = *(S32 *)&vector.mV[VX];
243 integer2bytestream(stream, offset, value);
244}
245
246inline void bytestream2quaternion(LLQuaternion &quat, const U8 *stream, S32 &offset)
247{
248 S32 value = bytestream2integer(stream, offset);
249 quat.mQ[VS] = *(F32 *)&value;
250 if (!llfinite(quat.mQ[VS]))
251 {
252 quat.mQ[VS] = 0;
253 set_fault(stream, LSRF_MATH);
254 }
255 value = bytestream2integer(stream, offset);
256 quat.mQ[VZ] = *(F32 *)&value;
257 if (!llfinite(quat.mQ[VZ]))
258 {
259 quat.mQ[VZ] = 0;
260 set_fault(stream, LSRF_MATH);
261 }
262 value = bytestream2integer(stream, offset);
263 quat.mQ[VY] = *(F32 *)&value;
264 if (!llfinite(quat.mQ[VY]))
265 {
266 quat.mQ[VY] = 0;
267 set_fault(stream, LSRF_MATH);
268 }
269 value = bytestream2integer(stream, offset);
270 quat.mQ[VX] = *(F32 *)&value;
271 if (!llfinite(quat.mQ[VX]))
272 {
273 quat.mQ[VX] = 0;
274 set_fault(stream, LSRF_MATH);
275 }
276}
277
278inline void quaternion2bytestream(U8 *stream, S32 &offset, LLQuaternion &quat)
279{
280 S32 value = *(S32 *)&quat.mQ[VS];
281 integer2bytestream(stream, offset, value);
282 value = *(S32 *)&quat.mQ[VZ];
283 integer2bytestream(stream, offset, value);
284 value = *(S32 *)&quat.mQ[VY];
285 integer2bytestream(stream, offset, value);
286 value = *(S32 *)&quat.mQ[VX];
287 integer2bytestream(stream, offset, value);
288}
289
290inline S32 get_register(const U8 *stream, LSCRIPTRegisters reg)
291{
292 S32 offset = gLSCRIPTRegisterAddresses[reg];
293 return bytestream2integer(stream, offset);
294}
295
296inline F32 get_register_fp(U8 *stream, LSCRIPTRegisters reg)
297{
298 S32 offset = gLSCRIPTRegisterAddresses[reg];
299 F32 value = bytestream2float(stream, offset);
300 if (!llfinite(value))
301 {
302 value = 0;
303 set_fault(stream, LSRF_MATH);
304 }
305 return value;
306}
307inline U64 get_register_u64(U8 *stream, LSCRIPTRegisters reg)
308{
309 S32 offset = gLSCRIPTRegisterAddresses[reg];
310 return bytestream2u64(stream, offset);
311}
312
313inline U64 get_event_register(U8 *stream, LSCRIPTRegisters reg, S32 major_version)
314{
315 if (major_version == 1)
316 {
317 S32 offset = gLSCRIPTRegisterAddresses[reg];
318 return (U64)bytestream2integer(stream, offset);
319 }
320 else if (major_version == 2)
321 {
322 S32 offset = gLSCRIPTRegisterAddresses[reg + (LREG_NCE - LREG_CE)];
323 return bytestream2u64(stream, offset);
324 }
325 else
326 {
327 S32 offset = gLSCRIPTRegisterAddresses[reg];
328 return (U64)bytestream2integer(stream, offset);
329 }
330}
331
332inline void set_register(U8 *stream, LSCRIPTRegisters reg, S32 value)
333{
334 S32 offset = gLSCRIPTRegisterAddresses[reg];
335 integer2bytestream(stream, offset, value);
336}
337
338inline void set_register_fp(U8 *stream, LSCRIPTRegisters reg, F32 value)
339{
340 S32 offset = gLSCRIPTRegisterAddresses[reg];
341 float2bytestream(stream, offset, value);
342}
343
344inline void set_register_u64(U8 *stream, LSCRIPTRegisters reg, U64 value)
345{
346 S32 offset = gLSCRIPTRegisterAddresses[reg];
347 u642bytestream(stream, offset, value);
348}
349
350inline void set_event_register(U8 *stream, LSCRIPTRegisters reg, U64 value, S32 major_version)
351{
352 if (major_version == 1)
353 {
354 S32 offset = gLSCRIPTRegisterAddresses[reg];
355 integer2bytestream(stream, offset, (S32)value);
356 }
357 else if (major_version == 2)
358 {
359 S32 offset = gLSCRIPTRegisterAddresses[reg + (LREG_NCE - LREG_CE)];
360 u642bytestream(stream, offset, value);
361 }
362 else
363 {
364 S32 offset = gLSCRIPTRegisterAddresses[reg];
365 integer2bytestream(stream, offset, (S32)value);
366 }
367}
368
369
370inline F32 add_register_fp(U8 *stream, LSCRIPTRegisters reg, F32 value)
371{
372 S32 offset = gLSCRIPTRegisterAddresses[reg];
373 F32 newvalue = bytestream2float(stream, offset);
374 newvalue += value;
375 if (!llfinite(newvalue))
376 {
377 newvalue = 0;
378 set_fault(stream, LSRF_MATH);
379 }
380 offset = gLSCRIPTRegisterAddresses[reg];
381 float2bytestream(stream, offset, newvalue);
382 return newvalue;
383}
384
385void lsa_print_heap(U8 *buffer);
386
387
388inline void set_fault(const U8 *stream, LSCRIPTRunTimeFaults fault)
389{
390 S32 fr = get_register(stream, LREG_FR);
391 // record the first error
392 if (!fr)
393 {
394 if ( (fault == LSRF_HEAP_ERROR)
395 ||(fault == LSRF_STACK_HEAP_COLLISION)
396 ||(fault == LSRF_BOUND_CHECK_ERROR))
397 {
398 reset_hp_to_safe_spot(stream);
399// lsa_print_heap((U8 *)stream);
400 }
401 fr = LSCRIPTRunTimeFaultBits[fault];
402 set_register((U8 *)stream, LREG_FR, fr);
403 }
404}
405
406inline BOOL set_ip(U8 *stream, S32 ip)
407{
408 // Verify that the Instruction Pointer is in a valid
409 // code area (between the Global Function Register
410 // and Heap Register).
411 S32 gfr = get_register(stream, LREG_GFR);
412 if (ip == 0)
413 {
414 set_register(stream, LREG_IP, ip);
415 return TRUE;
416 }
417 if (ip < gfr)
418 {
419 set_fault(stream, LSRF_BOUND_CHECK_ERROR);
420 return FALSE;
421 }
422 S32 hr = get_register(stream, LREG_HR);
423 if (ip >= hr)
424 {
425 set_fault(stream, LSRF_BOUND_CHECK_ERROR);
426 return FALSE;
427 }
428 set_register(stream, LREG_IP, ip);
429 return TRUE;
430}
431
432inline BOOL set_bp(U8 *stream, S32 bp)
433{
434 // Verify that the Base Pointer is in a valid
435 // data area (between the Heap Pointer and
436 // the Top of Memory, and below the
437 // Stack Pointer).
438 S32 hp = get_register(stream, LREG_HP);
439 if (bp <= hp)
440 {
441 set_fault(stream, LSRF_STACK_HEAP_COLLISION);
442 return FALSE;
443 }
444 S32 tm = get_register(stream, LREG_TM);
445 if (bp >= tm)
446 {
447 set_fault(stream, LSRF_BOUND_CHECK_ERROR);
448 return FALSE;
449 }
450 S32 sp = get_register(stream, LREG_SP);
451 if (bp < sp)
452 {
453 set_fault(stream, LSRF_BOUND_CHECK_ERROR);
454 return FALSE;
455 }
456 set_register(stream, LREG_BP, bp);
457 return TRUE;
458}
459
460inline BOOL set_sp(U8 *stream, S32 sp)
461{
462 // Verify that the Stack Pointer is in a valid
463 // data area (between the Heap Pointer and
464 // the Top of Memory).
465 S32 hp = get_register(stream, LREG_HP);
466 if (sp <= hp)
467 {
468 set_fault(stream, LSRF_STACK_HEAP_COLLISION);
469 return FALSE;
470 }
471 S32 tm = get_register(stream, LREG_TM);
472 if (sp >= tm)
473 {
474 set_fault(stream, LSRF_BOUND_CHECK_ERROR);
475 return FALSE;
476 }
477 set_register(stream, LREG_SP, sp);
478 return TRUE;
479}
480
481inline void lscript_push(U8 *stream, U8 value)
482{
483 S32 sp = get_register(stream, LREG_SP);
484 sp -= 1;
485
486 if (set_sp(stream, sp))
487 {
488 *(stream + sp) = value;
489 }
490}
491
492inline void lscript_push(U8 *stream, S32 value)
493{
494 S32 sp = get_register(stream, LREG_SP);
495 sp -= LSCRIPTDataSize[LST_INTEGER];
496
497 if (set_sp(stream, sp))
498 {
499 integer2bytestream(stream, sp, value);
500 }
501}
502
503inline void lscript_push(U8 *stream, F32 value)
504{
505 S32 sp = get_register(stream, LREG_SP);
506 sp -= LSCRIPTDataSize[LST_FLOATINGPOINT];
507
508 if (set_sp(stream, sp))
509 {
510 float2bytestream(stream, sp, value);
511 }
512}
513
514inline void lscript_push(U8 *stream, LLVector3 &value)
515{
516 S32 sp = get_register(stream, LREG_SP);
517 sp -= LSCRIPTDataSize[LST_VECTOR];
518
519 if (set_sp(stream, sp))
520 {
521 vector2bytestream(stream, sp, value);
522 }
523}
524
525inline void lscript_push(U8 *stream, LLQuaternion &value)
526{
527 S32 sp = get_register(stream, LREG_SP);
528 sp -= LSCRIPTDataSize[LST_QUATERNION];
529
530 if (set_sp(stream, sp))
531 {
532 quaternion2bytestream(stream, sp, value);
533 }
534}
535
536inline void lscript_pusharg(U8 *stream, S32 arg)
537{
538 S32 sp = get_register(stream, LREG_SP);
539 sp -= arg;
540
541 set_sp(stream, sp);
542}
543
544inline void lscript_poparg(U8 *stream, S32 arg)
545{
546 S32 sp = get_register(stream, LREG_SP);
547 sp += arg;
548
549 set_sp(stream, sp);
550}
551
552inline U8 lscript_pop_char(U8 *stream)
553{
554 S32 sp = get_register(stream, LREG_SP);
555 U8 value = *(stream + sp++);
556 set_sp(stream, sp);
557 return value;
558}
559
560inline S32 lscript_pop_int(U8 *stream)
561{
562 S32 sp = get_register(stream, LREG_SP);
563 S32 value = bytestream2integer(stream, sp);
564 set_sp(stream, sp);
565 return value;
566}
567
568inline F32 lscript_pop_float(U8 *stream)
569{
570 S32 sp = get_register(stream, LREG_SP);
571 F32 value = bytestream2float(stream, sp);
572 if (!llfinite(value))
573 {
574 value = 0;
575 set_fault(stream, LSRF_MATH);
576 }
577 set_sp(stream, sp);
578 return value;
579}
580
581inline void lscript_pop_vector(U8 *stream, LLVector3 &value)
582{
583 S32 sp = get_register(stream, LREG_SP);
584 bytestream2vector(value, stream, sp);
585 set_sp(stream, sp);
586}
587
588inline void lscript_pop_quaternion(U8 *stream, LLQuaternion &value)
589{
590 S32 sp = get_register(stream, LREG_SP);
591 bytestream2quaternion(value, stream, sp);
592 set_sp(stream, sp);
593}
594
595inline void lscript_pusharge(U8 *stream, S32 value)
596{
597 S32 sp = get_register(stream, LREG_SP);
598 sp -= value;
599 if (set_sp(stream, sp))
600 {
601 S32 i;
602 for (i = 0; i < value; i++)
603 {
604 *(stream + sp++) = 0;
605 }
606 }
607}
608
609inline BOOL lscript_check_local(U8 *stream, S32 &address, S32 size)
610{
611 S32 sp = get_register(stream, LREG_SP);
612 S32 bp = get_register(stream, LREG_BP);
613
614 address += size;
615 address = bp - address;
616
617 if (address < sp - size)
618 {
619 set_fault(stream, LSRF_BOUND_CHECK_ERROR);
620 return FALSE;
621 }
622 S32 tm = get_register(stream, LREG_TM);
623 if (address + size > tm)
624 {
625 set_fault(stream, LSRF_BOUND_CHECK_ERROR);
626 return FALSE;
627 }
628 return TRUE;
629}
630
631inline BOOL lscript_check_global(U8 *stream, S32 &address, S32 size)
632{
633 S32 gvr = get_register(stream, LREG_GVR);
634
635 // Possibility of overwriting registers? -- DK 09/07/04
636 if (address < 0)
637 {
638 set_fault(stream, LSRF_BOUND_CHECK_ERROR);
639 return FALSE;
640 }
641
642 address += gvr;
643 S32 gfr = get_register(stream, LREG_GFR);
644
645 if (address + size > gfr)
646 {
647 set_fault(stream, LSRF_BOUND_CHECK_ERROR);
648 return FALSE;
649 }
650 return TRUE;
651}
652
653inline void lscript_local_store(U8 *stream, S32 address, S32 value)
654{
655 if (lscript_check_local(stream, address, LSCRIPTDataSize[LST_INTEGER]))
656 integer2bytestream(stream, address, value);
657}
658
659inline void lscript_local_store(U8 *stream, S32 address, F32 value)
660{
661 if (lscript_check_local(stream, address, LSCRIPTDataSize[LST_FLOATINGPOINT]))
662 float2bytestream(stream, address, value);
663}
664
665inline void lscript_local_store(U8 *stream, S32 address, LLVector3 value)
666{
667 if (lscript_check_local(stream, address, LSCRIPTDataSize[LST_VECTOR]))
668 vector2bytestream(stream, address, value);
669}
670
671inline void lscript_local_store(U8 *stream, S32 address, LLQuaternion value)
672{
673 if (lscript_check_local(stream, address, LSCRIPTDataSize[LST_QUATERNION]))
674 quaternion2bytestream(stream, address, value);
675}
676
677inline void lscript_global_store(U8 *stream, S32 address, S32 value)
678{
679 if (lscript_check_global(stream, address, LSCRIPTDataSize[LST_INTEGER]))
680 integer2bytestream(stream, address, value);
681}
682
683inline void lscript_global_store(U8 *stream, S32 address, F32 value)
684{
685 if (lscript_check_global(stream, address, LSCRIPTDataSize[LST_FLOATINGPOINT]))
686 float2bytestream(stream, address, value);
687}
688
689inline void lscript_global_store(U8 *stream, S32 address, LLVector3 value)
690{
691 if (lscript_check_global(stream, address, LSCRIPTDataSize[LST_VECTOR]))
692 vector2bytestream(stream, address, value);
693}
694
695inline void lscript_global_store(U8 *stream, S32 address, LLQuaternion value)
696{
697 if (lscript_check_global(stream, address, LSCRIPTDataSize[LST_QUATERNION]))
698 quaternion2bytestream(stream, address, value);
699}
700
701inline S32 lscript_local_get(U8 *stream, S32 address)
702{
703 if (lscript_check_local(stream, address, LSCRIPTDataSize[LST_INTEGER]))
704 return bytestream2integer(stream, address);
705 return 0;
706}
707
708inline void lscript_local_get(U8 *stream, S32 address, F32 &value)
709{
710 if (lscript_check_local(stream, address, LSCRIPTDataSize[LST_FLOATINGPOINT]))
711 value = bytestream2float(stream, address);
712 if (!llfinite(value))
713 {
714 value = 0;
715 set_fault(stream, LSRF_MATH);
716 }
717}
718
719inline void lscript_local_get(U8 *stream, S32 address, LLVector3 &value)
720{
721 if (lscript_check_local(stream, address, LSCRIPTDataSize[LST_VECTOR]))
722 bytestream2vector(value, stream, address);
723}
724
725inline void lscript_local_get(U8 *stream, S32 address, LLQuaternion &value)
726{
727 if (lscript_check_local(stream, address, LSCRIPTDataSize[LST_QUATERNION]))
728 bytestream2quaternion(value, stream, address);
729}
730
731inline S32 lscript_global_get(U8 *stream, S32 address)
732{
733 if (lscript_check_global(stream, address, LSCRIPTDataSize[LST_INTEGER]))
734 return bytestream2integer(stream, address);
735 return 0;
736}
737
738inline void lscript_global_get(U8 *stream, S32 address, F32 &value)
739{
740 if (lscript_check_global(stream, address, LSCRIPTDataSize[LST_FLOATINGPOINT]))
741 value = bytestream2float(stream, address);
742 if (!llfinite(value))
743 {
744 value = 0;
745 set_fault(stream, LSRF_MATH);
746 }
747}
748
749inline void lscript_global_get(U8 *stream, S32 address, LLVector3 &value)
750{
751 if (lscript_check_global(stream, address, LSCRIPTDataSize[LST_VECTOR]))
752 bytestream2vector(value, stream, address);
753}
754
755inline void lscript_global_get(U8 *stream, S32 address, LLQuaternion &value)
756{
757 if (lscript_check_global(stream, address, LSCRIPTDataSize[LST_QUATERNION]))
758 bytestream2quaternion(value, stream, address);
759}
760
761
762
763inline S32 get_state_event_opcoode_start(U8 *stream, S32 state, LSCRIPTStateEventType event)
764{
765 // get the start of the state table
766 S32 sr = get_register(stream, LREG_SR);
767
768 // get the position of the jump to the desired state
769 S32 value = get_register(stream, LREG_VN);
770
771 S32 state_offset_offset = 0;
772 S32 major_version = 0;
773 if (value == LSL2_VERSION1_END_NUMBER)
774 {
775 major_version = LSL2_MAJOR_VERSION_ONE;
776 state_offset_offset = sr + LSCRIPTDataSize[LST_INTEGER] + LSCRIPTDataSize[LST_INTEGER]*2*state;
777 }
778 else if (value == LSL2_VERSION_NUMBER)
779 {
780 major_version = LSL2_MAJOR_VERSION_TWO;
781 state_offset_offset = sr + LSCRIPTDataSize[LST_INTEGER] + LSCRIPTDataSize[LST_INTEGER]*3*state;
782 }
783
784 // get the actual position in memory of the desired state
785 S32 state_offset = sr + bytestream2integer(stream, state_offset_offset);
786
787 // save that value
788 S32 state_offset_base = state_offset;
789
790 // jump past the state name
791 S32 event_jump_offset = state_offset_base + bytestream2integer(stream, state_offset);
792
793 // get the location of the event offset
794 S32 event_offset = event_jump_offset + LSCRIPTDataSize[LST_INTEGER]*2*get_event_handler_jump_position(get_event_register(stream, LREG_ER, major_version), event);
795
796 // now, jump to the event
797 S32 event_start = bytestream2integer(stream, event_offset);
798 event_start += event_jump_offset;
799
800 S32 event_start_original = event_start;
801
802 // now skip past the parameters
803 S32 opcode_offset = bytestream2integer(stream, event_start);
804 return opcode_offset + event_start_original;
805}
806
807inline U64 get_handled_events(U8 *stream, S32 state)
808{
809 U64 retvalue = 0;
810 // get the start of the state table
811 S32 sr = get_register(stream, LREG_SR);
812
813 // get the position of the jump to the desired state
814 S32 value = get_register(stream, LREG_VN);
815 S32 state_handled_offset = 0;
816 if (value == LSL2_VERSION1_END_NUMBER)
817 {
818 state_handled_offset = sr + LSCRIPTDataSize[LST_INTEGER]*2*state + 2*LSCRIPTDataSize[LST_INTEGER];
819 retvalue = bytestream2integer(stream, state_handled_offset);
820 }
821 else if (value == LSL2_VERSION_NUMBER)
822 {
823 state_handled_offset = sr + LSCRIPTDataSize[LST_INTEGER]*3*state + 2*LSCRIPTDataSize[LST_INTEGER];
824 retvalue = bytestream2u64(stream, state_handled_offset);
825 }
826
827 // get the handled events
828 return retvalue;
829}
830
831inline S32 get_event_stack_size(U8 *stream, S32 state, LSCRIPTStateEventType event)
832{
833 // get the start of the state table
834 S32 sr = get_register(stream, LREG_SR);
835
836 // get state offset
837 S32 value = get_register(stream, LREG_VN);
838 S32 state_offset_offset = 0;
839 S32 major_version = 0;
840 if (value == LSL2_VERSION1_END_NUMBER)
841 {
842 major_version = LSL2_MAJOR_VERSION_ONE;
843 state_offset_offset = sr + LSCRIPTDataSize[LST_INTEGER] + LSCRIPTDataSize[LST_INTEGER]*2*state;
844 }
845 else if (value == LSL2_VERSION_NUMBER)
846 {
847 major_version = LSL2_MAJOR_VERSION_TWO;
848 state_offset_offset = sr + LSCRIPTDataSize[LST_INTEGER] + LSCRIPTDataSize[LST_INTEGER]*3*state;
849 }
850
851 S32 state_offset = bytestream2integer(stream, state_offset_offset);
852 state_offset += sr;
853
854 state_offset_offset = state_offset;
855
856 // skip to jump table
857 S32 jump_table = bytestream2integer(stream, state_offset_offset);
858
859 jump_table += state_offset;
860
861 // get the position of the jump to the desired state
862 S32 stack_size_offset = jump_table + LSCRIPTDataSize[LST_INTEGER]*2*get_event_handler_jump_position(get_event_register(stream, LREG_ER, major_version), event) + LSCRIPTDataSize[LST_INTEGER];
863
864 // get the handled events
865 S32 stack_size = bytestream2integer(stream, stack_size_offset);
866 return stack_size;
867}
868
869inline LSCRIPTStateEventType return_first_event(S32 event)
870{
871 S32 count = 1;
872 while (count < LSTT_EOF)
873 {
874 if (event & 0x1)
875 {
876 return (LSCRIPTStateEventType) count;
877 }
878 else
879 {
880 event >>= 1;
881 count++;
882 }
883 }
884 return LSTT_NULL;
885}
886
887
888// the safe instruction versions of these commands will only work if offset is between
889// GFR and HR, meaning that it is an instruction (more or less) in global functions or event handlers
890
891inline BOOL safe_instruction_check_address(U8 *stream, S32 offset, S32 size)
892{
893 S32 gfr = get_register(stream, LREG_GFR);
894 if (offset < gfr)
895 {
896 set_fault(stream, LSRF_BOUND_CHECK_ERROR);
897 return FALSE;
898 }
899 else
900 {
901 S32 hr = get_register(stream, LREG_HR);
902 if (offset + size > hr)
903 {
904 set_fault(stream, LSRF_BOUND_CHECK_ERROR);
905 return FALSE;
906 }
907 else
908 {
909 return TRUE;
910 }
911 }
912}
913
914inline BOOL safe_heap_check_address(U8 *stream, S32 offset, S32 size)
915{
916 S32 hr = get_register(stream, LREG_HR);
917 if (offset < hr)
918 {
919 set_fault(stream, LSRF_BOUND_CHECK_ERROR);
920 return FALSE;
921 }
922 else
923 {
924 S32 hp = get_register(stream, LREG_HP);
925 if (offset + size > hp)
926 {
927 set_fault(stream, LSRF_BOUND_CHECK_ERROR);
928 return FALSE;
929 }
930 else
931 {
932 return TRUE;
933 }
934 }
935}
936
937inline U8 safe_instruction_bytestream2byte(U8 *stream, S32 &offset)
938{
939 if (safe_instruction_check_address(stream, offset, 1))
940 {
941 return *(stream + offset++);
942 }
943 else
944 {
945 return 0;
946 }
947}
948
949inline void safe_instruction_byte2bytestream(U8 *stream, S32 &offset, U8 byte)
950{
951 if (safe_instruction_check_address(stream, offset, 1))
952 {
953 *(stream + offset++) = byte;
954 }
955}
956
957inline S32 safe_instruction_bytestream2integer(U8 *stream, S32 &offset)
958{
959 if (safe_instruction_check_address(stream, offset, LSCRIPTDataSize[LST_INTEGER]))
960 {
961 return (bytestream2integer(stream, offset));
962 }
963 else
964 {
965 return 0;
966 }
967}
968
969inline void safe_instruction_integer2bytestream(U8 *stream, S32 &offset, S32 value)
970{
971 if (safe_instruction_check_address(stream, offset, LSCRIPTDataSize[LST_INTEGER]))
972 {
973 integer2bytestream(stream, offset, value);
974 }
975}
976
977inline U16 safe_instruction_bytestream2u16(U8 *stream, S32 &offset)
978{
979 if (safe_instruction_check_address(stream, offset, 2))
980 {
981 return (bytestream2u16(stream, offset));
982 }
983 else
984 {
985 return 0;
986 }
987}
988
989inline void safe_instruction_u162bytestream(U8 *stream, S32 &offset, U16 value)
990{
991 if (safe_instruction_check_address(stream, offset, 2))
992 {
993 u162bytestream(stream, offset, value);
994 }
995}
996
997inline F32 safe_instruction_bytestream2float(U8 *stream, S32 &offset)
998{
999 if (safe_instruction_check_address(stream, offset, LSCRIPTDataSize[LST_INTEGER]))
1000 {
1001 F32 value = bytestream2float(stream, offset);
1002 if (!llfinite(value))
1003 {
1004 value = 0;
1005 set_fault(stream, LSRF_MATH);
1006 }
1007 return value;
1008 }
1009 else
1010 {
1011 return 0;
1012 }
1013}
1014
1015inline void safe_instruction_float2bytestream(U8 *stream, S32 &offset, F32 value)
1016{
1017 if (safe_instruction_check_address(stream, offset, LSCRIPTDataSize[LST_FLOATINGPOINT]))
1018 {
1019 float2bytestream(stream, offset, value);
1020 }
1021}
1022
1023inline void safe_instruction_bytestream2char(char *buffer, U8 *stream, S32 &offset)
1024{
1025 while ( (safe_instruction_check_address(stream, offset, 1))
1026 &&(*buffer++ = *(stream + offset++)))
1027 ;
1028}
1029
1030inline void safe_instruction_bytestream_count_char(U8 *stream, S32 &offset)
1031{
1032 while ( (safe_instruction_check_address(stream, offset, 1))
1033 &&(*(stream + offset++)))
1034 ;
1035}
1036
1037inline void safe_heap_bytestream_count_char(U8 *stream, S32 &offset)
1038{
1039 while ( (safe_heap_check_address(stream, offset, 1))
1040 &&(*(stream + offset++)))
1041 ;
1042}
1043
1044inline void safe_instruction_char2bytestream(U8 *stream, S32 &offset, char *buffer)
1045{
1046 while ( (safe_instruction_check_address(stream, offset, 1))
1047 &&(*(stream + offset++) = *buffer++))
1048 ;
1049}
1050
1051inline void safe_instruction_bytestream2vector(LLVector3 &value, U8 *stream, S32 &offset)
1052{
1053 if (safe_instruction_check_address(stream, offset, LSCRIPTDataSize[LST_VECTOR]))
1054 {
1055 bytestream2vector(value, stream, offset);
1056 }
1057}
1058
1059inline void safe_instruction_vector2bytestream(U8 *stream, S32 &offset, LLVector3 &value)
1060{
1061 if (safe_instruction_check_address(stream, offset, LSCRIPTDataSize[LST_VECTOR]))
1062 {
1063 vector2bytestream(stream, offset, value);
1064 }
1065}
1066
1067inline void safe_instruction_bytestream2quaternion(LLQuaternion &value, U8 *stream, S32 &offset)
1068{
1069 if (safe_instruction_check_address(stream, offset, LSCRIPTDataSize[LST_QUATERNION]))
1070 {
1071 bytestream2quaternion(value, stream, offset);
1072 }
1073}
1074
1075inline void safe_instruction_quaternion2bytestream(U8 *stream, S32 &offset, LLQuaternion &value)
1076{
1077 if (safe_instruction_check_address(stream, offset, LSCRIPTDataSize[LST_QUATERNION]))
1078 {
1079 quaternion2bytestream(stream, offset, value);
1080 }
1081}
1082
1083static inline LSCRIPTType char2type(char type)
1084{
1085 switch(type)
1086 {
1087 case 'i':
1088 return LST_INTEGER;
1089 case 'f':
1090 return LST_FLOATINGPOINT;
1091 case 's':
1092 return LST_STRING;
1093 case 'k':
1094 return LST_KEY;
1095 case 'v':
1096 return LST_VECTOR;
1097 case 'q':
1098 return LST_QUATERNION;
1099 case 'l':
1100 return LST_LIST;
1101 default:
1102 return LST_NULL;
1103 }
1104}
1105
1106#endif
diff --git a/linden/indra/lscript/lscript_byteformat.h b/linden/indra/lscript/lscript_byteformat.h
new file mode 100644
index 0000000..a69f1fe
--- /dev/null
+++ b/linden/indra/lscript/lscript_byteformat.h
@@ -0,0 +1,563 @@
1/**
2 * @file lscript_byteformat.h
3 * @brief Shared code between compiler and assembler and LSL
4 *
5 * Copyright (c) 2002-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28#ifndef LL_LSCRIPT_BYTEFORMAT_H
29#define LL_LSCRIPT_BYTEFORMAT_H
30
31// Data shared between compiler/assembler and lscript execution code
32
33#include "stdtypes.h"
34
35const S32 LSL2_VERSION_NUMBER = 0x0200;
36const S32 LSL2_VERSION1_END_NUMBER = 0x0101;
37const S32 LSL2_VERSION2_START_NUMBER = 0x0200;
38
39const S32 LSL2_MAJOR_VERSION_ONE = 1;
40const S32 LSL2_MAJOR_VERSION_TWO = 2;
41const S32 LSL2_CURRENT_MAJOR_VERSION = LSL2_MAJOR_VERSION_TWO;
42
43const S32 TOP_OF_MEMORY = 16384;
44
45typedef enum e_lscript_registers
46{
47 LREG_INVALID,
48 LREG_IP, // instruction pointer
49 LREG_VN, // version number
50 LREG_BP, // base pointer - what local variables are referenced from
51 LREG_SP, // stack pointer - where the top of the stack is
52 LREG_HR, // heap register - where in memory does the heap start
53 LREG_HP, // heap pointer - where is the top of the heap?
54 LREG_CS, // current state - what state are we currently in?
55 LREG_NS, // next state - what state are we currently in?
56 LREG_CE, // current events - what events are waiting to be handled?
57 LREG_IE, // in event - which event handler are we currently in?
58 LREG_ER, // event register - what events do we have active handlers for?
59 LREG_FR, // fault register - which errors are currently active?
60 LREG_SLR, // sleep register - are we sleeping?
61 LREG_GVR, // global variable register - where do global variables start
62 LREG_GFR, // global function register - where do global functions start
63 LREG_SR, // state register - where do states start
64 LREG_TM, // top of memory - where is the top of memory
65 LREG_PR, // parameter register - data passed to script from launcher
66 LREG_ESR, // energy supply register - how much energy do we have on board?
67 LREG_NCE, // 64 bit current envents - what events are waiting to be handled?
68 LREG_NIE, // 64 bit in event - which event handler are we currently in?
69 LREG_NER, // 64 bit event register - what events do we have active handlers for?
70 LREG_EOF
71} LSCRIPTRegisters;
72
73const S32 gLSCRIPTRegisterAddresses[LREG_EOF] =
74{
75 0, // LREG_INVALID
76 4, // LREG_IP
77 8, // LREG_VN
78 12, // LREG_BP
79 16, // LREG_SP
80 20, // LREG_HR
81 24, // LREG_HP
82 28, // LREG_CS
83 32, // LREG_NS
84 36, // LREG_CE
85 40, // LREG_IE
86 44, // LREG_ER
87 48, // LREG_FR
88 52, // LREG_SLR
89 56, // LREG_GVR
90 60, // LREG_GFR
91 72, // LREG_SR
92 0, // LREG_TM
93 64, // LREG_PR
94 68, // LREG_ESR
95 76, // LREG_NCE
96 84, // LREG_NIE
97 92, // LREG_NER
98};
99
100const char * const gLSCRIPTRegisterNames[LREG_EOF] =
101{
102 "INVALID", // LREG_INVALID
103 "IP", // LREG_IP
104 "VN", // LREG_VN
105 "BP", // LREG_BP
106 "SP", // LREG_SP
107 "HR", // LREG_HR
108 "HP", // LREG_HP
109 "CS", // LREG_CS
110 "NS", // LREG_NS
111 "CE", // LREG_CE
112 "IE", // LREG_IE
113 "ER", // LREG_ER
114 "FR", // LREG_FR
115 "SLR", // LREG_SLR
116 "GVR", // LREG_GVR
117 "GFR", // LREG_GFR
118 "SR", // LREG_SR
119 "TM", // LREG_TM
120 "PR", // LREG_PR
121 "ESR", // LREG_ESR
122 "NCE", // LREG_NCE
123 "NIE", // LREG_NIE
124 "NER", // LREG_NER
125};
126
127typedef enum e_lscript_op_codes
128{
129 LOPC_INVALID,
130 LOPC_NOOP,
131 LOPC_POP,
132 LOPC_POPS,
133 LOPC_POPL,
134 LOPC_POPV,
135 LOPC_POPQ,
136 LOPC_POPARG,
137 LOPC_POPIP,
138 LOPC_POPBP,
139 LOPC_POPSP,
140 LOPC_POPSLR,
141 LOPC_DUP,
142 LOPC_DUPS,
143 LOPC_DUPL,
144 LOPC_DUPV,
145 LOPC_DUPQ,
146 LOPC_STORE,
147 LOPC_STORES,
148 LOPC_STOREL,
149 LOPC_STOREV,
150 LOPC_STOREQ,
151 LOPC_STOREG,
152 LOPC_STOREGS,
153 LOPC_STOREGL,
154 LOPC_STOREGV,
155 LOPC_STOREGQ,
156 LOPC_LOADP,
157 LOPC_LOADSP,
158 LOPC_LOADLP,
159 LOPC_LOADVP,
160 LOPC_LOADQP,
161 LOPC_LOADGP,
162 LOPC_LOADGLP,
163 LOPC_LOADGSP,
164 LOPC_LOADGVP,
165 LOPC_LOADGQP,
166 LOPC_PUSH,
167 LOPC_PUSHS,
168 LOPC_PUSHL,
169 LOPC_PUSHV,
170 LOPC_PUSHQ,
171 LOPC_PUSHG,
172 LOPC_PUSHGS,
173 LOPC_PUSHGL,
174 LOPC_PUSHGV,
175 LOPC_PUSHGQ,
176 LOPC_PUSHIP,
177 LOPC_PUSHBP,
178 LOPC_PUSHSP,
179 LOPC_PUSHARGB,
180 LOPC_PUSHARGI,
181 LOPC_PUSHARGF,
182 LOPC_PUSHARGS,
183 LOPC_PUSHARGV,
184 LOPC_PUSHARGQ,
185 LOPC_PUSHE,
186 LOPC_PUSHEV,
187 LOPC_PUSHEQ,
188 LOPC_PUSHARGE,
189 LOPC_ADD,
190 LOPC_SUB,
191 LOPC_MUL,
192 LOPC_DIV,
193 LOPC_MOD,
194 LOPC_EQ,
195 LOPC_NEQ,
196 LOPC_LEQ,
197 LOPC_GEQ,
198 LOPC_LESS,
199 LOPC_GREATER,
200 LOPC_BITAND,
201 LOPC_BITOR,
202 LOPC_BITXOR,
203 LOPC_BOOLAND,
204 LOPC_BOOLOR,
205 LOPC_NEG,
206 LOPC_BITNOT,
207 LOPC_BOOLNOT,
208 LOPC_JUMP,
209 LOPC_JUMPIF,
210 LOPC_JUMPNIF,
211 LOPC_STATE,
212 LOPC_CALL,
213 LOPC_RETURN,
214 LOPC_CAST,
215 LOPC_STACKTOS,
216 LOPC_STACKTOL,
217 LOPC_PRINT,
218 LOPC_CALLLIB,
219 LOPC_CALLLIB_TWO_BYTE,
220 LOPC_SHL,
221 LOPC_SHR,
222 LOPC_EOF
223} LSCRIPTOpCodesEnum;
224
225const U8 LSCRIPTOpCodes[LOPC_EOF] =
226{
227 0x00, // LOPC_INVALID
228 0x00, // LOPC_NOOP
229 0x01, // LOPC_POP
230 0x02, // LOPC_POPS
231 0x03, // LOPC_POPL
232 0x04, // LOPC_POPV
233 0x05, // LOPC_POPQ
234 0x06, // LOPC_POPARG
235 0x07, // LOPC_POPIP
236 0x08, // LOPC_POPBP
237 0x09, // LOPC_POPSP
238 0x0a, // LOPC_POPSLR
239 0x20, // LOPC_DUP
240 0x21, // LOPC_DUPS
241 0x22, // LOPC_DUPL
242 0x23, // LOPC_DUPV
243 0x24, // LOPC_DUPQ
244 0x30, // LOPC_STORE
245 0x31, // LOPC_STORES
246 0x32, // LOPC_STOREL
247 0x33, // LOPC_STOREV
248 0x34, // LOPC_STOREQ
249 0x35, // LOPC_STOREG
250 0x36, // LOPC_STOREGS
251 0x37, // LOPC_STOREGL
252 0x38, // LOPC_STOREGV
253 0x39, // LOPC_STOREGQ
254 0x3a, // LOPC_LOADP
255 0x3b, // LOPC_LOADSP
256 0x3c, // LOPC_LOADLP
257 0x3d, // LOPC_LOADVP
258 0x3e, // LOPC_LOADQP
259 0x3f, // LOPC_LOADGP
260 0x40, // LOPC_LOADGSP
261 0x41, // LOPC_LOADGLP
262 0x42, // LOPC_LOADGVP
263 0x43, // LOPC_LOADGQP
264 0x50, // LOPC_PUSH
265 0x51, // LOPC_PUSHS
266 0x52, // LOPC_PUSHL
267 0x53, // LOPC_PUSHV
268 0x54, // LOPC_PUSHQ
269 0x55, // LOPC_PUSHG
270 0x56, // LOPC_PUSHGS
271 0x57, // LOPC_PUSHGL
272 0x58, // LOPC_PUSHGV
273 0x59, // LOPC_PUSHGQ
274 0x5a, // LOPC_PUSHIP
275 0x5b, // LOPC_PUSHBP
276 0x5c, // LOPC_PUSHSP
277 0x5d, // LOPC_PUSHARGB
278 0x5e, // LOPC_PUSHARGI
279 0x5f, // LOPC_PUSHARGF
280 0x60, // LOPC_PUSHARGS
281 0x61, // LOPC_PUSHARGV
282 0x62, // LOPC_PUSHARGQ
283 0x63, // LOPC_PUSHE
284 0x64, // LOPC_PUSHEV
285 0x65, // LOPC_PUSHEQ
286 0x66, // LOPC_PUSHARGE
287 0x70, // LOPC_ADD
288 0x71, // LOPC_SUB
289 0x72, // LOPC_MUL
290 0x73, // LOPC_DIV
291 0x74, // LOPC_MOD
292 0x75, // LOPC_EQ
293 0x76, // LOPC_NEQ
294 0x77, // LOPC_LEQ
295 0x78, // LOPC_GEQ
296 0x79, // LOPC_LESS
297 0x7a, // LOPC_GREATER
298 0x7b, // LOPC_BITAND
299 0x7c, // LOPC_BITOR
300 0x7d, // LOPC_BITXOR
301 0x7e, // LOPC_BOOLAND
302 0x7f, // LOPC_BOOLOR
303 0x80, // LOPC_NEG
304 0x81, // LOPC_BITNOT
305 0x82, // LOPC_BOOLNOT
306 0x90, // LOPC_JUMP
307 0x91, // LOPC_JUMPIF
308 0x92, // LOPC_JUMPNIF
309 0x93, // LOPC_STATE
310 0x94, // LOPC_CALL
311 0x95, // LOPC_RETURN
312 0xa0, // LOPC_CAST
313 0xb0, // LOPC_STACKTOS
314 0xb1, // LOPC_STACKTOL
315 0xc0, // LOPC_PRINT
316 0xd0, // LOPC_CALLLIB
317 0xd1, // LOPC_CALLLIB_TWO_BYTE
318 0xe0, // LOPC_SHL
319 0xe1 // LOPC_SHR
320};
321
322typedef enum e_lscript_state_event_type
323{
324 LSTT_NULL,
325 LSTT_STATE_ENTRY,
326 LSTT_STATE_EXIT,
327 LSTT_TOUCH_START,
328 LSTT_TOUCH,
329 LSTT_TOUCH_END,
330 LSTT_COLLISION_START,
331 LSTT_COLLISION,
332 LSTT_COLLISION_END,
333 LSTT_LAND_COLLISION_START,
334 LSTT_LAND_COLLISION,
335 LSTT_LAND_COLLISION_END,
336 LSTT_TIMER,
337 LSTT_CHAT,
338 LSTT_REZ,
339 LSTT_SENSOR,
340 LSTT_NO_SENSOR,
341 LSTT_CONTROL,
342 LSTT_MONEY,
343 LSTT_EMAIL,
344 LSTT_AT_TARGET,
345 LSTT_NOT_AT_TARGET,
346 LSTT_AT_ROT_TARGET,
347 LSTT_NOT_AT_ROT_TARGET,
348 LSTT_RTPERMISSIONS,
349 LSTT_INVENTORY,
350 LSTT_ATTACH,
351 LSTT_DATASERVER,
352 LSTT_LINK_MESSAGE,
353 LSTT_MOVING_START,
354 LSTT_MOVING_END,
355 LSTT_OBJECT_REZ,
356 LSTT_REMOTE_DATA,
357 LSTT_HTTP_RESPONSE,
358 LSTT_EOF,
359
360 LSTT_STATE_BEGIN = LSTT_STATE_ENTRY,
361 LSTT_STATE_END = LSTT_EOF
362} LSCRIPTStateEventType;
363
364const U64 LSCRIPTStateBitField[LSTT_EOF] =
365{
366 0x0000000000000000, // LSTT_NULL
367 0x0000000000000001, // LSTT_STATE_ENTRY
368 0x0000000000000002, // LSTT_STATE_EXIT
369 0x0000000000000004, // LSTT_TOUCH_START
370 0x0000000000000008, // LSTT_TOUCH
371 0x0000000000000010, // LSTT_TOUCH_END
372 0x0000000000000020, // LSTT_COLLISION_START
373 0x0000000000000040, // LSTT_COLLISION
374 0x0000000000000080, // LSTT_COLLISION_END
375 0x0000000000000100, // LSTT_LAND_COLLISION_START
376 0x0000000000000200, // LSTT_LAND_COLLISION
377 0x0000000000000400, // LSTT_LAND_COLLISION_END
378 0x0000000000000800, // LSTT_TIMER
379 0x0000000000001000, // LSTT_CHAT
380 0x0000000000002000, // LSTT_REZ
381 0x0000000000004000, // LSTT_SENSOR
382 0x0000000000008000, // LSTT_NO_SENSOR
383 0x0000000000010000, // LSTT_CONTROL
384 0x0000000000020000, // LSTT_MONEY
385 0x0000000000040000, // LSTT_EMAIL
386 0x0000000000080000, // LSTT_AT_TARGET
387 0x0000000000100000, // LSTT_NOT_AT_TARGET
388 0x0000000000200000, // LSTT_AT_ROT_TARGET
389 0x0000000000400000, // LSTT_NOT_AT_ROT_TARGET
390 0x0000000000800000, // LSTT_RTPERMISSIONS
391 0x0000000001000000, // LSTT_INVENTORY
392 0x0000000002000000, // LSTT_ATTACH
393 0x0000000004000000, // LSTT_DATASERVER
394 0x0000000008000000, // LSTT_LINK_MESSAGE
395 0x0000000010000000, // LSTT_MOVING_START
396 0x0000000020000000, // LSTT_MOVING_END
397 0x0000000040000000, // LSTT_OBJECT_REZ
398 0x0000000080000000, // LSTT_REMOTE_DATA
399 0x0000000100000000LL // LSTT_HTTP_RESPOSE
400};
401
402inline S32 get_event_handler_jump_position(U64 bit_field, LSCRIPTStateEventType type)
403{
404 S32 count = 0, position = LSTT_STATE_ENTRY;
405 while (position < type)
406 {
407 if (bit_field & 0x1)
408 {
409 count++;
410 }
411 bit_field >>= 1;
412 position++;
413 }
414 return count;
415}
416
417inline S32 get_number_of_event_handlers(U64 bit_field)
418{
419 S32 count = 0, position = 0;
420 while (position < LSTT_EOF)
421 {
422 if (bit_field & 0x1)
423 {
424 count++;
425 }
426 bit_field >>= 1;
427 position++;
428 }
429 return count;
430}
431
432typedef enum e_lscript_types
433{
434 LST_NULL,
435 LST_INTEGER,
436 LST_FLOATINGPOINT,
437 LST_STRING,
438 LST_KEY,
439 LST_VECTOR,
440 LST_QUATERNION,
441 LST_LIST,
442 LST_UNDEFINED,
443 LST_EOF
444} LSCRIPTType;
445
446const U8 LSCRIPTTypeByte[LST_EOF] =
447{
448 LST_NULL,
449 LST_INTEGER,
450 LST_FLOATINGPOINT,
451 LST_STRING,
452 LST_KEY,
453 LST_VECTOR,
454 LST_QUATERNION,
455 LST_LIST,
456 LST_NULL,
457};
458
459const U8 LSCRIPTTypeHi4Bits[LST_EOF] =
460{
461 LST_NULL,
462 LST_INTEGER << 4,
463 LST_FLOATINGPOINT << 4,
464 LST_STRING << 4,
465 LST_KEY << 4,
466 LST_VECTOR << 4,
467 LST_QUATERNION << 4,
468 LST_LIST << 4,
469};
470
471const char * const LSCRIPTTypeNames[LST_EOF] =
472{
473 "VOID",
474 "integer",
475 "float",
476 "string",
477 "key",
478 "vector",
479 "quaternion",
480 "list",
481 "invalid"
482};
483
484const S32 LSCRIPTDataSize[LST_EOF] =
485{
486 0, // VOID
487 4, // integer
488 4, // float
489 4, // string
490 4, // key
491 12, // vector
492 16, // quaternion
493 4, // list
494 0 // invalid
495};
496
497
498typedef enum e_lscript_runtime_faults
499{
500 LSRF_INVALID,
501 LSRF_MATH,
502 LSRF_STACK_HEAP_COLLISION,
503 LSRF_BOUND_CHECK_ERROR,
504 LSRF_HEAP_ERROR,
505 LSRF_VERSION_MISMATCH,
506 LSRF_MISSING_INVENTORY,
507 LSRF_SANDBOX,
508 LSRF_CHAT_OVERRUN,
509 LSRF_TOO_MANY_LISTENS,
510 LSRF_NESTING_LISTS,
511 LSRF_EOF
512} LSCRIPTRunTimeFaults;
513
514extern char *LSCRIPTRunTimeFaultStrings[LSRF_EOF];
515
516const S32 LSCRIPTRunTimeFaultBits[LSRF_EOF] =
517{
518 0, // LSRF_INVALID
519 1, // LSRF_MATH
520 2, // LSRF_STACK_HEAP_COLLISION
521 3, // LSREF_BOUND_CHECK_ERROR
522 4, // LSREF_HEAP_ERROR
523 5, // LSREF_VERSION_MISMATCH
524 6, // LSREF_MISSING_INVENTORY
525 7, // LSRF_SANDBOX
526 8, // LSRF_CHAT_OVERRUN
527 9, // LSRF_TOO_MANY_LISTENS
528 10, // LSRF_NESTING_LISTS
529};
530
531typedef enum e_lscript_runtime_permissions
532{
533 SCRIPT_PERMISSION_DEBIT,
534 SCRIPT_PERMISSION_TAKE_CONTROLS,
535 SCRIPT_PERMISSION_REMAP_CONTROLS,
536 SCRIPT_PERMISSION_TRIGGER_ANIMATION,
537 SCRIPT_PERMISSION_ATTACH,
538 SCRIPT_PERMISSION_RELEASE_OWNERSHIP,
539 SCRIPT_PERMISSION_CHANGE_LINKS,
540 SCRIPT_PERMISSION_CHANGE_JOINTS,
541 SCRIPT_PERMISSION_CHANGE_PERMISSIONS,
542 SCRIPT_PERMISSION_TRACK_CAMERA,
543 SCRIPT_PERMISSION_CONTROL_CAMERA,
544 SCRIPT_PERMISSION_EOF
545} LSCRIPTRunTimePermissions;
546
547const U32 LSCRIPTRunTimePermissionBits[SCRIPT_PERMISSION_EOF] =
548{
549 (0x1 << 1), // SCRIPT_PERMISSION_DEBIT,
550 (0x1 << 2), // SCRIPT_PERMISSION_TAKE_CONTROLS,
551 (0x1 << 3), // SCRIPT_PERMISSION_REMAP_CONTROLS,
552 (0x1 << 4), // SCRIPT_PERMISSION_TRIGGER_ANIMATION,
553 (0x1 << 5), // SCRIPT_PERMISSION_ATTACH,
554 (0x1 << 6), // SCRIPT_PERMISSION_RELEASE_OWNERSHIP,
555 (0x1 << 7), // SCRIPT_PERMISSION_CHANGE_LINKS,
556 (0x1 << 8), // SCRIPT_PERMISSION_CHANGE_JOINTS,
557 (0x1 << 9), // SCRIPT_PERMISSION_CHANGE_PERMISSIONS
558 (0x1 << 10),// SCRIPT_PERMISSION_TRACK_CAMERA
559 (0x1 << 11),// SCRIPT_PERMISSION_CONTROL_CAMERA
560};
561
562#endif
563
diff --git a/linden/indra/lscript/lscript_compile/indra.l b/linden/indra/lscript/lscript_compile/indra.l
new file mode 100644
index 0000000..1290018
--- /dev/null
+++ b/linden/indra/lscript/lscript_compile/indra.l
@@ -0,0 +1,834 @@
1D [-]?[0-9]
2N [0-9]
3L [a-zA-Z_]
4H [a-fA-F0-9]
5E [Ee][+-]?{D}+
6FS (f|F)
7%e 8000
8%n 4000
9%p 5000
10
11%{
12#include <stdio.h>
13#include "stdtypes.h"
14#include "llmath.h"
15#include "lscript_tree.h"
16#include "lscript_typecheck.h"
17#include "lscript_resource.h"
18#include "llfile.h"
19#if LL_WINDOWS
20#include "ytab.h"
21#else
22#include "indra.y.h"
23#endif
24#include "lltimer.h"
25#include "indra_constants.h"
26#include "llagentconstants.h"
27#include "lllslconstants.h"
28#include "lluuid.h"
29#include "llassetstorage.h"
30#include "llpartdata.h"
31#include "llvehicleparams.h"
32#include "llpermissionsflags.h"
33#include "llfollowcamparams.h"
34#include "llparcelflags.h"
35#include "llregionflags.h"
36#include "lscript_http.h"
37
38void count();
39void comment();
40void parse_string();
41
42#define YYLMAX 16384
43#define YY_NEVER_INTERACTIVE 1 /* stops flex from calling isatty() */
44
45#if defined(__cplusplus)
46extern "C" { int yylex( void ); }
47extern "C" { int yyparse( void ); }
48extern "C" { int yyerror(const char *fmt, ...); }
49#endif
50
51%}
52
53%%
54"//" { gInternalLine++; gInternalColumn = 0; comment(); }
55
56"integer" { count(); return(INTEGER); }
57"float" { count(); return(FLOAT_TYPE); }
58"string" { count(); return(STRING); }
59"key" { count(); return(LLKEY); }
60"vector" { count(); return(VECTOR); }
61"quaternion" { count(); return(QUATERNION); }
62"rotation" { count(); return(QUATERNION); }
63"list" { count(); return(LIST); }
64
65"default" { count(); yylval.sval = new char[strlen(yytext) + 1]; strcpy(yylval.sval, yytext); return(STATE_DEFAULT); }
66"state" { count(); return(STATE); }
67"event" { count(); return(EVENT); }
68"jump" { count(); return(JUMP); }
69"return" { count(); return(RETURN); }
70"if" { count(); return(IF); }
71"else" { count(); return(ELSE); }
72"for" { count(); return(FOR); }
73"do" { count(); return(DO); }
74"while" { count(); return(WHILE); }
75
76"state_entry" { count(); return(STATE_ENTRY); }
77"state_exit" { count(); return(STATE_EXIT); }
78"touch_start" { count(); return(TOUCH_START); }
79"touch" { count(); return(TOUCH); }
80"touch_end" { count(); return(TOUCH_END); }
81"collision_start" { count(); return(COLLISION_START); }
82"collision" { count(); return(COLLISION); }
83"collision_end" { count(); return(COLLISION_END); }
84"land_collision_start" { count(); return(LAND_COLLISION_START); }
85"land_collision" { count(); return(LAND_COLLISION); }
86"land_collision_end" { count(); return(LAND_COLLISION_END); }
87"timer" { count(); return(TIMER); }
88"listen" { count(); return(CHAT); }
89"sensor" { count(); return(SENSOR); }
90"no_sensor" { count(); return(NO_SENSOR); }
91"control" { count(); return(CONTROL); }
92"print" { count(); return(PRINT); }
93"at_target" { count(); return(AT_TARGET); }
94"not_at_target" { count(); return(NOT_AT_TARGET); }
95"at_rot_target" { count(); return(AT_ROT_TARGET); }
96"not_at_rot_target" { count(); return(NOT_AT_ROT_TARGET); }
97"money" { count(); return(MONEY); }
98"email" { count(); return(EMAIL); }
99"run_time_permissions" { count(); return(RUN_TIME_PERMISSIONS); }
100"changed" { count(); return(INVENTORY); }
101"attach" { count(); return(ATTACH); }
102"dataserver" { count(); return(DATASERVER); }
103"moving_start" { count(); return(MOVING_START); }
104"moving_end" { count(); return(MOVING_END); }
105"link_message" { count(); return(LINK_MESSAGE); }
106"on_rez" { count(); return(REZ); }
107"object_rez" { count(); return(OBJECT_REZ); }
108"remote_data" { count(); return(REMOTE_DATA); }
109"http_response" { count(); return(HTTP_RESPONSE); }
110"." { count(); return(PERIOD); }
111
112
1130[xX]{H}+ { count(); yylval.ival = strtoul(yytext, NULL, 0); return(INTEGER_CONSTANT); }
114{D}+ { count(); yylval.ival = strtoul(yytext, NULL, 10); return(INTEGER_CONSTANT); }
115"TRUE" { count(); yylval.ival = 1; return(INTEGER_TRUE); }
116"FALSE" { count(); yylval.ival = 0; return(INTEGER_FALSE); }
117"STATUS_PHYSICS" { count(); yylval.ival = 0x1; return(INTEGER_CONSTANT); }
118"STATUS_ROTATE_X" { count(); yylval.ival = 0x2; return(INTEGER_CONSTANT); }
119"STATUS_ROTATE_Y" { count(); yylval.ival = 0x4; return(INTEGER_CONSTANT); }
120"STATUS_ROTATE_Z" { count(); yylval.ival = 0x8; return(INTEGER_CONSTANT); }
121"STATUS_PHANTOM" { count(); yylval.ival = 0x10; return(INTEGER_CONSTANT); }
122"STATUS_SANDBOX" { count(); yylval.ival = 0x20; return(INTEGER_CONSTANT); }
123"STATUS_BLOCK_GRAB" { count(); yylval.ival = 0x40; return(INTEGER_CONSTANT); }
124"STATUS_DIE_AT_EDGE" { count(); yylval.ival = 0x80; return(INTEGER_CONSTANT); }
125"STATUS_RETURN_AT_EDGE" { count(); yylval.ival = 0x100; return(INTEGER_CONSTANT); }
126"STATUS_CAST_SHADOWS" { count(); yylval.ival = 0x200; return(INTEGER_CONSTANT); }
127
128"AGENT_FLYING" { count(); yylval.ival = AGENT_FLYING; return(INTEGER_CONSTANT); }
129"AGENT_ATTACHMENTS" { count(); yylval.ival = AGENT_ATTACHMENTS; return(INTEGER_CONSTANT); }
130"AGENT_SCRIPTED" { count(); yylval.ival = AGENT_SCRIPTED; return(INTEGER_CONSTANT); }
131"AGENT_MOUSELOOK" { count(); yylval.ival = AGENT_MOUSELOOK; return(INTEGER_CONSTANT); }
132"AGENT_SITTING" { count(); yylval.ival = AGENT_SITTING; return(INTEGER_CONSTANT); }
133"AGENT_ON_OBJECT" { count(); yylval.ival = AGENT_ON_OBJECT; return(INTEGER_CONSTANT); }
134"AGENT_AWAY" { count(); yylval.ival = AGENT_AWAY; return(INTEGER_CONSTANT); }
135"AGENT_WALKING" { count(); yylval.ival = AGENT_WALKING; return(INTEGER_CONSTANT); }
136"AGENT_IN_AIR" { count(); yylval.ival = AGENT_IN_AIR; return(INTEGER_CONSTANT); }
137"AGENT_TYPING" { count(); yylval.ival = AGENT_TYPING; return(INTEGER_CONSTANT); }
138"AGENT_CROUCHING" { count(); yylval.ival = AGENT_CROUCHING; return(INTEGER_CONSTANT); }
139"AGENT_BUSY" { count(); yylval.ival = AGENT_BUSY; return(INTEGER_CONSTANT); }
140"AGENT_ALWAYS_RUN" { count(); yylval.ival = AGENT_ALWAYS_RUN; return(INTEGER_CONSTANT); }
141
142"CAMERA_PITCH" { count(); yylval.ival = FOLLOWCAM_PITCH; return(INTEGER_CONSTANT); }
143"CAMERA_FOCUS_OFFSET" { count(); yylval.ival = FOLLOWCAM_FOCUS_OFFSET; return (INTEGER_CONSTANT); }
144"CAMERA_POSITION_LAG" { count(); yylval.ival = FOLLOWCAM_POSITION_LAG; return (INTEGER_CONSTANT); }
145"CAMERA_FOCUS_LAG" { count(); yylval.ival = FOLLOWCAM_FOCUS_LAG; return (INTEGER_CONSTANT); }
146"CAMERA_DISTANCE" { count(); yylval.ival = FOLLOWCAM_DISTANCE; return (INTEGER_CONSTANT); }
147"CAMERA_BEHINDNESS_ANGLE" { count(); yylval.ival = FOLLOWCAM_BEHINDNESS_ANGLE; return (INTEGER_CONSTANT); }
148"CAMERA_BEHINDNESS_LAG" { count(); yylval.ival = FOLLOWCAM_BEHINDNESS_LAG; return (INTEGER_CONSTANT); }
149"CAMERA_POSITION_THRESHOLD" { count(); yylval.ival = FOLLOWCAM_POSITION_THRESHOLD; return (INTEGER_CONSTANT); }
150"CAMERA_FOCUS_THRESHOLD" { count(); yylval.ival = FOLLOWCAM_FOCUS_THRESHOLD; return (INTEGER_CONSTANT); }
151"CAMERA_ACTIVE" { count(); yylval.ival = FOLLOWCAM_ACTIVE; return (INTEGER_CONSTANT); }
152"CAMERA_POSITION" { count(); yylval.ival = FOLLOWCAM_POSITION; return (INTEGER_CONSTANT); }
153"CAMERA_FOCUS" { count(); yylval.ival = FOLLOWCAM_FOCUS; return (INTEGER_CONSTANT); }
154"CAMERA_POSITION_LOCKED" { count(); yylval.ival = FOLLOWCAM_POSITION_LOCKED; return (INTEGER_CONSTANT); }
155"CAMERA_FOCUS_LOCKED" { count(); yylval.ival = FOLLOWCAM_FOCUS_LOCKED; return (INTEGER_CONSTANT); }
156
157"ANIM_ON" { count(); yylval.ival = 0x1; return(INTEGER_CONSTANT); }
158"LOOP" { count(); yylval.ival = 0x2; return(INTEGER_CONSTANT); }
159"REVERSE" { count(); yylval.ival = 0x4; return(INTEGER_CONSTANT); }
160"PING_PONG" { count(); yylval.ival = 0x8; return(INTEGER_CONSTANT); }
161"SMOOTH" { count(); yylval.ival = 0x10; return(INTEGER_CONSTANT); }
162"ROTATE" { count(); yylval.ival = 0x20; return(INTEGER_CONSTANT); }
163"SCALE" { count(); yylval.ival = 0x40; return(INTEGER_CONSTANT); }
164
165"ALL_SIDES" { count(); yylval.ival = LSL_ALL_SIDES; return(INTEGER_CONSTANT); }
166"LINK_ROOT" { count(); yylval.ival = LSL_LINK_ROOT; return(INTEGER_CONSTANT); }
167"LINK_SET" { count(); yylval.ival = LSL_LINK_SET; return(INTEGER_CONSTANT); }
168"LINK_ALL_OTHERS" { count(); yylval.ival = LSL_LINK_ALL_OTHERS; return(INTEGER_CONSTANT); }
169"LINK_ALL_CHILDREN" { count(); yylval.ival = LSL_LINK_ALL_CHILDREN; return(INTEGER_CONSTANT); }
170"LINK_THIS" { count(); yylval.ival = LSL_LINK_THIS; return(INTEGER_CONSTANT); }
171
172"AGENT" { count(); yylval.ival = 0x1; return(INTEGER_CONSTANT); }
173"ACTIVE" { count(); yylval.ival = 0x2; return(INTEGER_CONSTANT); }
174"PASSIVE" { count(); yylval.ival = 0x4; return(INTEGER_CONSTANT); }
175"SCRIPTED" { count(); yylval.ival = 0x8; return(INTEGER_CONSTANT); }
176
177"CONTROL_FWD" { count(); yylval.ival = AGENT_CONTROL_AT_POS; return(INTEGER_CONSTANT); }
178"CONTROL_BACK" { count(); yylval.ival = AGENT_CONTROL_AT_NEG; return(INTEGER_CONSTANT); }
179"CONTROL_LEFT" { count(); yylval.ival = AGENT_CONTROL_LEFT_POS; return(INTEGER_CONSTANT); }
180"CONTROL_RIGHT" { count(); yylval.ival = AGENT_CONTROL_LEFT_NEG; return(INTEGER_CONSTANT); }
181"CONTROL_ROT_LEFT" { count(); yylval.ival = AGENT_CONTROL_YAW_POS; return(INTEGER_CONSTANT); }
182"CONTROL_ROT_RIGHT" { count(); yylval.ival = AGENT_CONTROL_YAW_NEG; return(INTEGER_CONSTANT); }
183"CONTROL_UP" { count(); yylval.ival = AGENT_CONTROL_UP_POS; return(INTEGER_CONSTANT); }
184"CONTROL_DOWN" { count(); yylval.ival = AGENT_CONTROL_UP_NEG; return(INTEGER_CONSTANT); }
185"CONTROL_LBUTTON" { count(); yylval.ival = AGENT_CONTROL_LBUTTON_DOWN; return(INTEGER_CONSTANT); }
186"CONTROL_ML_LBUTTON" { count(); yylval.ival = AGENT_CONTROL_ML_LBUTTON_DOWN; return(INTEGER_CONSTANT); }
187
188"PERMISSION_DEBIT" { count(); yylval.ival = LSCRIPTRunTimePermissionBits[SCRIPT_PERMISSION_DEBIT]; return(INTEGER_CONSTANT); }
189"PERMISSION_TAKE_CONTROLS" { count(); yylval.ival = LSCRIPTRunTimePermissionBits[SCRIPT_PERMISSION_TAKE_CONTROLS]; return(INTEGER_CONSTANT); }
190"PERMISSION_REMAP_CONTROLS" { count(); yylval.ival = LSCRIPTRunTimePermissionBits[SCRIPT_PERMISSION_REMAP_CONTROLS]; return(INTEGER_CONSTANT); }
191"PERMISSION_TRIGGER_ANIMATION" { count(); yylval.ival = LSCRIPTRunTimePermissionBits[SCRIPT_PERMISSION_TRIGGER_ANIMATION]; return(INTEGER_CONSTANT); }
192"PERMISSION_ATTACH" { count(); yylval.ival = LSCRIPTRunTimePermissionBits[SCRIPT_PERMISSION_ATTACH]; return(INTEGER_CONSTANT); }
193"PERMISSION_RELEASE_OWNERSHIP" { count(); yylval.ival = LSCRIPTRunTimePermissionBits[SCRIPT_PERMISSION_RELEASE_OWNERSHIP]; return(INTEGER_CONSTANT); }
194"PERMISSION_CHANGE_LINKS" { count(); yylval.ival = LSCRIPTRunTimePermissionBits[SCRIPT_PERMISSION_CHANGE_LINKS]; return(INTEGER_CONSTANT); }
195"PERMISSION_CHANGE_JOINTS" { count(); yylval.ival = LSCRIPTRunTimePermissionBits[SCRIPT_PERMISSION_CHANGE_JOINTS]; return(INTEGER_CONSTANT); }
196"PERMISSION_CHANGE_PERMISSIONS" { count(); yylval.ival = LSCRIPTRunTimePermissionBits[SCRIPT_PERMISSION_CHANGE_PERMISSIONS]; return(INTEGER_CONSTANT); }
197"PERMISSION_TRACK_CAMERA" { count(); yylval.ival = LSCRIPTRunTimePermissionBits[SCRIPT_PERMISSION_TRACK_CAMERA]; return(INTEGER_CONSTANT); }
198"PERMISSION_CONTROL_CAMERA" { count(); yylval.ival = LSCRIPTRunTimePermissionBits[SCRIPT_PERMISSION_CONTROL_CAMERA]; return(INTEGER_CONSTANT); }
199
200"INVENTORY_TEXTURE" { count(); yylval.ival = LLAssetType::AT_TEXTURE; return(INTEGER_CONSTANT); }
201"INVENTORY_SOUND" { count(); yylval.ival = LLAssetType::AT_SOUND; return(INTEGER_CONSTANT); }
202"INVENTORY_OBJECT" { count(); yylval.ival = LLAssetType::AT_OBJECT; return(INTEGER_CONSTANT); }
203"INVENTORY_SCRIPT" { count(); yylval.ival = LLAssetType::AT_LSL_TEXT; return(INTEGER_CONSTANT); }
204"INVENTORY_LANDMARK" { count(); yylval.ival = LLAssetType::AT_LANDMARK; return(INTEGER_CONSTANT); }
205"INVENTORY_CLOTHING" { count(); yylval.ival = LLAssetType::AT_CLOTHING; return(INTEGER_CONSTANT); }
206"INVENTORY_NOTECARD" { count(); yylval.ival = LLAssetType::AT_NOTECARD; return(INTEGER_CONSTANT); }
207"INVENTORY_BODYPART" { count(); yylval.ival = LLAssetType::AT_BODYPART; return(INTEGER_CONSTANT); }
208"INVENTORY_ANIMATION" { count(); yylval.ival = LLAssetType::AT_ANIMATION; return(INTEGER_CONSTANT); }
209"INVENTORY_GESTURE" { count(); yylval.ival = LLAssetType::AT_GESTURE; return(INTEGER_CONSTANT); }
210"INVENTORY_ALL" { count(); yylval.ival = LLAssetType::AT_NONE; return(INTEGER_CONSTANT); }
211"INVENTORY_NONE" { count(); yylval.ival = LLAssetType::AT_NONE; return(INTEGER_CONSTANT); }
212
213"CHANGED_INVENTORY" { count(); yylval.ival = 0x1; return(INTEGER_CONSTANT); }
214"CHANGED_COLOR" { count(); yylval.ival = 0x2; return(INTEGER_CONSTANT); }
215"CHANGED_SHAPE" { count(); yylval.ival = 0x4; return(INTEGER_CONSTANT); }
216"CHANGED_SCALE" { count(); yylval.ival = 0x8; return(INTEGER_CONSTANT); }
217"CHANGED_TEXTURE" { count(); yylval.ival = 0x10; return(INTEGER_CONSTANT); }
218"CHANGED_LINK" { count(); yylval.ival = 0x20; return(INTEGER_CONSTANT); }
219"CHANGED_ALLOWED_DROP" { count(); yylval.ival = 0x40; return(INTEGER_CONSTANT); }
220"CHANGED_OWNER" { count(); yylval.ival = 0x80; return(INTEGER_CONSTANT); }
221"CHANGED_REGION" { count(); yylval.ival = 0x100; return(INTEGER_CONSTANT); }
222"CHANGED_TELEPORT" { count(); yylval.ival = 0x200; return(INTEGER_CONSTANT); }
223
224"TYPE_INTEGER" { count(); yylval.ival = LST_INTEGER; return(INTEGER_CONSTANT); }
225"TYPE_FLOAT" { count(); yylval.ival = LST_FLOATINGPOINT; return(INTEGER_CONSTANT); }
226"TYPE_STRING" { count(); yylval.ival = LST_STRING; return(INTEGER_CONSTANT); }
227"TYPE_KEY" { count(); yylval.ival = LST_KEY; return(INTEGER_CONSTANT); }
228"TYPE_VECTOR" { count(); yylval.ival = LST_VECTOR; return(INTEGER_CONSTANT); }
229"TYPE_ROTATION" { count(); yylval.ival = LST_QUATERNION; return(INTEGER_CONSTANT); }
230"TYPE_INVALID" { count(); yylval.ival = LST_NULL; return(INTEGER_CONSTANT); }
231
232"NULL_KEY" { yylval.sval = new char[UUID_STR_LENGTH]; strcpy(yylval.sval, "00000000-0000-0000-0000-000000000000"); return(STRING_CONSTANT); }
233"EOF" { yylval.sval = new char[UUID_STR_LENGTH]; strcpy(yylval.sval, "\n\n\n"); return(STRING_CONSTANT); }
234
235"PI" { count(); yylval.fval = F_PI; return(FP_CONSTANT); }
236"TWO_PI" { count(); yylval.fval = F_TWO_PI; return(FP_CONSTANT); }
237"PI_BY_TWO" { count(); yylval.fval = F_PI_BY_TWO; return(FP_CONSTANT); }
238"DEG_TO_RAD" { count(); yylval.fval = DEG_TO_RAD; return(FP_CONSTANT); }
239"RAD_TO_DEG" { count(); yylval.fval = RAD_TO_DEG; return(FP_CONSTANT); }
240"SQRT2" { count(); yylval.fval = F_SQRT2; return(FP_CONSTANT); }
241
242"DEBUG_CHANNEL" { count(); yylval.ival = CHAT_CHANNEL_DEBUG; return(INTEGER_CONSTANT); }
243"PUBLIC_CHANNEL" { count(); yylval.ival = 0; return(INTEGER_CONSTANT); }
244
245"ZERO_VECTOR" { count(); return(ZERO_VECTOR); }
246"ZERO_ROTATION" { count(); return(ZERO_ROTATION); }
247
248"ATTACH_CHEST" { count(); yylval.ival = 1; return(INTEGER_CONSTANT); }
249"ATTACH_HEAD" { count(); yylval.ival = 2; return(INTEGER_CONSTANT); }
250"ATTACH_LSHOULDER" { count(); yylval.ival = 3; return(INTEGER_CONSTANT); }
251"ATTACH_RSHOULDER" { count(); yylval.ival = 4; return(INTEGER_CONSTANT); }
252"ATTACH_LHAND" { count(); yylval.ival = 5; return(INTEGER_CONSTANT); }
253"ATTACH_RHAND" { count(); yylval.ival = 6; return(INTEGER_CONSTANT); }
254"ATTACH_LFOOT" { count(); yylval.ival = 7; return(INTEGER_CONSTANT); }
255"ATTACH_RFOOT" { count(); yylval.ival = 8; return(INTEGER_CONSTANT); }
256"ATTACH_BACK" { count(); yylval.ival = 9; return(INTEGER_CONSTANT); }
257"ATTACH_PELVIS" { count(); yylval.ival = 10; return(INTEGER_CONSTANT); }
258"ATTACH_MOUTH" { count(); yylval.ival = 11; return(INTEGER_CONSTANT); }
259"ATTACH_CHIN" { count(); yylval.ival = 12; return(INTEGER_CONSTANT); }
260"ATTACH_LEAR" { count(); yylval.ival = 13; return(INTEGER_CONSTANT); }
261"ATTACH_REAR" { count(); yylval.ival = 14; return(INTEGER_CONSTANT); }
262"ATTACH_LEYE" { count(); yylval.ival = 15; return(INTEGER_CONSTANT); }
263"ATTACH_REYE" { count(); yylval.ival = 16; return(INTEGER_CONSTANT); }
264"ATTACH_NOSE" { count(); yylval.ival = 17; return(INTEGER_CONSTANT); }
265"ATTACH_RUARM" { count(); yylval.ival = 18; return(INTEGER_CONSTANT); }
266"ATTACH_RLARM" { count(); yylval.ival = 19; return(INTEGER_CONSTANT); }
267"ATTACH_LUARM" { count(); yylval.ival = 20; return(INTEGER_CONSTANT); }
268"ATTACH_LLARM" { count(); yylval.ival = 21; return(INTEGER_CONSTANT); }
269"ATTACH_RHIP" { count(); yylval.ival = 22; return(INTEGER_CONSTANT); }
270"ATTACH_RULEG" { count(); yylval.ival = 23; return(INTEGER_CONSTANT); }
271"ATTACH_RLLEG" { count(); yylval.ival = 24; return(INTEGER_CONSTANT); }
272"ATTACH_LHIP" { count(); yylval.ival = 25; return(INTEGER_CONSTANT); }
273"ATTACH_LULEG" { count(); yylval.ival = 26; return(INTEGER_CONSTANT); }
274"ATTACH_LLLEG" { count(); yylval.ival = 27; return(INTEGER_CONSTANT); }
275"ATTACH_BELLY" { count(); yylval.ival = 28; return(INTEGER_CONSTANT); }
276"ATTACH_RPEC" { count(); yylval.ival = 29; return(INTEGER_CONSTANT); }
277"ATTACH_LPEC" { count(); yylval.ival = 30; return(INTEGER_CONSTANT); }
278"ATTACH_HUD_CENTER_2" { count(); yylval.ival = 31; return(INTEGER_CONSTANT); }
279"ATTACH_HUD_TOP_RIGHT" { count(); yylval.ival = 32; return(INTEGER_CONSTANT); }
280"ATTACH_HUD_TOP_CENTER" { count(); yylval.ival = 33; return(INTEGER_CONSTANT); }
281"ATTACH_HUD_TOP_LEFT" { count(); yylval.ival = 34; return(INTEGER_CONSTANT); }
282"ATTACH_HUD_CENTER_1" { count(); yylval.ival = 35; return(INTEGER_CONSTANT); }
283"ATTACH_HUD_BOTTOM_LEFT" { count(); yylval.ival = 36; return(INTEGER_CONSTANT); }
284"ATTACH_HUD_BOTTOM" { count(); yylval.ival = 37; return(INTEGER_CONSTANT); }
285"ATTACH_HUD_BOTTOM_RIGHT" { count(); yylval.ival = 38; return(INTEGER_CONSTANT); }
286
287"LAND_LEVEL" { count(); yylval.ival = E_LANDBRUSH_LEVEL; return(INTEGER_CONSTANT); }
288"LAND_RAISE" { count(); yylval.ival = E_LANDBRUSH_RAISE; return(INTEGER_CONSTANT); }
289"LAND_LOWER" { count(); yylval.ival = E_LANDBRUSH_LOWER; return(INTEGER_CONSTANT); }
290"LAND_SMOOTH" { count(); yylval.ival = E_LANDBRUSH_SMOOTH; return(INTEGER_CONSTANT); }
291"LAND_NOISE" { count(); yylval.ival = E_LANDBRUSH_NOISE; return(INTEGER_CONSTANT); }
292"LAND_REVERT" { count(); yylval.ival = E_LANDBRUSH_REVERT; return(INTEGER_CONSTANT); }
293
294"LAND_SMALL_BRUSH" { count(); yylval.ival = 1; return(INTEGER_CONSTANT); }
295"LAND_MEDIUM_BRUSH" { count(); yylval.ival = 2; return(INTEGER_CONSTANT); }
296"LAND_LARGE_BRUSH" { count(); yylval.ival = 3; return(INTEGER_CONSTANT); }
297
298"DATA_ONLINE" { count(); yylval.ival = 1; return(INTEGER_CONSTANT); }
299"DATA_NAME" { count(); yylval.ival = 2; return(INTEGER_CONSTANT); }
300"DATA_BORN" { count(); yylval.ival = 3; return(INTEGER_CONSTANT); }
301"DATA_RATING" { count(); yylval.ival = 4; return(INTEGER_CONSTANT); }
302"DATA_SIM_POS" { count(); yylval.ival = 5; return(INTEGER_CONSTANT); }
303"DATA_SIM_STATUS" { count(); yylval.ival = 6; return(INTEGER_CONSTANT); }
304"DATA_SIM_RATING" { count(); yylval.ival = 7; return(INTEGER_CONSTANT); }
305"DATA_PAYINFO" { count(); yylval.ival = 8; return(INTEGER_CONSTANT); }
306
307"PAYMENT_INFO_ON_FILE" { count(); yylval.ival = 1; return(INTEGER_CONSTANT); }
308"PAYMENT_INFO_USED" { count(); yylval.ival = 2; return(INTEGER_CONSTANT); }
309
310"REMOTE_DATA_CHANNEL" { count(); yylval.ival = LSL_REMOTE_DATA_CHANNEL; return(INTEGER_CONSTANT); }
311"REMOTE_DATA_REQUEST" { count(); yylval.ival = LSL_REMOTE_DATA_REQUEST; return(INTEGER_CONSTANT); }
312"REMOTE_DATA_REPLY" { count(); yylval.ival = LSL_REMOTE_DATA_REPLY; return(INTEGER_CONSTANT); }
313
314
315"PSYS_PART_FLAGS" { count(); yylval.ival = LLPS_PART_FLAGS; return(INTEGER_CONSTANT); }
316"PSYS_PART_START_COLOR" { count(); yylval.ival = LLPS_PART_START_COLOR; return (INTEGER_CONSTANT); }
317"PSYS_PART_START_ALPHA" { count(); yylval.ival = LLPS_PART_START_ALPHA; return (INTEGER_CONSTANT); }
318"PSYS_PART_START_SCALE" { count(); yylval.ival = LLPS_PART_START_SCALE; return (INTEGER_CONSTANT); }
319"PSYS_PART_END_COLOR" { count(); yylval.ival = LLPS_PART_END_COLOR; return (INTEGER_CONSTANT); }
320"PSYS_PART_END_ALPHA" { count(); yylval.ival = LLPS_PART_END_ALPHA; return (INTEGER_CONSTANT); }
321"PSYS_PART_END_SCALE" { count(); yylval.ival = LLPS_PART_END_SCALE; return (INTEGER_CONSTANT); }
322"PSYS_PART_MAX_AGE" { count(); yylval.ival = LLPS_PART_MAX_AGE; return (INTEGER_CONSTANT); }
323
324
325"PSYS_PART_WIND_MASK" { count(); yylval.ival = LLPartData::LL_PART_WIND_MASK; return(INTEGER_CONSTANT); }
326"PSYS_PART_INTERP_COLOR_MASK" { count(); yylval.ival = LLPartData::LL_PART_INTERP_COLOR_MASK; return(INTEGER_CONSTANT); }
327"PSYS_PART_INTERP_SCALE_MASK" { count(); yylval.ival = LLPartData::LL_PART_INTERP_SCALE_MASK; return(INTEGER_CONSTANT); }
328"PSYS_PART_BOUNCE_MASK" { count(); yylval.ival = LLPartData::LL_PART_BOUNCE_MASK; return(INTEGER_CONSTANT); }
329"PSYS_PART_FOLLOW_SRC_MASK" { count(); yylval.ival = LLPartData::LL_PART_FOLLOW_SRC_MASK; return(INTEGER_CONSTANT); }
330"PSYS_PART_FOLLOW_VELOCITY_MASK" { count(); yylval.ival = LLPartData::LL_PART_FOLLOW_VELOCITY_MASK; return(INTEGER_CONSTANT); }
331"PSYS_PART_TARGET_POS_MASK" { count(); yylval.ival = LLPartData::LL_PART_TARGET_POS_MASK; return(INTEGER_CONSTANT); }
332"PSYS_PART_EMISSIVE_MASK" { count(); yylval.ival = LLPartData::LL_PART_EMISSIVE_MASK; return(INTEGER_CONSTANT); }
333"PSYS_PART_TARGET_LINEAR_MASK" { count(); yylval.ival = LLPartData::LL_PART_TARGET_LINEAR_MASK; return(INTEGER_CONSTANT); }
334
335
336"PSYS_SRC_MAX_AGE" { count(); yylval.ival = LLPS_SRC_MAX_AGE; return(INTEGER_CONSTANT); }
337"PSYS_SRC_PATTERN" { count(); yylval.ival = LLPS_SRC_PATTERN; return(INTEGER_CONSTANT); }
338"PSYS_SRC_INNERANGLE" { count(); yylval.ival = LLPS_SRC_INNERANGLE; return(INTEGER_CONSTANT); }
339"PSYS_SRC_OUTERANGLE" { count(); yylval.ival = LLPS_SRC_OUTERANGLE; return(INTEGER_CONSTANT); }
340"PSYS_SRC_ANGLE_BEGIN" { count(); yylval.ival = LLPS_SRC_ANGLE_BEGIN; return(INTEGER_CONSTANT); }
341"PSYS_SRC_ANGLE_END" { count(); yylval.ival = LLPS_SRC_ANGLE_END; return(INTEGER_CONSTANT); }
342"PSYS_SRC_BURST_RATE" { count(); yylval.ival = LLPS_SRC_BURST_RATE; return(INTEGER_CONSTANT); }
343"PSYS_SRC_BURST_PART_COUNT" { count(); yylval.ival = LLPS_SRC_BURST_PART_COUNT; return(INTEGER_CONSTANT); }
344"PSYS_SRC_BURST_RADIUS" { count(); yylval.ival = LLPS_SRC_BURST_RADIUS; return(INTEGER_CONSTANT); }
345"PSYS_SRC_BURST_SPEED_MIN" { count(); yylval.ival = LLPS_SRC_BURST_SPEED_MIN; return(INTEGER_CONSTANT); }
346"PSYS_SRC_BURST_SPEED_MAX" { count(); yylval.ival = LLPS_SRC_BURST_SPEED_MAX; return(INTEGER_CONSTANT); }
347"PSYS_SRC_ACCEL" { count(); yylval.ival = LLPS_SRC_ACCEL; return(INTEGER_CONSTANT); }
348"PSYS_SRC_TEXTURE" { count(); yylval.ival = LLPS_SRC_TEXTURE; return(INTEGER_CONSTANT); }
349"PSYS_SRC_TARGET_KEY" { count(); yylval.ival = LLPS_SRC_TARGET_UUID; return(INTEGER_CONSTANT); }
350"PSYS_SRC_OMEGA" { count(); yylval.ival = LLPS_SRC_OMEGA; return(INTEGER_CONSTANT); }
351
352"PSYS_SRC_OBJ_REL_MASK" { count(); yylval.ival = LLPartSysData::LL_PART_SRC_OBJ_REL_MASK; return(INTEGER_CONSTANT); }
353
354"PSYS_SRC_PATTERN_DROP" { count(); yylval.ival = LLPartSysData::LL_PART_SRC_PATTERN_DROP; return(INTEGER_CONSTANT); }
355"PSYS_SRC_PATTERN_EXPLODE" { count(); yylval.ival = LLPartSysData::LL_PART_SRC_PATTERN_EXPLODE; return(INTEGER_CONSTANT); }
356"PSYS_SRC_PATTERN_ANGLE" { count(); yylval.ival = LLPartSysData::LL_PART_SRC_PATTERN_ANGLE; return(INTEGER_CONSTANT); }
357"PSYS_SRC_PATTERN_ANGLE_CONE" { count(); yylval.ival = LLPartSysData::LL_PART_SRC_PATTERN_ANGLE_CONE; return(INTEGER_CONSTANT); }
358"PSYS_SRC_PATTERN_ANGLE_CONE_EMPTY" { count(); yylval.ival = LLPartSysData::LL_PART_SRC_PATTERN_ANGLE_CONE_EMPTY; return(INTEGER_CONSTANT); }
359
360
361"VEHICLE_TYPE_NONE" { count(); yylval.ival = VEHICLE_TYPE_NONE; return(INTEGER_CONSTANT); }
362"VEHICLE_TYPE_SLED" { count(); yylval.ival = VEHICLE_TYPE_SLED; return(INTEGER_CONSTANT); }
363"VEHICLE_TYPE_CAR" { count(); yylval.ival = VEHICLE_TYPE_CAR; return(INTEGER_CONSTANT); }
364"VEHICLE_TYPE_BOAT" { count(); yylval.ival = VEHICLE_TYPE_BOAT; return(INTEGER_CONSTANT); }
365"VEHICLE_TYPE_AIRPLANE" { count(); yylval.ival = VEHICLE_TYPE_AIRPLANE; return(INTEGER_CONSTANT); }
366"VEHICLE_TYPE_BALLOON" { count(); yylval.ival = VEHICLE_TYPE_BALLOON; return(INTEGER_CONSTANT); }
367
368"VEHICLE_REFERENCE_FRAME" { count(); yylval.ival = VEHICLE_REFERENCE_FRAME; return(INTEGER_CONSTANT); }
369"VEHICLE_LINEAR_FRICTION_TIMESCALE" { count(); yylval.ival = VEHICLE_LINEAR_FRICTION_TIMESCALE; return(INTEGER_CONSTANT); }
370"VEHICLE_ANGULAR_FRICTION_TIMESCALE" { count(); yylval.ival = VEHICLE_ANGULAR_FRICTION_TIMESCALE; return(INTEGER_CONSTANT); }
371"VEHICLE_LINEAR_MOTOR_DIRECTION" { count(); yylval.ival = VEHICLE_LINEAR_MOTOR_DIRECTION; return(INTEGER_CONSTANT); }
372"VEHICLE_ANGULAR_MOTOR_DIRECTION" { count(); yylval.ival = VEHICLE_ANGULAR_MOTOR_DIRECTION; return(INTEGER_CONSTANT); }
373"VEHICLE_LINEAR_MOTOR_OFFSET" { count(); yylval.ival = VEHICLE_LINEAR_MOTOR_OFFSET; return(INTEGER_CONSTANT); }
374
375
376
377"VEHICLE_HOVER_HEIGHT" { count(); yylval.ival = VEHICLE_HOVER_HEIGHT; return(INTEGER_CONSTANT); }
378"VEHICLE_HOVER_EFFICIENCY" { count(); yylval.ival = VEHICLE_HOVER_EFFICIENCY; return(INTEGER_CONSTANT); }
379"VEHICLE_HOVER_TIMESCALE" { count(); yylval.ival = VEHICLE_HOVER_TIMESCALE; return(INTEGER_CONSTANT); }
380"VEHICLE_BUOYANCY" { count(); yylval.ival = VEHICLE_BUOYANCY; return(INTEGER_CONSTANT); }
381
382"VEHICLE_LINEAR_DEFLECTION_EFFICIENCY" { count(); yylval.ival = VEHICLE_LINEAR_DEFLECTION_EFFICIENCY; return(INTEGER_CONSTANT); }
383"VEHICLE_LINEAR_DEFLECTION_TIMESCALE" { count(); yylval.ival = VEHICLE_LINEAR_DEFLECTION_TIMESCALE; return(INTEGER_CONSTANT); }
384"VEHICLE_LINEAR_MOTOR_TIMESCALE" { count(); yylval.ival = VEHICLE_LINEAR_MOTOR_TIMESCALE; return(INTEGER_CONSTANT); }
385"VEHICLE_LINEAR_MOTOR_DECAY_TIMESCALE" { count(); yylval.ival = VEHICLE_LINEAR_MOTOR_DECAY_TIMESCALE; return(INTEGER_CONSTANT); }
386
387"VEHICLE_ANGULAR_DEFLECTION_EFFICIENCY" { count(); yylval.ival = VEHICLE_ANGULAR_DEFLECTION_EFFICIENCY; return(INTEGER_CONSTANT); }
388"VEHICLE_ANGULAR_DEFLECTION_TIMESCALE" { count(); yylval.ival = VEHICLE_ANGULAR_DEFLECTION_TIMESCALE; return(INTEGER_CONSTANT); }
389"VEHICLE_ANGULAR_MOTOR_TIMESCALE" { count(); yylval.ival = VEHICLE_ANGULAR_MOTOR_TIMESCALE; return(INTEGER_CONSTANT); }
390"VEHICLE_ANGULAR_MOTOR_DECAY_TIMESCALE" { count(); yylval.ival = VEHICLE_ANGULAR_MOTOR_DECAY_TIMESCALE; return(INTEGER_CONSTANT); }
391
392"VEHICLE_VERTICAL_ATTRACTION_EFFICIENCY" { count(); yylval.ival = VEHICLE_VERTICAL_ATTRACTION_EFFICIENCY; return(INTEGER_CONSTANT); }
393"VEHICLE_VERTICAL_ATTRACTION_TIMESCALE" { count(); yylval.ival = VEHICLE_VERTICAL_ATTRACTION_TIMESCALE; return(INTEGER_CONSTANT); }
394
395"VEHICLE_BANKING_EFFICIENCY" { count(); yylval.ival = VEHICLE_BANKING_EFFICIENCY; return(INTEGER_CONSTANT); }
396"VEHICLE_BANKING_MIX" { count(); yylval.ival = VEHICLE_BANKING_MIX; return(INTEGER_CONSTANT); }
397"VEHICLE_BANKING_TIMESCALE" { count(); yylval.ival = VEHICLE_BANKING_TIMESCALE; return(INTEGER_CONSTANT); }
398
399"VEHICLE_FLAG_NO_FLY_UP" { count(); yylval.ival = VEHICLE_FLAG_NO_DEFLECTION_UP; return(INTEGER_CONSTANT); }
400"VEHICLE_FLAG_NO_DEFLECTION_UP" { count(); yylval.ival = VEHICLE_FLAG_NO_DEFLECTION_UP; return(INTEGER_CONSTANT); }
401"VEHICLE_FLAG_LIMIT_ROLL_ONLY" { count(); yylval.ival = VEHICLE_FLAG_LIMIT_ROLL_ONLY; return(INTEGER_CONSTANT); }
402"VEHICLE_FLAG_HOVER_WATER_ONLY" { count(); yylval.ival = VEHICLE_FLAG_HOVER_WATER_ONLY; return(INTEGER_CONSTANT); }
403"VEHICLE_FLAG_HOVER_TERRAIN_ONLY" { count(); yylval.ival = VEHICLE_FLAG_HOVER_TERRAIN_ONLY; return(INTEGER_CONSTANT); }
404"VEHICLE_FLAG_HOVER_GLOBAL_HEIGHT" { count(); yylval.ival = VEHICLE_FLAG_HOVER_GLOBAL_HEIGHT; return(INTEGER_CONSTANT); }
405"VEHICLE_FLAG_HOVER_UP_ONLY" { count(); yylval.ival = VEHICLE_FLAG_HOVER_UP_ONLY; return(INTEGER_CONSTANT); }
406"VEHICLE_FLAG_LIMIT_MOTOR_UP" { count(); yylval.ival = VEHICLE_FLAG_LIMIT_MOTOR_UP; return(INTEGER_CONSTANT); }
407"VEHICLE_FLAG_MOUSELOOK_STEER" { count(); yylval.ival = VEHICLE_FLAG_MOUSELOOK_STEER; return(INTEGER_CONSTANT); }
408"VEHICLE_FLAG_MOUSELOOK_BANK" { count(); yylval.ival = VEHICLE_FLAG_MOUSELOOK_BANK; return(INTEGER_CONSTANT); }
409"VEHICLE_FLAG_CAMERA_DECOUPLED" { count(); yylval.ival = VEHICLE_FLAG_CAMERA_DECOUPLED; return(INTEGER_CONSTANT); }
410
411
412
413"PRIM_TYPE" { count(); yylval.ival = LSL_PRIM_TYPE; return(INTEGER_CONSTANT); }
414"PRIM_MATERIAL" { count(); yylval.ival = LSL_PRIM_MATERIAL; return(INTEGER_CONSTANT); }
415"PRIM_PHYSICS" { count(); yylval.ival = LSL_PRIM_PHYSICS; return(INTEGER_CONSTANT); }
416"PRIM_FLEXIBLE" { count(); yylval.ival = LSL_PRIM_FLEXIBLE; return(INTEGER_CONSTANT); }
417"PRIM_POINT_LIGHT" { count(); yylval.ival = LSL_PRIM_POINT_LIGHT; return(INTEGER_CONSTANT); }
418"PRIM_TEMP_ON_REZ" { count(); yylval.ival = LSL_PRIM_TEMP_ON_REZ; return(INTEGER_CONSTANT); }
419"PRIM_PHANTOM" { count(); yylval.ival = LSL_PRIM_PHANTOM; return(INTEGER_CONSTANT); }
420"PRIM_CAST_SHADOWS" { count(); yylval.ival = LSL_PRIM_CAST_SHADOWS; return(INTEGER_CONSTANT); }
421"PRIM_POSITION" { count(); yylval.ival = LSL_PRIM_POSITION; return(INTEGER_CONSTANT); }
422"PRIM_SIZE" { count(); yylval.ival = LSL_PRIM_SIZE; return(INTEGER_CONSTANT); }
423"PRIM_ROTATION" { count(); yylval.ival = LSL_PRIM_ROTATION; return(INTEGER_CONSTANT); }
424"PRIM_TEXTURE" { count(); yylval.ival = LSL_PRIM_TEXTURE; return(INTEGER_CONSTANT); }
425"PRIM_COLOR" { count(); yylval.ival = LSL_PRIM_COLOR; return(INTEGER_CONSTANT); }
426"PRIM_BUMP_SHINY" { count(); yylval.ival = LSL_PRIM_BUMP_SHINY; return(INTEGER_CONSTANT); }
427"PRIM_FULLBRIGHT" { count(); yylval.ival = LSL_PRIM_FULLBRIGHT; return(INTEGER_CONSTANT); }
428"PRIM_TEXGEN" { count(); yylval.ival = LSL_PRIM_TEXGEN; return(INTEGER_CONSTANT); }
429
430"PRIM_TYPE_BOX" { count(); yylval.ival = LSL_PRIM_TYPE_BOX; return(INTEGER_CONSTANT); }
431"PRIM_TYPE_CYLINDER" { count(); yylval.ival = LSL_PRIM_TYPE_CYLINDER; return(INTEGER_CONSTANT); }
432"PRIM_TYPE_PRISM" { count(); yylval.ival = LSL_PRIM_TYPE_PRISM; return(INTEGER_CONSTANT); }
433"PRIM_TYPE_SPHERE" { count(); yylval.ival = LSL_PRIM_TYPE_SPHERE; return(INTEGER_CONSTANT); }
434"PRIM_TYPE_TORUS" { count(); yylval.ival = LSL_PRIM_TYPE_TORUS; return(INTEGER_CONSTANT); }
435"PRIM_TYPE_TUBE" { count(); yylval.ival = LSL_PRIM_TYPE_TUBE; return(INTEGER_CONSTANT); }
436"PRIM_TYPE_RING" { count(); yylval.ival = LSL_PRIM_TYPE_RING; return(INTEGER_CONSTANT); }
437
438"PRIM_HOLE_DEFAULT" { count(); yylval.ival = LSL_PRIM_HOLE_DEFAULT; return(INTEGER_CONSTANT); }
439"PRIM_HOLE_CIRCLE" { count(); yylval.ival = LSL_PRIM_HOLE_CIRCLE; return(INTEGER_CONSTANT); }
440"PRIM_HOLE_SQUARE" { count(); yylval.ival = LSL_PRIM_HOLE_SQUARE; return(INTEGER_CONSTANT); }
441"PRIM_HOLE_TRIANGLE" { count(); yylval.ival = LSL_PRIM_HOLE_TRIANGLE; return(INTEGER_CONSTANT); }
442
443"PRIM_MATERIAL_STONE" { count(); yylval.ival = LSL_PRIM_MATERIAL_STONE; return(INTEGER_CONSTANT); }
444"PRIM_MATERIAL_METAL" { count(); yylval.ival = LSL_PRIM_MATERIAL_METAL; return(INTEGER_CONSTANT); }
445"PRIM_MATERIAL_GLASS" { count(); yylval.ival = LSL_PRIM_MATERIAL_GLASS; return(INTEGER_CONSTANT); }
446"PRIM_MATERIAL_WOOD" { count(); yylval.ival = LSL_PRIM_MATERIAL_WOOD; return(INTEGER_CONSTANT); }
447"PRIM_MATERIAL_FLESH" { count(); yylval.ival = LSL_PRIM_MATERIAL_FLESH; return(INTEGER_CONSTANT); }
448"PRIM_MATERIAL_PLASTIC" { count(); yylval.ival = LSL_PRIM_MATERIAL_PLASTIC; return(INTEGER_CONSTANT); }
449"PRIM_MATERIAL_RUBBER" { count(); yylval.ival = LSL_PRIM_MATERIAL_RUBBER; return(INTEGER_CONSTANT); }
450"PRIM_MATERIAL_LIGHT" { count(); yylval.ival = LSL_PRIM_MATERIAL_LIGHT; return(INTEGER_CONSTANT); }
451
452"PRIM_SHINY_NONE" { count(); yylval.ival = LSL_PRIM_SHINY_NONE; return(INTEGER_CONSTANT); }
453"PRIM_SHINY_LOW" { count(); yylval.ival = LSL_PRIM_SHINY_LOW; return(INTEGER_CONSTANT); }
454"PRIM_SHINY_MEDIUM" { count(); yylval.ival = LSL_PRIM_SHINY_MEDIUM; return(INTEGER_CONSTANT); }
455"PRIM_SHINY_HIGH" { count(); yylval.ival = LSL_PRIM_SHINY_HIGH; return(INTEGER_CONSTANT); }
456
457"PRIM_BUMP_NONE" { count(); yylval.ival = LSL_PRIM_BUMP_NONE; return(INTEGER_CONSTANT); }
458"PRIM_BUMP_BRIGHT" { count(); yylval.ival = LSL_PRIM_BUMP_BRIGHT; return(INTEGER_CONSTANT); }
459"PRIM_BUMP_DARK" { count(); yylval.ival = LSL_PRIM_BUMP_DARK; return(INTEGER_CONSTANT); }
460"PRIM_BUMP_WOOD" { count(); yylval.ival = LSL_PRIM_BUMP_WOOD; return(INTEGER_CONSTANT); }
461"PRIM_BUMP_BARK" { count(); yylval.ival = LSL_PRIM_BUMP_BARK; return(INTEGER_CONSTANT); }
462"PRIM_BUMP_BRICKS" { count(); yylval.ival = LSL_PRIM_BUMP_BRICKS; return(INTEGER_CONSTANT); }
463"PRIM_BUMP_CHECKER" { count(); yylval.ival = LSL_PRIM_BUMP_CHECKER; return(INTEGER_CONSTANT); }
464"PRIM_BUMP_CONCRETE" { count(); yylval.ival = LSL_PRIM_BUMP_CONCRETE; return(INTEGER_CONSTANT); }
465"PRIM_BUMP_TILE" { count(); yylval.ival = LSL_PRIM_BUMP_TILE; return(INTEGER_CONSTANT); }
466"PRIM_BUMP_STONE" { count(); yylval.ival = LSL_PRIM_BUMP_STONE; return(INTEGER_CONSTANT); }
467"PRIM_BUMP_DISKS" { count(); yylval.ival = LSL_PRIM_BUMP_DISKS; return(INTEGER_CONSTANT); }
468"PRIM_BUMP_GRAVEL" { count(); yylval.ival = LSL_PRIM_BUMP_GRAVEL; return(INTEGER_CONSTANT); }
469"PRIM_BUMP_BLOBS" { count(); yylval.ival = LSL_PRIM_BUMP_BLOBS; return(INTEGER_CONSTANT); }
470"PRIM_BUMP_SIDING" { count(); yylval.ival = LSL_PRIM_BUMP_SIDING; return(INTEGER_CONSTANT); }
471"PRIM_BUMP_LARGETILE" { count(); yylval.ival = LSL_PRIM_BUMP_LARGETILE; return(INTEGER_CONSTANT); }
472"PRIM_BUMP_STUCCO" { count(); yylval.ival = LSL_PRIM_BUMP_STUCCO; return(INTEGER_CONSTANT); }
473"PRIM_BUMP_SUCTION" { count(); yylval.ival = LSL_PRIM_BUMP_SUCTION; return(INTEGER_CONSTANT); }
474"PRIM_BUMP_WEAVE" { count(); yylval.ival = LSL_PRIM_BUMP_WEAVE; return(INTEGER_CONSTANT); }
475
476"PRIM_TEXGEN_DEFAULT" { count(); yylval.ival = LSL_PRIM_TEXGEN_DEFAULT; return(INTEGER_CONSTANT); }
477"PRIM_TEXGEN_PLANAR" { count(); yylval.ival = LSL_PRIM_TEXGEN_PLANAR; return(INTEGER_CONSTANT); }
478
479"MASK_BASE" { count(); yylval.ival = 0; return(INTEGER_CONSTANT); }
480"MASK_OWNER" { count(); yylval.ival = 1; return(INTEGER_CONSTANT); }
481"MASK_GROUP" { count(); yylval.ival = 2; return(INTEGER_CONSTANT); }
482"MASK_EVERYONE" { count(); yylval.ival = 3; return(INTEGER_CONSTANT); }
483"MASK_NEXT" { count(); yylval.ival = 4; return(INTEGER_CONSTANT); }
484
485"PERM_TRANSFER" { count(); yylval.ival = PERM_TRANSFER; return(INTEGER_CONSTANT); }
486"PERM_MODIFY" { count(); yylval.ival = PERM_MODIFY; return(INTEGER_CONSTANT); }
487"PERM_COPY" { count(); yylval.ival = PERM_COPY; return(INTEGER_CONSTANT); }
488"PERM_MOVE" { count(); yylval.ival = PERM_MOVE; return(INTEGER_CONSTANT); }
489"PERM_ALL" { count(); yylval.ival = PERM_ALL; return(INTEGER_CONSTANT); }
490
491"PARCEL_MEDIA_COMMAND_STOP" { count(); yylval.ival = PARCEL_MEDIA_COMMAND_STOP; return(INTEGER_CONSTANT); }
492"PARCEL_MEDIA_COMMAND_PAUSE" { count(); yylval.ival = PARCEL_MEDIA_COMMAND_PAUSE; return(INTEGER_CONSTANT); }
493"PARCEL_MEDIA_COMMAND_PLAY" { count(); yylval.ival = PARCEL_MEDIA_COMMAND_PLAY; return(INTEGER_CONSTANT); }
494"PARCEL_MEDIA_COMMAND_LOOP" { count(); yylval.ival = PARCEL_MEDIA_COMMAND_LOOP; return(INTEGER_CONSTANT); }
495"PARCEL_MEDIA_COMMAND_TEXTURE" { count(); yylval.ival = PARCEL_MEDIA_COMMAND_TEXTURE; return(INTEGER_CONSTANT); }
496"PARCEL_MEDIA_COMMAND_URL" { count(); yylval.ival = PARCEL_MEDIA_COMMAND_URL; return(INTEGER_CONSTANT); }
497"PARCEL_MEDIA_COMMAND_TIME" { count(); yylval.ival = PARCEL_MEDIA_COMMAND_TIME; return(INTEGER_CONSTANT); }
498"PARCEL_MEDIA_COMMAND_AGENT" { count(); yylval.ival = PARCEL_MEDIA_COMMAND_AGENT; return(INTEGER_CONSTANT); }
499"PARCEL_MEDIA_COMMAND_UNLOAD" { count(); yylval.ival = PARCEL_MEDIA_COMMAND_UNLOAD; return(INTEGER_CONSTANT); }
500"PARCEL_MEDIA_COMMAND_AUTO_ALIGN" { count(); yylval.ival = PARCEL_MEDIA_COMMAND_AUTO_ALIGN; return(INTEGER_CONSTANT); }
501
502"LIST_STAT_MAX" { count(); yylval.ival = LIST_STAT_MAX; return(INTEGER_CONSTANT); }
503"LIST_STAT_MIN" { count(); yylval.ival = LIST_STAT_MIN; return(INTEGER_CONSTANT); }
504"LIST_STAT_MEAN" { count(); yylval.ival = LIST_STAT_MEAN; return(INTEGER_CONSTANT); }
505"LIST_STAT_MEDIAN" { count(); yylval.ival = LIST_STAT_MEDIAN; return(INTEGER_CONSTANT); }
506"LIST_STAT_STD_DEV" { count(); yylval.ival = LIST_STAT_STD_DEV; return(INTEGER_CONSTANT); }
507"LIST_STAT_SUM" { count(); yylval.ival = LIST_STAT_SUM; return(INTEGER_CONSTANT); }
508"LIST_STAT_SUM_SQUARES" { count(); yylval.ival = LIST_STAT_SUM_SQUARES; return(INTEGER_CONSTANT); }
509"LIST_STAT_NUM_COUNT" { count(); yylval.ival = LIST_STAT_NUM_COUNT; return(INTEGER_CONSTANT); }
510"LIST_STAT_GEOMETRIC_MEAN" { count(); yylval.ival = LIST_STAT_GEO_MEAN; return(INTEGER_CONSTANT); }
511"LIST_STAT_RANGE" { count(); yylval.ival = LIST_STAT_RANGE; return(INTEGER_CONSTANT); }
512
513"PAY_HIDE" { count(); yylval.ival = PAY_PRICE_HIDE; return(INTEGER_CONSTANT); }
514"PAY_DEFAULT" { count(); yylval.ival = PAY_PRICE_DEFAULT; return(INTEGER_CONSTANT); }
515
516"PARCEL_FLAG_ALLOW_FLY" { count(); yylval.ival = PF_ALLOW_FLY; return(INTEGER_CONSTANT); }
517"PARCEL_FLAG_ALLOW_GROUP_SCRIPTS" { count(); yylval.ival = PF_ALLOW_GROUP_SCRIPTS; return(INTEGER_CONSTANT); }
518"PARCEL_FLAG_ALLOW_SCRIPTS" { count(); yylval.ival = PF_ALLOW_OTHER_SCRIPTS; return(INTEGER_CONSTANT); }
519"PARCEL_FLAG_ALLOW_LANDMARK" { count(); yylval.ival = PF_ALLOW_LANDMARK; return(INTEGER_CONSTANT); }
520"PARCEL_FLAG_ALLOW_TERRAFORM" { count(); yylval.ival = PF_ALLOW_TERRAFORM; return(INTEGER_CONSTANT); }
521"PARCEL_FLAG_ALLOW_DAMAGE" { count(); yylval.ival = PF_ALLOW_DAMAGE; return(INTEGER_CONSTANT); }
522"PARCEL_FLAG_ALLOW_CREATE_OBJECTS" { count(); yylval.ival = PF_CREATE_OBJECTS; return(INTEGER_CONSTANT); }
523"PARCEL_FLAG_ALLOW_CREATE_GROUP_OBJECTS" { count(); yylval.ival = PF_CREATE_GROUP_OBJECTS; return(INTEGER_CONSTANT); }
524"PARCEL_FLAG_USE_ACCESS_GROUP" { count(); yylval.ival = PF_USE_ACCESS_GROUP; return(INTEGER_CONSTANT); }
525"PARCEL_FLAG_USE_ACCESS_LIST" { count(); yylval.ival = PF_USE_ACCESS_LIST; return(INTEGER_CONSTANT); }
526"PARCEL_FLAG_USE_BAN_LIST" { count(); yylval.ival = PF_USE_BAN_LIST; return(INTEGER_CONSTANT); }
527"PARCEL_FLAG_USE_LAND_PASS_LIST" { count(); yylval.ival = PF_USE_PASS_LIST; return(INTEGER_CONSTANT); }
528"PARCEL_FLAG_LOCAL_SOUND_ONLY" { count(); yylval.ival = PF_SOUND_LOCAL; return(INTEGER_CONSTANT); }
529"PARCEL_FLAG_RESTRICT_PUSHOBJECT" { count(); yylval.ival = PF_RESTRICT_PUSHOBJECT; return(INTEGER_CONSTANT); }
530"PARCEL_FLAG_ALLOW_GROUP_OBJECT_ENTRY" { count(); yylval.ival = PF_ALLOW_GROUP_OBJECT_ENTRY; return(INTEGER_CONSTANT); }
531"PARCEL_FLAG_ALLOW_ALL_OBJECT_ENTRY" { count(); yylval.ival = PF_ALLOW_ALL_OBJECT_ENTRY; return(INTEGER_CONSTANT); }
532
533"REGION_FLAG_ALLOW_DAMAGE" { count(); yylval.ival = REGION_FLAGS_ALLOW_DAMAGE; return(INTEGER_CONSTANT); }
534"REGION_FLAG_FIXED_SUN" { count(); yylval.ival = REGION_FLAGS_SUN_FIXED; return(INTEGER_CONSTANT); }
535"REGION_FLAG_BLOCK_TERRAFORM" { count(); yylval.ival = REGION_FLAGS_BLOCK_TERRAFORM; return(INTEGER_CONSTANT); }
536"REGION_FLAG_SANDBOX" { count(); yylval.ival = REGION_FLAGS_SANDBOX; return(INTEGER_CONSTANT); }
537"REGION_FLAG_DISABLE_COLLISIONS" { count(); yylval.ival = REGION_FLAGS_SKIP_COLLISIONS; return(INTEGER_CONSTANT); }
538"REGION_FLAG_DISABLE_PHYSICS" { count(); yylval.ival = REGION_FLAGS_SKIP_PHYSICS; return(INTEGER_CONSTANT); }
539"REGION_FLAG_BLOCK_FLY" { count(); yylval.ival = REGION_FLAGS_BLOCK_FLY; return(INTEGER_CONSTANT); }
540"REGION_FLAG_ALLOW_DIRECT_TELEPORT" { count(); yylval.ival = REGION_FLAGS_ALLOW_DIRECT_TELEPORT; return(INTEGER_CONSTANT); }
541"REGION_FLAG_RESTRICT_PUSHOBJECT" { count(); yylval.ival = REGION_FLAGS_RESTRICT_PUSHOBJECT; return(INTEGER_CONSTANT); }
542
543"HTTP_METHOD" { count(); yylval.ival = HTTP_METHOD; return(INTEGER_CONSTANT); }
544"HTTP_MIMETYPE" { count(); yylval.ival = HTTP_MIMETYPE; return(INTEGER_CONSTANT); }
545"HTTP_BODY_MAXLENGTH" { count(); yylval.ival = HTTP_BODY_MAXLENGTH; return(INTEGER_CONSTANT); }
546"HTTP_BODY_TRUNCATED" { count(); yylval.ival = HTTP_BODY_TRUNCATED; return(INTEGER_CONSTANT); }
547"HTTP_VERIFY_CERT" { count(); yylval.ival = HTTP_VERIFY_CERT; return(INTEGER_CONSTANT); }
548
549"PARCEL_COUNT_TOTAL" { count(); yylval.ival = OC_TOTAL; return(INTEGER_CONSTANT); }
550"PARCEL_COUNT_OWNER" { count(); yylval.ival = OC_OWNER; return(INTEGER_CONSTANT); }
551"PARCEL_COUNT_GROUP" { count(); yylval.ival = OC_GROUP; return(INTEGER_CONSTANT); }
552"PARCEL_COUNT_OTHER" { count(); yylval.ival = OC_OTHER; return(INTEGER_CONSTANT); }
553"PARCEL_COUNT_SELECTED" { count(); yylval.ival = OC_SELECTED; return(INTEGER_CONSTANT); }
554"PARCEL_COUNT_TEMP" { count(); yylval.ival = OC_TEMP; return(INTEGER_CONSTANT); }
555
556"PARCEL_DETAILS_NAME" { count(); yylval.ival = PARCEL_DETAILS_NAME; return(INTEGER_CONSTANT); }
557"PARCEL_DETAILS_DESC" { count(); yylval.ival = PARCEL_DETAILS_DESC; return(INTEGER_CONSTANT); }
558"PARCEL_DETAILS_OWNER" { count(); yylval.ival = PARCEL_DETAILS_OWNER; return(INTEGER_CONSTANT); }
559"PARCEL_DETAILS_GROUP" { count(); yylval.ival = PARCEL_DETAILS_GROUP; return(INTEGER_CONSTANT); }
560"PARCEL_DETAILS_AREA" { count(); yylval.ival = PARCEL_DETAILS_AREA; return(INTEGER_CONSTANT); }
561
562{L}({L}|{N})* { count(); yylval.sval = new char[strlen(yytext) + 1]; strcpy(yylval.sval, yytext); return(IDENTIFIER); }
563
564{D}+{E} { count(); yylval.fval = (F32)atof(yytext); return(FP_CONSTANT); }
565{D}*"."{D}+({E})?{FS}? { count(); yylval.fval = (F32)atof(yytext); return(FP_CONSTANT); }
566{D}+"."{D}*({E})?{FS}? { count(); yylval.fval = (F32)atof(yytext); return(FP_CONSTANT); }
567
568L?\"(\\.|[^\\"])*\" { parse_string(); count(); return(STRING_CONSTANT); }
569
570"++" { count(); return(INC_OP); }
571"--" { count(); return(DEC_OP); }
572"+=" { count(); return(ADD_ASSIGN); }
573"-=" { count(); return(SUB_ASSIGN); }
574"*=" { count(); return(MUL_ASSIGN); }
575"/=" { count(); return(DIV_ASSIGN); }
576"%=" { count(); return(MOD_ASSIGN); }
577";" { count(); return(';'); }
578"{" { count(); return('{'); }
579"}" { count(); return('}'); }
580"," { count(); return(','); }
581"=" { count(); return('='); }
582"(" { count(); return('('); }
583")" { count(); return(')'); }
584"-" { count(); return('-'); }
585"+" { count(); return('+'); }
586"*" { count(); return('*'); }
587"/" { count(); return('/'); }
588"%" { count(); return('%'); }
589"@" { count(); return('@'); }
590":" { count(); return(':'); }
591">" { count(); return('>'); }
592"<" { count(); return('<'); }
593"]" { count(); return(']'); }
594"[" { count(); return('['); }
595"==" { count(); return(EQ); }
596"!=" { count(); return(NEQ); }
597">=" { count(); return(GEQ); }
598"<=" { count(); return(LEQ); }
599"&" { count(); return('&'); }
600"|" { count(); return('|'); }
601"^" { count(); return('^'); }
602"~" { count(); return('~'); }
603"!" { count(); return('!'); }
604"&&" { count(); return(BOOLEAN_AND); }
605"||" { count(); return(BOOLEAN_OR); }
606"<<" { count(); return(SHIFT_LEFT); }
607">>" { count(); return(SHIFT_RIGHT); }
608
609[ \t\v\n\f] { count(); }
610. { /* ignore bad characters */ }
611
612%%
613
614LLScriptAllocationManager *gAllocationManager;
615LLScriptScript *gScriptp;
616
617// Prototype for the yacc parser entry point
618int yyparse(void);
619
620int yyerror(const char *fmt, ...)
621{
622 gErrorToText.writeError(yyout, gLine, gColumn, LSERROR_SYNTAX_ERROR);
623 return 0;
624}
625
626#define LL_MKS_YACC 0
627#if LL_WINDOWS && LL_MKS_YACC
628int yyinput(void)
629{
630 return input();
631}
632#endif
633
634//#define EMERGENCY_DEBUG_PRINTOUTS
635//#define EMIT_CIL_ASSEMBLER
636
637BOOL lscript_compile(const char* src_filename, const char* dst_filename,
638 const char* err_filename, BOOL is_god_like)
639{
640 BOOL b_parse_ok = FALSE;
641 BOOL b_dummy = FALSE;
642 U64 b_dummy_count = FALSE;
643 LSCRIPTType type = LST_NULL;
644
645 gInternalColumn = 0;
646 gInternalLine = 0;
647 gScriptp = NULL;
648
649 gErrorToText.init();
650 init_supported_expressions();
651 init_temp_jumps();
652 gAllocationManager = new LLScriptAllocationManager();
653
654 yyin = LLFile::fopen(src_filename, "r");
655 if (yyin)
656 {
657 yyout = LLFile::fopen(err_filename, "w");
658
659 // Reset the lexer's internal buffering.
660#if LL_DARWIN || LL_LINUX || !LL_MKS_YACC
661 yyrestart(yyin);
662#else
663 yy_reset();
664#endif
665 b_parse_ok = !yyparse();
666
667 if (b_parse_ok)
668 {
669#ifdef EMERGENCY_DEBUG_PRINTOUTS
670 char compiled[256];
671 sprintf(compiled, "%s.o", src_filename);
672 FILE* compfile;
673 compfile = LLFile::fopen(compiled, "w");
674#endif
675
676 if(dst_filename)
677 {
678 gScriptp->setBytecodeDest(dst_filename);
679 }
680
681 gScriptp->mGodLike = is_god_like;
682
683 gScopeStringTable = new LLStringTable(16384);
684#ifdef EMERGENCY_DEBUG_PRINTOUTS
685 gScriptp->recurse(compfile, 0, 4, LSCP_PRETTY_PRINT, LSPRUNE_INVALID, b_dummy, NULL, type, type, b_dummy_count, NULL, NULL, 0, NULL, 0, NULL);
686#endif
687 gScriptp->recurse(yyout, 0, 0, LSCP_PRUNE, LSPRUNE_INVALID, b_dummy, NULL, type, type, b_dummy_count, NULL, NULL, 0, NULL, 0, NULL);
688 gScriptp->recurse(yyout, 0, 0, LSCP_SCOPE_PASS1, LSPRUNE_INVALID, b_dummy, NULL, type, type, b_dummy_count, NULL, NULL, 0, NULL, 0, NULL);
689 gScriptp->recurse(yyout, 0, 0, LSCP_SCOPE_PASS2, LSPRUNE_INVALID, b_dummy, NULL, type, type, b_dummy_count, NULL, NULL, 0, NULL, 0, NULL);
690 gScriptp->recurse(yyout, 0, 0, LSCP_TYPE, LSPRUNE_INVALID, b_dummy, NULL, type, type, b_dummy_count, NULL, NULL, 0, NULL, 0, NULL);
691 if (!gErrorToText.getErrors())
692 {
693 gScriptp->recurse(yyout, 0, 0, LSCP_RESOURCE, LSPRUNE_INVALID, b_dummy, NULL, type, type, b_dummy_count, NULL, NULL, 0, NULL, 0, NULL);
694#ifdef EMERGENCY_DEBUG_PRINTOUTS
695 gScriptp->recurse(yyout, 0, 0, LSCP_EMIT_ASSEMBLY, LSPRUNE_INVALID, b_dummy, NULL, type, type, b_dummy_count, NULL, NULL, 0, NULL, 0, NULL);
696#endif
697#ifdef EMIT_CIL_ASSEMBLER
698 const char* cil_output_file_name = dst_filename? dst_filename : "lscript.cil";
699 FILE* cilout = LLFile::fopen(cil_output_file_name, "w");
700 if(NULL == cilout)
701 {
702 fprintf(yyout, "Error opening cil output file %s\n", cil_output_file_name);
703 }
704 else
705 {
706 gScriptp->recurse(cilout, 0, 0, LSCP_EMIT_CIL_ASSEMBLY, LSPRUNE_INVALID, b_dummy, NULL, type, type, b_dummy_count, NULL, NULL, 0, NULL, 0, NULL);
707 if(fclose(cilout) == EOF)
708 {
709 fprintf(yyout, "Error closing cil output file %s\n", cil_output_file_name);
710 }
711 }
712#endif
713 gScriptp->recurse(yyout, 0, 0, LSCP_EMIT_BYTE_CODE, LSPRUNE_INVALID, b_dummy, NULL, type, type, b_dummy_count, NULL, NULL, 0, NULL, 0, NULL);
714 }
715 delete gScopeStringTable;
716 gScopeStringTable = NULL;
717#ifdef EMERGENCY_DEBUG_PRINTOUTS
718 fclose(compfile);
719#endif
720 }
721 fclose(yyout);
722 }
723
724 fclose(yyin);
725 delete gAllocationManager;
726 delete gScopeStringTable;
727
728 return b_parse_ok && !gErrorToText.getErrors();
729}
730
731
732BOOL lscript_compile(char *filename, BOOL is_god_like = FALSE)
733{
734 char src_filename[MAX_STRING];
735 sprintf(src_filename, "%s.lsl", filename);
736 char err_filename[MAX_STRING];
737 sprintf(err_filename, "%s.out", filename);
738 return lscript_compile(src_filename, NULL, err_filename, is_god_like);
739}
740
741
742S32 yywrap()
743{
744 return(1);
745}
746
747void comment()
748{
749 char c;
750
751#if LL_DARWIN
752 while ((c = yyinput()) != '\n' && c != 0 && c != EOF)
753 ;
754#else
755 while ((c = yyinput()) != '\n' && c != 0)
756 ;
757#endif
758
759
760}
761
762void count()
763{
764 S32 i;
765
766 gColumn = gInternalColumn;
767 gLine = gInternalLine;
768
769 for (i = 0; yytext[i] != '\0'; i++)
770 if (yytext[i] == '\n')
771 {
772 gInternalLine++;
773 gInternalColumn = 0;
774 }
775 else if (yytext[i] == '\t')
776 gInternalColumn += 4 - (gInternalColumn % 8);
777 else
778 gInternalColumn++;
779}
780
781void parse_string()
782{
783 S32 length = (S32)strlen(yytext);
784 length = length - 2;
785 char *temp = yytext + 1;
786
787 S32 i;
788 S32 escapes = 0;
789 S32 tabs = 0;
790 for (i = 0; i < length; i++)
791 {
792 if (temp[i] == '\\')
793 {
794 escapes++;
795 i++;
796 if (temp[i] == 't')
797 tabs++;
798 }
799 }
800
801 S32 newlength = length - escapes + tabs*3;
802 yylval.sval = new char[newlength + 1];
803
804 char *dest = yylval.sval;
805
806 for (i = 0; i < length; i++)
807 {
808 if (temp[i] == '\\')
809 {
810 i++;
811 // linefeed
812 if (temp[i] == 'n')
813 {
814 *dest++ = 10;
815 }
816 else if (temp[i] == 't')
817 {
818 *dest++ = ' ';
819 *dest++ = ' ';
820 *dest++ = ' ';
821 *dest++ = ' ';
822 }
823 else
824 {
825 *dest++ = temp[i];
826 }
827 }
828 else
829 {
830 *dest++ = temp[i];
831 }
832 }
833 yylval.sval[newlength] = 0;
834}
diff --git a/linden/indra/lscript/lscript_compile/indra.y b/linden/indra/lscript/lscript_compile/indra.y
new file mode 100644
index 0000000..7744649
--- /dev/null
+++ b/linden/indra/lscript/lscript_compile/indra.y
@@ -0,0 +1,1680 @@
1%{
2 #include "stdtypes.h"
3 #include "lscript_tree.h"
4
5 #ifdef __cplusplus
6 extern "C" {
7 #endif
8
9 int yylex(void);
10 int yyparse( void );
11 int yyerror(const char *fmt, ...);
12
13 #if LL_LINUX
14 // broken yacc codegen... --ryan.
15 #define getenv getenv_workaround
16 #endif
17
18 #ifdef __cplusplus
19 }
20 #endif
21%}
22
23%union
24{
25 S32 ival;
26 F32 fval;
27 char *sval;
28 class LLScriptType *type;
29 class LLScriptConstant *constant;
30 class LLScriptIdentifier *identifier;
31 class LLScriptSimpleAssignable *assignable;
32 class LLScriptGlobalVariable *global;
33 class LLScriptEvent *event;
34 class LLScriptEventHandler *handler;
35 class LLScriptExpression *expression;
36 class LLScriptStatement *statement;
37 class LLScriptGlobalFunctions *global_funcs;
38 class LLScriptFunctionDec *global_decl;
39 class LLScriptState *state;
40 class LLScritpGlobalStorage *global_store;
41 class LLScriptScript *script;
42};
43
44%token INTEGER
45%token FLOAT_TYPE
46%token STRING
47%token LLKEY
48%token VECTOR
49%token QUATERNION
50%token LIST
51
52%token STATE_DEFAULT
53%token STATE
54%token EVENT
55%token JUMP
56%token RETURN
57
58%token STATE_ENTRY
59%token STATE_EXIT
60%token TOUCH_START
61%token TOUCH
62%token TOUCH_END
63%token COLLISION_START
64%token COLLISION
65%token COLLISION_END
66%token LAND_COLLISION_START
67%token LAND_COLLISION
68%token LAND_COLLISION_END
69%token TIMER
70%token CHAT
71%token SENSOR
72%token NO_SENSOR
73%token CONTROL
74%token AT_TARGET
75%token NOT_AT_TARGET
76%token AT_ROT_TARGET
77%token NOT_AT_ROT_TARGET
78%token MONEY
79%token EMAIL
80%token RUN_TIME_PERMISSIONS
81%token INVENTORY
82%token ATTACH
83%token DATASERVER
84%token MOVING_START
85%token MOVING_END
86%token REZ
87%token OBJECT_REZ
88%token LINK_MESSAGE
89%token REMOTE_DATA
90%token HTTP_RESPONSE
91
92%token <sval> IDENTIFIER
93%token <sval> STATE_DEFAULT
94
95%token <ival> INTEGER_CONSTANT
96%token <ival> INTEGER_TRUE
97%token <ival> INTEGER_FALSE
98
99%token <fval> FP_CONSTANT
100
101%token <sval> STRING_CONSTANT
102
103%token INC_OP
104%token DEC_OP
105%token ADD_ASSIGN
106%token SUB_ASSIGN
107%token MUL_ASSIGN
108%token DIV_ASSIGN
109%token MOD_ASSIGN
110
111%token EQ
112%token NEQ
113%token GEQ
114%token LEQ
115
116%token BOOLEAN_AND
117%token BOOLEAN_OR
118
119%token SHIFT_LEFT
120%token SHIFT_RIGHT
121
122%token IF
123%token ELSE
124%token FOR
125%token DO
126%token WHILE
127
128%token PRINT
129
130%token PERIOD
131
132%token ZERO_VECTOR
133%token ZERO_ROTATION
134
135%nonassoc LOWER_THAN_ELSE
136%nonassoc ELSE
137
138
139%type <script> lscript_program
140%type <global_store> globals
141%type <global_store> global
142%type <global> global_variable
143%type <assignable> simple_assignable
144%type <assignable> simple_assignable_no_list
145%type <constant> constant
146%type <assignable> special_constant
147%type <assignable> vector_constant
148%type <assignable> quaternion_constant
149%type <assignable> list_constant
150%type <assignable> list_entries
151%type <assignable> list_entry
152%type <type> typename
153%type <global_funcs> global_function
154%type <global_decl> function_parameters
155%type <global_decl> function_parameter
156%type <state> states
157%type <state> other_states
158%type <state> default
159%type <state> state
160%type <handler> state_body
161%type <handler> event
162%type <event> state_entry
163%type <event> state_exit
164%type <event> touch_start
165%type <event> touch
166%type <event> touch_end
167%type <event> collision_start
168%type <event> collision
169%type <event> collision_end
170%type <event> land_collision_start
171%type <event> land_collision
172%type <event> land_collision_end
173%type <event> at_target
174%type <event> not_at_target
175%type <event> at_rot_target
176%type <event> not_at_rot_target
177%type <event> money
178%type <event> email
179%type <event> run_time_permissions
180%type <event> inventory
181%type <event> attach
182%type <event> dataserver
183%type <event> moving_start
184%type <event> moving_end
185%type <event> rez
186%type <event> object_rez
187%type <event> remote_data
188%type <event> http_response
189%type <event> link_message
190%type <event> timer
191%type <event> chat
192%type <event> sensor
193%type <event> no_sensor
194%type <event> control
195%type <statement> compound_statement
196%type <statement> statement
197%type <statement> statements
198%type <statement> declaration
199%type <statement> ';'
200%type <statement> '@'
201%type <expression> nextforexpressionlist
202%type <expression> forexpressionlist
203%type <expression> nextfuncexpressionlist
204%type <expression> funcexpressionlist
205%type <expression> nextlistexpressionlist
206%type <expression> listexpressionlist
207%type <expression> unarypostfixexpression
208%type <expression> vector_initializer
209%type <expression> quaternion_initializer
210%type <expression> list_initializer
211%type <expression> lvalue
212%type <expression> '-'
213%type <expression> '!'
214%type <expression> '~'
215%type <expression> '='
216%type <expression> '<'
217%type <expression> '>'
218%type <expression> '+'
219%type <expression> '*'
220%type <expression> '/'
221%type <expression> '%'
222%type <expression> '&'
223%type <expression> '|'
224%type <expression> '^'
225%type <expression> ADD_ASSIGN
226%type <expression> SUB_ASSIGN
227%type <expression> MUL_ASSIGN
228%type <expression> DIV_ASSIGN
229%type <expression> MOD_ASSIGN
230%type <expression> EQ
231%type <expression> NEQ
232%type <expression> LEQ
233%type <expression> GEQ
234%type <expression> BOOLEAN_AND
235%type <expression> BOOLEAN_OR
236%type <expression> SHIFT_LEFT
237%type <expression> SHIFT_RIGHT
238%type <expression> INC_OP
239%type <expression> DEC_OP
240%type <expression> '('
241%type <expression> ')'
242%type <expression> PRINT
243%type <identifier> name_type
244%type <expression> expression
245%type <expression> unaryexpression
246%type <expression> typecast
247
248%right '=' MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN ADD_ASSIGN SUB_ASSIGN
249%left BOOLEAN_AND BOOLEAN_OR
250%left '|'
251%left '^'
252%left '&'
253%left EQ NEQ
254%left '<' LEQ '>' GEQ
255%left SHIFT_LEFT SHIFT_RIGHT
256%left '+' '-'
257%left '*' '/' '%'
258%right '!' '~' INC_OP DEC_OP
259%nonassoc INITIALIZER
260
261%%
262
263lscript_program
264 : globals states
265 {
266 $$ = new LLScriptScript($1, $2);
267 gAllocationManager->addAllocation($$);
268 gScriptp = $$;
269 }
270 | states
271 {
272 $$ = new LLScriptScript(NULL, $1);
273 gAllocationManager->addAllocation($$);
274 gScriptp = $$;
275 }
276 ;
277
278globals
279 : global
280 {
281 $$ = $1;
282 }
283 | global globals
284 {
285 $$ = $1;
286 $1->addGlobal($2);
287 }
288 ;
289
290global
291 : global_variable
292 {
293 $$ = new LLScritpGlobalStorage($1);
294 gAllocationManager->addAllocation($$);
295 }
296 | global_function
297 {
298 $$ = new LLScritpGlobalStorage($1);
299 gAllocationManager->addAllocation($$);
300 }
301 ;
302
303name_type
304 : typename IDENTIFIER
305 {
306 $$ = new LLScriptIdentifier(gLine, gColumn, $2, $1);
307 gAllocationManager->addAllocation($$);
308 }
309 ;
310
311global_variable
312 : name_type ';'
313 {
314 $$ = new LLScriptGlobalVariable(gLine, gColumn, $1->mType, $1, NULL);
315 gAllocationManager->addAllocation($$);
316 }
317 | name_type '=' simple_assignable ';'
318 {
319 $$ = new LLScriptGlobalVariable(gLine, gColumn, $1->mType, $1, $3);
320 gAllocationManager->addAllocation($$);
321 }
322 ;
323
324simple_assignable
325 : simple_assignable_no_list
326 {
327 $$ = $1;
328 }
329 | list_constant
330 {
331 $$ = $1;
332 }
333 ;
334
335simple_assignable_no_list
336 : IDENTIFIER
337 {
338 LLScriptIdentifier *id = new LLScriptIdentifier(gLine, gColumn, $1);
339 gAllocationManager->addAllocation(id);
340 $$ = new LLScriptSAIdentifier(gLine, gColumn, id);
341 gAllocationManager->addAllocation($$);
342 }
343 | constant
344 {
345 $$ = new LLScriptSAConstant(gLine, gColumn, $1);
346 gAllocationManager->addAllocation($$);
347 }
348 | special_constant
349 {
350 $$ = $1;
351 }
352 ;
353
354constant
355 : INTEGER_CONSTANT
356 {
357 $$ = new LLScriptConstantInteger(gLine, gColumn, $1);
358 gAllocationManager->addAllocation($$);
359 }
360 | INTEGER_TRUE
361 {
362 $$ = new LLScriptConstantInteger(gLine, gColumn, $1);
363 gAllocationManager->addAllocation($$);
364 }
365 | INTEGER_FALSE
366 {
367 $$ = new LLScriptConstantInteger(gLine, gColumn, $1);
368 gAllocationManager->addAllocation($$);
369 }
370 | FP_CONSTANT
371 {
372 $$ = new LLScriptConstantFloat(gLine, gColumn, $1);
373 gAllocationManager->addAllocation($$);
374 }
375 | STRING_CONSTANT
376 {
377 $$ = new LLScriptConstantString(gLine, gColumn, $1);
378 gAllocationManager->addAllocation($$);
379 }
380 ;
381
382special_constant
383 : vector_constant
384 {
385 $$ = $1;
386 }
387 | quaternion_constant
388 {
389 $$ = $1;
390 }
391 ;
392
393vector_constant
394 : '<' simple_assignable ',' simple_assignable ',' simple_assignable '>'
395 {
396 $$ = new LLScriptSAVector(gLine, gColumn, $2, $4, $6);
397 gAllocationManager->addAllocation($$);
398 }
399 | ZERO_VECTOR
400 {
401 LLScriptConstantFloat *cf0 = new LLScriptConstantFloat(gLine, gColumn, 0.f);
402 gAllocationManager->addAllocation(cf0);
403 LLScriptSAConstant *sa0 = new LLScriptSAConstant(gLine, gColumn, cf0);
404 gAllocationManager->addAllocation(sa0);
405 LLScriptConstantFloat *cf1 = new LLScriptConstantFloat(gLine, gColumn, 0.f);
406 gAllocationManager->addAllocation(cf1);
407 LLScriptSAConstant *sa1 = new LLScriptSAConstant(gLine, gColumn, cf1);
408 gAllocationManager->addAllocation(sa1);
409 LLScriptConstantFloat *cf2 = new LLScriptConstantFloat(gLine, gColumn, 0.f);
410 gAllocationManager->addAllocation(cf2);
411 LLScriptSAConstant *sa2 = new LLScriptSAConstant(gLine, gColumn, cf2);
412 gAllocationManager->addAllocation(sa2);
413 $$ = new LLScriptSAVector(gLine, gColumn, sa0, sa1, sa2);
414 gAllocationManager->addAllocation($$);
415 }
416 ;
417
418quaternion_constant
419 : '<' simple_assignable ',' simple_assignable ',' simple_assignable ',' simple_assignable '>'
420 {
421 $$ = new LLScriptSAQuaternion(gLine, gColumn, $2, $4, $6, $8);
422 gAllocationManager->addAllocation($$);
423 }
424 | ZERO_ROTATION
425 {
426 LLScriptConstantFloat *cf0 = new LLScriptConstantFloat(gLine, gColumn, 0.f);
427 gAllocationManager->addAllocation(cf0);
428 LLScriptSAConstant *sa0 = new LLScriptSAConstant(gLine, gColumn, cf0);
429 gAllocationManager->addAllocation(sa0);
430 LLScriptConstantFloat *cf1 = new LLScriptConstantFloat(gLine, gColumn, 0.f);
431 gAllocationManager->addAllocation(cf1);
432 LLScriptSAConstant *sa1 = new LLScriptSAConstant(gLine, gColumn, cf1);
433 gAllocationManager->addAllocation(sa1);
434 LLScriptConstantFloat *cf2 = new LLScriptConstantFloat(gLine, gColumn, 0.f);
435 gAllocationManager->addAllocation(cf2);
436 LLScriptSAConstant *sa2 = new LLScriptSAConstant(gLine, gColumn, cf2);
437 gAllocationManager->addAllocation(sa2);
438 LLScriptConstantFloat *cf3 = new LLScriptConstantFloat(gLine, gColumn, 1.f);
439 gAllocationManager->addAllocation(cf3);
440 LLScriptSAConstant *sa3 = new LLScriptSAConstant(gLine, gColumn, cf3);
441 gAllocationManager->addAllocation(sa3);
442 $$ = new LLScriptSAQuaternion(gLine, gColumn, sa0, sa1, sa2, sa3);
443 gAllocationManager->addAllocation($$);
444 }
445 ;
446
447list_constant
448 : '[' list_entries ']'
449 {
450 $$ = new LLScriptSAList(gLine, gColumn, $2);
451 gAllocationManager->addAllocation($$);
452 }
453 | '[' ']'
454 {
455 $$ = new LLScriptSAList(gLine, gColumn, NULL);
456 gAllocationManager->addAllocation($$);
457 }
458 ;
459
460list_entries
461 : list_entry
462 {
463 $$ = $1;
464 }
465 | list_entry ',' list_entries
466 {
467 $$ = $1;
468 $1->addAssignable($3);
469 }
470 ;
471
472list_entry
473 : simple_assignable_no_list
474 {
475 $$ = $1;
476 }
477 ;
478
479typename
480 : INTEGER
481 {
482 $$ = new LLScriptType(gLine, gColumn, LST_INTEGER);
483 gAllocationManager->addAllocation($$);
484 }
485 | FLOAT_TYPE
486 {
487 $$ = new LLScriptType(gLine, gColumn, LST_FLOATINGPOINT);
488 gAllocationManager->addAllocation($$);
489 }
490 | STRING
491 {
492 $$ = new LLScriptType(gLine, gColumn, LST_STRING);
493 gAllocationManager->addAllocation($$);
494 }
495 | LLKEY
496 {
497 $$ = new LLScriptType(gLine, gColumn, LST_KEY);
498 gAllocationManager->addAllocation($$);
499 }
500 | VECTOR
501 {
502 $$ = new LLScriptType(gLine, gColumn, LST_VECTOR);
503 gAllocationManager->addAllocation($$);
504 }
505 | QUATERNION
506 {
507 $$ = new LLScriptType(gLine, gColumn, LST_QUATERNION);
508 gAllocationManager->addAllocation($$);
509 }
510 | LIST
511 {
512 $$ = new LLScriptType(gLine, gColumn, LST_LIST);
513 gAllocationManager->addAllocation($$);
514 }
515 ;
516
517global_function
518 : IDENTIFIER '(' ')' compound_statement
519 {
520 LLScriptIdentifier *id = new LLScriptIdentifier(gLine, gColumn, $1);
521 gAllocationManager->addAllocation(id);
522 $$ = new LLScriptGlobalFunctions(gLine, gColumn, NULL, id, NULL, $4);
523 gAllocationManager->addAllocation($$);
524 }
525 | name_type '(' ')' compound_statement
526 {
527 $$ = new LLScriptGlobalFunctions(gLine, gColumn, $1->mType, $1, NULL, $4);
528 gAllocationManager->addAllocation($$);
529 }
530 | IDENTIFIER '(' function_parameters ')' compound_statement
531 {
532 LLScriptIdentifier *id = new LLScriptIdentifier(gLine, gColumn, $1);
533 gAllocationManager->addAllocation(id);
534 $$ = new LLScriptGlobalFunctions(gLine, gColumn, NULL, id, $3, $5);
535 gAllocationManager->addAllocation($$);
536 }
537 | name_type '(' function_parameters ')' compound_statement
538 {
539 $$ = new LLScriptGlobalFunctions(gLine, gColumn, $1->mType, $1, $3, $5);
540 gAllocationManager->addAllocation($$);
541 }
542 ;
543
544function_parameters
545 : function_parameter
546 {
547 $$ = $1;
548 }
549 | function_parameter ',' function_parameters
550 {
551 $$ = $1;
552 $1->addFunctionParameter($3);
553 }
554 ;
555
556function_parameter
557 : typename IDENTIFIER
558 {
559 LLScriptIdentifier *id = new LLScriptIdentifier(gLine, gColumn, $2);
560 gAllocationManager->addAllocation(id);
561 $$ = new LLScriptFunctionDec(gLine, gColumn, $1, id);
562 gAllocationManager->addAllocation($$);
563 }
564 ;
565
566states
567 : default
568 {
569 $$ = $1;
570 }
571 | default other_states
572 {
573 $$ = $1;
574 $1->mNextp = $2;
575 }
576 ;
577
578other_states
579 : state
580 {
581 $$ = $1;
582 }
583 | state other_states
584 {
585 $$ = $1;
586 $1->addState($2);
587 }
588 ;
589
590default
591 : STATE_DEFAULT '{' state_body '}'
592 {
593 LLScriptIdentifier *id = new LLScriptIdentifier(gLine, gColumn, $1);
594 gAllocationManager->addAllocation(id);
595 $$ = new LLScriptState(gLine, gColumn, LSSTYPE_DEFAULT, id, $3);
596 gAllocationManager->addAllocation($$);
597 }
598 ;
599
600state
601 : STATE IDENTIFIER '{' state_body '}'
602 {
603 LLScriptIdentifier *id = new LLScriptIdentifier(gLine, gColumn, $2);
604 gAllocationManager->addAllocation(id);
605 $$ = new LLScriptState(gLine, gColumn, LSSTYPE_USER, id, $4);
606 gAllocationManager->addAllocation($$);
607 }
608 ;
609
610state_body
611 : event
612 {
613 $$ = $1;
614 }
615 | event state_body
616 {
617 $$ = $1;
618 $1->addEvent($2);
619 }
620 ;
621
622event
623 : state_entry compound_statement
624 {
625 $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
626 gAllocationManager->addAllocation($$);
627 }
628 | state_exit compound_statement
629 {
630 $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
631 gAllocationManager->addAllocation($$);
632 }
633 | touch_start compound_statement
634 {
635 $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
636 gAllocationManager->addAllocation($$);
637 }
638 | touch compound_statement
639 {
640 $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
641 gAllocationManager->addAllocation($$);
642 }
643 | touch_end compound_statement
644 {
645 $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
646 gAllocationManager->addAllocation($$);
647 }
648 | collision_start compound_statement
649 {
650 $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
651 gAllocationManager->addAllocation($$);
652 }
653 | collision compound_statement
654 {
655 $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
656 gAllocationManager->addAllocation($$);
657 }
658 | collision_end compound_statement
659 {
660 $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
661 gAllocationManager->addAllocation($$);
662 }
663 | land_collision_start compound_statement
664 {
665 $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
666 gAllocationManager->addAllocation($$);
667 }
668 | land_collision compound_statement
669 {
670 $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
671 gAllocationManager->addAllocation($$);
672 }
673 | land_collision_end compound_statement
674 {
675 $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
676 gAllocationManager->addAllocation($$);
677 }
678 | timer compound_statement
679 {
680 $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
681 gAllocationManager->addAllocation($$);
682 }
683 | chat compound_statement
684 {
685 $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
686 gAllocationManager->addAllocation($$);
687 }
688 | sensor compound_statement
689 {
690 $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
691 gAllocationManager->addAllocation($$);
692 }
693 | no_sensor compound_statement
694 {
695 $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
696 gAllocationManager->addAllocation($$);
697 }
698 | at_target compound_statement
699 {
700 $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
701 gAllocationManager->addAllocation($$);
702 }
703 | not_at_target compound_statement
704 {
705 $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
706 gAllocationManager->addAllocation($$);
707 }
708 | at_rot_target compound_statement
709 {
710 $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
711 gAllocationManager->addAllocation($$);
712 }
713 | not_at_rot_target compound_statement
714 {
715 $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
716 gAllocationManager->addAllocation($$);
717 }
718 | money compound_statement
719 {
720 $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
721 gAllocationManager->addAllocation($$);
722 }
723 | email compound_statement
724 {
725 $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
726 gAllocationManager->addAllocation($$);
727 }
728 | run_time_permissions compound_statement
729 {
730 $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
731 gAllocationManager->addAllocation($$);
732 }
733 | inventory compound_statement
734 {
735 $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
736 gAllocationManager->addAllocation($$);
737 }
738 | attach compound_statement
739 {
740 $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
741 gAllocationManager->addAllocation($$);
742 }
743 | dataserver compound_statement
744 {
745 $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
746 gAllocationManager->addAllocation($$);
747 }
748 | control compound_statement
749 {
750 $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
751 gAllocationManager->addAllocation($$);
752 }
753 | moving_start compound_statement
754 {
755 $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
756 gAllocationManager->addAllocation($$);
757 }
758 | moving_end compound_statement
759 {
760 $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
761 gAllocationManager->addAllocation($$);
762 }
763 | rez compound_statement
764 {
765 $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
766 gAllocationManager->addAllocation($$);
767 }
768 | object_rez compound_statement
769 {
770 $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
771 gAllocationManager->addAllocation($$);
772 }
773 | link_message compound_statement
774 {
775 $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
776 gAllocationManager->addAllocation($$);
777 }
778 | remote_data compound_statement
779 {
780 $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
781 gAllocationManager->addAllocation($$);
782 }
783 | http_response compound_statement
784 {
785 $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
786 gAllocationManager->addAllocation($$);
787 }
788 ;
789
790state_entry
791 : STATE_ENTRY '(' ')'
792 {
793 $$ = new LLScriptStateEntryEvent(gLine, gColumn);
794 gAllocationManager->addAllocation($$);
795 }
796 ;
797
798state_exit
799 : STATE_EXIT '(' ')'
800 {
801 $$ = new LLScriptStateExitEvent(gLine, gColumn);
802 gAllocationManager->addAllocation($$);
803 }
804 ;
805
806touch_start
807 : TOUCH_START '(' INTEGER IDENTIFIER ')'
808 {
809 LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4);
810 gAllocationManager->addAllocation(id1);
811 $$ = new LLScriptTouchStartEvent(gLine, gColumn, id1);
812 gAllocationManager->addAllocation($$);
813 }
814 ;
815
816touch
817 : TOUCH '(' INTEGER IDENTIFIER ')'
818 {
819 LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4);
820 gAllocationManager->addAllocation(id1);
821 $$ = new LLScriptTouchEvent(gLine, gColumn, id1);
822 gAllocationManager->addAllocation($$);
823 }
824 ;
825
826touch_end
827 : TOUCH_END '(' INTEGER IDENTIFIER ')'
828 {
829 LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4);
830 gAllocationManager->addAllocation(id1);
831 $$ = new LLScriptTouchEndEvent(gLine, gColumn, id1);
832 gAllocationManager->addAllocation($$);
833 }
834 ;
835
836collision_start
837 : COLLISION_START '(' INTEGER IDENTIFIER ')'
838 {
839 LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4);
840 gAllocationManager->addAllocation(id1);
841 $$ = new LLScriptCollisionStartEvent(gLine, gColumn, id1);
842 gAllocationManager->addAllocation($$);
843 }
844 ;
845
846collision
847 : COLLISION '(' INTEGER IDENTIFIER ')'
848 {
849 LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4);
850 gAllocationManager->addAllocation(id1);
851 $$ = new LLScriptCollisionEvent(gLine, gColumn, id1);
852 gAllocationManager->addAllocation($$);
853 }
854 ;
855
856collision_end
857 : COLLISION_END '(' INTEGER IDENTIFIER ')'
858 {
859 LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4);
860 gAllocationManager->addAllocation(id1);
861 $$ = new LLScriptCollisionEndEvent(gLine, gColumn, id1);
862 gAllocationManager->addAllocation($$);
863 }
864 ;
865
866land_collision_start
867 : LAND_COLLISION_START '(' VECTOR IDENTIFIER ')'
868 {
869 LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4);
870 gAllocationManager->addAllocation(id1);
871 $$ = new LLScriptLandCollisionStartEvent(gLine, gColumn, id1);
872 gAllocationManager->addAllocation($$);
873 }
874 ;
875
876land_collision
877 : LAND_COLLISION '(' VECTOR IDENTIFIER ')'
878 {
879 LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4);
880 gAllocationManager->addAllocation(id1);
881 $$ = new LLScriptLandCollisionEvent(gLine, gColumn, id1);
882 gAllocationManager->addAllocation($$);
883 }
884 ;
885
886land_collision_end
887 : LAND_COLLISION_END '(' VECTOR IDENTIFIER ')'
888 {
889 LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4);
890 gAllocationManager->addAllocation(id1);
891 $$ = new LLScriptLandCollisionEndEvent(gLine, gColumn, id1);
892 gAllocationManager->addAllocation($$);
893 }
894 ;
895
896at_target
897 : AT_TARGET '(' INTEGER IDENTIFIER ',' VECTOR IDENTIFIER ',' VECTOR IDENTIFIER ')'
898 {
899 LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4);
900 gAllocationManager->addAllocation(id1);
901 LLScriptIdentifier *id2 = new LLScriptIdentifier(gLine, gColumn, $7);
902 gAllocationManager->addAllocation(id2);
903 LLScriptIdentifier *id3 = new LLScriptIdentifier(gLine, gColumn, $10);
904 gAllocationManager->addAllocation(id3);
905 $$ = new LLScriptAtTarget(gLine, gColumn, id1, id2, id3);
906 gAllocationManager->addAllocation($$);
907 }
908 ;
909
910not_at_target
911 : NOT_AT_TARGET '(' ')'
912 {
913 $$ = new LLScriptNotAtTarget(gLine, gColumn);
914 gAllocationManager->addAllocation($$);
915 }
916 ;
917
918at_rot_target
919 : AT_ROT_TARGET '(' INTEGER IDENTIFIER ',' QUATERNION IDENTIFIER ',' QUATERNION IDENTIFIER ')'
920 {
921 LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4);
922 gAllocationManager->addAllocation(id1);
923 LLScriptIdentifier *id2 = new LLScriptIdentifier(gLine, gColumn, $7);
924 gAllocationManager->addAllocation(id2);
925 LLScriptIdentifier *id3 = new LLScriptIdentifier(gLine, gColumn, $10);
926 gAllocationManager->addAllocation(id3);
927 $$ = new LLScriptAtRotTarget(gLine, gColumn, id1, id2, id3);
928 gAllocationManager->addAllocation($$);
929 }
930 ;
931
932not_at_rot_target
933 : NOT_AT_ROT_TARGET '(' ')'
934 {
935 $$ = new LLScriptNotAtRotTarget(gLine, gColumn);
936 gAllocationManager->addAllocation($$);
937 }
938 ;
939
940money
941 : MONEY '(' LLKEY IDENTIFIER ',' INTEGER IDENTIFIER ')'
942 {
943 LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4);
944 gAllocationManager->addAllocation(id1);
945 LLScriptIdentifier *id2 = new LLScriptIdentifier(gLine, gColumn, $7);
946 gAllocationManager->addAllocation(id2);
947 $$ = new LLScriptMoneyEvent(gLine, gColumn, id1, id2);
948 gAllocationManager->addAllocation($$);
949 }
950 ;
951
952email
953 : EMAIL '(' STRING IDENTIFIER ',' STRING IDENTIFIER ',' STRING IDENTIFIER ',' STRING IDENTIFIER ',' INTEGER IDENTIFIER ')'
954 {
955 LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4);
956 gAllocationManager->addAllocation(id1);
957 LLScriptIdentifier *id2 = new LLScriptIdentifier(gLine, gColumn, $7);
958 gAllocationManager->addAllocation(id2);
959 LLScriptIdentifier *id3 = new LLScriptIdentifier(gLine, gColumn, $10);
960 gAllocationManager->addAllocation(id3);
961 LLScriptIdentifier *id4 = new LLScriptIdentifier(gLine, gColumn, $13);
962 gAllocationManager->addAllocation(id4);
963 LLScriptIdentifier *id5 = new LLScriptIdentifier(gLine, gColumn, $16);
964 gAllocationManager->addAllocation(id5);
965 $$ = new LLScriptEmailEvent(gLine, gColumn, id1, id2, id3, id4, id5);
966 gAllocationManager->addAllocation($$);
967 }
968 ;
969
970run_time_permissions
971 : RUN_TIME_PERMISSIONS '(' INTEGER IDENTIFIER ')'
972 {
973 LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4);
974 gAllocationManager->addAllocation(id1);
975 $$ = new LLScriptRTPEvent(gLine, gColumn, id1);
976 gAllocationManager->addAllocation($$);
977 }
978 ;
979
980inventory
981 : INVENTORY '(' INTEGER IDENTIFIER ')'
982 {
983 LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4);
984 gAllocationManager->addAllocation(id1);
985 $$ = new LLScriptInventoryEvent(gLine, gColumn, id1);
986 gAllocationManager->addAllocation($$);
987 }
988 ;
989
990attach
991 : ATTACH '(' LLKEY IDENTIFIER ')'
992 {
993 LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4);
994 gAllocationManager->addAllocation(id1);
995 $$ = new LLScriptAttachEvent(gLine, gColumn, id1);
996 gAllocationManager->addAllocation($$);
997 }
998 ;
999
1000dataserver
1001 : DATASERVER '(' LLKEY IDENTIFIER ',' STRING IDENTIFIER')'
1002 {
1003 LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4);
1004 gAllocationManager->addAllocation(id1);
1005 LLScriptIdentifier *id2 = new LLScriptIdentifier(gLine, gColumn, $7);
1006 gAllocationManager->addAllocation(id2);
1007 $$ = new LLScriptDataserverEvent(gLine, gColumn, id1, id2);
1008 gAllocationManager->addAllocation($$);
1009 }
1010 ;
1011
1012moving_start
1013 : MOVING_START '(' ')'
1014 {
1015 $$ = new LLScriptMovingStartEvent(gLine, gColumn);
1016 gAllocationManager->addAllocation($$);
1017 }
1018 ;
1019
1020moving_end
1021 : MOVING_END '(' ')'
1022 {
1023 $$ = new LLScriptMovingEndEvent(gLine, gColumn);
1024 gAllocationManager->addAllocation($$);
1025 }
1026 ;
1027
1028timer
1029 : TIMER '(' ')'
1030 {
1031 $$ = new LLScriptTimerEvent(gLine, gColumn);
1032 gAllocationManager->addAllocation($$);
1033 }
1034 ;
1035
1036chat
1037 : CHAT '(' INTEGER IDENTIFIER ',' STRING IDENTIFIER ',' LLKEY IDENTIFIER ',' STRING IDENTIFIER ')'
1038 {
1039 LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4);
1040 gAllocationManager->addAllocation(id1);
1041 LLScriptIdentifier *id2 = new LLScriptIdentifier(gLine, gColumn, $7);
1042 gAllocationManager->addAllocation(id2);
1043 LLScriptIdentifier *id3 = new LLScriptIdentifier(gLine, gColumn, $10);
1044 gAllocationManager->addAllocation(id3);
1045 LLScriptIdentifier *id4 = new LLScriptIdentifier(gLine, gColumn, $13);
1046 gAllocationManager->addAllocation(id4);
1047 $$ = new LLScriptChatEvent(gLine, gColumn, id1, id2, id3, id4);
1048 gAllocationManager->addAllocation($$);
1049 }
1050 ;
1051
1052sensor
1053 : SENSOR '(' INTEGER IDENTIFIER ')'
1054 {
1055 LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4);
1056 gAllocationManager->addAllocation(id1);
1057 $$ = new LLScriptSensorEvent(gLine, gColumn, id1);
1058 gAllocationManager->addAllocation($$);
1059 }
1060 ;
1061
1062no_sensor
1063 : NO_SENSOR '(' ')'
1064 {
1065 $$ = new LLScriptNoSensorEvent(gLine, gColumn);
1066 gAllocationManager->addAllocation($$);
1067 }
1068 ;
1069
1070control
1071 : CONTROL '(' LLKEY IDENTIFIER ',' INTEGER IDENTIFIER ',' INTEGER IDENTIFIER ')'
1072 {
1073 LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4);
1074 gAllocationManager->addAllocation(id1);
1075 LLScriptIdentifier *id2 = new LLScriptIdentifier(gLine, gColumn, $7);
1076 gAllocationManager->addAllocation(id2);
1077 LLScriptIdentifier *id3 = new LLScriptIdentifier(gLine, gColumn, $10);
1078 gAllocationManager->addAllocation(id3);
1079 $$ = new LLScriptControlEvent(gLine, gColumn, id1, id2, id3);
1080 gAllocationManager->addAllocation($$);
1081 }
1082 ;
1083
1084rez
1085 : REZ '(' INTEGER IDENTIFIER ')'
1086 {
1087 LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4);
1088 gAllocationManager->addAllocation(id1);
1089 $$ = new LLScriptRezEvent(gLine, gColumn, id1);
1090 gAllocationManager->addAllocation($$);
1091 }
1092 ;
1093
1094object_rez
1095 : OBJECT_REZ '(' LLKEY IDENTIFIER ')'
1096 {
1097 LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4);
1098 gAllocationManager->addAllocation(id1);
1099 $$ = new LLScriptObjectRezEvent(gLine, gColumn, id1);
1100 gAllocationManager->addAllocation($$);
1101 }
1102 ;
1103
1104link_message
1105 : LINK_MESSAGE '(' INTEGER IDENTIFIER ',' INTEGER IDENTIFIER ',' STRING IDENTIFIER ',' LLKEY IDENTIFIER ')'
1106 {
1107 LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4);
1108 gAllocationManager->addAllocation(id1);
1109 LLScriptIdentifier *id2 = new LLScriptIdentifier(gLine, gColumn, $7);
1110 gAllocationManager->addAllocation(id2);
1111 LLScriptIdentifier *id3 = new LLScriptIdentifier(gLine, gColumn, $10);
1112 gAllocationManager->addAllocation(id3);
1113 LLScriptIdentifier *id4 = new LLScriptIdentifier(gLine, gColumn, $13);
1114 gAllocationManager->addAllocation(id4);
1115 $$ = new LLScriptLinkMessageEvent(gLine, gColumn, id1, id2, id3, id4);
1116 gAllocationManager->addAllocation($$);
1117 }
1118 ;
1119
1120remote_data
1121 : REMOTE_DATA '(' INTEGER IDENTIFIER ',' LLKEY IDENTIFIER ',' LLKEY IDENTIFIER ',' STRING IDENTIFIER ',' INTEGER IDENTIFIER ',' STRING IDENTIFIER ')'
1122 {
1123 LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4);
1124 gAllocationManager->addAllocation(id1);
1125 LLScriptIdentifier *id2 = new LLScriptIdentifier(gLine, gColumn, $7);
1126 gAllocationManager->addAllocation(id2);
1127 LLScriptIdentifier *id3 = new LLScriptIdentifier(gLine, gColumn, $10);
1128 gAllocationManager->addAllocation(id3);
1129 LLScriptIdentifier *id4 = new LLScriptIdentifier(gLine, gColumn, $13);
1130 gAllocationManager->addAllocation(id4);
1131 LLScriptIdentifier *id5 = new LLScriptIdentifier(gLine, gColumn, $16);
1132 gAllocationManager->addAllocation(id4);
1133 LLScriptIdentifier *id6 = new LLScriptIdentifier(gLine, gColumn, $19);
1134 gAllocationManager->addAllocation(id4);
1135 $$ = new LLScriptRemoteEvent(gLine, gColumn, id1, id2, id3, id4, id5, id6);
1136 gAllocationManager->addAllocation($$);
1137 }
1138 ;
1139
1140http_response
1141 : HTTP_RESPONSE '(' LLKEY IDENTIFIER ',' INTEGER IDENTIFIER ',' LIST IDENTIFIER ',' STRING IDENTIFIER ')'
1142 {
1143 LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4);
1144 gAllocationManager->addAllocation(id1);
1145 LLScriptIdentifier *id2 = new LLScriptIdentifier(gLine, gColumn, $7);
1146 gAllocationManager->addAllocation(id2);
1147 LLScriptIdentifier *id3 = new LLScriptIdentifier(gLine, gColumn, $10);
1148 gAllocationManager->addAllocation(id3);
1149 LLScriptIdentifier *id4 = new LLScriptIdentifier(gLine, gColumn, $13);
1150 gAllocationManager->addAllocation(id4);
1151 $$ = new LLScriptHTTPResponseEvent(gLine, gColumn, id1, id2, id3, id4);
1152 gAllocationManager->addAllocation($$);
1153 }
1154 ;
1155
1156compound_statement
1157 : '{' '}'
1158 {
1159 $$ = new LLScriptCompoundStatement(gLine, gColumn, NULL);
1160 gAllocationManager->addAllocation($$);
1161 }
1162 | '{' statements '}'
1163 {
1164 $$ = new LLScriptCompoundStatement(gLine, gColumn, $2);
1165 gAllocationManager->addAllocation($$);
1166 }
1167 ;
1168
1169statements
1170 : statement
1171 {
1172 $$ = $1;
1173 }
1174 | statements statement
1175 {
1176 $$ = new LLScriptStatementSequence(gLine, gColumn, $1, $2);
1177 gAllocationManager->addAllocation($$);
1178 }
1179 ;
1180
1181statement
1182 : ';'
1183 {
1184 $$ = new LLScriptNOOP(gLine, gColumn);
1185 gAllocationManager->addAllocation($$);
1186 }
1187 | STATE IDENTIFIER ';'
1188 {
1189 LLScriptIdentifier *id = new LLScriptIdentifier(gLine, gColumn, $2);
1190 gAllocationManager->addAllocation(id);
1191 $$ = new LLScriptStateChange(gLine, gColumn, id);
1192 gAllocationManager->addAllocation($$);
1193 }
1194 | STATE STATE_DEFAULT ';'
1195 {
1196 LLScriptIdentifier *id = new LLScriptIdentifier(gLine, gColumn, $2);
1197 gAllocationManager->addAllocation(id);
1198 $$ = new LLScriptStateChange(gLine, gColumn, id);
1199 gAllocationManager->addAllocation($$);
1200 }
1201 | JUMP IDENTIFIER ';'
1202 {
1203 LLScriptIdentifier *id = new LLScriptIdentifier(gLine, gColumn, $2);
1204 gAllocationManager->addAllocation(id);
1205 $$ = new LLScriptJump(gLine, gColumn, id);
1206 gAllocationManager->addAllocation($$);
1207 }
1208 | '@' IDENTIFIER ';'
1209 {
1210 LLScriptIdentifier *id = new LLScriptIdentifier(gLine, gColumn, $2);
1211 gAllocationManager->addAllocation(id);
1212 $$ = new LLScriptLabel(gLine, gColumn, id);
1213 gAllocationManager->addAllocation($$);
1214 }
1215 | RETURN expression ';'
1216 {
1217 $$ = new LLScriptReturn(gLine, gColumn, $2);
1218 gAllocationManager->addAllocation($$);
1219 }
1220 | RETURN ';'
1221 {
1222 $$ = new LLScriptReturn(gLine, gColumn, NULL);
1223 gAllocationManager->addAllocation($$);
1224 }
1225 | expression ';'
1226 {
1227 $$ = new LLScriptExpressionStatement(gLine, gColumn, $1);
1228 gAllocationManager->addAllocation($$);
1229 }
1230 | declaration ';'
1231 {
1232 $$ = $1;
1233 }
1234 | compound_statement
1235 {
1236 $$ = $1;
1237 }
1238 | IF '(' expression ')' statement %prec LOWER_THAN_ELSE
1239 {
1240 $$ = new LLScriptIf(gLine, gColumn, $3, $5);
1241 $5->mAllowDeclarations = FALSE;
1242 gAllocationManager->addAllocation($$);
1243 }
1244 | IF '(' expression ')' statement ELSE statement
1245 {
1246 $$ = new LLScriptIfElse(gLine, gColumn, $3, $5, $7);
1247 $5->mAllowDeclarations = FALSE;
1248 $7->mAllowDeclarations = FALSE;
1249 gAllocationManager->addAllocation($$);
1250 }
1251 | FOR '(' forexpressionlist ';' expression ';' forexpressionlist ')' statement
1252 {
1253 $$ = new LLScriptFor(gLine, gColumn, $3, $5, $7, $9);
1254 $9->mAllowDeclarations = FALSE;
1255 gAllocationManager->addAllocation($$);
1256 }
1257 | DO statement WHILE '(' expression ')' ';'
1258 {
1259 $$ = new LLScriptDoWhile(gLine, gColumn, $2, $5);
1260 $2->mAllowDeclarations = FALSE;
1261 gAllocationManager->addAllocation($$);
1262 }
1263 | WHILE '(' expression ')' statement
1264 {
1265 $$ = new LLScriptWhile(gLine, gColumn, $3, $5);
1266 $5->mAllowDeclarations = FALSE;
1267 gAllocationManager->addAllocation($$);
1268 }
1269 ;
1270
1271declaration
1272 : typename IDENTIFIER
1273 {
1274 LLScriptIdentifier *id = new LLScriptIdentifier(gLine, gColumn, $2);
1275 gAllocationManager->addAllocation(id);
1276 $$ = new LLScriptDeclaration(gLine, gColumn, $1, id, NULL);
1277 gAllocationManager->addAllocation($$);
1278 }
1279 | typename IDENTIFIER '=' expression
1280 {
1281 LLScriptIdentifier *id = new LLScriptIdentifier(gLine, gColumn, $2);
1282 gAllocationManager->addAllocation(id);
1283 $$ = new LLScriptDeclaration(gLine, gColumn, $1, id, $4);
1284 gAllocationManager->addAllocation($$);
1285 }
1286 ;
1287
1288forexpressionlist
1289 : /* empty */
1290 {
1291 $$ = NULL;
1292 }
1293 | nextforexpressionlist
1294 {
1295 $$ = $1;
1296 }
1297 ;
1298
1299nextforexpressionlist
1300 : expression
1301 {
1302 $$ = new LLScriptForExpressionList(gLine, gColumn, $1, NULL);
1303 gAllocationManager->addAllocation($$);
1304 }
1305 | expression ',' nextforexpressionlist
1306 {
1307 $$ = new LLScriptForExpressionList(gLine, gColumn, $1, $3);
1308 gAllocationManager->addAllocation($$);
1309 }
1310 ;
1311
1312funcexpressionlist
1313 : /* empty */
1314 {
1315 $$ = NULL;
1316 }
1317 | nextfuncexpressionlist
1318 {
1319 $$ = $1;
1320 }
1321 ;
1322
1323nextfuncexpressionlist
1324 : expression
1325 {
1326 $$ = new LLScriptFuncExpressionList(gLine, gColumn, $1, NULL);
1327 gAllocationManager->addAllocation($$);
1328 }
1329 | expression ',' nextfuncexpressionlist
1330 {
1331 $$ = new LLScriptFuncExpressionList(gLine, gColumn, $1, $3);
1332 gAllocationManager->addAllocation($$);
1333 }
1334 ;
1335
1336listexpressionlist
1337 : /* empty */
1338 {
1339 $$ = NULL;
1340 }
1341 | nextlistexpressionlist
1342 {
1343 $$ = $1;
1344 }
1345 ;
1346
1347nextlistexpressionlist
1348 : expression
1349 {
1350 $$ = new LLScriptListExpressionList(gLine, gColumn, $1, NULL);
1351 gAllocationManager->addAllocation($$);
1352 }
1353 | expression ',' nextlistexpressionlist
1354 {
1355 $$ = new LLScriptListExpressionList(gLine, gColumn, $1, $3);
1356 gAllocationManager->addAllocation($$);
1357 }
1358 ;
1359
1360expression
1361 : unaryexpression
1362 {
1363 $$ = $1;
1364 }
1365 | lvalue '=' expression
1366 {
1367 $$ = new LLScriptAssignment(gLine, gColumn, $1, $3);
1368 gAllocationManager->addAllocation($$);
1369 }
1370 | lvalue ADD_ASSIGN expression
1371 {
1372 $$ = new LLScriptAddAssignment(gLine, gColumn, $1, $3);
1373 gAllocationManager->addAllocation($$);
1374 }
1375 | lvalue SUB_ASSIGN expression
1376 {
1377 $$ = new LLScriptSubAssignment(gLine, gColumn, $1, $3);
1378 gAllocationManager->addAllocation($$);
1379 }
1380 | lvalue MUL_ASSIGN expression
1381 {
1382 $$ = new LLScriptMulAssignment(gLine, gColumn, $1, $3);
1383 gAllocationManager->addAllocation($$);
1384 }
1385 | lvalue DIV_ASSIGN expression
1386 {
1387 $$ = new LLScriptDivAssignment(gLine, gColumn, $1, $3);
1388 gAllocationManager->addAllocation($$);
1389 }
1390 | lvalue MOD_ASSIGN expression
1391 {
1392 $$ = new LLScriptModAssignment(gLine, gColumn, $1, $3);
1393 gAllocationManager->addAllocation($$);
1394 }
1395 | expression EQ expression
1396 {
1397 $$ = new LLScriptEquality(gLine, gColumn, $1, $3);
1398 gAllocationManager->addAllocation($$);
1399 }
1400 | expression NEQ expression
1401 {
1402 $$ = new LLScriptNotEquals(gLine, gColumn, $1, $3);
1403 gAllocationManager->addAllocation($$);
1404 }
1405 | expression LEQ expression
1406 {
1407 $$ = new LLScriptLessEquals(gLine, gColumn, $1, $3);
1408 gAllocationManager->addAllocation($$);
1409 }
1410 | expression GEQ expression
1411 {
1412 $$ = new LLScriptGreaterEquals(gLine, gColumn, $1, $3);
1413 gAllocationManager->addAllocation($$);
1414 }
1415 | expression '<' expression
1416 {
1417 $$ = new LLScriptLessThan(gLine, gColumn, $1, $3);
1418 gAllocationManager->addAllocation($$);
1419 }
1420 | expression '>' expression
1421 {
1422 $$ = new LLScriptGreaterThan(gLine, gColumn, $1, $3);
1423 gAllocationManager->addAllocation($$);
1424 }
1425 | expression '+' expression
1426 {
1427 $$ = new LLScriptPlus(gLine, gColumn, $1, $3);
1428 gAllocationManager->addAllocation($$);
1429 }
1430 | expression '-' expression
1431 {
1432 $$ = new LLScriptMinus(gLine, gColumn, $1, $3);
1433 gAllocationManager->addAllocation($$);
1434 }
1435 | expression '*' expression
1436 {
1437 $$ = new LLScriptTimes(gLine, gColumn, $1, $3);
1438 gAllocationManager->addAllocation($$);
1439 }
1440 | expression '/' expression
1441 {
1442 $$ = new LLScriptDivide(gLine, gColumn, $1, $3);
1443 gAllocationManager->addAllocation($$);
1444 }
1445 | expression '%' expression
1446 {
1447 $$ = new LLScriptMod(gLine, gColumn, $1, $3);
1448 gAllocationManager->addAllocation($$);
1449 }
1450 | expression '&' expression
1451 {
1452 $$ = new LLScriptBitAnd(gLine, gColumn, $1, $3);
1453 gAllocationManager->addAllocation($$);
1454 }
1455 | expression '|' expression
1456 {
1457 $$ = new LLScriptBitOr(gLine, gColumn, $1, $3);
1458 gAllocationManager->addAllocation($$);
1459 }
1460 | expression '^' expression
1461 {
1462 $$ = new LLScriptBitXor(gLine, gColumn, $1, $3);
1463 gAllocationManager->addAllocation($$);
1464 }
1465 | expression BOOLEAN_AND expression
1466 {
1467 $$ = new LLScriptBooleanAnd(gLine, gColumn, $1, $3);
1468 gAllocationManager->addAllocation($$);
1469 }
1470 | expression BOOLEAN_OR expression
1471 {
1472 $$ = new LLScriptBooleanOr(gLine, gColumn, $1, $3);
1473 gAllocationManager->addAllocation($$);
1474 }
1475 | expression SHIFT_LEFT expression
1476 {
1477 $$ = new LLScriptShiftLeft(gLine, gColumn, $1, $3);
1478 gAllocationManager->addAllocation($$);
1479 }
1480 | expression SHIFT_RIGHT expression
1481 {
1482 $$ = new LLScriptShiftRight(gLine, gColumn, $1, $3);
1483 gAllocationManager->addAllocation($$);
1484 }
1485 ;
1486
1487unaryexpression
1488 : '-' expression
1489 {
1490 $$ = new LLScriptUnaryMinus(gLine, gColumn, $2);
1491 gAllocationManager->addAllocation($$);
1492 }
1493 | '!' expression
1494 {
1495 $$ = new LLScriptBooleanNot(gLine, gColumn, $2);
1496 gAllocationManager->addAllocation($$);
1497 }
1498 | '~' expression
1499 {
1500 $$ = new LLScriptBitNot(gLine, gColumn, $2);
1501 gAllocationManager->addAllocation($$);
1502 }
1503 | INC_OP lvalue
1504 {
1505 $$ = new LLScriptPreIncrement(gLine, gColumn, $2);
1506 gAllocationManager->addAllocation($$);
1507 }
1508 | DEC_OP lvalue
1509 {
1510 $$ = new LLScriptPreDecrement(gLine, gColumn, $2);
1511 gAllocationManager->addAllocation($$);
1512 }
1513 | typecast
1514 {
1515 $$ = $1;
1516 }
1517 | unarypostfixexpression
1518 {
1519 $$ = $1;
1520 }
1521 | '(' expression ')'
1522 {
1523 $$ = new LLScriptParenthesis(gLine, gColumn, $2);
1524 gAllocationManager->addAllocation($$);
1525 }
1526 ;
1527
1528typecast
1529 : '(' typename ')' lvalue
1530 {
1531 $$ = new LLScriptTypeCast(gLine, gColumn, $2, $4);
1532 gAllocationManager->addAllocation($$);
1533 }
1534 | '(' typename ')' constant
1535 {
1536 LLScriptConstantExpression *temp = new LLScriptConstantExpression(gLine, gColumn, $4);
1537 gAllocationManager->addAllocation(temp);
1538 $$ = new LLScriptTypeCast(gLine, gColumn, $2, temp);
1539 gAllocationManager->addAllocation($$);
1540 }
1541 | '(' typename ')' unarypostfixexpression
1542 {
1543 $$ = new LLScriptTypeCast(gLine, gColumn, $2, $4);
1544 gAllocationManager->addAllocation($$);
1545 }
1546 | '(' typename ')' '(' expression ')'
1547 {
1548 $$ = new LLScriptTypeCast(gLine, gColumn, $2, $5);
1549 gAllocationManager->addAllocation($$);
1550 }
1551 ;
1552
1553unarypostfixexpression
1554 : vector_initializer
1555 {
1556 $$ = $1;
1557 }
1558 | quaternion_initializer
1559 {
1560 $$ = $1;
1561 }
1562 | list_initializer
1563 {
1564 $$ = $1;
1565 }
1566 | lvalue
1567 {
1568 $$ = $1;
1569 }
1570 | lvalue INC_OP
1571 {
1572 $$ = new LLScriptPostIncrement(gLine, gColumn, $1);
1573 gAllocationManager->addAllocation($$);
1574 }
1575 | lvalue DEC_OP
1576 {
1577 $$ = new LLScriptPostDecrement(gLine, gColumn, $1);
1578 gAllocationManager->addAllocation($$);
1579 }
1580 | IDENTIFIER '(' funcexpressionlist ')'
1581 {
1582 LLScriptIdentifier *id = new LLScriptIdentifier(gLine, gColumn, $1);
1583 gAllocationManager->addAllocation(id);
1584 $$ = new LLScriptFunctionCall(gLine, gColumn, id, $3);
1585 gAllocationManager->addAllocation($$);
1586 }
1587 | PRINT '(' expression ')'
1588 {
1589 $$ = new LLScriptPrint(gLine, gColumn, $3);
1590 gAllocationManager->addAllocation($$);
1591 }
1592 | constant
1593 {
1594 $$ = new LLScriptConstantExpression(gLine, gColumn, $1);
1595 gAllocationManager->addAllocation($$);
1596 }
1597 ;
1598
1599vector_initializer
1600 : '<' expression ',' expression ',' expression '>' %prec INITIALIZER
1601 {
1602 $$ = new LLScriptVectorInitializer(gLine, gColumn, $2, $4, $6);
1603 gAllocationManager->addAllocation($$);
1604 }
1605 | ZERO_VECTOR
1606 {
1607 LLScriptConstantFloat *cf0 = new LLScriptConstantFloat(gLine, gColumn, 0.f);
1608 gAllocationManager->addAllocation(cf0);
1609 LLScriptConstantExpression *sa0 = new LLScriptConstantExpression(gLine, gColumn, cf0);
1610 gAllocationManager->addAllocation(sa0);
1611 LLScriptConstantFloat *cf1 = new LLScriptConstantFloat(gLine, gColumn, 0.f);
1612 gAllocationManager->addAllocation(cf1);
1613 LLScriptConstantExpression *sa1 = new LLScriptConstantExpression(gLine, gColumn, cf1);
1614 gAllocationManager->addAllocation(sa1);
1615 LLScriptConstantFloat *cf2 = new LLScriptConstantFloat(gLine, gColumn, 0.f);
1616 gAllocationManager->addAllocation(cf2);
1617 LLScriptConstantExpression *sa2 = new LLScriptConstantExpression(gLine, gColumn, cf2);
1618 gAllocationManager->addAllocation(sa2);
1619 $$ = new LLScriptVectorInitializer(gLine, gColumn, sa0, sa1, sa2);
1620 gAllocationManager->addAllocation($$);
1621 }
1622 ;
1623
1624quaternion_initializer
1625 : '<' expression ',' expression ',' expression ',' expression '>' %prec INITIALIZER
1626 {
1627 $$ = new LLScriptQuaternionInitializer(gLine, gColumn, $2, $4, $6, $8);
1628 gAllocationManager->addAllocation($$);
1629 }
1630 | ZERO_ROTATION
1631 {
1632 LLScriptConstantFloat *cf0 = new LLScriptConstantFloat(gLine, gColumn, 0.f);
1633 gAllocationManager->addAllocation(cf0);
1634 LLScriptConstantExpression *sa0 = new LLScriptConstantExpression(gLine, gColumn, cf0);
1635 gAllocationManager->addAllocation(sa0);
1636 LLScriptConstantFloat *cf1 = new LLScriptConstantFloat(gLine, gColumn, 0.f);
1637 gAllocationManager->addAllocation(cf1);
1638 LLScriptConstantExpression *sa1 = new LLScriptConstantExpression(gLine, gColumn, cf1);
1639 gAllocationManager->addAllocation(sa1);
1640 LLScriptConstantFloat *cf2 = new LLScriptConstantFloat(gLine, gColumn, 0.f);
1641 gAllocationManager->addAllocation(cf2);
1642 LLScriptConstantExpression *sa2 = new LLScriptConstantExpression(gLine, gColumn, cf2);
1643 gAllocationManager->addAllocation(sa2);
1644 LLScriptConstantFloat *cf3 = new LLScriptConstantFloat(gLine, gColumn, 1.f);
1645 gAllocationManager->addAllocation(cf3);
1646 LLScriptConstantExpression *sa3 = new LLScriptConstantExpression(gLine, gColumn, cf3);
1647 gAllocationManager->addAllocation(sa3);
1648 $$ = new LLScriptQuaternionInitializer(gLine, gColumn, sa0, sa1, sa2, sa3);
1649 gAllocationManager->addAllocation($$);
1650 }
1651 ;
1652
1653list_initializer
1654 : '[' listexpressionlist ']' %prec INITIALIZER
1655 {
1656 $$ = new LLScriptListInitializer(gLine, gColumn, $2);
1657 gAllocationManager->addAllocation($$);
1658 }
1659 ;
1660
1661lvalue
1662 : IDENTIFIER
1663 {
1664 LLScriptIdentifier *id = new LLScriptIdentifier(gLine, gColumn, $1);
1665 gAllocationManager->addAllocation(id);
1666 $$ = new LLScriptLValue(gLine, gColumn, id, NULL);
1667 gAllocationManager->addAllocation($$);
1668 }
1669 | IDENTIFIER PERIOD IDENTIFIER
1670 {
1671 LLScriptIdentifier *id = new LLScriptIdentifier(gLine, gColumn, $1);
1672 gAllocationManager->addAllocation(id);
1673 LLScriptIdentifier *ac = new LLScriptIdentifier(gLine, gColumn, $3);
1674 gAllocationManager->addAllocation(id);
1675 $$ = new LLScriptLValue(gLine, gColumn, id, ac);
1676 gAllocationManager->addAllocation($$);
1677 }
1678 ;
1679
1680%%
diff --git a/linden/indra/lscript/lscript_compile/lscript_alloc.cpp b/linden/indra/lscript/lscript_compile/lscript_alloc.cpp
new file mode 100644
index 0000000..8aadb8d
--- /dev/null
+++ b/linden/indra/lscript/lscript_compile/lscript_alloc.cpp
@@ -0,0 +1,27 @@
1/**
2 * @file lscript_alloc.cpp
3 * @brief Allocation tracking
4 *
5 * Copyright (c) 2002-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
diff --git a/linden/indra/lscript/lscript_compile/lscript_bytecode.cpp b/linden/indra/lscript/lscript_compile/lscript_bytecode.cpp
new file mode 100644
index 0000000..6d18a1a
--- /dev/null
+++ b/linden/indra/lscript/lscript_compile/lscript_bytecode.cpp
@@ -0,0 +1,318 @@
1/**
2 * @file lscript_bytecode.cpp
3 * @brief classes to build actual bytecode
4 *
5 * Copyright (c) 2002-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28#include "linden_common.h"
29
30#include "lscript_bytecode.h"
31#include "lscript_error.h"
32
33#if defined(_MSC_VER)
34# pragma warning(disable: 4102) // 'yy_more' : unreferenced label
35# pragma warning(disable: 4702) // unreachable code
36#endif
37
38LLScriptJumpTable::LLScriptJumpTable()
39{
40}
41
42LLScriptJumpTable::~LLScriptJumpTable()
43{
44 mLabelMap.deleteAllData();
45 mJumpMap.deleteAllData();
46}
47
48void LLScriptJumpTable::addLabel(char *name, S32 offset)
49{
50 char *temp = gScopeStringTable->addString(name);
51 mLabelMap[temp] = new S32(offset);
52}
53
54void LLScriptJumpTable::addJump(char *name, S32 offset)
55{
56 char *temp = gScopeStringTable->addString(name);
57 mJumpMap[temp] = new S32(offset);
58}
59
60
61LLScriptByteCodeChunk::LLScriptByteCodeChunk(BOOL b_need_jumps)
62: mCodeChunk(NULL), mCurrentOffset(0), mJumpTable(NULL)
63{
64 if (b_need_jumps)
65 {
66 mJumpTable = new LLScriptJumpTable();
67 }
68}
69
70LLScriptByteCodeChunk::~LLScriptByteCodeChunk()
71{
72 delete [] mCodeChunk;
73 delete mJumpTable;
74}
75
76void LLScriptByteCodeChunk::addByte(U8 byte)
77{
78 if (mCodeChunk)
79 {
80 U8 *temp = new U8[mCurrentOffset + 1];
81 memcpy(temp, mCodeChunk, mCurrentOffset);
82 delete [] mCodeChunk;
83 mCodeChunk = temp;
84 }
85 else
86 {
87 mCodeChunk = new U8[1];
88 }
89 *(mCodeChunk + mCurrentOffset++) = byte;
90}
91
92void LLScriptByteCodeChunk::addU16(U16 data)
93{
94 U8 temp[2];
95 S32 offset = 0;
96 u162bytestream(temp, offset, data);
97 addBytes(temp, 2);
98}
99
100void LLScriptByteCodeChunk::addBytes(U8 *bytes, S32 size)
101{
102 if (mCodeChunk)
103 {
104 U8 *temp = new U8[mCurrentOffset + size];
105 memcpy(temp, mCodeChunk, mCurrentOffset);
106 delete [] mCodeChunk;
107 mCodeChunk = temp;
108 }
109 else
110 {
111 mCodeChunk = new U8[size];
112 }
113 memcpy(mCodeChunk + mCurrentOffset, bytes, size);
114 mCurrentOffset += size;
115}
116
117void LLScriptByteCodeChunk::addBytes(char *bytes, S32 size)
118{
119 if (mCodeChunk)
120 {
121 U8 *temp = new U8[mCurrentOffset + size];
122 memcpy(temp, mCodeChunk, mCurrentOffset);
123 delete [] mCodeChunk;
124 mCodeChunk = temp;
125 }
126 else
127 {
128 mCodeChunk = new U8[size];
129 }
130 memcpy(mCodeChunk + mCurrentOffset, bytes, size);
131 mCurrentOffset += size;
132}
133
134void LLScriptByteCodeChunk::addBytes(S32 size)
135{
136 if (mCodeChunk)
137 {
138 U8 *temp = new U8[mCurrentOffset + size];
139 memcpy(temp, mCodeChunk, mCurrentOffset);
140 delete [] mCodeChunk;
141 mCodeChunk = temp;
142 }
143 else
144 {
145 mCodeChunk = new U8[size];
146 }
147 memset(mCodeChunk + mCurrentOffset, 0, size);
148 mCurrentOffset += size;
149}
150
151void LLScriptByteCodeChunk::addBytesDontInc(S32 size)
152{
153 if (mCodeChunk)
154 {
155 U8 *temp = new U8[mCurrentOffset + size];
156 memcpy(temp, mCodeChunk, mCurrentOffset);
157 delete [] mCodeChunk;
158 mCodeChunk = temp;
159 }
160 else
161 {
162 mCodeChunk = new U8[size];
163 }
164 memset(mCodeChunk + mCurrentOffset, 0, size);
165}
166
167void LLScriptByteCodeChunk::addInteger(S32 value)
168{
169 U8 temp[4];
170 S32 offset = 0;
171 integer2bytestream(temp, offset, value);
172 addBytes(temp, 4);
173}
174
175void LLScriptByteCodeChunk::addFloat(F32 value)
176{
177 U8 temp[4];
178 S32 offset = 0;
179 float2bytestream(temp, offset, value);
180 addBytes(temp, 4);
181}
182
183void LLScriptByteCodeChunk::addLabel(char *name)
184{
185 if (mJumpTable)
186 {
187 mJumpTable->addLabel(name, mCurrentOffset);
188 }
189}
190
191void LLScriptByteCodeChunk::addJump(char *name)
192{
193 if (mJumpTable)
194 {
195 mJumpTable->addJump(name, mCurrentOffset);
196 }
197}
198
199// format is Byte 0: jump op code Byte 1 - 4: offset
200// the jump position points to Byte 5, so we need to add the data at
201// offset - 4, offset - 3, offset - 2, and offset - 1
202
203// offset is label - jump
204
205void LLScriptByteCodeChunk::connectJumps()
206{
207 char *jump;
208 S32 offset, jumppos;
209
210 if (mJumpTable)
211 {
212 for (jump = mJumpTable->mJumpMap.getFirstKey();
213 jump;
214 jump = mJumpTable->mJumpMap.getNextKey())
215 {
216 jumppos = *mJumpTable->mJumpMap[jump];
217 offset = *mJumpTable->mLabelMap[jump] - jumppos;
218 jumppos = jumppos - 4;
219 integer2bytestream(mCodeChunk, jumppos, offset);
220 }
221 }
222}
223
224LLScriptScriptCodeChunk::LLScriptScriptCodeChunk(S32 total_size)
225: mTotalSize(total_size), mCompleteCode(NULL)
226{
227 mRegisters = new LLScriptByteCodeChunk(FALSE);
228 mGlobalVariables = new LLScriptByteCodeChunk(FALSE);
229 mGlobalFunctions = new LLScriptByteCodeChunk(FALSE);
230 mStates = new LLScriptByteCodeChunk(FALSE);
231 mHeap = new LLScriptByteCodeChunk(FALSE);
232}
233
234LLScriptScriptCodeChunk::~LLScriptScriptCodeChunk()
235{
236 delete mRegisters;
237 delete mGlobalVariables;
238 delete mGlobalFunctions;
239 delete mStates;
240 delete mHeap;
241 delete [] mCompleteCode;
242}
243
244void LLScriptScriptCodeChunk::build(FILE *efp, FILE *bcfp)
245{
246 S32 code_data_size = mRegisters->mCurrentOffset +
247 mGlobalVariables->mCurrentOffset +
248 mGlobalFunctions->mCurrentOffset +
249 mStates->mCurrentOffset +
250 mHeap->mCurrentOffset;
251
252 S32 offset = 0;
253
254 if (code_data_size < mTotalSize)
255 {
256 mCompleteCode = new U8[mTotalSize];
257 memset(mCompleteCode, 0, mTotalSize);
258
259 memcpy(mCompleteCode, mRegisters->mCodeChunk, mRegisters->mCurrentOffset);
260 offset += mRegisters->mCurrentOffset;
261
262 set_register(mCompleteCode, LREG_IP, 0);
263 set_register(mCompleteCode, LREG_VN, LSL2_VERSION_NUMBER);
264 set_event_register(mCompleteCode, LREG_IE, 0, LSL2_CURRENT_MAJOR_VERSION);
265 set_register(mCompleteCode, LREG_BP, mTotalSize - 1);
266 set_register(mCompleteCode, LREG_SP, mTotalSize - 1);
267
268 set_register(mCompleteCode, LREG_GVR, offset);
269
270 memcpy(mCompleteCode + offset, mGlobalVariables->mCodeChunk, mGlobalVariables->mCurrentOffset);
271 offset += mGlobalVariables->mCurrentOffset;
272
273 set_register(mCompleteCode, LREG_GFR, offset);
274
275 memcpy(mCompleteCode + offset, mGlobalFunctions->mCodeChunk, mGlobalFunctions->mCurrentOffset);
276 offset += mGlobalFunctions->mCurrentOffset;
277
278 set_register(mCompleteCode, LREG_SR, offset);
279 // zero is, by definition the default state
280 set_register(mCompleteCode, LREG_CS, 0);
281 set_register(mCompleteCode, LREG_NS, 0);
282 set_event_register(mCompleteCode, LREG_CE, LSCRIPTStateBitField[LSTT_STATE_ENTRY], LSL2_CURRENT_MAJOR_VERSION);
283 S32 default_state_offset = 0;
284 if (LSL2_CURRENT_MAJOR_VERSION == LSL2_MAJOR_VERSION_TWO)
285 {
286 default_state_offset = 8;
287 }
288 else
289 {
290 default_state_offset = 4;
291 }
292 set_event_register(mCompleteCode, LREG_ER, bytestream2u64(mStates->mCodeChunk, default_state_offset), LSL2_CURRENT_MAJOR_VERSION);
293
294 memcpy(mCompleteCode + offset, mStates->mCodeChunk, mStates->mCurrentOffset);
295 offset += mStates->mCurrentOffset;
296
297 set_register(mCompleteCode, LREG_HR, offset);
298
299 memcpy(mCompleteCode + offset, mHeap->mCodeChunk, mHeap->mCurrentOffset);
300 offset += mHeap->mCurrentOffset;
301
302 set_register(mCompleteCode, LREG_HP, offset);
303 set_register(mCompleteCode, LREG_FR, 0);
304 set_register(mCompleteCode, LREG_SLR, 0);
305 set_register(mCompleteCode, LREG_ESR, 0);
306 set_register(mCompleteCode, LREG_PR, 0);
307 set_register(mCompleteCode, LREG_TM, mTotalSize);
308
309
310 fwrite(mCompleteCode, 1, mTotalSize, bcfp);
311 }
312 else
313 {
314 gErrorToText.writeError(efp, 0, 0, LSERROR_ASSEMBLE_OUT_OF_MEMORY);
315 }
316}
317
318LLScriptScriptCodeChunk *gScriptCodeChunk;
diff --git a/linden/indra/lscript/lscript_compile/lscript_bytecode.h b/linden/indra/lscript/lscript_compile/lscript_bytecode.h
new file mode 100644
index 0000000..5628b2e
--- /dev/null
+++ b/linden/indra/lscript/lscript_compile/lscript_bytecode.h
@@ -0,0 +1,90 @@
1/**
2 * @file lscript_bytecode.h
3 * @brief classes to build actual bytecode
4 *
5 * Copyright (c) 2002-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28#ifndef LL_LSCRIPT_BYTECODE_H
29#define LL_LSCRIPT_BYTECODE_H
30
31#include "lscript_byteconvert.h"
32#include "lscript_scope.h"
33
34class LLScriptJumpTable
35{
36public:
37 LLScriptJumpTable();
38 ~LLScriptJumpTable();
39
40 void addLabel(char *name, S32 offset);
41 void addJump(char *name, S32 offset);
42
43 LLMap<char *, S32 *> mLabelMap;
44 LLMap<char *, S32 *> mJumpMap;
45};
46
47class LLScriptByteCodeChunk
48{
49public:
50 LLScriptByteCodeChunk(BOOL b_need_jumps);
51 ~LLScriptByteCodeChunk();
52
53 void addByte(U8 byte);
54 void addU16(U16 data);
55 void addBytes(U8 *bytes, S32 size);
56 void addBytes(char *bytes, S32 size);
57 void addBytes(S32 size);
58 void addBytesDontInc(S32 size);
59 void addInteger(S32 value);
60 void addFloat(F32 value);
61 void addLabel(char *name);
62 void addJump(char *name);
63 void connectJumps();
64
65 U8 *mCodeChunk;
66 S32 mCurrentOffset;
67 LLScriptJumpTable *mJumpTable;
68};
69
70class LLScriptScriptCodeChunk
71{
72public:
73 LLScriptScriptCodeChunk(S32 total_size);
74 ~LLScriptScriptCodeChunk();
75
76 void build(FILE *efp, FILE *bcfp);
77
78 LLScriptByteCodeChunk *mRegisters;
79 LLScriptByteCodeChunk *mGlobalVariables;
80 LLScriptByteCodeChunk *mGlobalFunctions;
81 LLScriptByteCodeChunk *mStates;
82 LLScriptByteCodeChunk *mHeap;
83 S32 mTotalSize;
84 U8 *mCompleteCode;
85};
86
87extern LLScriptScriptCodeChunk *gScriptCodeChunk;
88
89#endif
90
diff --git a/linden/indra/lscript/lscript_compile/lscript_compile.vcproj b/linden/indra/lscript/lscript_compile/lscript_compile.vcproj
new file mode 100644
index 0000000..581fa27
--- /dev/null
+++ b/linden/indra/lscript/lscript_compile/lscript_compile.vcproj
@@ -0,0 +1,222 @@
1<?xml version="1.0" encoding="Windows-1252"?>
2<VisualStudioProject
3 ProjectType="Visual C++"
4 Version="7.10"
5 Name="lscript_compile"
6 ProjectGUID="{44CE6D82-7320-4609-8FC3-5965C19F4808}"
7 Keyword="Win32Proj">
8 <Platforms>
9 <Platform
10 Name="Win32"/>
11 </Platforms>
12 <Configurations>
13 <Configuration
14 Name="Debug|Win32"
15 OutputDirectory="../../lib_$(ConfigurationName)/i686-win32"
16 IntermediateDirectory="Debug"
17 ConfigurationType="4"
18 CharacterSet="1">
19 <Tool
20 Name="VCCLCompilerTool"
21 Optimization="0"
22 AdditionalIncludeDirectories="..;..\..\llcommon;..\..\llmath;..\..\llvfs;..\..\llmessage;..\..\llinventory"
23 PreprocessorDefinitions="WIN32;_DEBUG;_LIB;LL_WINDOWS;LL_DEBUG"
24 MinimalRebuild="TRUE"
25 BasicRuntimeChecks="3"
26 RuntimeLibrary="1"
27 StructMemberAlignment="4"
28 ForceConformanceInForLoopScope="TRUE"
29 UsePrecompiledHeader="0"
30 WarningLevel="3"
31 WarnAsError="FALSE"
32 Detect64BitPortabilityProblems="FALSE"
33 DebugInformationFormat="4"/>
34 <Tool
35 Name="VCCustomBuildTool"/>
36 <Tool
37 Name="VCLibrarianTool"
38 OutputFile="$(OutDir)/lscript_compile.lib"/>
39 <Tool
40 Name="VCMIDLTool"/>
41 <Tool
42 Name="VCPostBuildEventTool"/>
43 <Tool
44 Name="VCPreBuildEventTool"/>
45 <Tool
46 Name="VCPreLinkEventTool"/>
47 <Tool
48 Name="VCResourceCompilerTool"/>
49 <Tool
50 Name="VCWebServiceProxyGeneratorTool"/>
51 <Tool
52 Name="VCXMLDataGeneratorTool"/>
53 <Tool
54 Name="VCManagedWrapperGeneratorTool"/>
55 <Tool
56 Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
57 </Configuration>
58 <Configuration
59 Name="Release|Win32"
60 OutputDirectory="../../lib_$(ConfigurationName)/i686-win32"
61 IntermediateDirectory="Release"
62 ConfigurationType="4"
63 CharacterSet="1">
64 <Tool
65 Name="VCCLCompilerTool"
66 AdditionalIncludeDirectories="..;..\..\llcommon;..\..\llmath;..\..\llvfs;..\..\llmessage;..\..\llinventory"
67 PreprocessorDefinitions="WIN32;NDEBUG;_LIB;LL_WINDOWS;LL_RELEASE"
68 RuntimeLibrary="0"
69 StructMemberAlignment="0"
70 ForceConformanceInForLoopScope="TRUE"
71 UsePrecompiledHeader="0"
72 WarningLevel="3"
73 WarnAsError="FALSE"
74 Detect64BitPortabilityProblems="FALSE"
75 DebugInformationFormat="3"/>
76 <Tool
77 Name="VCCustomBuildTool"/>
78 <Tool
79 Name="VCLibrarianTool"
80 OutputFile="$(OutDir)/lscript_compile.lib"/>
81 <Tool
82 Name="VCMIDLTool"/>
83 <Tool
84 Name="VCPostBuildEventTool"/>
85 <Tool
86 Name="VCPreBuildEventTool"/>
87 <Tool
88 Name="VCPreLinkEventTool"/>
89 <Tool
90 Name="VCResourceCompilerTool"/>
91 <Tool
92 Name="VCWebServiceProxyGeneratorTool"/>
93 <Tool
94 Name="VCXMLDataGeneratorTool"/>
95 <Tool
96 Name="VCManagedWrapperGeneratorTool"/>
97 <Tool
98 Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
99 </Configuration>
100 <Configuration
101 Name="ReleaseNoOpt|Win32"
102 OutputDirectory="../../lib_$(ConfigurationName)/i686-win32"
103 IntermediateDirectory="$(ConfigurationName)"
104 ConfigurationType="4"
105 CharacterSet="1">
106 <Tool
107 Name="VCCLCompilerTool"
108 Optimization="0"
109 AdditionalIncludeDirectories="..;..\..\llcommon;..\..\llmath;..\..\llvfs;..\..\llmessage;..\..\llinventory"
110 PreprocessorDefinitions="WIN32;NDEBUG;_LIB;LL_WINDOWS;LL_RELEASE"
111 RuntimeLibrary="0"
112 StructMemberAlignment="0"
113 ForceConformanceInForLoopScope="TRUE"
114 UsePrecompiledHeader="0"
115 WarningLevel="3"
116 WarnAsError="FALSE"
117 Detect64BitPortabilityProblems="FALSE"
118 DebugInformationFormat="3"/>
119 <Tool
120 Name="VCCustomBuildTool"/>
121 <Tool
122 Name="VCLibrarianTool"
123 OutputFile="$(OutDir)/lscript_compile.lib"/>
124 <Tool
125 Name="VCMIDLTool"/>
126 <Tool
127 Name="VCPostBuildEventTool"/>
128 <Tool
129 Name="VCPreBuildEventTool"/>
130 <Tool
131 Name="VCPreLinkEventTool"/>
132 <Tool
133 Name="VCResourceCompilerTool"/>
134 <Tool
135 Name="VCWebServiceProxyGeneratorTool"/>
136 <Tool
137 Name="VCXMLDataGeneratorTool"/>
138 <Tool
139 Name="VCManagedWrapperGeneratorTool"/>
140 <Tool
141 Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
142 </Configuration>
143 </Configurations>
144 <References>
145 </References>
146 <Files>
147 <Filter
148 Name="Source Files"
149 Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
150 UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
151 <File
152 RelativePath=".\lex_yy.cpp">
153 </File>
154 <File
155 RelativePath=".\lscript_alloc.cpp">
156 </File>
157 <File
158 RelativePath=".\lscript_bytecode.cpp">
159 </File>
160 <File
161 RelativePath=".\lscript_error.cpp">
162 </File>
163 <File
164 RelativePath=".\lscript_heap.cpp">
165 </File>
166 <File
167 RelativePath=".\lscript_resource.cpp">
168 </File>
169 <File
170 RelativePath=".\lscript_scope.cpp">
171 </File>
172 <File
173 RelativePath=".\lscript_tree.cpp">
174 </File>
175 <File
176 RelativePath=".\lscript_typecheck.cpp">
177 </File>
178 <File
179 RelativePath=".\ytab.cpp">
180 </File>
181 </Filter>
182 <Filter
183 Name="Header Files"
184 Filter="h;hpp;hxx;hm;inl;inc;xsd"
185 UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
186 <File
187 RelativePath=".\generated_lex_yy.hpp">
188 </File>
189 <File
190 RelativePath=".\generated_ytab.hpp">
191 </File>
192 <File
193 RelativePath=".\lscript_bytecode.h">
194 </File>
195 <File
196 RelativePath=".\lscript_error.h">
197 </File>
198 <File
199 RelativePath=".\lscript_heap.h">
200 </File>
201 <File
202 RelativePath=".\lscript_resource.h">
203 </File>
204 <File
205 RelativePath=".\lscript_scope.h">
206 </File>
207 <File
208 RelativePath=".\lscript_tree.h">
209 </File>
210 <File
211 RelativePath=".\lscript_typecheck.h">
212 </File>
213 </Filter>
214 <Filter
215 Name="Resource Files"
216 Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
217 UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
218 </Filter>
219 </Files>
220 <Globals>
221 </Globals>
222</VisualStudioProject>
diff --git a/linden/indra/lscript/lscript_compile/lscript_compile_fb.vcproj b/linden/indra/lscript/lscript_compile/lscript_compile_fb.vcproj
new file mode 100755
index 0000000..c61e6ec
--- /dev/null
+++ b/linden/indra/lscript/lscript_compile/lscript_compile_fb.vcproj
@@ -0,0 +1,106 @@
1<?xml version="1.0" encoding="Windows-1252"?>
2<VisualStudioProject
3 ProjectType="Visual C++"
4 Version="7.10"
5 Name="lscript_compile_fb"
6 ProjectGUID="{B771CF1B-E253-47BD-8B0A-6B0440CC9228}"
7 RootNamespace="lscript_compile_fb"
8 Keyword="MakeFileProj">
9 <Platforms>
10 <Platform
11 Name="Win32"/>
12 </Platforms>
13 <Configurations>
14 <Configuration
15 Name="Debug|Win32"
16 OutputDirectory="."
17 IntermediateDirectory="Debug_fb"
18 ConfigurationType="10">
19 <Tool
20 Name="VCCustomBuildTool"/>
21 <Tool
22 Name="VCMIDLTool"/>
23 <Tool
24 Name="VCPostBuildEventTool"/>
25 <Tool
26 Name="VCPreBuildEventTool"/>
27 </Configuration>
28 <Configuration
29 Name="Release|Win32"
30 OutputDirectory="."
31 IntermediateDirectory="Release_fb"
32 ConfigurationType="10">
33 <Tool
34 Name="VCCustomBuildTool"/>
35 <Tool
36 Name="VCMIDLTool"/>
37 <Tool
38 Name="VCPostBuildEventTool"/>
39 <Tool
40 Name="VCPreBuildEventTool"/>
41 </Configuration>
42 </Configurations>
43 <References>
44 </References>
45 <Files>
46 <Filter
47 Name="Source Files"
48 Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
49 UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
50 </Filter>
51 <Filter
52 Name="Header Files"
53 Filter="h;hpp;hxx;hm;inl;inc;xsd"
54 UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
55 </Filter>
56 <Filter
57 Name="Resource Files"
58 Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
59 UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
60 </Filter>
61 <File
62 RelativePath=".\indra.l">
63 <FileConfiguration
64 Name="Debug|Win32">
65 <Tool
66 Name="VCCustomBuildTool"
67 Description="Building lex_yy.cpp"
68 CommandLine="C:\cygwin\bin\flex.exe -olex_yy.cpp indra.l
69"
70 Outputs="lex_yy.cpp"/>
71 </FileConfiguration>
72 <FileConfiguration
73 Name="Release|Win32">
74 <Tool
75 Name="VCCustomBuildTool"
76 Description="Building lex_yy.cpp"
77 CommandLine="C:\cygwin\bin\flex.exe -olex_yy.cpp indra.l
78"
79 Outputs="lex_yy.cpp"/>
80 </FileConfiguration>
81 </File>
82 <File
83 RelativePath=".\indra.y">
84 <FileConfiguration
85 Name="Debug|Win32">
86 <Tool
87 Name="VCCustomBuildTool"
88 Description="Building ytab.cpp"
89 CommandLine="C:\cygwin\bin\bison.exe -o ytab.cpp -v -d indra.y
90"
91 Outputs="ytab.cpp;ytab.h"/>
92 </FileConfiguration>
93 <FileConfiguration
94 Name="Release|Win32">
95 <Tool
96 Name="VCCustomBuildTool"
97 Description="Building ytab.cpp"
98 CommandLine="C:\cygwin\bin\bison.exe -y -d -v -o ytab.cpp indra.y
99C:\cygwin\bin\mv.exe ytab.hpp ytab.h"
100 Outputs="ytab.cpp;ytab.h"/>
101 </FileConfiguration>
102 </File>
103 </Files>
104 <Globals>
105 </Globals>
106</VisualStudioProject>
diff --git a/linden/indra/lscript/lscript_compile/lscript_error.cpp b/linden/indra/lscript/lscript_compile/lscript_error.cpp
new file mode 100644
index 0000000..d9f4d49
--- /dev/null
+++ b/linden/indra/lscript/lscript_compile/lscript_error.cpp
@@ -0,0 +1,96 @@
1/**
2 * @file lscript_error.cpp
3 * @brief error reporting class and strings
4 *
5 * Copyright (c) 2002-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28#include "linden_common.h"
29
30#include "lscript_error.h"
31
32S32 gColumn = 0;
33S32 gLine = 0;
34S32 gInternalColumn = 0;
35S32 gInternalLine = 0;
36
37LLScriptGenerateErrorText gErrorToText;
38
39void LLScriptFilePosition::fdotabs(FILE *fp, S32 tabs, S32 tabsize)
40{
41 S32 i;
42 for (i = 0; i < tabs * tabsize; i++)
43 {
44 fprintf(fp, " ");
45 }
46}
47
48char *gWarningText[LSWARN_EOF] =
49{
50 "INVALID",
51 "Dead code found beyond return statement"
52};
53
54char *gErrorText[LSERROR_EOF] =
55{
56 "INVALID",
57 "Syntax error",
58 "Not all code paths return a value",
59 "Function returns a value but return statement doesn't",
60 "Return statement type doesn't match function return type",
61 "Global functions can't change state",
62 "Name previously declared within scope",
63 "Name not defined within scope",
64 "Type mismatch",
65 "Expression must act on LValue",
66 "Byte code assembly failed -- out of memory",
67 "Function call mismatches type or number of arguments",
68 "Use of vector or quaternion method on incorrect type",
69 "Lists can't be included in lists",
70 "Unitialized variables can't be included in lists",
71 "Declaration requires a new scope -- use { and }"
72};
73
74void LLScriptGenerateErrorText::writeWarning(FILE *fp, LLScriptFilePosition *pos, LSCRIPTWarnings warning)
75{
76 fprintf(fp, "(%d, %d) : WARNING : %s\n", pos->mLineNumber, pos->mColumnNumber, gWarningText[warning]);
77 mTotalWarnings++;
78}
79
80void LLScriptGenerateErrorText::writeWarning(FILE *fp, S32 line, S32 col, LSCRIPTWarnings warning)
81{
82 fprintf(fp, "(%d, %d) : WARNING : %s\n", line, col, gWarningText[warning]);
83 mTotalWarnings++;
84}
85
86void LLScriptGenerateErrorText::writeError(FILE *fp, LLScriptFilePosition *pos, LSCRIPTErrors error)
87{
88 fprintf(fp, "(%d, %d) : ERROR : %s\n", pos->mLineNumber, pos->mColumnNumber, gErrorText[error]);
89 mTotalErrors++;
90}
91
92void LLScriptGenerateErrorText::writeError(FILE *fp, S32 line, S32 col, LSCRIPTErrors error)
93{
94 fprintf(fp, "(%d, %d) : ERROR : %s\n", line, col, gErrorText[error]);
95 mTotalErrors++;
96}
diff --git a/linden/indra/lscript/lscript_compile/lscript_error.h b/linden/indra/lscript/lscript_compile/lscript_error.h
new file mode 100644
index 0000000..8541d31
--- /dev/null
+++ b/linden/indra/lscript/lscript_compile/lscript_error.h
@@ -0,0 +1,151 @@
1/**
2 * @file lscript_error.h
3 * @brief error reporting class and strings
4 *
5 * Copyright (c) 2002-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28#ifndef LL_LSCRIPT_ERROR_H
29#define LL_LSCRIPT_ERROR_H
30
31#include <stdio.h>
32#include "stdtypes.h"
33#include "lscript_scope.h"
34
35
36typedef enum e_lscript_compile_pass
37{
38 LSCP_INVALID,
39 LSCP_PRETTY_PRINT,
40 LSCP_PRUNE,
41 LSCP_SCOPE_PASS1,
42 LSCP_SCOPE_PASS2,
43 LSCP_TYPE,
44 LSCP_RESOURCE,
45 LSCP_EMIT_ASSEMBLY,
46 LSCP_EMIT_BYTE_CODE,
47 LSCP_DETERMINE_HANDLERS,
48 LSCP_LIST_BUILD_SIMPLE,
49 LSCP_TO_STACK,
50 LSCP_BUILD_FUNCTION_ARGS,
51 LSCP_EMIT_CIL_ASSEMBLY,
52 LSCP_EOF
53} LSCRIPTCompilePass;
54
55typedef enum e_lscript_prune_type
56{
57 LSPRUNE_INVALID,
58 LSPRUNE_GLOBAL_VOIDS,
59 LSPRUNE_GLOBAL_NON_VOIDS,
60 LSPRUNE_EVENTS,
61 LSPRUNE_DEAD_CODE,
62 LSPRUNE_EOF
63} LSCRIPTPruneType;
64
65extern S32 gColumn;
66extern S32 gLine;
67extern S32 gInternalColumn;
68extern S32 gInternalLine;
69
70
71// used to describe where in the file this piece is
72class LLScriptByteCodeChunk;
73
74class LLScriptLibData;
75
76class LLScriptFilePosition
77{
78public:
79 LLScriptFilePosition(S32 line, S32 col)
80 : mLineNumber(line), mColumnNumber(col), mByteOffset(0), mByteSize(0)
81 {
82 }
83
84 virtual ~LLScriptFilePosition() {}
85
86 virtual void recurse(FILE *fp, S32 tabs, S32 tabsize,
87 LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg,
88 LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count,
89 LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata) = 0;
90 virtual S32 getSize() = 0;
91
92 void fdotabs(FILE *fp, S32 tabs, S32 tabsize);
93
94 S32 mLineNumber;
95 S32 mColumnNumber;
96
97 S32 mByteOffset;
98 S32 mByteSize;
99};
100
101typedef enum e_lscript_warnings
102{
103 LSWARN_INVALID,
104 LSWARN_DEAD_CODE,
105 LSWARN_EOF
106} LSCRIPTWarnings;
107
108typedef enum e_lscript_errors
109{
110 LSERROR_INVALID,
111 LSERROR_SYNTAX_ERROR,
112 LSERROR_NO_RETURN,
113 LSERROR_INVALID_VOID_RETURN,
114 LSERROR_INVALID_RETURN,
115 LSERROR_STATE_CHANGE_IN_GLOBAL,
116 LSERROR_DUPLICATE_NAME,
117 LSERROR_UNDEFINED_NAME,
118 LSERROR_TYPE_MISMATCH,
119 LSERROR_EXPRESSION_ON_LVALUE,
120 LSERROR_ASSEMBLE_OUT_OF_MEMORY,
121 LSERROR_FUNCTION_TYPE_ERROR,
122 LSERROR_VECTOR_METHOD_ERROR,
123 LSERROR_NO_LISTS_IN_LISTS,
124 LSERROR_NO_UNITIALIZED_VARIABLES_IN_LISTS,
125 LSERROR_NEED_NEW_SCOPE,
126 LSERROR_EOF
127} LSCRIPTErrors;
128
129class LLScriptGenerateErrorText
130{
131public:
132 LLScriptGenerateErrorText() { init(); }
133 ~LLScriptGenerateErrorText() {}
134
135 void init() { mTotalErrors = 0; mTotalWarnings = 0; }
136
137 void writeWarning(FILE *fp, LLScriptFilePosition *pos, LSCRIPTWarnings warning);
138 void writeWarning(FILE *fp, S32 line, S32 col, LSCRIPTWarnings warning);
139 void writeError(FILE *fp, LLScriptFilePosition *pos, LSCRIPTErrors error);
140 void writeError(FILE *fp, S32 line, S32 col, LSCRIPTErrors error);
141
142 BOOL getErrors() { return mTotalErrors; }
143 BOOL getWarnings() { return mTotalWarnings; }
144
145 S32 mTotalErrors;
146 S32 mTotalWarnings;
147};
148
149extern LLScriptGenerateErrorText gErrorToText;
150
151#endif
diff --git a/linden/indra/lscript/lscript_compile/lscript_heap.cpp b/linden/indra/lscript/lscript_compile/lscript_heap.cpp
new file mode 100644
index 0000000..4adf84a
--- /dev/null
+++ b/linden/indra/lscript/lscript_compile/lscript_heap.cpp
@@ -0,0 +1,68 @@
1/**
2 * @file lscript_heap.cpp
3 * @brief classes to manage script heap
4 *
5 * Copyright (c) 2002-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28#if 0
29
30#include "linden_common.h"
31
32#include "lscript_heap.h"
33
34LLScriptHeapEntry::LLScriptHeapEntry(U8 *entry)
35: mEntry(entry)
36{
37 S32 offset = 0;
38 mNext = bytestream2integer(entry, offset);
39 mRefCount = bytestream2integer(entry, offset);
40 mType = *(entry + offset);
41 mData = entry + offset;
42 mListOffset = offset;
43}
44
45LLScriptHeapEntry::LLScriptHeapEntry(U8 *heap, S32 offset)
46: mNext(0x9), mType(0), mRefCount(0), mEntry(heap + offset), mData(heap + offset + 0x9), mListOffset(0x9)
47{
48}
49
50LLScriptHeapEntry::~LLScriptHeapEntry()
51{
52}
53
54void LLScriptHeapEntry::addString(char *string)
55{
56 S32 size = strlen(string) + 1;
57 S32 offset = 0;
58 memcpy(mData, string, size);
59 mNext += size;
60 integer2bytestream(mEntry, offset, mNext);
61 mRefCount++;
62 integer2bytestream(mEntry, offset, mRefCount);
63 *(mEntry + offset) = LSCRIPTTypeByte[LST_STRING];
64}
65
66
67
68#endif
diff --git a/linden/indra/lscript/lscript_compile/lscript_heap.h b/linden/indra/lscript/lscript_compile/lscript_heap.h
new file mode 100644
index 0000000..6c934ff
--- /dev/null
+++ b/linden/indra/lscript/lscript_compile/lscript_heap.h
@@ -0,0 +1,59 @@
1/**
2 * @file lscript_heap.h
3 * @brief classes to manage script heap
4 *
5 * Copyright (c) 2002-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28#if 0
29
30#ifndef LL_LSCRIPT_HEAP_H
31#define LL_LSCRIPT_HEAP_H
32
33#include "lscript_byteconvert.h"
34//#include "vmath.h"
35#include "v3math.h"
36#include "llquaternion.h"
37
38class LLScriptHeapEntry
39{
40public:
41 LLScriptHeapEntry(U8 *entry);
42 LLScriptHeapEntry(U8 *heap, S32 offset);
43 ~LLScriptHeapEntry();
44
45 void addString(char *string);
46
47 S32 mNext;
48 U8 mType;
49 S32 mRefCount;
50 S32 mListOffset;
51 U8 *mEntry;
52 U8 *mData;
53 U8 *mListEntry;
54};
55
56#endif
57
58#endif
59
diff --git a/linden/indra/lscript/lscript_compile/lscript_resource.cpp b/linden/indra/lscript/lscript_compile/lscript_resource.cpp
new file mode 100644
index 0000000..c29b4d0
--- /dev/null
+++ b/linden/indra/lscript/lscript_compile/lscript_resource.cpp
@@ -0,0 +1,37 @@
1/**
2 * @file lscript_resource.cpp
3 * @brief resource determination prior to assembly
4 *
5 * Copyright (c) 2002-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28#include "linden_common.h"
29
30#include "lscript_resource.h"
31
32void init_temp_jumps()
33{
34 gTempJumpCount = 0;
35}
36
37S32 gTempJumpCount = 0;
diff --git a/linden/indra/lscript/lscript_compile/lscript_resource.h b/linden/indra/lscript/lscript_compile/lscript_resource.h
new file mode 100644
index 0000000..37a0413
--- /dev/null
+++ b/linden/indra/lscript/lscript_compile/lscript_resource.h
@@ -0,0 +1,40 @@
1/**
2 * @file lscript_resource.h
3 * @brief resource determination prior to assembly
4 *
5 * Copyright (c) 2002-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28#ifndef LL_LSCRIPT_RESOURCE_H
29#define LL_LSCRIPT_RESOURCE_H
30
31#include <stdio.h>
32#include "stdtypes.h"
33#include "lscript_scope.h"
34
35void init_temp_jumps();
36
37extern S32 gTempJumpCount;
38
39#endif
40
diff --git a/linden/indra/lscript/lscript_compile/lscript_scope.cpp b/linden/indra/lscript/lscript_compile/lscript_scope.cpp
new file mode 100644
index 0000000..eb05746
--- /dev/null
+++ b/linden/indra/lscript/lscript_compile/lscript_scope.cpp
@@ -0,0 +1,32 @@
1/**
2 * @file lscript_scope.cpp
3 * @brief builds nametable and checks scope
4 *
5 * Copyright (c) 2002-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28#include "linden_common.h"
29
30#include "lscript_tree.h"
31
32LLStringTable *gScopeStringTable;
diff --git a/linden/indra/lscript/lscript_compile/lscript_scope.h b/linden/indra/lscript/lscript_compile/lscript_scope.h
new file mode 100644
index 0000000..ff20ad3
--- /dev/null
+++ b/linden/indra/lscript/lscript_compile/lscript_scope.h
@@ -0,0 +1,407 @@
1/**
2 * @file lscript_scope.h
3 * @brief builds nametable and checks scope
4 *
5 * Copyright (c) 2002-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28#ifndef LL_LSCRIPT_SCOPE_H
29#define LL_LSCRIPT_SCOPE_H
30
31#include "string_table.h"
32#include "llmap.h"
33#include "lscript_byteformat.h"
34
35typedef enum e_lscript_identifier_type
36{
37 LIT_INVALID,
38 LIT_GLOBAL,
39 LIT_VARIABLE,
40 LIT_FUNCTION,
41 LIT_LABEL,
42 LIT_STATE,
43 LIT_HANDLER,
44 LIT_LIBRARY_FUNCTION,
45 LIT_EOF
46} LSCRIPTIdentifierType;
47
48const char LSCRIPTFunctionTypeStrings[LST_EOF] =
49{
50 '0',
51 'i',
52 'f',
53 's',
54 'k',
55 'v',
56 'q',
57 'l',
58 '0'
59};
60
61const char * const LSCRIPTListDescription[LST_EOF] =
62{
63 "PUSHARGB 0",
64 "PUSHARGB 1",
65 "PUSHARGB 2",
66 "PUSHARGB 3",
67 "PUSHARGB 4",
68 "PUSHARGB 5",
69 "PUSHARGB 6",
70 "PUSHARGB 7",
71 "PUSHARGB 0"
72};
73
74const char * const LSCRIPTTypePush[LST_EOF] =
75{
76 "INVALID",
77 "PUSHE",
78 "PUSHE",
79 "PUSHE",
80 "PUSHE",
81 "PUSHEV",
82 "PUSHEQ",
83 "PUSHE",
84 "undefined"
85};
86
87const char * const LSCRIPTTypeReturn[LST_EOF] =
88{
89 "INVALID",
90 "LOADP -12",
91 "LOADP -12",
92 "STORES -12\nPOP",
93 "STORES -12\nPOP",
94 "LOADVP -20",
95 "LOADQP -24",
96 "LOADLP -12",
97 "undefined"
98};
99
100const char * const LSCRIPTTypePop[LST_EOF] =
101{
102 "INVALID",
103 "POP",
104 "POP",
105 "POPS",
106 "POPS",
107 "POPV",
108 "POPQ",
109 "POPL",
110 "undefined"
111};
112
113const char * const LSCRIPTTypeDuplicate[LST_EOF] =
114{
115 "INVALID",
116 "DUP",
117 "DUP",
118 "DUPS",
119 "DUPS",
120 "DUPV",
121 "DUPQ",
122 "DUPL",
123 "undefined"
124};
125
126const char * const LSCRIPTTypeLocalStore[LST_EOF] =
127{
128 "INVALID",
129 "STORE ",
130 "STORE ",
131 "STORES ",
132 "STORES ",
133 "STOREV ",
134 "STOREQ ",
135 "STOREL ",
136 "undefined"
137};
138
139const char * const LSCRIPTTypeLocalDeclaration[LST_EOF] =
140{
141 "INVALID",
142 "STOREP ",
143 "STOREP ",
144 "STORESP ",
145 "STORESP ",
146 "STOREVP ",
147 "STOREQP ",
148 "STORELP ",
149 "undefined"
150};
151
152const char * const LSCRIPTTypeGlobalStore[LST_EOF] =
153{
154 "INVALID",
155 "STOREG ",
156 "STOREG ",
157 "STORESG ",
158 "STORESG ",
159 "STOREGV ",
160 "STOREGQ ",
161 "STORELG ",
162 "undefined"
163};
164
165const char * const LSCRIPTTypeLocalPush[LST_EOF] =
166{
167 "INVALID",
168 "PUSH ",
169 "PUSH ",
170 "PUSHS ",
171 "PUSHS ",
172 "PUSHV ",
173 "PUSHQ ",
174 "PUSHL ",
175 "undefined"
176};
177
178const char * const LSCRIPTTypeLocalPush1[LST_EOF] =
179{
180 "INVALID",
181 "PUSHARGI 1",
182 "PUSHARGF 1",
183 "undefined",
184 "undefined",
185 "undefined",
186 "undefined",
187 "undefined",
188 "undefined"
189};
190
191const char * const LSCRIPTTypeGlobalPush[LST_EOF] =
192{
193 "INVALID",
194 "PUSHG ",
195 "PUSHG ",
196 "PUSHGS ",
197 "PUSHGS ",
198 "PUSHGV ",
199 "PUSHGQ ",
200 "PUSHGL ",
201 "undefined"
202};
203
204class LLScriptSimpleAssignable;
205
206class LLScriptArgString
207{
208public:
209 LLScriptArgString() : mString(NULL) {}
210 ~LLScriptArgString() { delete [] mString; }
211
212 LSCRIPTType getType(S32 count)
213 {
214 if (!mString)
215 return LST_NULL;
216 S32 length = (S32)strlen(mString);
217 if (count >= length)
218 {
219 return LST_NULL;
220 }
221 switch(mString[count])
222 {
223 case 'i':
224 return LST_INTEGER;
225 case 'f':
226 return LST_FLOATINGPOINT;
227 case 's':
228 return LST_STRING;
229 case 'k':
230 return LST_KEY;
231 case 'v':
232 return LST_VECTOR;
233 case 'q':
234 return LST_QUATERNION;
235 case 'l':
236 return LST_LIST;
237 default:
238 return LST_NULL;
239 }
240 }
241
242 void addType(LSCRIPTType type)
243 {
244 S32 count = 0;
245 if (mString)
246 {
247 count = (S32)strlen(mString);
248 char *temp = new char[count + 2];
249 memcpy(temp, mString, count);
250 delete [] mString;
251 mString = temp;
252 mString[count + 1] = 0;
253 }
254 else
255 {
256 mString = new char[count + 2];
257 mString[count + 1] = 0;
258 }
259 mString[count++] = LSCRIPTFunctionTypeStrings[type];
260 }
261
262 S32 getNumber()
263 {
264 if (mString)
265 return (S32)strlen(mString);
266 else
267 return 0;
268 }
269
270 char *mString;
271};
272
273class LLScriptScopeEntry
274{
275public:
276 LLScriptScopeEntry(char *identifier, LSCRIPTIdentifierType idtype, LSCRIPTType type, S32 count = 0)
277 : mIdentifier(identifier), mIDType(idtype), mType(type), mOffset(0), mSize(0), mAssignable(NULL), mCount(count), mLibraryNumber(0)
278 {
279 }
280
281 ~LLScriptScopeEntry() {}
282
283 char *mIdentifier;
284 LSCRIPTIdentifierType mIDType;
285 LSCRIPTType mType;
286 S32 mOffset;
287 S32 mSize;
288 LLScriptSimpleAssignable *mAssignable;
289 S32 mCount; // NOTE: Index for locals in CIL.
290 U16 mLibraryNumber;
291 LLScriptArgString mFunctionArgs;
292 LLScriptArgString mLocals;
293};
294
295class LLScriptScope
296{
297public:
298 LLScriptScope(LLStringTable *stable)
299 : mParentScope(NULL), mSTable(stable), mFunctionCount(0), mStateCount(0)
300 {
301 }
302
303 ~LLScriptScope()
304 {
305 mEntryMap.deleteAllData();
306 }
307
308 LLScriptScopeEntry *addEntry(char *identifier, LSCRIPTIdentifierType idtype, LSCRIPTType type)
309 {
310 char *name = mSTable->addString(identifier);
311 if (!mEntryMap.checkData(name))
312 {
313 if (idtype == LIT_FUNCTION)
314 mEntryMap[name] = new LLScriptScopeEntry(name, idtype, type, mFunctionCount++);
315 else if (idtype == LIT_STATE)
316 mEntryMap[name] = new LLScriptScopeEntry(name, idtype, type, mStateCount++);
317 else
318 mEntryMap[name] = new LLScriptScopeEntry(name, idtype, type);
319 return mEntryMap[name];
320 }
321 else
322 {
323 // identifier already exists at this scope
324 return NULL;
325 }
326 }
327
328 BOOL checkEntry(char *identifier)
329 {
330 char *name = mSTable->addString(identifier);
331 if (mEntryMap.checkData(name))
332 {
333 return TRUE;
334 }
335 else
336 {
337 // identifier already exists at this scope
338 return FALSE;
339 }
340 }
341
342 LLScriptScopeEntry *findEntry(char *identifier)
343 {
344 char *name = mSTable->addString(identifier);
345 LLScriptScope *scope = this;
346
347 while (scope)
348 {
349 if (scope->mEntryMap.checkData(name))
350 {
351 // cool, we found it at this scope
352 return scope->mEntryMap[name];
353 }
354 scope = scope->mParentScope;
355 }
356 return NULL;
357 }
358
359 LLScriptScopeEntry *findEntryTyped(char *identifier, LSCRIPTIdentifierType idtype)
360 {
361 char *name = mSTable->addString(identifier);
362 LLScriptScope *scope = this;
363
364 while (scope)
365 {
366 if (scope->mEntryMap.checkData(name))
367 {
368 // need to check type, and if type is function we need to check both types
369 if (idtype == LIT_FUNCTION)
370 {
371 if (scope->mEntryMap[name]->mIDType == LIT_FUNCTION)
372 {
373 return scope->mEntryMap[name];
374 }
375 else if (scope->mEntryMap[name]->mIDType == LIT_LIBRARY_FUNCTION)
376 {
377 return scope->mEntryMap[name];
378 }
379 }
380 else if (scope->mEntryMap[name]->mIDType == idtype)
381 {
382 // cool, we found it at this scope
383 return scope->mEntryMap[name];
384 }
385 }
386 scope = scope->mParentScope;
387 }
388 return NULL;
389 }
390
391 void addParentScope(LLScriptScope *scope)
392 {
393 mParentScope = scope;
394 }
395
396 LLMap<char *, LLScriptScopeEntry *> mEntryMap;
397 LLScriptScope *mParentScope;
398 LLStringTable *mSTable;
399 S32 mFunctionCount;
400 S32 mStateCount;
401};
402
403extern LLStringTable *gScopeStringTable;
404
405
406
407#endif
diff --git a/linden/indra/lscript/lscript_compile/lscript_tree.cpp b/linden/indra/lscript/lscript_compile/lscript_tree.cpp
new file mode 100644
index 0000000..bda09dd
--- /dev/null
+++ b/linden/indra/lscript/lscript_compile/lscript_tree.cpp
@@ -0,0 +1,10017 @@
1/**
2 * @file lscript_tree.cpp
3 * @brief implements methods for lscript_tree.h classes
4 *
5 * Copyright (c) 2002-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28// TO DO: Move print functionality from .h file to here
29
30#include "linden_common.h"
31
32#include "lscript_tree.h"
33#include "lscript_typecheck.h"
34#include "lscript_resource.h"
35#include "lscript_bytecode.h"
36#include "lscript_heap.h"
37#include "lscript_library.h"
38#include "lscript_alloc.h"
39
40//#define LSL_INCLUDE_DEBUG_INFO
41
42void print_cil_box(FILE* fp, LSCRIPTType type)
43{
44 switch(type)
45 {
46 case LST_INTEGER:
47 fprintf(fp, "box [mscorlib]System.Int32\n");
48 break;
49 case LST_FLOATINGPOINT:
50 fprintf(fp, "box [mscorlib]System.Double\n");
51 break;
52 case LST_STRING:
53 case LST_KEY:
54 fprintf(fp, "box [mscorlib]System.String\n");
55 break;
56 case LST_VECTOR:
57 fprintf(fp, "box [LScriptLibrary]LLVector\n");
58 break;
59 case LST_QUATERNION:
60 fprintf(fp, "box [LScriptLibrary]LLQuaternion\n");
61 break;
62 default:
63 break;
64 }
65}
66
67void print_cil_type(FILE* fp, LSCRIPTType type)
68{
69 switch(type)
70 {
71 case LST_INTEGER:
72 fprintf(fp, "int32");
73 break;
74 case LST_FLOATINGPOINT:
75 fprintf(fp, "float32");
76 break;
77 case LST_STRING:
78 case LST_KEY:
79 fprintf(fp, "string");
80 break;
81 case LST_VECTOR:
82 fprintf(fp, "valuetype [LScriptLibrary]LLVector");
83 break;
84 case LST_QUATERNION:
85 fprintf(fp, "valuetype [LScriptLibrary]LLQuaternion");
86 break;
87 case LST_LIST:
88 fprintf(fp, "class [mscorlib]System.Collections.ArrayList");
89 break;
90 case LST_NULL:
91 fprintf(fp, "void");
92 break;
93 default:
94 break;
95 }
96}
97
98void LLScriptType::recurse(FILE *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)
99{
100 if (gErrorToText.getErrors())
101 {
102 return;
103 }
104 switch(pass)
105 {
106 case LSCP_PRETTY_PRINT:
107 case LSCP_EMIT_ASSEMBLY:
108 fprintf(fp,"%s",LSCRIPTTypeNames[mType]);
109 break;
110 case LSCP_TYPE:
111 type = mType;
112 break;
113 case LSCP_EMIT_CIL_ASSEMBLY:
114 print_cil_type(fp, mType);
115 break;
116 default:
117 break;
118 }
119}
120
121S32 LLScriptType::getSize()
122{
123 return LSCRIPTDataSize[mType];
124}
125
126void LLScriptConstant::recurse(FILE *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)
127{
128 if (gErrorToText.getErrors())
129 {
130 return;
131 }
132 switch(pass)
133 {
134 case LSCP_PRETTY_PRINT:
135 case LSCP_EMIT_ASSEMBLY:
136 fprintf(fp,"Script Constant Base class -- should never get here!\n");
137 break;
138 default:
139 break;
140 }
141}
142
143S32 LLScriptConstant::getSize()
144{
145 printf("Script Constant Base class -- should never get here!\n");
146 return 0;
147}
148
149
150
151void LLScriptConstantInteger::recurse(FILE *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)
152{
153 if (gErrorToText.getErrors())
154 {
155 return;
156 }
157 switch(pass)
158 {
159 case LSCP_PRETTY_PRINT:
160 fprintf(fp, "%d", mValue);
161 break;
162 case LSCP_EMIT_ASSEMBLY:
163 fprintf(fp, "PUSHARGI %d\n", mValue);
164 break;
165 case LSCP_TYPE:
166 type = mType;
167 break;
168 case LSCP_EMIT_BYTE_CODE:
169 {
170 chunk->addInteger(mValue);
171 type = mType;
172 }
173 break;
174 case LSCP_TO_STACK:
175 {
176 chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGI]);
177 chunk->addInteger(mValue);
178 type = mType;
179 }
180 break;
181 case LSCP_LIST_BUILD_SIMPLE:
182 {
183 *ldata = new LLScriptLibData(mValue);
184 }
185 break;
186 case LSCP_EMIT_CIL_ASSEMBLY:
187 fprintf(fp, "ldc.i4 %d\n", mValue);
188 break;
189 default:
190 break;
191 }
192}
193
194S32 LLScriptConstantInteger::getSize()
195{
196 return LSCRIPTDataSize[LST_INTEGER];
197}
198
199void LLScriptConstantFloat::recurse(FILE *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)
200{
201 if (gErrorToText.getErrors())
202 {
203 return;
204 }
205 switch(pass)
206 {
207 case LSCP_PRETTY_PRINT:
208 fprintf(fp, "%5.5f", mValue);
209 break;
210 case LSCP_EMIT_ASSEMBLY:
211 fprintf(fp, "PUSHARGF %5.5f\n", mValue);
212 break;
213 case LSCP_TYPE:
214 type = mType;
215 break;
216 case LSCP_EMIT_BYTE_CODE:
217 {
218 chunk->addFloat(mValue);
219 type = mType;
220 }
221 break;
222 case LSCP_TO_STACK:
223 {
224 chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGF]);
225 chunk->addFloat(mValue);
226 type = mType;
227 }
228 break;
229 case LSCP_LIST_BUILD_SIMPLE:
230 {
231 *ldata = new LLScriptLibData(mValue);
232 }
233 break;
234 case LSCP_EMIT_CIL_ASSEMBLY:
235 fprintf(fp, "ldc.r8 %5.5f\n", mValue); // NOTE: Precision?
236 default:
237 break;
238 }
239}
240
241S32 LLScriptConstantFloat::getSize()
242{
243 return LSCRIPTDataSize[LST_FLOATINGPOINT];
244}
245
246void print_escape_quotes(FILE* fp, const char* str)
247{
248 putc('"', fp);
249 for(const char* c = str; *c != '\0'; ++c)
250 {
251 if(*c == '"')
252 {
253 putc('\\', fp);
254 }
255 putc(*c, fp);
256 }
257 putc('"', fp);
258}
259
260void LLScriptConstantString::recurse(FILE *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)
261{
262 if (gErrorToText.getErrors())
263 {
264 return;
265 }
266 switch(pass)
267 {
268 case LSCP_PRETTY_PRINT:
269 fprintf(fp, "\"%s\"", mValue);
270 break;
271 case LSCP_EMIT_ASSEMBLY:
272 fprintf(fp, "PUSHARGS \"%s\"\n", mValue);
273 fprintf(fp, "STACKTOS %lu\n", strlen(mValue) + 1);
274 break;
275 case LSCP_TYPE:
276 type = mType;
277 break;
278 case LSCP_EMIT_BYTE_CODE:
279 {
280 chunk->addInteger(heap->mCurrentOffset + 1);
281 LLScriptLibData *data = new LLScriptLibData(mValue);
282 U8 *temp;
283 S32 size = lsa_create_data_block(&temp, data, heap->mCurrentOffset);
284
285 heap->addBytes(temp, size);
286 delete [] temp;
287 delete data;
288 }
289 break;
290 case LSCP_TO_STACK:
291 {
292 chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGS]);
293 chunk->addBytes(mValue, (S32)strlen(mValue) + 1);
294 type = mType;
295 }
296 break;
297 case LSCP_LIST_BUILD_SIMPLE:
298 {
299 *ldata = new LLScriptLibData(mValue);
300 }
301 break;
302 case LSCP_EMIT_CIL_ASSEMBLY:
303 fprintf(fp, "ldstr ");
304 print_escape_quotes(fp, mValue);
305 fprintf(fp, "\n");
306 default:
307 break;
308 }
309}
310
311S32 LLScriptConstantString::getSize()
312{
313 return (S32)strlen(mValue) + 1;
314}
315
316
317void LLScriptIdentifier::recurse(FILE *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)
318{
319 if (gErrorToText.getErrors())
320 {
321 return;
322 }
323 switch(pass)
324 {
325 case LSCP_PRETTY_PRINT:
326 fprintf(fp, "%s", mName);
327 break;
328 case LSCP_EMIT_ASSEMBLY:
329 if (mScopeEntry)
330 {
331 if (mScopeEntry->mIDType == LIT_VARIABLE)
332 {
333 fprintf(fp, "$BP + %d [%s]", mScopeEntry->mOffset, mName);
334 }
335 else if (mScopeEntry->mIDType == LIT_GLOBAL)
336 {
337 fprintf(fp, "$GVR + %d [%s]", mScopeEntry->mOffset, mName);
338 }
339 else
340 {
341 fprintf(fp, "%s", mName);
342 }
343 }
344 break;
345 case LSCP_TYPE:
346 if (mScopeEntry)
347 type = mScopeEntry->mType;
348 else
349 type = LST_NULL;
350 break;
351 case LSCP_RESOURCE:
352 if (mScopeEntry)
353 {
354 if (mScopeEntry->mIDType == LIT_VARIABLE)
355 {
356// fprintf(fp, "LOCAL : %d : %d : %s\n", mScopeEntry->mOffset, mScopeEntry->mSize, mName);
357 }
358 else if (mScopeEntry->mIDType == LIT_GLOBAL)
359 {
360// fprintf(fp, "GLOBAL: %d : %d : %s\n", mScopeEntry->mOffset, mScopeEntry->mSize, mName);
361 }
362 }
363 break;
364 case LSCP_LIST_BUILD_SIMPLE:
365 {
366 if (mScopeEntry)
367 {
368 if (mScopeEntry->mType == LST_LIST)
369 {
370 gErrorToText.writeError(fp, this, LSERROR_NO_LISTS_IN_LISTS);
371 }
372 else if (mScopeEntry->mAssignable)
373 {
374 mScopeEntry->mAssignable->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, ldata);
375 }
376 else
377 {
378 gErrorToText.writeError(fp, this, LSERROR_NO_UNITIALIZED_VARIABLES_IN_LISTS);
379 }
380 }
381 else
382 {
383 gErrorToText.writeError(fp, this, LSERROR_UNDEFINED_NAME);
384 }
385 }
386 break;
387 case LSCP_EMIT_CIL_ASSEMBLY:
388 fprintf(fp, "%s", mName);
389 break;
390 default:
391 break;
392 }
393}
394
395S32 LLScriptIdentifier::getSize()
396{
397
398 return 0;
399}
400
401
402
403void LLScriptSimpleAssignable::addAssignable(LLScriptSimpleAssignable *assign)
404{
405 if (mNextp)
406 {
407 assign->mNextp = mNextp;
408 }
409 mNextp = assign;
410}
411
412void LLScriptSimpleAssignable::recurse(FILE *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)
413{
414 if (gErrorToText.getErrors())
415 {
416 return;
417 }
418 fprintf(fp, "Simple Assignable Base Class -- should never get here!\n");
419}
420
421S32 LLScriptSimpleAssignable::getSize()
422{
423
424 printf("Simple Assignable Base Class -- should never get here!\n");
425 return 0;
426}
427
428void LLScriptSAIdentifier::recurse(FILE *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)
429{
430 if (gErrorToText.getErrors())
431 {
432 return;
433 }
434 switch(pass)
435 {
436 case LSCP_PRETTY_PRINT:
437 case LSCP_EMIT_ASSEMBLY:
438 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
439 if (mNextp)
440 {
441 fprintf(fp, ", ");
442 mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
443 }
444 break;
445 case LSCP_SCOPE_PASS1:
446 {
447 LLScriptScopeEntry *entry = scope->findEntry(mIdentifier->mName);
448 if (!entry)
449 {
450 gErrorToText.writeError(fp, this, LSERROR_UNDEFINED_NAME);
451 }
452 else
453 {
454 // if we did find it, make sure this identifier is associated with the correct scope entry
455 mIdentifier->mScopeEntry = entry;
456 }
457 if (mNextp)
458 {
459 mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
460 }
461 }
462 break;
463 case LSCP_EMIT_BYTE_CODE:
464 {
465 if (mIdentifier->mScopeEntry)
466 {
467 if(mIdentifier->mScopeEntry->mAssignable)
468 {
469 mIdentifier->mScopeEntry->mAssignable->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
470 }
471 else
472 {
473 // Babbage: 29/8/06: If the scope entry has no mAssignable,
474 // set the default type and add the default 0 value to the
475 // chunk. Without this SAVectors and SAQuaternions will
476 // assume the arbitrary current type is the assignable type
477 // and may attempt to access a null chunk. (SL-20156)
478 type = mIdentifier->mScopeEntry->mType;
479 chunk->addBytes(LSCRIPTDataSize[type]);
480 }
481 }
482 if (mNextp)
483 {
484 mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
485 }
486 }
487 break;
488 case LSCP_LIST_BUILD_SIMPLE:
489 {
490 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, ldata);
491 if (mNextp)
492 {
493 mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, &(*ldata)->mListp);
494 }
495 }
496 break;
497 default:
498 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
499 if (mNextp)
500 {
501 mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
502 }
503 break;
504 }
505}
506
507S32 LLScriptSAIdentifier::getSize()
508{
509 return mIdentifier->getSize();
510}
511
512void LLScriptSAConstant::recurse(FILE *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)
513{
514 if (gErrorToText.getErrors())
515 {
516 return;
517 }
518 switch(pass)
519 {
520 case LSCP_PRETTY_PRINT:
521 case LSCP_EMIT_ASSEMBLY:
522 mConstant->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
523 if (mNextp)
524 {
525 fprintf(fp, ", ");
526 mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
527 }
528 break;
529 case LSCP_LIST_BUILD_SIMPLE:
530 {
531 mConstant->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, ldata);
532 if (mNextp)
533 {
534 mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, &(*ldata)->mListp);
535 }
536 }
537 break;
538 default:
539 mConstant->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
540 if (mNextp)
541 {
542 mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
543 }
544 break;
545 }
546}
547
548S32 LLScriptSAConstant::getSize()
549{
550 return mConstant->getSize();
551}
552
553void print_cil_cast(FILE* fp, LSCRIPTType srcType, LSCRIPTType targetType)
554{
555 switch(srcType)
556 {
557 case LST_INTEGER:
558 switch(targetType)
559 {
560 case LST_FLOATINGPOINT:
561 fprintf(fp, "conv.r8\n");
562 break;
563 case LST_STRING:
564 fprintf(fp, "call string class [mscorlib]System.Convert::ToString(int32)\n");
565 break;
566 case LST_LIST:
567 fprintf(fp, "box [mscorlib]System.Int32\n");
568 fprintf(fp, "call class [mscorlib]System.Collections.ArrayList class [LScriptLibrary]LScriptInternal::CreateList()\n");
569 fprintf(fp, "call class [mscorlib]System.Collections.ArrayList class [LScriptLibrary]LScriptInternal::AddReturnList(object, class [mscorlib]System.Collections.ArrayList)\n");
570 break;
571 default:
572 break;
573 }
574 break;
575 case LST_FLOATINGPOINT:
576 switch(targetType)
577 {
578 case LST_INTEGER:
579 fprintf(fp, "conv.i4\n");
580 break;
581 case LST_STRING:
582 fprintf(fp, "call string class [mscorlib]System.Convert::ToString(float32)\n");
583 break;
584 case LST_LIST:
585 fprintf(fp, "call class [mscorlib]System.Collections.ArrayList [LScriptLibrary]LScriptInternal::CreateList(object)\n");
586 break;
587 default:
588 break;
589 }
590 break;
591 case LST_STRING:
592 switch(targetType)
593 {
594 case LST_INTEGER:
595 fprintf(fp, "call int32 valuetype [mscorlib]System.Int32::Parse(string)\n");
596 break;
597 case LST_FLOATINGPOINT:
598 fprintf(fp, "call float64 valuetype [mscorlib]System.Double::Parse(string)\n");
599 break;
600 case LST_LIST:
601 fprintf(fp, "call class [mscorlib]System.Collections.ArrayList [LScriptLibrary]LScriptInternal::CreateList(object)\n");
602 break;
603 case LST_VECTOR:
604 fprintf(fp, "call valuetype [LScriptLibrary]LLVector valuetype [LScriptLibrary]LLVector::'Parse'(string)\n");
605 break;
606 case LST_QUATERNION:
607 fprintf(fp, "call valuetype [LScriptLibrary]LLQuaternion valuetype [LScriptLibrary]LLQuaternion::'Parse'(string)\n");
608 break;
609 default:
610 break;
611 }
612 break;
613 case LST_KEY:
614 switch(targetType)
615 {
616 case LST_KEY:
617 break;
618 case LST_STRING:
619 break;
620 case LST_LIST:
621 fprintf(fp, "call class [mscorlib]System.Collections.ArrayList [LScriptLibrary]LScriptInternal::CreateList(object)\n");
622 break;
623 default:
624 break;
625 }
626 break;
627 case LST_VECTOR:
628 switch(targetType)
629 {
630 case LST_VECTOR:
631 break;
632 case LST_STRING:
633 fprintf(fp, "call string valuetype [LScriptLibrary]LLVector::'ToString'(valuetype [LScriptLibrary]LLVector)\n");
634 break;
635 case LST_LIST:
636 fprintf(fp, "call class [mscorlib]System.Collections.ArrayList [LScriptLibrary]LScriptInternal::CreateList(object)\n");
637 break;
638 default:
639 break;
640 }
641 break;
642 case LST_QUATERNION:
643 switch(targetType)
644 {
645 case LST_QUATERNION:
646 break;
647 case LST_STRING:
648 fprintf(fp, "call string valuetype [LScriptLibrary]LLQuaternion::'ToString'(valuetype [LScriptLibrary]LLQuaternion)\n");
649 break;
650 case LST_LIST:
651 fprintf(fp, "call class [mscorlib]System.Collections.ArrayList [LScriptLibrary]LScriptInternal::CreateList(object)\n");
652 break;
653 default:
654 break;
655 }
656 break;
657 case LST_LIST:
658 switch(targetType)
659 {
660 case LST_LIST:
661 break;
662 case LST_STRING:
663 fprintf(fp, "call string [LScriptLibrary]LScriptInternal::ListToString(class [mscorlib]System.Collections.ArrayList)\n");
664 break;
665 default:
666 break;
667 }
668 break;
669 default:
670 break;
671 }
672}
673
674bool is_SA_constant_integer(LLScriptSimpleAssignable* sa)
675{
676 // HACK: Downcast based on type.
677 return (sa->mType == LSSAT_CONSTANT && ((LLScriptSAConstant*) sa)->mConstant->mType == LST_INTEGER);
678}
679
680void LLScriptSAVector::recurse(FILE *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)
681{
682 if (gErrorToText.getErrors())
683 {
684 return;
685 }
686 switch(pass)
687 {
688 case LSCP_PRETTY_PRINT:
689 case LSCP_EMIT_ASSEMBLY:
690 fprintf(fp, "< ");
691 mEntry3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
692 fprintf(fp, ", ");
693 mEntry2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
694 fprintf(fp, ", ");
695 mEntry1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
696 fprintf(fp, " >");
697 if (mNextp)
698 {
699 fprintf(fp, ", ");
700 mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
701 }
702 break;
703 case LSCP_TYPE:
704 // vector's take floats
705 mEntry3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
706 if (!legal_assignment(LST_FLOATINGPOINT, type))
707 {
708 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
709 }
710 mEntry2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
711 if (!legal_assignment(LST_FLOATINGPOINT, type))
712 {
713 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
714 }
715 mEntry1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
716 if (!legal_assignment(LST_FLOATINGPOINT, type))
717 {
718 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
719 }
720 type = LST_VECTOR;
721 if (mNextp)
722 {
723 mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
724 }
725 break;
726 case LSCP_EMIT_BYTE_CODE:
727 mEntry3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
728 if (type == LST_INTEGER)
729 {
730 S32 offset = chunk->mCurrentOffset - 4;
731 bytestream_int2float(chunk->mCodeChunk, offset);
732 }
733 mEntry2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
734 if (type == LST_INTEGER)
735 {
736 S32 offset = chunk->mCurrentOffset - 4;
737 bytestream_int2float(chunk->mCodeChunk, offset);
738 }
739 mEntry1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
740 if (type == LST_INTEGER)
741 {
742 S32 offset = chunk->mCurrentOffset - 4;
743 bytestream_int2float(chunk->mCodeChunk, offset);
744 }
745 if (mNextp)
746 {
747 mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
748 }
749 break;
750 case LSCP_LIST_BUILD_SIMPLE:
751 {
752 LLScriptByteCodeChunk *list = new LLScriptByteCodeChunk(FALSE);
753 mEntry3->recurse(fp, tabs, tabsize, LSCP_EMIT_BYTE_CODE, ptype, prunearg, scope, type, basetype, count, list, heap, stacksize, entry, entrycount, NULL);
754 if (type == LST_INTEGER)
755 {
756 S32 offset = list->mCurrentOffset - 4;
757 bytestream_int2float(list->mCodeChunk, offset);
758 }
759 mEntry2->recurse(fp, tabs, tabsize, LSCP_EMIT_BYTE_CODE, ptype, prunearg, scope, type, basetype, count, list, heap, stacksize, entry, entrycount, NULL);
760 if (type == LST_INTEGER)
761 {
762 S32 offset = list->mCurrentOffset - 4;
763 bytestream_int2float(list->mCodeChunk, offset);
764 }
765 mEntry1->recurse(fp, tabs, tabsize, LSCP_EMIT_BYTE_CODE, ptype, prunearg, scope, type, basetype, count, list, heap, stacksize, entry, entrycount, NULL);
766 if (type == LST_INTEGER)
767 {
768 S32 offset = list->mCurrentOffset - 4;
769 bytestream_int2float(list->mCodeChunk, offset);
770 }
771 LLVector3 vec;
772 S32 offset = 0;
773 bytestream2vector(vec, list->mCodeChunk, offset);
774 *ldata = new LLScriptLibData(vec);
775 delete list;
776 if (mNextp)
777 {
778 mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, &(*ldata)->mListp);
779 }
780 }
781 break;
782 case LSCP_EMIT_CIL_ASSEMBLY:
783
784 // Load arguments.
785 mEntry1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
786 if(is_SA_constant_integer(mEntry1))
787 {
788 print_cil_cast(fp, LST_INTEGER, LST_FLOATINGPOINT);
789 }
790 mEntry2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
791 if(is_SA_constant_integer(mEntry3))
792 {
793 print_cil_cast(fp, LST_INTEGER, LST_FLOATINGPOINT);
794 }
795 mEntry3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
796 if(is_SA_constant_integer(mEntry3))
797 {
798 print_cil_cast(fp, LST_INTEGER, LST_FLOATINGPOINT);
799 }
800
801 // Call named ctor, which leaves new Vector on stack, so it can be saved in to local or argument just like a primitive type.
802 fprintf(fp, "call valuetype [LScriptLibrary]LLVector valuetype [LScriptLibrary]LLVector::'create'(float32, float32, float32)\n");
803
804 // Next.
805 if (mNextp)
806 {
807 mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
808 }
809 break;
810 default:
811 mEntry3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
812 mEntry2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
813 mEntry1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
814 if (mNextp)
815 {
816 mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
817 }
818 break;
819 }
820}
821
822S32 LLScriptSAVector::getSize()
823{
824 return mEntry1->getSize() + mEntry2->getSize() + mEntry3->getSize();
825}
826
827void LLScriptSAQuaternion::recurse(FILE *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)
828{
829 if (gErrorToText.getErrors())
830 {
831 return;
832 }
833 switch(pass)
834 {
835 case LSCP_PRETTY_PRINT:
836 case LSCP_EMIT_ASSEMBLY:
837 fprintf(fp, "< ");
838 mEntry4->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
839 fprintf(fp, ", ");
840 mEntry3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
841 fprintf(fp, ", ");
842 mEntry2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
843 fprintf(fp, ", ");
844 mEntry1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
845 fprintf(fp, " >");
846 if (mNextp)
847 {
848 fprintf(fp, ", ");
849 mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
850 }
851 break;
852 case LSCP_TYPE:
853 // vector's take floats
854 mEntry4->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
855 if (!legal_assignment(LST_FLOATINGPOINT, type))
856 {
857 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
858 }
859 mEntry3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
860 if (!legal_assignment(LST_FLOATINGPOINT, type))
861 {
862 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
863 }
864 mEntry2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
865 if (!legal_assignment(LST_FLOATINGPOINT, type))
866 {
867 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
868 }
869 mEntry1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
870 if (!legal_assignment(LST_FLOATINGPOINT, type))
871 {
872 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
873 }
874 type = LST_QUATERNION;
875 if (mNextp)
876 {
877 mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
878 }
879 break;
880 case LSCP_EMIT_BYTE_CODE:
881 mEntry4->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
882 if (type == LST_INTEGER)
883 {
884 S32 offset = chunk->mCurrentOffset - 4;
885 bytestream_int2float(chunk->mCodeChunk, offset);
886 }
887 mEntry3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
888 if (type == LST_INTEGER)
889 {
890 S32 offset = chunk->mCurrentOffset - 4;
891 bytestream_int2float(chunk->mCodeChunk, offset);
892 }
893 mEntry2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
894 if (type == LST_INTEGER)
895 {
896 S32 offset = chunk->mCurrentOffset - 4;
897 bytestream_int2float(chunk->mCodeChunk, offset);
898 }
899 mEntry1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
900 if (type == LST_INTEGER)
901 {
902 S32 offset = chunk->mCurrentOffset - 4;
903 bytestream_int2float(chunk->mCodeChunk, offset);
904 }
905 if (mNextp)
906 {
907 mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
908 }
909 break;
910 case LSCP_LIST_BUILD_SIMPLE:
911 {
912 LLScriptByteCodeChunk *list = new LLScriptByteCodeChunk(FALSE);
913 mEntry4->recurse(fp, tabs, tabsize, LSCP_EMIT_BYTE_CODE, ptype, prunearg, scope, type, basetype, count, list, heap, stacksize, entry, entrycount, NULL);
914 if (type == LST_INTEGER)
915 {
916 S32 offset = list->mCurrentOffset - 4;
917 bytestream_int2float(list->mCodeChunk, offset);
918 }
919 mEntry3->recurse(fp, tabs, tabsize, LSCP_EMIT_BYTE_CODE, ptype, prunearg, scope, type, basetype, count, list, heap, stacksize, entry, entrycount, NULL);
920 if (type == LST_INTEGER)
921 {
922 S32 offset = list->mCurrentOffset - 4;
923 bytestream_int2float(list->mCodeChunk, offset);
924 }
925 mEntry2->recurse(fp, tabs, tabsize, LSCP_EMIT_BYTE_CODE, ptype, prunearg, scope, type, basetype, count, list, heap, stacksize, entry, entrycount, NULL);
926 if (type == LST_INTEGER)
927 {
928 S32 offset = list->mCurrentOffset - 4;
929 bytestream_int2float(list->mCodeChunk, offset);
930 }
931 mEntry1->recurse(fp, tabs, tabsize, LSCP_EMIT_BYTE_CODE, ptype, prunearg, scope, type, basetype, count, list, heap, stacksize, entry, entrycount, NULL);
932 if (type == LST_INTEGER)
933 {
934 S32 offset = list->mCurrentOffset - 4;
935 bytestream_int2float(list->mCodeChunk, offset);
936 }
937 LLQuaternion quat;
938 S32 offset = 0;
939 bytestream2quaternion(quat, list->mCodeChunk, offset);
940 *ldata = new LLScriptLibData(quat);
941 delete list;
942 if (mNextp)
943 {
944 mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, &(*ldata)->mListp);
945 }
946 }
947 break;
948 case LSCP_EMIT_CIL_ASSEMBLY:
949
950 // Load arguments.
951 mEntry1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
952 if(is_SA_constant_integer(mEntry1))
953 {
954 print_cil_cast(fp, LST_INTEGER, LST_FLOATINGPOINT);
955 }
956 mEntry2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
957 if(is_SA_constant_integer(mEntry2))
958 {
959 print_cil_cast(fp, LST_INTEGER, LST_FLOATINGPOINT);
960 }
961 mEntry3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
962 if(is_SA_constant_integer(mEntry3))
963 {
964 print_cil_cast(fp, LST_INTEGER, LST_FLOATINGPOINT);
965 }
966 mEntry4->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
967 if(is_SA_constant_integer(mEntry4))
968 {
969 print_cil_cast(fp, LST_INTEGER, LST_FLOATINGPOINT);
970 }
971
972 // Call named ctor, which leaves new Vector on stack, so it can be saved in to local or argument just like a primitive type.
973 fprintf(fp, "call valuetype [LScriptLibrary]LLQuaternion valuetype [LScriptLibrary]LLQuaternion::'create'(float32, float32, float32, float32)\n");
974
975 // Next.
976 if (mNextp)
977 {
978 mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
979 }
980 break;
981 default:
982 mEntry4->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
983 mEntry3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
984 mEntry2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
985 mEntry1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
986 if (mNextp)
987 {
988 mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
989 }
990 break;
991 }
992}
993
994S32 LLScriptSAQuaternion::getSize()
995{
996 return mEntry1->getSize() + mEntry2->getSize() + mEntry3->getSize() + mEntry4->getSize();
997}
998
999void LLScriptSAList::recurse(FILE *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)
1000{
1001 if (gErrorToText.getErrors())
1002 {
1003 return;
1004 }
1005 switch(pass)
1006 {
1007 case LSCP_PRETTY_PRINT:
1008 case LSCP_EMIT_ASSEMBLY:
1009 fprintf(fp, "[ ");
1010 if (mEntryList)
1011 mEntryList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
1012 fprintf(fp, " ]");
1013 if (mNextp)
1014 {
1015 fprintf(fp, ", ");
1016 mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
1017 }
1018 break;
1019 case LSCP_TYPE:
1020 if (mEntryList)
1021 mEntryList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
1022 type = LST_LIST;
1023 if (mNextp)
1024 {
1025 mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
1026 }
1027 break;
1028 case LSCP_EMIT_BYTE_CODE:
1029 {
1030 LLScriptLibData *list_data = new LLScriptLibData;
1031
1032 list_data->mType = LST_LIST;
1033 if (mEntryList)
1034 mEntryList->recurse(fp, tabs, tabsize, LSCP_LIST_BUILD_SIMPLE, ptype, prunearg, scope, type, basetype, count, chunk, NULL, stacksize, entry, entrycount, &(list_data->mListp));
1035
1036 U8 *temp;
1037 chunk->addInteger(heap->mCurrentOffset + 1);
1038 S32 size = lsa_create_data_block(&temp, list_data, heap->mCurrentOffset);
1039 heap->addBytes(temp, size);
1040 delete list_data;
1041 delete [] temp;
1042
1043 if (mNextp)
1044 {
1045 mNextp->recurse(fp, tabs, tabsize, LSCP_EMIT_BYTE_CODE, ptype, prunearg, scope, type, basetype, count, chunk, NULL, stacksize, entry, entrycount, NULL);
1046 }
1047 }
1048 break;
1049 default:
1050 if (mEntryList)
1051 mEntryList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, ldata);
1052 if (mNextp)
1053 {
1054 mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, ldata);
1055 }
1056 break;
1057 }
1058}
1059
1060S32 LLScriptSAList::getSize()
1061{
1062 return mEntryList->getSize();
1063}
1064
1065void LLScriptGlobalVariable::addGlobal(LLScriptGlobalVariable *global)
1066{
1067 if (mNextp)
1068 {
1069 global->mNextp = mNextp;
1070 }
1071 mNextp = global;
1072}
1073
1074void LLScriptGlobalVariable::gonext(FILE *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)
1075{
1076 switch(pass)
1077 {
1078 case LSCP_PRETTY_PRINT:
1079 if (mNextp)
1080 {
1081 mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
1082 }
1083 break;
1084 default:
1085 if (mNextp)
1086 {
1087 mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
1088 }
1089 break;
1090 }
1091}
1092
1093void LLScriptGlobalVariable::recurse(FILE *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)
1094{
1095 if (gErrorToText.getErrors())
1096 {
1097 return;
1098 }
1099 switch(pass)
1100 {
1101 case LSCP_PRETTY_PRINT:
1102 mType->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
1103 fprintf(fp,"\t");
1104 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
1105 if (mAssignable)
1106 {
1107 fprintf(fp, " = ");
1108 mAssignable->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
1109 }
1110 fprintf(fp, ";\n");
1111 break;
1112 case LSCP_EMIT_ASSEMBLY:
1113 mType->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
1114 fprintf(fp,"\t");
1115 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
1116 if (mAssignable)
1117 {
1118 fprintf(fp, " = ");
1119 mAssignable->recurse(fp, tabs, tabsize, LSCP_PRETTY_PRINT, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
1120 fprintf(fp, "\n");
1121 fprintf(fp, "Offset: %d Type: %d\n", mIdentifier->mScopeEntry->mOffset, (S32)LSCRIPTTypeByte[mType->mType]);
1122 }
1123 else
1124 {
1125 fprintf(fp, "\n");
1126 fprintf(fp, "Offset: %d Type: %d\n", mIdentifier->mScopeEntry->mOffset, (S32)LSCRIPTTypeByte[mType->mType]);
1127 }
1128 break;
1129 case LSCP_SCOPE_PASS1:
1130 if (scope->checkEntry(mIdentifier->mName))
1131 {
1132 gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
1133 }
1134 else
1135 {
1136 if (mAssignable)
1137 {
1138 mAssignable->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
1139 }
1140 // this needs to go after expression decent to make sure that we don't add ourselves or something silly
1141 mIdentifier->mScopeEntry = scope->addEntry(mIdentifier->mName, LIT_GLOBAL, mType->mType);
1142 if (mIdentifier->mScopeEntry && mAssignable)
1143 mIdentifier->mScopeEntry->mAssignable = mAssignable;
1144 }
1145 break;
1146 case LSCP_TYPE:
1147 // if the variable has an assignable, it must assignable to the variable's type
1148 if (mAssignable)
1149 {
1150 mAssignable->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
1151 mAssignableType = type;
1152 if (!legal_assignment(mType->mType, mAssignableType))
1153 {
1154 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
1155 }
1156 }
1157 break;
1158 case LSCP_RESOURCE:
1159 {
1160 // we're just tryng to determine how much space the variable needs
1161 // it also includes the name of the variable as well as the type
1162 // plus 4 bytes of offset from it's apparent address to the actual data
1163#ifdef LSL_INCLUDE_DEBUG_INFO
1164 count += strlen(mIdentifier->mName) + 1 + 1 + 4;
1165#else
1166 count += 1 + 1 + 4;
1167#endif
1168 mIdentifier->mScopeEntry->mOffset = (S32)count;
1169 mIdentifier->mScopeEntry->mSize = mType->getSize();
1170 count += mIdentifier->mScopeEntry->mSize;
1171 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
1172 }
1173 break;
1174 case LSCP_EMIT_BYTE_CODE:
1175 {
1176 // order for global variables
1177 // 0 - 4: offset to actual data
1178 S32 offsetoffset = chunk->mCurrentOffset;
1179 S32 offsetdelta = 0;
1180 chunk->addBytes(4);
1181 // type
1182 char vtype;
1183 vtype = LSCRIPTTypeByte[mType->mType];
1184 chunk->addBytes(&vtype, 1);
1185 // null terminated name
1186#ifdef LSL_INCLUDE_DEBUG_INFO
1187 chunk->addBytes(mIdentifier->mName, strlen(mIdentifier->mName) + 1);
1188#else
1189 chunk->addBytes(1);
1190#endif
1191 // put correct offset delta in
1192 offsetdelta = chunk->mCurrentOffset - offsetoffset;
1193 integer2bytestream(chunk->mCodeChunk, offsetoffset, offsetdelta);
1194
1195 // now we need space for the variable itself
1196 LLScriptByteCodeChunk *value = new LLScriptByteCodeChunk(FALSE);
1197 if (mAssignable)
1198 {
1199 mAssignable->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, value, heap, stacksize, entry, entrycount, NULL);
1200 // need to put sneaky type conversion here
1201 if (mAssignableType != mType->mType)
1202 {
1203 // the only legal case that is a problem is int->float
1204 if (mType->mType == LST_FLOATINGPOINT && mAssignableType == LST_INTEGER)
1205 {
1206 S32 offset = value->mCurrentOffset - 4;
1207 bytestream_int2float(value->mCodeChunk, offset);
1208 }
1209 }
1210 }
1211 else
1212 {
1213 if ( (mType->mType == LST_STRING)
1214 ||(mType->mType == LST_KEY))
1215 {
1216 // string and keys (even empty ones) need heap entries
1217 chunk->addInteger(heap->mCurrentOffset + 1);
1218 LLScriptLibData *data = new LLScriptLibData("");
1219 U8 *temp;
1220 S32 size = lsa_create_data_block(&temp, data, heap->mCurrentOffset);
1221
1222 heap->addBytes(temp, size);
1223 delete [] temp;
1224 delete data;
1225 }
1226 else if (mType->mType == LST_LIST)
1227 {
1228 chunk->addInteger(heap->mCurrentOffset + 1);
1229 LLScriptLibData *data = new LLScriptLibData;
1230 data->mType = LST_LIST;
1231 U8 *temp;
1232 S32 size = lsa_create_data_block(&temp, data, heap->mCurrentOffset);
1233
1234 heap->addBytes(temp, size);
1235 delete [] temp;
1236 delete data;
1237 }
1238 else if (mType->mType == LST_QUATERNION)
1239 {
1240 chunk->addFloat(1.f);
1241 chunk->addFloat(0.f);
1242 chunk->addFloat(0.f);
1243 chunk->addFloat(0.f);
1244 }
1245 else
1246 {
1247 value->addBytes(LSCRIPTDataSize[mType->mType]);
1248 }
1249 }
1250 chunk->addBytes(value->mCodeChunk, value->mCurrentOffset);
1251 delete value;
1252 }
1253 break;
1254 case LSCP_EMIT_CIL_ASSEMBLY:
1255
1256 // Initialisation inside ctor.
1257 if (mAssignable)
1258 {
1259 fprintf(fp, "ldarg.0\n");
1260 mAssignable->recurse(fp, tabs, tabsize, LSCP_EMIT_CIL_ASSEMBLY, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
1261 fprintf(fp, "stfld ");
1262 mType->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
1263 fprintf(fp," LSL::");
1264 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
1265 fprintf(fp, "\n");
1266 }
1267 break;
1268 default:
1269 mType->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
1270 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
1271 if (mAssignable)
1272 {
1273 mAssignable->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
1274 }
1275 break;
1276 }
1277 gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
1278}
1279
1280S32 LLScriptGlobalVariable::getSize()
1281{
1282 S32 return_size;
1283
1284 return_size = mType->getSize();
1285 return return_size;
1286}
1287
1288void LLScriptEvent::recurse(FILE *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)
1289{
1290 fprintf(fp, "Event Base Class -- should never get here!\n");
1291}
1292
1293S32 LLScriptEvent::getSize()
1294{
1295 printf("Event Base Class -- should never get here!\n");
1296 return 0;
1297}
1298
1299void LLScriptStateEntryEvent::recurse(FILE *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)
1300{
1301 if (gErrorToText.getErrors())
1302 {
1303 return;
1304 }
1305 switch(pass)
1306 {
1307 case LSCP_PRETTY_PRINT:
1308 fdotabs(fp, tabs, tabsize);
1309 fprintf(fp, "state_entry()\n");
1310 break;
1311 case LSCP_EMIT_ASSEMBLY:
1312 fprintf(fp, "state_entry()\n");
1313 break;
1314 case LSCP_EMIT_BYTE_CODE:
1315 {
1316#ifdef LSL_INCLUDE_DEBUG_INFO
1317 char name[] = "state_entry";
1318 chunk->addBytes(name, strlen(name) + 1);
1319#endif
1320 }
1321 break;
1322 case LSCP_EMIT_CIL_ASSEMBLY:
1323 fprintf(fp, "state_entry()");
1324 break;
1325 default:
1326 break;
1327 }
1328}
1329
1330S32 LLScriptStateEntryEvent::getSize()
1331{
1332 return 0;
1333}
1334
1335void LLScriptStateExitEvent::recurse(FILE *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)
1336{
1337 if (gErrorToText.getErrors())
1338 {
1339 return;
1340 }
1341 switch(pass)
1342 {
1343 case LSCP_PRETTY_PRINT:
1344 fdotabs(fp, tabs, tabsize);
1345 fprintf(fp, "state_exit()\n");
1346 break;
1347 case LSCP_EMIT_ASSEMBLY:
1348 fprintf(fp, "state_exit()\n");
1349 break;
1350 case LSCP_EMIT_BYTE_CODE:
1351 {
1352#ifdef LSL_INCLUDE_DEBUG_INFO
1353 char name[] = "state_exit";
1354 chunk->addBytes(name, strlen(name) + 1);
1355#endif
1356 }
1357 break;
1358 case LSCP_EMIT_CIL_ASSEMBLY:
1359 fprintf(fp, "state_exit()");
1360 break;
1361 default:
1362 break;
1363 }
1364}
1365
1366S32 LLScriptStateExitEvent::getSize()
1367{
1368 return 0;
1369}
1370
1371void LLScriptTouchStartEvent::recurse(FILE *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)
1372{
1373 if (gErrorToText.getErrors())
1374 {
1375 return;
1376 }
1377 switch(pass)
1378 {
1379 case LSCP_PRETTY_PRINT:
1380 case LSCP_EMIT_ASSEMBLY:
1381 fdotabs(fp, tabs, tabsize);
1382 fprintf(fp, "touch_start( integer ");
1383 mCount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
1384 fprintf(fp, " )\n");
1385 break;
1386 break;
1387 case LSCP_SCOPE_PASS1:
1388 if (scope->checkEntry(mCount->mName))
1389 {
1390 gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
1391 }
1392 else
1393 {
1394 mCount->mScopeEntry = scope->addEntry(mCount->mName, LIT_VARIABLE, LST_INTEGER);
1395 }
1396 break;
1397 case LSCP_RESOURCE:
1398 {
1399 // we're just tryng to determine how much space the variable needs
1400 if (mCount->mScopeEntry)
1401 {
1402 mCount->mScopeEntry->mOffset = (S32)count;
1403 mCount->mScopeEntry->mSize = 4;
1404 count += mCount->mScopeEntry->mSize;
1405 }
1406 }
1407 break;
1408 case LSCP_EMIT_BYTE_CODE:
1409 {
1410#ifdef LSL_INCLUDE_DEBUG_INFO
1411 char name[] = "touch_start";
1412 chunk->addBytes(name, strlen(name) + 1);
1413 chunk->addBytes(mCount->mName, strlen(mCount->mName) + 1);
1414#endif
1415 }
1416 break;
1417 default:
1418 mCount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
1419 break;
1420 }
1421}
1422
1423S32 LLScriptTouchStartEvent::getSize()
1424{
1425 // integer = 4
1426 return 4;
1427}
1428
1429void LLScriptTouchEvent::recurse(FILE *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)
1430{
1431 if (gErrorToText.getErrors())
1432 {
1433 return;
1434 }
1435 switch(pass)
1436 {
1437 case LSCP_PRETTY_PRINT:
1438 case LSCP_EMIT_ASSEMBLY:
1439 fdotabs(fp, tabs, tabsize);
1440 fprintf(fp, "touch( integer ");
1441 mCount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
1442 fprintf(fp, " )\n");
1443 break;
1444 break;
1445 case LSCP_SCOPE_PASS1:
1446 if (scope->checkEntry(mCount->mName))
1447 {
1448 gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
1449 }
1450 else
1451 {
1452 mCount->mScopeEntry = scope->addEntry(mCount->mName, LIT_VARIABLE, LST_INTEGER);
1453 }
1454 break;
1455 case LSCP_RESOURCE:
1456 {
1457 // we're just tryng to determine how much space the variable needs
1458 if (mCount->mScopeEntry)
1459 {
1460 mCount->mScopeEntry->mOffset = (S32)count;
1461 mCount->mScopeEntry->mSize = 4;
1462 count += mCount->mScopeEntry->mSize;
1463 }
1464 }
1465 break;
1466 case LSCP_EMIT_BYTE_CODE:
1467 {
1468#ifdef LSL_INCLUDE_DEBUG_INFO
1469 char name[] = "touch";
1470 chunk->addBytes(name, strlen(name) + 1);
1471 chunk->addBytes(mCount->mName, strlen(mCount->mName) + 1);
1472#endif
1473 }
1474 break;
1475 default:
1476 mCount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
1477 break;
1478 }
1479}
1480
1481S32 LLScriptTouchEvent::getSize()
1482{
1483 // integer = 4
1484 return 4;
1485}
1486
1487void LLScriptTouchEndEvent::recurse(FILE *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)
1488{
1489 if (gErrorToText.getErrors())
1490 {
1491 return;
1492 }
1493 switch(pass)
1494 {
1495 case LSCP_PRETTY_PRINT:
1496 case LSCP_EMIT_ASSEMBLY:
1497 fdotabs(fp, tabs, tabsize);
1498 fprintf(fp, "touch_end( integer ");
1499 mCount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
1500 fprintf(fp, " )\n");
1501 break;
1502 break;
1503 case LSCP_SCOPE_PASS1:
1504 if (scope->checkEntry(mCount->mName))
1505 {
1506 gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
1507 }
1508 else
1509 {
1510 mCount->mScopeEntry = scope->addEntry(mCount->mName, LIT_VARIABLE, LST_INTEGER);
1511 }
1512 break;
1513 case LSCP_RESOURCE:
1514 {
1515 // we're just tryng to determine how much space the variable needs
1516 if (mCount->mScopeEntry)
1517 {
1518 mCount->mScopeEntry->mOffset = (S32)count;
1519 mCount->mScopeEntry->mSize = 4;
1520 count += mCount->mScopeEntry->mSize;
1521 }
1522 }
1523 break;
1524 case LSCP_EMIT_BYTE_CODE:
1525 {
1526#ifdef LSL_INCLUDE_DEBUG_INFO
1527 char name[] = "touch_end";
1528 chunk->addBytes(name, strlen(name) + 1);
1529 chunk->addBytes(mCount->mName, strlen(mCount->mName) + 1);
1530#endif
1531 }
1532 break;
1533 default:
1534 mCount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
1535 break;
1536 }
1537}
1538
1539S32 LLScriptTouchEndEvent::getSize()
1540{
1541 // integer = 4
1542 return 4;
1543}
1544
1545void LLScriptCollisionStartEvent::recurse(FILE *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)
1546{
1547 if (gErrorToText.getErrors())
1548 {
1549 return;
1550 }
1551 switch(pass)
1552 {
1553 case LSCP_PRETTY_PRINT:
1554 case LSCP_EMIT_ASSEMBLY:
1555 fdotabs(fp, tabs, tabsize);
1556 fprintf(fp, "collision_start( integer ");
1557 mCount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
1558 fprintf(fp, " )\n");
1559 break;
1560 break;
1561 case LSCP_SCOPE_PASS1:
1562 if (scope->checkEntry(mCount->mName))
1563 {
1564 gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
1565 }
1566 else
1567 {
1568 mCount->mScopeEntry = scope->addEntry(mCount->mName, LIT_VARIABLE, LST_INTEGER);
1569 }
1570 break;
1571 case LSCP_RESOURCE:
1572 {
1573 // we're just tryng to determine how much space the variable needs
1574 if (mCount->mScopeEntry)
1575 {
1576 mCount->mScopeEntry->mOffset = (S32)count;
1577 mCount->mScopeEntry->mSize = 4;
1578 count += mCount->mScopeEntry->mSize;
1579 }
1580 }
1581 break;
1582 case LSCP_EMIT_BYTE_CODE:
1583 {
1584#ifdef LSL_INCLUDE_DEBUG_INFO
1585 char name[] = "collision_start";
1586 chunk->addBytes(name, (S32)strlen(name) + 1);
1587 chunk->addBytes(mCount->mName, (S32)strlen(mCount->mName) + 1);
1588#endif
1589 }
1590 break;
1591 default:
1592 mCount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
1593 break;
1594 }
1595}
1596
1597S32 LLScriptCollisionStartEvent::getSize()
1598{
1599 // integer = 4
1600 return 4;
1601}
1602
1603void LLScriptCollisionEvent::recurse(FILE *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)
1604{
1605 if (gErrorToText.getErrors())
1606 {
1607 return;
1608 }
1609 switch(pass)
1610 {
1611 case LSCP_PRETTY_PRINT:
1612 case LSCP_EMIT_ASSEMBLY:
1613 fdotabs(fp, tabs, tabsize);
1614 fprintf(fp, "collision( integer ");
1615 mCount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
1616 fprintf(fp, " )\n");
1617 break;
1618 break;
1619 case LSCP_SCOPE_PASS1:
1620 if (scope->checkEntry(mCount->mName))
1621 {
1622 gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
1623 }
1624 else
1625 {
1626 mCount->mScopeEntry = scope->addEntry(mCount->mName, LIT_VARIABLE, LST_INTEGER);
1627 }
1628 break;
1629 case LSCP_RESOURCE:
1630 {
1631 // we're just tryng to determine how much space the variable needs
1632 if (mCount->mScopeEntry)
1633 {
1634 mCount->mScopeEntry->mOffset = (S32)count;
1635 mCount->mScopeEntry->mSize = 4;
1636 count += mCount->mScopeEntry->mSize;
1637 }
1638 }
1639 break;
1640 case LSCP_EMIT_BYTE_CODE:
1641 {
1642#ifdef LSL_INCLUDE_DEBUG_INFO
1643 char name[] = "collision";
1644 chunk->addBytes(name, strlen(name) + 1);
1645 chunk->addBytes(mCount->mName, strlen(mCount->mName) + 1);
1646#endif
1647 }
1648 break;
1649 default:
1650 mCount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
1651 break;
1652 }
1653}
1654
1655S32 LLScriptCollisionEvent::getSize()
1656{
1657 // integer = 4
1658 return 4;
1659}
1660
1661void LLScriptCollisionEndEvent::recurse(FILE *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)
1662{
1663 if (gErrorToText.getErrors())
1664 {
1665 return;
1666 }
1667 switch(pass)
1668 {
1669 case LSCP_PRETTY_PRINT:
1670 case LSCP_EMIT_ASSEMBLY:
1671 fdotabs(fp, tabs, tabsize);
1672 fprintf(fp, "collision_end( integer ");
1673 mCount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
1674 fprintf(fp, " )\n");
1675 break;
1676 break;
1677 case LSCP_SCOPE_PASS1:
1678 if (scope->checkEntry(mCount->mName))
1679 {
1680 gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
1681 }
1682 else
1683 {
1684 mCount->mScopeEntry = scope->addEntry(mCount->mName, LIT_VARIABLE, LST_INTEGER);
1685 }
1686 break;
1687 case LSCP_RESOURCE:
1688 {
1689 // we're just tryng to determine how much space the variable needs
1690 if (mCount->mScopeEntry)
1691 {
1692 mCount->mScopeEntry->mOffset = (S32)count;
1693 mCount->mScopeEntry->mSize = 4;
1694 count += mCount->mScopeEntry->mSize;
1695 }
1696 }
1697 break;
1698 case LSCP_EMIT_BYTE_CODE:
1699 {
1700#ifdef LSL_INCLUDE_DEBUG_INFO
1701 char name[] = "collision_end";
1702 chunk->addBytes(name, strlen(name) + 1);
1703 chunk->addBytes(mCount->mName, strlen(mCount->mName) + 1);
1704#endif
1705 }
1706 break;
1707 default:
1708 mCount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
1709 break;
1710 }
1711}
1712
1713S32 LLScriptCollisionEndEvent::getSize()
1714{
1715 // integer = 4
1716 return 4;
1717}
1718
1719void LLScriptLandCollisionStartEvent::recurse(FILE *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)
1720{
1721 if (gErrorToText.getErrors())
1722 {
1723 return;
1724 }
1725 switch(pass)
1726 {
1727 case LSCP_PRETTY_PRINT:
1728 case LSCP_EMIT_ASSEMBLY:
1729 fdotabs(fp, tabs, tabsize);
1730 fprintf(fp, "land_collision_start( vector ");
1731 mPosition->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
1732 fprintf(fp, " )\n");
1733 break;
1734 case LSCP_SCOPE_PASS1:
1735 if (scope->checkEntry(mPosition->mName))
1736 {
1737 gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
1738 }
1739 else
1740 {
1741 mPosition->mScopeEntry = scope->addEntry(mPosition->mName, LIT_VARIABLE, LST_VECTOR);
1742 }
1743 break;
1744 case LSCP_RESOURCE:
1745 {
1746 // we're just tryng to determine how much space the variable needs
1747 if (mPosition->mScopeEntry)
1748 {
1749 mPosition->mScopeEntry->mOffset = (S32)count;
1750 mPosition->mScopeEntry->mSize = 12;
1751 count += mPosition->mScopeEntry->mSize;
1752 }
1753 }
1754 break;
1755 case LSCP_EMIT_BYTE_CODE:
1756 {
1757#ifdef LSL_INCLUDE_DEBUG_INFO
1758 char name[] = "land_collision_start";
1759 chunk->addBytes(name, strlen(name) + 1);
1760 chunk->addBytes(mPosition->mName, strlen(mPosition->mName) + 1);
1761#endif
1762 }
1763 break;
1764 default:
1765 mPosition->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
1766 break;
1767 }
1768}
1769
1770S32 LLScriptLandCollisionStartEvent::getSize()
1771{
1772 // vector = 12
1773 return 12;
1774}
1775
1776
1777
1778void LLScriptLandCollisionEvent::recurse(FILE *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)
1779{
1780 if (gErrorToText.getErrors())
1781 {
1782 return;
1783 }
1784 switch(pass)
1785 {
1786 case LSCP_PRETTY_PRINT:
1787 case LSCP_EMIT_ASSEMBLY:
1788 fdotabs(fp, tabs, tabsize);
1789 fprintf(fp, "land_collision( vector ");
1790 mPosition->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
1791 fprintf(fp, " )\n");
1792 break;
1793 case LSCP_SCOPE_PASS1:
1794 if (scope->checkEntry(mPosition->mName))
1795 {
1796 gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
1797 }
1798 else
1799 {
1800 mPosition->mScopeEntry = scope->addEntry(mPosition->mName, LIT_VARIABLE, LST_VECTOR);
1801 }
1802 break;
1803 case LSCP_RESOURCE:
1804 {
1805 // we're just tryng to determine how much space the variable needs
1806 if (mPosition->mScopeEntry)
1807 {
1808 mPosition->mScopeEntry->mOffset = (S32)count;
1809 mPosition->mScopeEntry->mSize = 12;
1810 count += mPosition->mScopeEntry->mSize;
1811 }
1812 }
1813 break;
1814 case LSCP_EMIT_BYTE_CODE:
1815 {
1816#ifdef LSL_INCLUDE_DEBUG_INFO
1817 char name[] = "land_collision";
1818 chunk->addBytes(name, strlen(name) + 1);
1819 chunk->addBytes(mPosition->mName, strlen(mPosition->mName) + 1);
1820#endif
1821 }
1822 break;
1823 default:
1824 mPosition->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
1825 break;
1826 }
1827}
1828
1829S32 LLScriptLandCollisionEvent::getSize()
1830{
1831 // vector = 12
1832 return 12;
1833}
1834
1835
1836void LLScriptLandCollisionEndEvent::recurse(FILE *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)
1837{
1838 if (gErrorToText.getErrors())
1839 {
1840 return;
1841 }
1842 switch(pass)
1843 {
1844 case LSCP_PRETTY_PRINT:
1845 case LSCP_EMIT_ASSEMBLY:
1846 fdotabs(fp, tabs, tabsize);
1847 fprintf(fp, "land_collision_end( vector ");
1848 mPosition->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
1849 fprintf(fp, " )\n");
1850 break;
1851 case LSCP_SCOPE_PASS1:
1852 if (scope->checkEntry(mPosition->mName))
1853 {
1854 gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
1855 }
1856 else
1857 {
1858 mPosition->mScopeEntry = scope->addEntry(mPosition->mName, LIT_VARIABLE, LST_VECTOR);
1859 }
1860 break;
1861 case LSCP_RESOURCE:
1862 {
1863 // we're just tryng to determine how much space the variable needs
1864 if (mPosition->mScopeEntry)
1865 {
1866 mPosition->mScopeEntry->mOffset = (S32)count;
1867 mPosition->mScopeEntry->mSize = 12;
1868 count += mPosition->mScopeEntry->mSize;
1869 }
1870 }
1871 break;
1872 case LSCP_EMIT_BYTE_CODE:
1873 {
1874#ifdef LSL_INCLUDE_DEBUG_INFO
1875 char name[] = "land_collision_end";
1876 chunk->addBytes(name, strlen(name) + 1);
1877 chunk->addBytes(mPosition->mName, strlen(mPosition->mName) + 1);
1878#endif
1879 }
1880 break;
1881 default:
1882 mPosition->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
1883 break;
1884 }
1885}
1886
1887S32 LLScriptLandCollisionEndEvent::getSize()
1888{
1889 // vector = 12
1890 return 12;
1891}
1892
1893
1894void LLScriptInventoryEvent::recurse(FILE *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)
1895{
1896 if (gErrorToText.getErrors())
1897 {
1898 return;
1899 }
1900 switch(pass)
1901 {
1902 case LSCP_PRETTY_PRINT:
1903 case LSCP_EMIT_ASSEMBLY:
1904 fdotabs(fp, tabs, tabsize);
1905 fprintf(fp, "changed( integer ");
1906 mChange->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
1907 fprintf(fp, " )\n");
1908 break;
1909 case LSCP_SCOPE_PASS1:
1910 if (scope->checkEntry(mChange->mName))
1911 {
1912 gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
1913 }
1914 else
1915 {
1916 mChange->mScopeEntry = scope->addEntry(mChange->mName, LIT_VARIABLE, LST_INTEGER);
1917 }
1918 break;
1919 case LSCP_RESOURCE:
1920 {
1921 // we're just tryng to determine how much space the variable needs
1922 if (mChange->mScopeEntry)
1923 {
1924 mChange->mScopeEntry->mOffset = (S32)count;
1925 mChange->mScopeEntry->mSize = 4;
1926 count += mChange->mScopeEntry->mSize;
1927 }
1928 }
1929 break;
1930 case LSCP_EMIT_BYTE_CODE:
1931 {
1932#ifdef LSL_INCLUDE_DEBUG_INFO
1933 char name[] = "changed";
1934 chunk->addBytes(name, strlen(name) + 1);
1935 chunk->addBytes(mChange->mName, strlen(mChange->mName) + 1);
1936#endif
1937 }
1938 break;
1939 default:
1940 mChange->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
1941 break;
1942 }
1943}
1944
1945S32 LLScriptInventoryEvent::getSize()
1946{
1947 // integer = 4
1948 return 4;
1949}
1950
1951void LLScriptAttachEvent::recurse(FILE *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)
1952{
1953 if (gErrorToText.getErrors())
1954 {
1955 return;
1956 }
1957 switch(pass)
1958 {
1959 case LSCP_PRETTY_PRINT:
1960 case LSCP_EMIT_ASSEMBLY:
1961 fdotabs(fp, tabs, tabsize);
1962 fprintf(fp, "attach( key ");
1963 mAttach->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
1964 fprintf(fp, " )\n");
1965 break;
1966 case LSCP_SCOPE_PASS1:
1967 if (scope->checkEntry(mAttach->mName))
1968 {
1969 gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
1970 }
1971 else
1972 {
1973 mAttach->mScopeEntry = scope->addEntry(mAttach->mName, LIT_VARIABLE, LST_KEY);
1974 }
1975 break;
1976 case LSCP_RESOURCE:
1977 {
1978 // we're just tryng to determine how much space the variable needs
1979 if (mAttach->mScopeEntry)
1980 {
1981 mAttach->mScopeEntry->mOffset = (S32)count;
1982 mAttach->mScopeEntry->mSize = 4;
1983 count += mAttach->mScopeEntry->mSize;
1984 }
1985 }
1986 break;
1987 case LSCP_EMIT_BYTE_CODE:
1988 {
1989#ifdef LSL_INCLUDE_DEBUG_INFO
1990 char name[] = "attach";
1991 chunk->addBytes(name, strlen(name) + 1);
1992 chunk->addBytes(mAttach->mName, strlen(mAttach->mName) + 1);
1993#endif
1994 }
1995 break;
1996 default:
1997 mAttach->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
1998 break;
1999 }
2000}
2001
2002S32 LLScriptAttachEvent::getSize()
2003{
2004 // key = 4
2005 return 4;
2006}
2007
2008void LLScriptDataserverEvent::recurse(FILE *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)
2009{
2010 if (gErrorToText.getErrors())
2011 {
2012 return;
2013 }
2014 switch(pass)
2015 {
2016 case LSCP_PRETTY_PRINT:
2017 case LSCP_EMIT_ASSEMBLY:
2018 fdotabs(fp, tabs, tabsize);
2019 fprintf(fp, "dataserver( key ");
2020 mID->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
2021 fprintf(fp, ", string ");
2022 mData->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
2023 fprintf(fp, " )\n");
2024 break;
2025 case LSCP_SCOPE_PASS1:
2026 if (scope->checkEntry(mID->mName))
2027 {
2028 gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
2029 }
2030 else
2031 {
2032 mID->mScopeEntry = scope->addEntry(mID->mName, LIT_VARIABLE, LST_KEY);
2033 }
2034 if (scope->checkEntry(mData->mName))
2035 {
2036 gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
2037 }
2038 else
2039 {
2040 mData->mScopeEntry = scope->addEntry(mData->mName, LIT_VARIABLE, LST_STRING);
2041 }
2042 break;
2043 case LSCP_RESOURCE:
2044 {
2045 // we're just tryng to determine how much space the variable needs
2046 if (mID->mScopeEntry)
2047 {
2048 mID->mScopeEntry->mOffset = (S32)count;
2049 mID->mScopeEntry->mSize = 4;
2050 count += mID->mScopeEntry->mSize;
2051 mData->mScopeEntry->mOffset = (S32)count;
2052 mData->mScopeEntry->mSize = 4;
2053 count += mData->mScopeEntry->mSize;
2054 }
2055 }
2056 break;
2057 case LSCP_EMIT_BYTE_CODE:
2058 {
2059#ifdef LSL_INCLUDE_DEBUG_INFO
2060 char name[] = "dataserver";
2061 chunk->addBytes(name, strlen(name) + 1);
2062 chunk->addBytes(mID->mName, strlen(mID->mName) + 1);
2063 chunk->addBytes(mData->mName, strlen(mData->mName) + 1);
2064#endif
2065 }
2066 break;
2067 default:
2068 mID->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
2069 mData->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
2070 break;
2071 }
2072}
2073
2074S32 LLScriptDataserverEvent::getSize()
2075{
2076 // key + string = 8
2077 return 8;
2078}
2079
2080void LLScriptTimerEvent::recurse(FILE *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)
2081{
2082 if (gErrorToText.getErrors())
2083 {
2084 return;
2085 }
2086 switch(pass)
2087 {
2088 case LSCP_PRETTY_PRINT:
2089 fdotabs(fp, tabs, tabsize);
2090 fprintf(fp, "timer()\n");
2091 break;
2092 case LSCP_EMIT_ASSEMBLY:
2093 fprintf(fp, "timer()\n");
2094 break;
2095 case LSCP_EMIT_BYTE_CODE:
2096 {
2097#ifdef LSL_INCLUDE_DEBUG_INFO
2098 char name[] = "timer";
2099 chunk->addBytes(name, strlen(name) + 1);
2100#endif
2101 }
2102 break;
2103 default:
2104 break;
2105 }
2106}
2107
2108S32 LLScriptTimerEvent::getSize()
2109{
2110 return 0;
2111}
2112
2113void LLScriptMovingStartEvent::recurse(FILE *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)
2114{
2115 if (gErrorToText.getErrors())
2116 {
2117 return;
2118 }
2119 switch(pass)
2120 {
2121 case LSCP_PRETTY_PRINT:
2122 case LSCP_EMIT_ASSEMBLY:
2123 fdotabs(fp, tabs, tabsize);
2124 fprintf(fp, "moving_start()\n");
2125 break;
2126 case LSCP_EMIT_BYTE_CODE:
2127 {
2128#ifdef LSL_INCLUDE_DEBUG_INFO
2129 char name[] = "moving_start";
2130 chunk->addBytes(name, strlen(name) + 1);
2131#endif
2132 }
2133 break;
2134 default:
2135 break;
2136 }
2137}
2138
2139S32 LLScriptMovingStartEvent::getSize()
2140{
2141 return 0;
2142}
2143
2144void LLScriptMovingEndEvent::recurse(FILE *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)
2145{
2146 if (gErrorToText.getErrors())
2147 {
2148 return;
2149 }
2150 switch(pass)
2151 {
2152 case LSCP_PRETTY_PRINT:
2153 case LSCP_EMIT_ASSEMBLY:
2154 fdotabs(fp, tabs, tabsize);
2155 fprintf(fp, "moving_end()\n");
2156 break;
2157 case LSCP_EMIT_BYTE_CODE:
2158 {
2159#ifdef LSL_INCLUDE_DEBUG_INFO
2160 char name[] = "moving_end";
2161 chunk->addBytes(name, strlen(name) + 1);
2162#endif
2163 }
2164 break;
2165 default:
2166 break;
2167 }
2168}
2169
2170S32 LLScriptMovingEndEvent::getSize()
2171{
2172 return 0;
2173}
2174
2175void LLScriptRTPEvent::recurse(FILE *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)
2176{
2177 if (gErrorToText.getErrors())
2178 {
2179 return;
2180 }
2181 switch(pass)
2182 {
2183 case LSCP_PRETTY_PRINT:
2184 case LSCP_EMIT_ASSEMBLY:
2185 fdotabs(fp, tabs, tabsize);
2186 fprintf(fp, "chat( integer ");
2187 mRTPermissions->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
2188 fprintf(fp, " )\n");
2189 break;
2190 case LSCP_SCOPE_PASS1:
2191 if (scope->checkEntry(mRTPermissions->mName))
2192 {
2193 gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
2194 }
2195 else
2196 {
2197 mRTPermissions->mScopeEntry = scope->addEntry(mRTPermissions->mName, LIT_VARIABLE, LST_INTEGER);
2198 }
2199 break;
2200 case LSCP_RESOURCE:
2201 {
2202 // we're just tryng to determine how much space the variable needs
2203 if (mRTPermissions->mScopeEntry)
2204 {
2205 mRTPermissions->mScopeEntry->mOffset = (S32)count;
2206 mRTPermissions->mScopeEntry->mSize = 4;
2207 count += mRTPermissions->mScopeEntry->mSize;
2208 }
2209 }
2210 break;
2211 case LSCP_EMIT_BYTE_CODE:
2212 {
2213#ifdef LSL_INCLUDE_DEBUG_INFO
2214 char name[] = "chat";
2215 chunk->addBytes(name, strlen(name) + 1);
2216 chunk->addBytes(mRTPermissions->mName, strlen(mRTPermissions->mName) + 1);
2217#endif
2218 }
2219 break;
2220 default:
2221 mRTPermissions->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
2222 break;
2223 }
2224}
2225
2226S32 LLScriptRTPEvent::getSize()
2227{
2228 // integer = 4
2229 return 4;
2230}
2231
2232void LLScriptChatEvent::recurse(FILE *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)
2233{
2234 if (gErrorToText.getErrors())
2235 {
2236 return;
2237 }
2238 switch(pass)
2239 {
2240 case LSCP_PRETTY_PRINT:
2241 case LSCP_EMIT_ASSEMBLY:
2242 fdotabs(fp, tabs, tabsize);
2243 fprintf(fp, "chat( integer ");
2244 mChannel->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
2245 fprintf(fp, ", string ");
2246 mName->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
2247 fprintf(fp, ", key ");
2248 mID->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
2249 fprintf(fp, ", string ");
2250 mMessage->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
2251 fprintf(fp, " )\n");
2252 break;
2253 case LSCP_SCOPE_PASS1:
2254 if (scope->checkEntry(mChannel->mName))
2255 {
2256 gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
2257 }
2258 else
2259 {
2260 mChannel->mScopeEntry = scope->addEntry(mChannel->mName, LIT_VARIABLE, LST_INTEGER);
2261 }
2262 if (scope->checkEntry(mName->mName))
2263 {
2264 gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
2265 }
2266 else
2267 {
2268 mName->mScopeEntry = scope->addEntry(mName->mName, LIT_VARIABLE, LST_STRING);
2269 }
2270 if (scope->checkEntry(mID->mName))
2271 {
2272 gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
2273 }
2274 else
2275 {
2276 mID->mScopeEntry = scope->addEntry(mID->mName, LIT_VARIABLE, LST_KEY);
2277 }
2278 if (scope->checkEntry(mMessage->mName))
2279 {
2280 gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
2281 }
2282 else
2283 {
2284 mMessage->mScopeEntry = scope->addEntry(mMessage->mName, LIT_VARIABLE, LST_STRING);
2285 }
2286 break;
2287 case LSCP_RESOURCE:
2288 {
2289 // we're just tryng to determine how much space the variable needs
2290 if (mName->mScopeEntry)
2291 {
2292 mChannel->mScopeEntry->mOffset = (S32)count;
2293 mChannel->mScopeEntry->mSize = 4;
2294 count += mChannel->mScopeEntry->mSize;
2295 mName->mScopeEntry->mOffset = (S32)count;
2296 mName->mScopeEntry->mSize = 4;
2297 count += mName->mScopeEntry->mSize;
2298 mID->mScopeEntry->mOffset = (S32)count;
2299 mID->mScopeEntry->mSize = 4;
2300 count += mID->mScopeEntry->mSize;
2301 mMessage->mScopeEntry->mOffset = (S32)count;
2302 mMessage->mScopeEntry->mSize = 4;
2303 count += mMessage->mScopeEntry->mSize;
2304 }
2305 }
2306 break;
2307 case LSCP_EMIT_BYTE_CODE:
2308 {
2309#ifdef LSL_INCLUDE_DEBUG_INFO
2310 char name[] = "chat";
2311 chunk->addBytes(name, strlen(name) + 1);
2312 chunk->addBytes(mChannel->mName, strlen(mChannel->mName) + 1);
2313 chunk->addBytes(mName->mName, strlen(mName->mName) + 1);
2314 chunk->addBytes(mID->mName, strlen(mID->mName) + 1);
2315 chunk->addBytes(mMessage->mName, strlen(mMessage->mName) + 1);
2316#endif
2317 }
2318 break;
2319 default:
2320 mChannel->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
2321 mName->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
2322 mID->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
2323 mMessage->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
2324 break;
2325 }
2326}
2327
2328S32 LLScriptChatEvent::getSize()
2329{
2330 // integer + key + string + string = 16
2331 return 16;
2332}
2333
2334void LLScriptSensorEvent::recurse(FILE *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)
2335{
2336 if (gErrorToText.getErrors())
2337 {
2338 return;
2339 }
2340 switch(pass)
2341 {
2342 case LSCP_PRETTY_PRINT:
2343 case LSCP_EMIT_ASSEMBLY:
2344 fdotabs(fp, tabs, tabsize);
2345 fprintf(fp, "sensor( integer ");
2346 mNumber->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
2347 fprintf(fp, " )\n");
2348 break;
2349 case LSCP_SCOPE_PASS1:
2350 if (scope->checkEntry(mNumber->mName))
2351 {
2352 gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
2353 }
2354 else
2355 {
2356 mNumber->mScopeEntry = scope->addEntry(mNumber->mName, LIT_VARIABLE, LST_INTEGER);
2357 }
2358 break;
2359 case LSCP_RESOURCE:
2360 {
2361 // we're just tryng to determine how much space the variable needs
2362 if (mNumber->mScopeEntry)
2363 {
2364 mNumber->mScopeEntry->mOffset = (S32)count;
2365 mNumber->mScopeEntry->mSize = 4;
2366 count += mNumber->mScopeEntry->mSize;
2367 }
2368 }
2369 break;
2370 case LSCP_EMIT_BYTE_CODE:
2371 {
2372#ifdef LSL_INCLUDE_DEBUG_INFO
2373 char name[] = "sensor";
2374 chunk->addBytes(name, strlen(name) + 1);
2375 chunk->addBytes(mNumber->mName, strlen(mNumber->mName) + 1);
2376#endif
2377 }
2378 break;
2379 default:
2380 mNumber->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
2381 break;
2382 }
2383}
2384
2385S32 LLScriptSensorEvent::getSize()
2386{
2387 // integer = 4
2388 return 4;
2389}
2390
2391void LLScriptObjectRezEvent::recurse(FILE *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)
2392{
2393 if (gErrorToText.getErrors())
2394 {
2395 return;
2396 }
2397 switch(pass)
2398 {
2399 case LSCP_PRETTY_PRINT:
2400 case LSCP_EMIT_ASSEMBLY:
2401 fdotabs(fp, tabs, tabsize);
2402 fprintf(fp, "object_rez( key ");
2403 mID->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
2404 fprintf(fp, " )\n");
2405 break;
2406 case LSCP_SCOPE_PASS1:
2407 if (scope->checkEntry(mID->mName))
2408 {
2409 gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
2410 }
2411 else
2412 {
2413 mID->mScopeEntry = scope->addEntry(mID->mName, LIT_VARIABLE, LST_KEY);
2414 }
2415 break;
2416 case LSCP_RESOURCE:
2417 {
2418 // we're just tryng to determine how much space the variable needs
2419 if (mID->mScopeEntry)
2420 {
2421 mID->mScopeEntry->mOffset = (S32)count;
2422 mID->mScopeEntry->mSize = 4;
2423 count += mID->mScopeEntry->mSize;
2424 }
2425 }
2426 break;
2427 case LSCP_EMIT_BYTE_CODE:
2428 {
2429#ifdef LSL_INCLUDE_DEBUG_INFO
2430 char name[] = "sensor";
2431 chunk->addBytes(name, strlen(name) + 1);
2432 chunk->addBytes(mID->mName, strlen(mID->mName) + 1);
2433#endif
2434 }
2435 break;
2436 default:
2437 mID->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
2438 break;
2439 }
2440}
2441
2442S32 LLScriptObjectRezEvent::getSize()
2443{
2444 // key = 4
2445 return 4;
2446}
2447
2448void LLScriptControlEvent::recurse(FILE *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)
2449{
2450 if (gErrorToText.getErrors())
2451 {
2452 return;
2453 }
2454 switch(pass)
2455 {
2456 case LSCP_PRETTY_PRINT:
2457 case LSCP_EMIT_ASSEMBLY:
2458 fdotabs(fp, tabs, tabsize);
2459 fprintf(fp, "control( key ");
2460 mName->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
2461 fprintf(fp, ", integer ");
2462 mLevels->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
2463 fprintf(fp, ", integer ");
2464 mEdges->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
2465 fprintf(fp, " )\n");
2466 break;
2467 case LSCP_SCOPE_PASS1:
2468 if (scope->checkEntry(mName->mName))
2469 {
2470 gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
2471 }
2472 else
2473 {
2474 mName->mScopeEntry = scope->addEntry(mName->mName, LIT_VARIABLE, LST_KEY);
2475 }
2476 if (scope->checkEntry(mLevels->mName))
2477 {
2478 gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
2479 }
2480 else
2481 {
2482 mLevels->mScopeEntry = scope->addEntry(mLevels->mName, LIT_VARIABLE, LST_INTEGER);
2483 }
2484 if (scope->checkEntry(mEdges->mName))
2485 {
2486 gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
2487 }
2488 else
2489 {
2490 mEdges->mScopeEntry = scope->addEntry(mEdges->mName, LIT_VARIABLE, LST_INTEGER);
2491 }
2492 break;
2493 case LSCP_RESOURCE:
2494 {
2495 // we're just tryng to determine how much space the variable needs
2496 if (mName->mScopeEntry)
2497 {
2498 mName->mScopeEntry->mOffset = (S32)count;
2499 mName->mScopeEntry->mSize = 4;
2500 count += mName->mScopeEntry->mSize;
2501 mLevels->mScopeEntry->mOffset = (S32)count;
2502 mLevels->mScopeEntry->mSize = 4;
2503 count += mLevels->mScopeEntry->mSize;
2504 mEdges->mScopeEntry->mOffset = (S32)count;
2505 mEdges->mScopeEntry->mSize = 4;
2506 count += mEdges->mScopeEntry->mSize;
2507 }
2508 }
2509 break;
2510 case LSCP_EMIT_BYTE_CODE:
2511 {
2512#ifdef LSL_INCLUDE_DEBUG_INFO
2513 char name[] = "control";
2514 chunk->addBytes(name, strlen(name) + 1);
2515 chunk->addBytes(mName->mName, strlen(mName->mName) + 1);
2516 chunk->addBytes(mLevels->mName, strlen(mLevels->mName) + 1);
2517 chunk->addBytes(mEdges->mName, strlen(mEdges->mName) + 1);
2518#endif
2519 }
2520 break;
2521 default:
2522 mName->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
2523 mLevels->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
2524 mEdges->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
2525 break;
2526 }
2527}
2528
2529S32 LLScriptControlEvent::getSize()
2530{
2531 // key + integer + integer = 12
2532 return 12;
2533}
2534
2535void LLScriptLinkMessageEvent::recurse(FILE *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)
2536{
2537 if (gErrorToText.getErrors())
2538 {
2539 return;
2540 }
2541 switch(pass)
2542 {
2543 case LSCP_PRETTY_PRINT:
2544 case LSCP_EMIT_ASSEMBLY:
2545 fdotabs(fp, tabs, tabsize);
2546 fprintf(fp, "link_message( integer ");
2547 mSender->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
2548 fprintf(fp, ", integer ");
2549 mNum->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
2550 fprintf(fp, ", string ");
2551 mStr->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
2552 fprintf(fp, ", key ");
2553 mID->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
2554 fprintf(fp, " )\n");
2555 break;
2556 case LSCP_SCOPE_PASS1:
2557 if (scope->checkEntry(mSender->mName))
2558 {
2559 gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
2560 }
2561 else
2562 {
2563 mSender->mScopeEntry = scope->addEntry(mSender->mName, LIT_VARIABLE, LST_INTEGER);
2564 }
2565 if (scope->checkEntry(mNum->mName))
2566 {
2567 gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
2568 }
2569 else
2570 {
2571 mNum->mScopeEntry = scope->addEntry(mNum->mName, LIT_VARIABLE, LST_INTEGER);
2572 }
2573 if (scope->checkEntry(mStr->mName))
2574 {
2575 gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
2576 }
2577 else
2578 {
2579 mStr->mScopeEntry = scope->addEntry(mStr->mName, LIT_VARIABLE, LST_STRING);
2580 }
2581 if (scope->checkEntry(mID->mName))
2582 {
2583 gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
2584 }
2585 else
2586 {
2587 mID->mScopeEntry = scope->addEntry(mID->mName, LIT_VARIABLE, LST_KEY);
2588 }
2589 break;
2590 case LSCP_RESOURCE:
2591 {
2592 // we're just tryng to determine how much space the variable needs
2593 if (mSender->mScopeEntry)
2594 {
2595 mSender->mScopeEntry->mOffset = (S32)count;
2596 mSender->mScopeEntry->mSize = 4;
2597 count += mSender->mScopeEntry->mSize;
2598 mNum->mScopeEntry->mOffset = (S32)count;
2599 mNum->mScopeEntry->mSize = 4;
2600 count += mNum->mScopeEntry->mSize;
2601 mStr->mScopeEntry->mOffset = (S32)count;
2602 mStr->mScopeEntry->mSize = 4;
2603 count += mStr->mScopeEntry->mSize;
2604 mID->mScopeEntry->mOffset = (S32)count;
2605 mID->mScopeEntry->mSize = 4;
2606 count += mID->mScopeEntry->mSize;
2607 }
2608 }
2609 break;
2610 case LSCP_EMIT_BYTE_CODE:
2611 {
2612#ifdef LSL_INCLUDE_DEBUG_INFO
2613 char name[] = "link_message";
2614 chunk->addBytes(name, strlen(name) + 1);
2615 chunk->addBytes(mSender->mName, strlen(mSender->mName) + 1);
2616 chunk->addBytes(mNum->mName, strlen(mNum->mName) + 1);
2617 chunk->addBytes(mStr->mName, strlen(mStr->mName) + 1);
2618 chunk->addBytes(mID->mName, strlen(mID->mName) + 1);
2619#endif
2620 }
2621 break;
2622 default:
2623 mSender->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
2624 mNum->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
2625 mStr->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
2626 mID->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
2627 break;
2628 }
2629}
2630
2631S32 LLScriptLinkMessageEvent::getSize()
2632{
2633 // integer + key + integer + string = 16
2634 return 16;
2635}
2636
2637void LLScriptRemoteEvent::recurse(FILE *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)
2638{
2639 if (gErrorToText.getErrors())
2640 {
2641 return;
2642 }
2643 switch(pass)
2644 {
2645 case LSCP_PRETTY_PRINT:
2646 case LSCP_EMIT_ASSEMBLY:
2647 fdotabs(fp, tabs, tabsize);
2648 fprintf(fp, "remote_event( integer ");
2649 mType->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
2650 fprintf(fp, ", key ");
2651 mChannel->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
2652 fprintf(fp, ", key ");
2653 mMessageID->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
2654 fprintf(fp, ", string ");
2655 mSender->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
2656 fprintf(fp, ", integer ");
2657 mIntVal->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
2658 fprintf(fp, ", string ");
2659 mStrVal->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
2660 fprintf(fp, " )\n");
2661 break;
2662 case LSCP_SCOPE_PASS1:
2663 if (scope->checkEntry(mType->mName))
2664 {
2665 gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
2666 }
2667 else
2668 {
2669 mType->mScopeEntry = scope->addEntry(mType->mName, LIT_VARIABLE, LST_INTEGER);
2670 }
2671 if (scope->checkEntry(mChannel->mName))
2672 {
2673 gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
2674 }
2675 else
2676 {
2677 mChannel->mScopeEntry = scope->addEntry(mChannel->mName, LIT_VARIABLE, LST_KEY);
2678 }
2679 if (scope->checkEntry(mMessageID->mName))
2680 {
2681 gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
2682 }
2683 else
2684 {
2685 mMessageID->mScopeEntry = scope->addEntry(mMessageID->mName, LIT_VARIABLE, LST_KEY);
2686 }
2687 if (scope->checkEntry(mSender->mName))
2688 {
2689 gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
2690 }
2691 else
2692 {
2693 mSender->mScopeEntry = scope->addEntry(mSender->mName, LIT_VARIABLE, LST_STRING);
2694 }
2695 if (scope->checkEntry(mIntVal->mName))
2696 {
2697 gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
2698 }
2699 else
2700 {
2701 mIntVal->mScopeEntry = scope->addEntry(mIntVal->mName, LIT_VARIABLE, LST_INTEGER);
2702 }
2703 if (scope->checkEntry(mStrVal->mName))
2704 {
2705 gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
2706 }
2707 else
2708 {
2709 mStrVal->mScopeEntry = scope->addEntry(mStrVal->mName, LIT_VARIABLE, LST_STRING);
2710 }
2711 break;
2712 case LSCP_RESOURCE:
2713 {
2714 // we're just tryng to determine how much space the variable needs
2715 if (mType->mScopeEntry)
2716 {
2717 mType->mScopeEntry->mOffset = (S32)count;
2718 mType->mScopeEntry->mSize = 4;
2719 count += mType->mScopeEntry->mSize;
2720 mChannel->mScopeEntry->mOffset = (S32)count;
2721 mChannel->mScopeEntry->mSize = 4;
2722 count += mChannel->mScopeEntry->mSize;
2723 mMessageID->mScopeEntry->mOffset = (S32)count;
2724 mMessageID->mScopeEntry->mSize = 4;
2725 count += mMessageID->mScopeEntry->mSize;
2726 mSender->mScopeEntry->mOffset = (S32)count;
2727 mSender->mScopeEntry->mSize = 4;
2728 count += mSender->mScopeEntry->mSize;
2729 mIntVal->mScopeEntry->mOffset = (S32)count;
2730 mIntVal->mScopeEntry->mSize = 4;
2731 count += mIntVal->mScopeEntry->mSize;
2732 mStrVal->mScopeEntry->mOffset = (S32)count;
2733 mStrVal->mScopeEntry->mSize = 4;
2734 count += mStrVal->mScopeEntry->mSize;
2735 }
2736 }
2737 break;
2738 case LSCP_EMIT_BYTE_CODE:
2739 {
2740#ifdef LSL_INCLUDE_DEBUG_INFO
2741 char name[] = "remote_event";
2742 chunk->addBytes(name, strlen(name) + 1);
2743 chunk->addBytes(mType->mName, strlen(mType->mName) + 1);
2744 chunk->addBytes(mChannel->mName, strlen(mChannel->mName) + 1);
2745 chunk->addBytes(mMessageID->mName, strlen(mMessageID->mName) + 1);
2746 chunk->addBytes(mSender->mName, strlen(mSender->mName) + 1);
2747 chunk->addBytes(mIntVal->mName, strlen(mIntVal->mName) + 1);
2748 chunk->addBytes(mStrVal->mName, strlen(mStrVal->mName) + 1);
2749#endif
2750 }
2751 break;
2752 default:
2753 mType->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
2754 mChannel->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
2755 mMessageID->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
2756 mSender->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
2757 mIntVal->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
2758 mStrVal->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
2759 break;
2760 }
2761}
2762
2763S32 LLScriptRemoteEvent::getSize()
2764{
2765 // integer + key + key + string + integer + string = 24
2766 return 24;
2767}
2768
2769void LLScriptHTTPResponseEvent::recurse(FILE *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)
2770{
2771 if (gErrorToText.getErrors())
2772 {
2773 return;
2774 }
2775 switch(pass)
2776 {
2777 case LSCP_PRETTY_PRINT:
2778 case LSCP_EMIT_ASSEMBLY:
2779 fdotabs(fp, tabs, tabsize);
2780 fprintf(fp, "http_response( key ");
2781 mRequestId->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
2782 fprintf(fp, ", integer ");
2783 mStatus->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
2784 fprintf(fp, ", list ");
2785 mMetadata->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
2786 fprintf(fp, ", string ");
2787 mBody->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
2788 fprintf(fp, " )\n");
2789 break;
2790
2791 case LSCP_SCOPE_PASS1:
2792 if (scope->checkEntry(mRequestId->mName))
2793 {
2794 gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
2795 }
2796 else
2797 {
2798 mRequestId->mScopeEntry = scope->addEntry(mRequestId->mName, LIT_VARIABLE, LST_KEY);
2799 }
2800
2801 if (scope->checkEntry(mStatus->mName))
2802 {
2803 gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
2804 }
2805 else
2806 {
2807 mStatus->mScopeEntry = scope->addEntry(mStatus->mName, LIT_VARIABLE, LST_INTEGER);
2808 }
2809
2810 if (scope->checkEntry(mMetadata->mName))
2811 {
2812 gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
2813 }
2814 else
2815 {
2816 mMetadata->mScopeEntry = scope->addEntry(mMetadata->mName, LIT_VARIABLE, LST_LIST);
2817 }
2818
2819 if (scope->checkEntry(mBody->mName))
2820 {
2821 gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
2822 }
2823 else
2824 {
2825 mBody->mScopeEntry = scope->addEntry(mBody->mName, LIT_VARIABLE, LST_STRING);
2826 }
2827 break;
2828
2829 case LSCP_RESOURCE:
2830 {
2831 // we're just tryng to determine how much space the variable needs
2832 if (mRequestId->mScopeEntry)
2833 {
2834 mRequestId->mScopeEntry->mOffset = (S32)count;
2835 mRequestId->mScopeEntry->mSize = 4;
2836 count += mRequestId->mScopeEntry->mSize;
2837
2838 mStatus->mScopeEntry->mOffset = (S32)count;
2839 mStatus->mScopeEntry->mSize = 4;
2840 count += mStatus->mScopeEntry->mSize;
2841
2842 mMetadata->mScopeEntry->mOffset = (S32)count;
2843 mMetadata->mScopeEntry->mSize = 4;
2844 count += mMetadata->mScopeEntry->mSize;
2845
2846 mBody->mScopeEntry->mOffset = (S32)count;
2847 mBody->mScopeEntry->mSize = 4;
2848 count += mBody->mScopeEntry->mSize;
2849 }
2850 }
2851 break;
2852
2853 case LSCP_EMIT_BYTE_CODE:
2854 {
2855#ifdef LSL_INCLUDE_DEBUG_INFO
2856 char name[] = "http_response";
2857 chunk->addBytes(name, strlen(name) + 1);
2858 chunk->addBytes(mRequestId->mName, strlen(mRequestId->mName) + 1);
2859 chunk->addBytes(mStatus->mName, strlen(mStatus->mName) + 1);
2860 chunk->addBytes(mMetadata->mName, strlen(mMetadata->mName) + 1);
2861 chunk->addBytes(mBody->mName, strlen(mBody->mName) + 1);
2862#endif
2863 }
2864 break;
2865
2866 default:
2867 mRequestId->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
2868 mStatus->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
2869 mMetadata->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
2870 mBody->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
2871 break;
2872 }
2873}
2874
2875S32 LLScriptHTTPResponseEvent::getSize()
2876{
2877 // key + integer + list + string = 16
2878 return 16;
2879}
2880
2881
2882void LLScriptMoneyEvent::recurse(FILE *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)
2883{
2884 if (gErrorToText.getErrors())
2885 {
2886 return;
2887 }
2888 switch(pass)
2889 {
2890 case LSCP_PRETTY_PRINT:
2891 case LSCP_EMIT_ASSEMBLY:
2892 fdotabs(fp, tabs, tabsize);
2893 fprintf(fp, "money( key ");
2894 mName->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
2895 fprintf(fp, ", integer ");
2896 mAmount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
2897 fprintf(fp, " )\n");
2898 break;
2899 case LSCP_SCOPE_PASS1:
2900 if (scope->checkEntry(mName->mName))
2901 {
2902 gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
2903 }
2904 else
2905 {
2906 mName->mScopeEntry = scope->addEntry(mName->mName, LIT_VARIABLE, LST_KEY);
2907 }
2908 if (scope->checkEntry(mAmount->mName))
2909 {
2910 gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
2911 }
2912 else
2913 {
2914 mAmount->mScopeEntry = scope->addEntry(mAmount->mName, LIT_VARIABLE, LST_INTEGER);
2915 }
2916 break;
2917 case LSCP_RESOURCE:
2918 {
2919 // we're just tryng to determine how much space the variable needs
2920 if (mName->mScopeEntry)
2921 {
2922 mName->mScopeEntry->mOffset = (S32)count;
2923 mName->mScopeEntry->mSize = 4;
2924 count += mName->mScopeEntry->mSize;
2925 mAmount->mScopeEntry->mOffset = (S32)count;
2926 mAmount->mScopeEntry->mSize = 4;
2927 count += mAmount->mScopeEntry->mSize;
2928 }
2929 }
2930 break;
2931 case LSCP_EMIT_BYTE_CODE:
2932 {
2933#ifdef LSL_INCLUDE_DEBUG_INFO
2934 char name[] = "money";
2935 chunk->addBytes(name, strlen(name) + 1);
2936 chunk->addBytes(mName->mName, strlen(mName->mName) + 1);
2937 chunk->addBytes(mAmount->mName, strlen(mAmount->mName) + 1);
2938#endif
2939 }
2940 break;
2941 default:
2942 mName->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
2943 mAmount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
2944 break;
2945 }
2946}
2947
2948S32 LLScriptMoneyEvent::getSize()
2949{
2950 // key + integer = 8
2951 return 8;
2952}
2953
2954void LLScriptEmailEvent::recurse(FILE *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)
2955{
2956 if (gErrorToText.getErrors())
2957 {
2958 return;
2959 }
2960 switch(pass)
2961 {
2962 case LSCP_PRETTY_PRINT:
2963 case LSCP_EMIT_ASSEMBLY:
2964 fdotabs(fp, tabs, tabsize);
2965 fprintf(fp, "email( string ");
2966 mTime->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
2967 fprintf(fp, ", string ");
2968 mAddress->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
2969 fprintf(fp, ", string ");
2970 mSubject->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
2971 fprintf(fp, ", string ");
2972 mBody->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
2973 fprintf(fp, ", integer ");
2974 mNumber->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
2975 fprintf(fp, " )\n");
2976 break;
2977 case LSCP_SCOPE_PASS1:
2978 if (scope->checkEntry(mTime->mName))
2979 {
2980 gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
2981 }
2982 else
2983 {
2984 mTime->mScopeEntry = scope->addEntry(mTime->mName, LIT_VARIABLE, LST_STRING);
2985 }
2986 if (scope->checkEntry(mAddress->mName))
2987 {
2988 gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
2989 }
2990 else
2991 {
2992 mAddress->mScopeEntry = scope->addEntry(mAddress->mName, LIT_VARIABLE, LST_STRING);
2993 }
2994 if (scope->checkEntry(mSubject->mName))
2995 {
2996 gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
2997 }
2998 else
2999 {
3000 mSubject->mScopeEntry = scope->addEntry(mSubject->mName, LIT_VARIABLE, LST_STRING);
3001 }
3002 if (scope->checkEntry(mBody->mName))
3003 {
3004 gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
3005 }
3006 else
3007 {
3008 mBody->mScopeEntry = scope->addEntry(mBody->mName, LIT_VARIABLE, LST_STRING);
3009 }
3010 if (scope->checkEntry(mNumber->mName))
3011 {
3012 gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
3013 }
3014 else
3015 {
3016 mNumber->mScopeEntry = scope->addEntry(mNumber->mName, LIT_VARIABLE, LST_INTEGER);
3017 }
3018 break;
3019 case LSCP_RESOURCE:
3020 {
3021 // we're just tryng to determine how much space the variable needs
3022 if (mAddress->mScopeEntry)
3023 {
3024 mTime->mScopeEntry->mOffset = (S32)count;
3025 mTime->mScopeEntry->mSize = 4;
3026 count += mTime->mScopeEntry->mSize;
3027 mAddress->mScopeEntry->mOffset = (S32)count;
3028 mAddress->mScopeEntry->mSize = 4;
3029 count += mAddress->mScopeEntry->mSize;
3030 mSubject->mScopeEntry->mOffset = (S32)count;
3031 mSubject->mScopeEntry->mSize = 4;
3032 count += mSubject->mScopeEntry->mSize;
3033 mBody->mScopeEntry->mOffset = (S32)count;
3034 mBody->mScopeEntry->mSize = 4;
3035 count += mBody->mScopeEntry->mSize;
3036 mNumber->mScopeEntry->mOffset = (S32)count;
3037 mNumber->mScopeEntry->mSize = 4;
3038 count += mNumber->mScopeEntry->mSize;
3039 }
3040 }
3041 break;
3042 case LSCP_EMIT_BYTE_CODE:
3043 {
3044#ifdef LSL_INCLUDE_DEBUG_INFO
3045 char name[] = "email";
3046 chunk->addBytes(name, strlen(name) + 1);
3047 chunk->addBytes(mTime->mName, strlen(mTime->mName) + 1);
3048 chunk->addBytes(mAddress->mName, strlen(mAddress->mName) + 1);
3049 chunk->addBytes(mSubject->mName, strlen(mSubject->mName) + 1);
3050 chunk->addBytes(mBody->mName, strlen(mBody->mName) + 1);
3051 chunk->addBytes(mNumber->mName, strlen(mNumber->mName) + 1);
3052#endif
3053 }
3054 break;
3055 default:
3056 mTime->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
3057 mAddress->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
3058 mSubject->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
3059 mBody->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
3060 mNumber->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
3061 break;
3062 }
3063}
3064
3065S32 LLScriptEmailEvent::getSize()
3066{
3067 // string + string + string + string + integer = 16
3068 return 20;
3069}
3070
3071void LLScriptRezEvent::recurse(FILE *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)
3072{
3073 if (gErrorToText.getErrors())
3074 {
3075 return;
3076 }
3077 switch(pass)
3078 {
3079 case LSCP_PRETTY_PRINT:
3080 case LSCP_EMIT_ASSEMBLY:
3081 fdotabs(fp, tabs, tabsize);
3082 fprintf(fp, "rez( integer ");
3083 mStartParam->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
3084 fprintf(fp, " )\n");
3085 break;
3086 case LSCP_SCOPE_PASS1:
3087 if (scope->checkEntry(mStartParam->mName))
3088 {
3089 gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
3090 }
3091 else
3092 {
3093 mStartParam->mScopeEntry = scope->addEntry(mStartParam->mName, LIT_VARIABLE, LST_INTEGER);
3094 }
3095 break;
3096 case LSCP_RESOURCE:
3097 {
3098 // we're just tryng to determine how much space the variable needs
3099 if (mStartParam->mScopeEntry)
3100 {
3101 mStartParam->mScopeEntry->mOffset = (S32)count;
3102 mStartParam->mScopeEntry->mSize = 4;
3103 count += mStartParam->mScopeEntry->mSize;
3104 }
3105 }
3106 break;
3107 case LSCP_EMIT_BYTE_CODE:
3108 {
3109#ifdef LSL_INCLUDE_DEBUG_INFO
3110 char name[] = "rez";
3111 chunk->addBytes(name, strlen(name) + 1);
3112 chunk->addBytes(mStartParam->mName, strlen(mStartParam->mName) + 1);
3113#endif
3114 }
3115 break;
3116 default:
3117 mStartParam->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
3118 break;
3119 }
3120}
3121
3122S32 LLScriptRezEvent::getSize()
3123{
3124 // integer = 4
3125 return 4;
3126}
3127
3128void LLScriptNoSensorEvent::recurse(FILE *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)
3129{
3130 if (gErrorToText.getErrors())
3131 {
3132 return;
3133 }
3134 switch(pass)
3135 {
3136 case LSCP_PRETTY_PRINT:
3137 fdotabs(fp, tabs, tabsize);
3138 fprintf(fp, "no_sensor()\n");
3139 break;
3140 case LSCP_EMIT_ASSEMBLY:
3141 fprintf(fp, "no_sensor()\n");
3142 break;
3143 case LSCP_EMIT_BYTE_CODE:
3144 {
3145#ifdef LSL_INCLUDE_DEBUG_INFO
3146 char name[] = "no_sensor";
3147 chunk->addBytes(name, strlen(name) + 1);
3148#endif
3149 }
3150 break;
3151 default:
3152 break;
3153 }
3154}
3155
3156S32 LLScriptNoSensorEvent::getSize()
3157{
3158 return 0;
3159}
3160
3161void LLScriptAtTarget::recurse(FILE *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)
3162{
3163 if (gErrorToText.getErrors())
3164 {
3165 return;
3166 }
3167 switch(pass)
3168 {
3169 case LSCP_PRETTY_PRINT:
3170 case LSCP_EMIT_ASSEMBLY:
3171 fdotabs(fp, tabs, tabsize);
3172 fprintf(fp, "at_target( integer ");
3173 mTargetNumber->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
3174 fprintf(fp, ", vector ");
3175 mTargetPosition->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
3176 fprintf(fp, ", vector ");
3177 mOurPosition->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
3178 fprintf(fp, " )\n");
3179 break;
3180 case LSCP_SCOPE_PASS1:
3181 if (scope->checkEntry(mTargetNumber->mName))
3182 {
3183 gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
3184 }
3185 else
3186 {
3187 mTargetNumber->mScopeEntry = scope->addEntry(mTargetNumber->mName, LIT_VARIABLE, LST_INTEGER);
3188 }
3189 if (scope->checkEntry(mTargetPosition->mName))
3190 {
3191 gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
3192 }
3193 else
3194 {
3195 mTargetPosition->mScopeEntry = scope->addEntry(mTargetPosition->mName, LIT_VARIABLE, LST_VECTOR);
3196 }
3197 if (scope->checkEntry(mOurPosition->mName))
3198 {
3199 gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
3200 }
3201 else
3202 {
3203 mOurPosition->mScopeEntry = scope->addEntry(mOurPosition->mName, LIT_VARIABLE, LST_VECTOR);
3204 }
3205 break;
3206 case LSCP_RESOURCE:
3207 {
3208 // we're just tryng to determine how much space the variable needs
3209 if (mTargetNumber->mScopeEntry)
3210 {
3211 mTargetNumber->mScopeEntry->mOffset = (S32)count;
3212 mTargetNumber->mScopeEntry->mSize = 4;
3213 count += mTargetNumber->mScopeEntry->mSize;
3214 mTargetPosition->mScopeEntry->mOffset = (S32)count;
3215 mTargetPosition->mScopeEntry->mSize = 12;
3216 count += mTargetPosition->mScopeEntry->mSize;
3217 mOurPosition->mScopeEntry->mOffset = (S32)count;
3218 mOurPosition->mScopeEntry->mSize = 12;
3219 count += mOurPosition->mScopeEntry->mSize;
3220 }
3221 }
3222 break;
3223 case LSCP_EMIT_BYTE_CODE:
3224 {
3225#ifdef LSL_INCLUDE_DEBUG_INFO
3226 char name[] = "at_target";
3227 chunk->addBytes(name, strlen(name) + 1);
3228 chunk->addBytes(mTargetNumber->mName, strlen(mTargetNumber->mName) + 1);
3229 chunk->addBytes(mTargetPosition->mName, strlen(mTargetPosition->mName) + 1);
3230 chunk->addBytes(mOurPosition->mName, strlen(mOurPosition->mName) + 1);
3231#endif
3232 }
3233 break;
3234 default:
3235 mTargetNumber->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
3236 mTargetPosition->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
3237 mOurPosition->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
3238 break;
3239 }
3240}
3241
3242S32 LLScriptAtTarget::getSize()
3243{
3244 // integer + vector + vector = 28
3245 return 28;
3246}
3247
3248
3249
3250void LLScriptNotAtTarget::recurse(FILE *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)
3251{
3252 if (gErrorToText.getErrors())
3253 {
3254 return;
3255 }
3256 switch(pass)
3257 {
3258 case LSCP_PRETTY_PRINT:
3259 fdotabs(fp, tabs, tabsize);
3260 fprintf(fp, "not_at_target()\n");
3261 break;
3262 case LSCP_EMIT_ASSEMBLY:
3263 fprintf(fp, "not_at_target()\n");
3264 break;
3265 case LSCP_EMIT_BYTE_CODE:
3266 {
3267#ifdef LSL_INCLUDE_DEBUG_INFO
3268 char name[] = "not_at_target";
3269 chunk->addBytes(name, strlen(name) + 1);
3270#endif
3271 }
3272 break;
3273 default:
3274 break;
3275 }
3276}
3277
3278S32 LLScriptNotAtTarget::getSize()
3279{
3280 return 0;
3281}
3282
3283void LLScriptAtRotTarget::recurse(FILE *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)
3284{
3285 if (gErrorToText.getErrors())
3286 {
3287 return;
3288 }
3289 switch(pass)
3290 {
3291 case LSCP_PRETTY_PRINT:
3292 case LSCP_EMIT_ASSEMBLY:
3293 fdotabs(fp, tabs, tabsize);
3294 fprintf(fp, "at_target( integer ");
3295 mTargetNumber->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
3296 fprintf(fp, ", quaternion ");
3297 mTargetRotation->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
3298 fprintf(fp, ", quaternion ");
3299 mOurRotation->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
3300 fprintf(fp, " )\n");
3301 break;
3302 case LSCP_SCOPE_PASS1:
3303 if (scope->checkEntry(mTargetNumber->mName))
3304 {
3305 gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
3306 }
3307 else
3308 {
3309 mTargetNumber->mScopeEntry = scope->addEntry(mTargetNumber->mName, LIT_VARIABLE, LST_INTEGER);
3310 }
3311 if (scope->checkEntry(mTargetRotation->mName))
3312 {
3313 gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
3314 }
3315 else
3316 {
3317 mTargetRotation->mScopeEntry = scope->addEntry(mTargetRotation->mName, LIT_VARIABLE, LST_QUATERNION);
3318 }
3319 if (scope->checkEntry(mOurRotation->mName))
3320 {
3321 gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
3322 }
3323 else
3324 {
3325 mOurRotation->mScopeEntry = scope->addEntry(mOurRotation->mName, LIT_VARIABLE, LST_QUATERNION);
3326 }
3327 break;
3328 case LSCP_RESOURCE:
3329 {
3330 // we're just tryng to determine how much space the variable needs
3331 if (mTargetNumber->mScopeEntry)
3332 {
3333 mTargetNumber->mScopeEntry->mOffset = (S32)count;
3334 mTargetNumber->mScopeEntry->mSize = 4;
3335 count += mTargetNumber->mScopeEntry->mSize;
3336 mTargetRotation->mScopeEntry->mOffset = (S32)count;
3337 mTargetRotation->mScopeEntry->mSize = 16;
3338 count += mTargetRotation->mScopeEntry->mSize;
3339 mOurRotation->mScopeEntry->mOffset = (S32)count;
3340 mOurRotation->mScopeEntry->mSize = 16;
3341 count += mOurRotation->mScopeEntry->mSize;
3342 }
3343 }
3344 break;
3345 case LSCP_EMIT_BYTE_CODE:
3346 {
3347#ifdef LSL_INCLUDE_DEBUG_INFO
3348 char name[] = "at_rot_target";
3349 chunk->addBytes(name, strlen(name) + 1);
3350 chunk->addBytes(mTargetNumber->mName, strlen(mTargetNumber->mName) + 1);
3351 chunk->addBytes(mTargetRotation->mName, strlen(mTargetRotation->mName) + 1);
3352 chunk->addBytes(mOurRotation->mName, strlen(mOurRotation->mName) + 1);
3353#endif
3354 }
3355 break;
3356 default:
3357 mTargetNumber->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
3358 mTargetRotation->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
3359 mOurRotation->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
3360 break;
3361 }
3362}
3363
3364S32 LLScriptAtRotTarget::getSize()
3365{
3366 // integer + quaternion + quaternion = 36
3367 return 36;
3368}
3369
3370
3371
3372void LLScriptNotAtRotTarget::recurse(FILE *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)
3373{
3374 if (gErrorToText.getErrors())
3375 {
3376 return;
3377 }
3378 switch(pass)
3379 {
3380 case LSCP_PRETTY_PRINT:
3381 fdotabs(fp, tabs, tabsize);
3382 fprintf(fp, "not_at_rot_target()\n");
3383 break;
3384 case LSCP_EMIT_ASSEMBLY:
3385 fprintf(fp, "not_at_rot_target()\n");
3386 break;
3387 case LSCP_EMIT_BYTE_CODE:
3388 {
3389#ifdef LSL_INCLUDE_DEBUG_INFO
3390 char name[] = "not_at_rot_target";
3391 chunk->addBytes(name, strlen(name) + 1);
3392#endif
3393 }
3394 break;
3395 default:
3396 break;
3397 }
3398}
3399
3400S32 LLScriptNotAtRotTarget::getSize()
3401{
3402 return 0;
3403}
3404
3405
3406
3407void LLScriptExpression::addExpression(LLScriptExpression *expression)
3408{
3409 if (mNextp)
3410 {
3411 expression->mNextp = mNextp;
3412 }
3413 mNextp = expression;
3414}
3415
3416void LLScriptExpression::recurse(FILE *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)
3417{
3418 fprintf(fp, "Expression Base Class -- should never get here!\n");
3419}
3420
3421S32 LLScriptExpression::getSize()
3422{
3423 printf("Expression Base Class -- should never get here!\n");
3424 return 0;
3425}
3426
3427void LLScriptExpression::gonext(FILE *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)
3428{
3429 if (gErrorToText.getErrors())
3430 {
3431 return;
3432 }
3433 switch(pass)
3434 {
3435 case LSCP_PRETTY_PRINT:
3436 if (mNextp)
3437 {
3438 fprintf(fp, ", ");
3439 mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
3440 }
3441 break;
3442 default:
3443 if (mNextp)
3444 {
3445 mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
3446 }
3447 break;
3448 }
3449}
3450
3451void LLScriptForExpressionList::recurse(FILE *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)
3452{
3453 if (gErrorToText.getErrors())
3454 {
3455 return;
3456 }
3457 switch(pass)
3458 {
3459 case LSCP_PRETTY_PRINT:
3460 mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
3461 if (mSecondp)
3462 {
3463 fprintf(fp, ", ");
3464 mSecondp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
3465 }
3466 break;
3467 case LSCP_EMIT_ASSEMBLY:
3468 mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
3469 if (mFirstp->mReturnType)
3470 {
3471 fprintf(fp, "%s\n", LSCRIPTTypePop[mFirstp->mReturnType]);
3472 }
3473 if (mSecondp)
3474 {
3475 mSecondp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
3476 if (mSecondp->mReturnType)
3477 {
3478 fprintf(fp, "%s\n", LSCRIPTTypePop[mSecondp->mReturnType]);
3479 }
3480 }
3481 break;
3482 case LSCP_TO_STACK:
3483 mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
3484 switch(mFirstp->mReturnType)
3485 {
3486 case LST_INTEGER:
3487 case LST_FLOATINGPOINT:
3488 chunk->addByte(LSCRIPTOpCodes[LOPC_POP]);
3489 break;
3490 case LST_STRING:
3491 case LST_KEY:
3492 chunk->addByte(LSCRIPTOpCodes[LOPC_POPS]);
3493 break;
3494 case LST_LIST:
3495 chunk->addByte(LSCRIPTOpCodes[LOPC_POPL]);
3496 break;
3497 case LST_VECTOR:
3498 chunk->addByte(LSCRIPTOpCodes[LOPC_POPV]);
3499 break;
3500 case LST_QUATERNION:
3501 chunk->addByte(LSCRIPTOpCodes[LOPC_POPQ]);
3502 break;
3503 default:
3504 break;
3505 }
3506 if (mSecondp)
3507 {
3508 mSecondp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
3509 switch(mSecondp->mReturnType)
3510 {
3511 case LST_INTEGER:
3512 case LST_FLOATINGPOINT:
3513 chunk->addByte(LSCRIPTOpCodes[LOPC_POP]);
3514 break;
3515 case LST_STRING:
3516 case LST_KEY:
3517 chunk->addByte(LSCRIPTOpCodes[LOPC_POPS]);
3518 break;
3519 case LST_LIST:
3520 chunk->addByte(LSCRIPTOpCodes[LOPC_POPL]);
3521 break;
3522 case LST_VECTOR:
3523 chunk->addByte(LSCRIPTOpCodes[LOPC_POPV]);
3524 break;
3525 case LST_QUATERNION:
3526 chunk->addByte(LSCRIPTOpCodes[LOPC_POPQ]);
3527 break;
3528 default:
3529 break;
3530 }
3531 }
3532 break;
3533 case LSCP_EMIT_CIL_ASSEMBLY:
3534 mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
3535 if (mFirstp->mReturnType)
3536 {
3537 fprintf(fp, "pop\n");
3538 }
3539 if (mSecondp)
3540 {
3541 mSecondp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
3542 if (mSecondp->mReturnType)
3543 {
3544 fprintf(fp, "pop\n");
3545 }
3546 }
3547 break;
3548 default:
3549 mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
3550 if (mSecondp)
3551 {
3552 mSecondp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
3553 }
3554 break;
3555 }
3556}
3557
3558S32 LLScriptForExpressionList::getSize()
3559{
3560 return 0;
3561}
3562
3563void LLScriptFuncExpressionList::recurse(FILE *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)
3564{
3565 if (gErrorToText.getErrors())
3566 {
3567 return;
3568 }
3569 switch(pass)
3570 {
3571 case LSCP_PRETTY_PRINT:
3572 mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
3573 if (mSecondp)
3574 {
3575 fprintf(fp, ", ");
3576 mSecondp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
3577 }
3578 break;
3579 case LSCP_TYPE:
3580 {
3581 mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
3582 if (!entry->mFunctionArgs.getType(entrycount))
3583 {
3584 gErrorToText.writeError(fp, this, LSERROR_FUNCTION_TYPE_ERROR);
3585 }
3586 if (!legal_assignment(entry->mFunctionArgs.getType(entrycount), mFirstp->mReturnType))
3587 {
3588 gErrorToText.writeError(fp, this, LSERROR_FUNCTION_TYPE_ERROR);
3589 }
3590 count++;
3591 entrycount++;
3592 if (mSecondp)
3593 {
3594 mSecondp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
3595 if (mSecondp->mReturnType)
3596 {
3597 count++;
3598 if (!entry->mFunctionArgs.getType(entrycount))
3599 {
3600 gErrorToText.writeError(fp, this, LSERROR_FUNCTION_TYPE_ERROR);
3601 }
3602 if (!legal_assignment(entry->mFunctionArgs.getType(entrycount), mSecondp->mReturnType))
3603 {
3604 gErrorToText.writeError(fp, this, LSERROR_FUNCTION_TYPE_ERROR);
3605 }
3606 }
3607 }
3608 }
3609 break;
3610 case LSCP_EMIT_ASSEMBLY:
3611 {
3612 mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
3613 LSCRIPTType argtype = entry->mFunctionArgs.getType(entrycount);
3614 if (argtype != mFirstp->mReturnType)
3615 {
3616 fprintf(fp, "CAST %s->%s\n", LSCRIPTTypeNames[mFirstp->mReturnType], LSCRIPTTypeNames[argtype]);
3617 }
3618 entrycount++;
3619 if (mSecondp)
3620 {
3621 mSecondp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
3622 if (mSecondp->mReturnType)
3623 {
3624 argtype = entry->mFunctionArgs.getType(entrycount);
3625 if (argtype != mSecondp->mReturnType)
3626 {
3627 fprintf(fp, "CAST %s->%s\n", LSCRIPTTypeNames[mSecondp->mReturnType], LSCRIPTTypeNames[argtype]);
3628 }
3629 }
3630 }
3631 }
3632 break;
3633 case LSCP_TO_STACK:
3634 {
3635 mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
3636 LSCRIPTType argtype = entry->mFunctionArgs.getType(entrycount);
3637 if (argtype != mFirstp->mReturnType)
3638 {
3639 chunk->addByte(LSCRIPTOpCodes[LOPC_CAST]);
3640 U8 castbyte = LSCRIPTTypeByte[argtype] | LSCRIPTTypeHi4Bits[mFirstp->mReturnType];
3641 chunk->addByte(castbyte);
3642 }
3643 entrycount++;
3644 if (mSecondp)
3645 {
3646 mSecondp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
3647 if (mSecondp->mReturnType)
3648 {
3649 argtype = entry->mFunctionArgs.getType(entrycount);
3650 if (argtype != mSecondp->mReturnType)
3651 {
3652 chunk->addByte(LSCRIPTOpCodes[LOPC_CAST]);
3653 U8 castbyte = LSCRIPTTypeByte[argtype] | LSCRIPTTypeHi4Bits[mSecondp->mReturnType];
3654 chunk->addByte(castbyte);
3655 }
3656 }
3657 }
3658 }
3659 break;
3660 /* TODO: Fix conflict between global/local variable determination needing caller scope and cast determination here needs callee scope...
3661 case LSCP_EMIT_CIL_ASSEMBLY:
3662 {
3663 mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
3664 LSCRIPTType argtype = entry->mFunctionArgs.getType(entrycount);
3665 if (argtype != mFirstp->mReturnType)
3666 {
3667 print_cil_cast(fp, mFirstp->mReturnType, argtype);
3668 }
3669 entrycount++;
3670 if (mSecondp)
3671 {
3672 mSecondp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
3673 if (mSecondp->mReturnType)
3674 {
3675 argtype = entry->mFunctionArgs.getType(entrycount);
3676 if (argtype != mSecondp->mReturnType)
3677 {
3678 print_cil_cast(fp, mFirstp->mReturnType, argtype);
3679 }
3680 }
3681 }
3682 }
3683 break;
3684 */
3685 default:
3686 mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
3687 if (mSecondp)
3688 {
3689 mSecondp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
3690 }
3691 break;
3692 }
3693}
3694
3695S32 LLScriptFuncExpressionList::getSize()
3696{
3697 return 0;
3698}
3699
3700void LLScriptListExpressionList::recurse(FILE *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)
3701{
3702 if (gErrorToText.getErrors())
3703 {
3704 return;
3705 }
3706 switch(pass)
3707 {
3708 case LSCP_PRETTY_PRINT:
3709 mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
3710 if (mSecondp)
3711 {
3712 fprintf(fp, ", ");
3713 mSecondp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
3714 }
3715 break;
3716 case LSCP_EMIT_ASSEMBLY:
3717 mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
3718 if (mFirstp->mType != LET_LIST_EXPRESSION_LIST)
3719 {
3720 fprintf(fp, "%s\n", LSCRIPTListDescription[mFirstp->mReturnType]);
3721 count++;
3722 }
3723 if (mSecondp)
3724 {
3725 mSecondp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
3726 if (mSecondp->mType != LET_LIST_EXPRESSION_LIST)
3727 {
3728 fprintf(fp, "%s\n", LSCRIPTListDescription[mSecondp->mReturnType]);
3729 count++;
3730 }
3731 }
3732 break;
3733 case LSCP_TO_STACK:
3734 mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
3735 if (mFirstp->mType != LET_LIST_EXPRESSION_LIST)
3736 {
3737 chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGB]);
3738 chunk->addByte(LSCRIPTTypeByte[mFirstp->mReturnType]);
3739 count++;
3740 }
3741 if (mSecondp)
3742 {
3743 mSecondp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
3744 if (mSecondp->mType != LET_LIST_EXPRESSION_LIST)
3745 {
3746 chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGB]);
3747 chunk->addByte(LSCRIPTTypeByte[mSecondp->mReturnType]);
3748 count++;
3749 }
3750 }
3751 break;
3752 case LSCP_EMIT_CIL_ASSEMBLY:
3753 // Evaluate expressions in reverse order so first expression is on top of stack.
3754 // Results can then be popped and appended to list to result in list with correct order.
3755 if (mSecondp)
3756 {
3757 mSecondp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
3758 if (mSecondp->mType != LET_LIST_EXPRESSION_LIST)
3759 {
3760 // Box value.
3761 print_cil_box(fp, mSecondp->mReturnType);
3762
3763 ++count;
3764 }
3765 }
3766 mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
3767 if (mFirstp->mType != LET_LIST_EXPRESSION_LIST)
3768 {
3769 // Box value.
3770 print_cil_box(fp, mFirstp->mReturnType);
3771
3772 ++count;
3773 }
3774 break;
3775 default:
3776 mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
3777 if (mSecondp)
3778 {
3779 mSecondp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
3780 }
3781 break;
3782 }
3783}
3784
3785S32 LLScriptListExpressionList::getSize()
3786{
3787 return 0;
3788}
3789
3790// Returns true if identifier is a parameter and false if identifier is a local variable within function_scope.
3791bool is_parameter(LLScriptIdentifier* identifier, LLScriptScopeEntry* function_scope)
3792{
3793 // Function offset stores offset of first local.
3794 // Compare variable offset with function offset to
3795 // determine whether variable is local or parameter.
3796 return (identifier->mScopeEntry->mOffset < function_scope->mOffset);
3797}
3798
3799// If assignment is to global variable, pushes this pointer on to stack.
3800void print_cil_load_address(FILE* fp, LLScriptExpression* exp, LLScriptScopeEntry* function_scope)
3801{
3802 LLScriptLValue *lvalue = (LLScriptLValue *) exp;
3803 LLScriptIdentifier *ident = lvalue->mIdentifier;
3804
3805 // If global (member), load this pointer.
3806 if(ident->mScopeEntry->mIDType == LIT_GLOBAL)
3807 {
3808 fprintf(fp, "ldarg.0\n");
3809 }
3810
3811 // If accessor, load address of object.
3812 if(lvalue->mAccessor)
3813 {
3814 if(ident->mScopeEntry->mIDType == LIT_VARIABLE)
3815 {
3816 if(is_parameter(ident, function_scope))
3817 {
3818 // Parameter, load by name.
3819 fprintf(fp, "ldarga.s %s\n", ident->mScopeEntry->mIdentifier);
3820 }
3821 else
3822 {
3823 // Local, load by index.
3824 fprintf(fp, "ldloca.s %d\n", ident->mScopeEntry->mCount);
3825 }
3826 }
3827 else if (ident->mScopeEntry->mIDType == LIT_GLOBAL)
3828 {
3829 fprintf(fp, "ldflda ");
3830 print_cil_type(fp, ident->mScopeEntry->mType);
3831 fprintf(fp, " LSL::%s\n", ident->mScopeEntry->mIdentifier);
3832 }
3833 }
3834}
3835
3836void print_cil_accessor(FILE* fp, LLScriptLValue *lvalue)
3837{
3838 LLScriptIdentifier *ident = lvalue->mIdentifier;
3839 print_cil_type(fp, lvalue->mReturnType);
3840 fprintf(fp, " ");
3841 print_cil_type(fp, ident->mScopeEntry->mType);
3842 fprintf(fp, "::%s\n", lvalue->mAccessor->mName);
3843}
3844
3845void print_cil_member(FILE* fp, LLScriptIdentifier *ident)
3846{
3847 print_cil_type(fp, ident->mScopeEntry->mType);
3848 fprintf(fp, " LSL::%s\n", ident->mScopeEntry->mIdentifier);
3849}
3850
3851void LLScriptLValue::recurse(FILE *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)
3852{
3853 if (gErrorToText.getErrors())
3854 {
3855 return;
3856 }
3857 switch(pass)
3858 {
3859 case LSCP_PRETTY_PRINT:
3860 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
3861 if (mAccessor)
3862 {
3863 fprintf(fp, ".");
3864 mAccessor->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
3865 }
3866 break;
3867 case LSCP_EMIT_ASSEMBLY:
3868 if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
3869 {
3870 if (mAccessor)
3871 {
3872 fprintf(fp, "%s%d [%s.%s]\n", LSCRIPTTypeLocalPush[mReturnType], mIdentifier->mScopeEntry->mOffset + mOffset, mIdentifier->mName, mAccessor->mName);
3873 }
3874 else
3875 {
3876 fprintf(fp, "%s%d [%s]\n", LSCRIPTTypeLocalPush[mIdentifier->mScopeEntry->mType], mIdentifier->mScopeEntry->mOffset, mIdentifier->mName);
3877 }
3878 }
3879 else if (mIdentifier->mScopeEntry->mIDType == LIT_GLOBAL)
3880 {
3881 if (mAccessor)
3882 {
3883 fprintf(fp, "%s%d [%s.%s]\n", LSCRIPTTypeGlobalPush[mReturnType], mIdentifier->mScopeEntry->mOffset + mOffset, mIdentifier->mName, mAccessor->mName);
3884 }
3885 else
3886 {
3887 fprintf(fp, "%s%d [%s]\n", LSCRIPTTypeGlobalPush[mIdentifier->mScopeEntry->mType], mIdentifier->mScopeEntry->mOffset, mIdentifier->mName);
3888 }
3889 }
3890 else
3891 {
3892 fprintf(fp, "Unexpected LValue!\n");
3893 }
3894 break;
3895 case LSCP_SCOPE_PASS1:
3896 {
3897 LLScriptScopeEntry *entry = scope->findEntry(mIdentifier->mName);
3898 if (!entry || ( (entry->mIDType != LIT_GLOBAL) && (entry->mIDType != LIT_VARIABLE)))
3899 {
3900 gErrorToText.writeError(fp, this, LSERROR_UNDEFINED_NAME);
3901 }
3902 else
3903 {
3904 // if we did find it, make sure this identifier is associated with the correct scope entry
3905 mIdentifier->mScopeEntry = entry;
3906 }
3907 }
3908 break;
3909 case LSCP_TYPE:
3910 // if we have an accessor, we need to change what type our identifier returns and set our offset value
3911 if (mIdentifier->mScopeEntry)
3912 {
3913 if (mAccessor)
3914 {
3915 BOOL b_ok = FALSE;
3916 if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
3917 {
3918 if (mIdentifier->mScopeEntry->mType == LST_VECTOR)
3919 {
3920 if (!strcmp("x", mAccessor->mName))
3921 {
3922 mOffset = 0;
3923 b_ok = TRUE;
3924 }
3925 else if (!strcmp("y", mAccessor->mName))
3926 {
3927 mOffset = 4;
3928 b_ok = TRUE;
3929 }
3930 else if (!strcmp("z", mAccessor->mName))
3931 {
3932 mOffset = 8;
3933 b_ok = TRUE;
3934 }
3935 }
3936 else if (mIdentifier->mScopeEntry->mType == LST_QUATERNION)
3937 {
3938 if (!strcmp("x", mAccessor->mName))
3939 {
3940 mOffset = 0;
3941 b_ok = TRUE;
3942 }
3943 else if (!strcmp("y", mAccessor->mName))
3944 {
3945 mOffset = 4;
3946 b_ok = TRUE;
3947 }
3948 else if (!strcmp("z", mAccessor->mName))
3949 {
3950 mOffset = 8;
3951 b_ok = TRUE;
3952 }
3953 else if (!strcmp("s", mAccessor->mName))
3954 {
3955 mOffset = 12;
3956 b_ok = TRUE;
3957 }
3958 }
3959 }
3960 else
3961 {
3962 if (mIdentifier->mScopeEntry->mType == LST_VECTOR)
3963 {
3964 if (!strcmp("x", mAccessor->mName))
3965 {
3966 mOffset = 8;
3967 b_ok = TRUE;
3968 }
3969 else if (!strcmp("y", mAccessor->mName))
3970 {
3971 mOffset = 4;
3972 b_ok = TRUE;
3973 }
3974 else if (!strcmp("z", mAccessor->mName))
3975 {
3976 mOffset = 0;
3977 b_ok = TRUE;
3978 }
3979 }
3980 else if (mIdentifier->mScopeEntry->mType == LST_QUATERNION)
3981 {
3982 if (!strcmp("x", mAccessor->mName))
3983 {
3984 mOffset = 12;
3985 b_ok = TRUE;
3986 }
3987 else if (!strcmp("y", mAccessor->mName))
3988 {
3989 mOffset = 8;
3990 b_ok = TRUE;
3991 }
3992 else if (!strcmp("z", mAccessor->mName))
3993 {
3994 mOffset = 4;
3995 b_ok = TRUE;
3996 }
3997 else if (!strcmp("s", mAccessor->mName))
3998 {
3999 mOffset = 0;
4000 b_ok = TRUE;
4001 }
4002 }
4003 }
4004 if (b_ok)
4005 {
4006 mReturnType = type = LST_FLOATINGPOINT;
4007 }
4008 else
4009 {
4010 gErrorToText.writeError(fp, this, LSERROR_VECTOR_METHOD_ERROR);
4011 }
4012 }
4013 else
4014 {
4015 mReturnType = type = mIdentifier->mScopeEntry->mType;
4016 }
4017 }
4018 else
4019 {
4020 mReturnType = type = LST_UNDEFINED;
4021 }
4022 break;
4023 case LSCP_TO_STACK:
4024 {
4025 switch(mReturnType)
4026 {
4027 case LST_INTEGER:
4028 case LST_FLOATINGPOINT:
4029 if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
4030 {
4031 chunk->addByte(LSCRIPTOpCodes[LOPC_PUSH]);
4032 }
4033 else
4034 {
4035 chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHG]);
4036 }
4037 break;
4038 case LST_KEY:
4039 case LST_STRING:
4040 if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
4041 {
4042 chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHS]);
4043 }
4044 else
4045 {
4046 chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHGS]);
4047 }
4048 break;
4049 case LST_LIST:
4050 if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
4051 {
4052 chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHL]);
4053 }
4054 else
4055 {
4056 chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHGL]);
4057 }
4058 break;
4059 case LST_VECTOR:
4060 if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
4061 {
4062 chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHV]);
4063 }
4064 else
4065 {
4066 chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHGV]);
4067 }
4068 break;
4069 case LST_QUATERNION:
4070 if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
4071 {
4072 chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHQ]);
4073 }
4074 else
4075 {
4076 chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHGQ]);
4077 }
4078 break;
4079 default:
4080 if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
4081 {
4082 chunk->addByte(LSCRIPTOpCodes[LOPC_PUSH]);
4083 }
4084 else
4085 {
4086 chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHG]);
4087 }
4088 break;
4089 }
4090 S32 address = mIdentifier->mScopeEntry->mOffset + mOffset;
4091 chunk->addInteger(address);
4092 }
4093 break;
4094 case LSCP_EMIT_CIL_ASSEMBLY:
4095 print_cil_load_address(fp, this, entry);
4096 if(mAccessor)
4097 {
4098 fprintf(fp, "ldfld ");
4099 print_cil_accessor(fp, this);
4100 }
4101 else if(mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
4102 {
4103 if(is_parameter(mIdentifier, entry))
4104 {
4105 // Parameter, load by name.
4106 fprintf(fp, "ldarg.s %s\n", mIdentifier->mScopeEntry->mIdentifier);
4107 }
4108 else
4109 {
4110 // Local, load by index.
4111 fprintf(fp, "ldloc.s %d\n", mIdentifier->mScopeEntry->mCount);
4112 }
4113 }
4114 else if (mIdentifier->mScopeEntry->mIDType == LIT_GLOBAL)
4115 {
4116 fprintf(fp, "ldfld ");
4117 print_cil_member(fp, mIdentifier);
4118 }
4119 else
4120 {
4121 fprintf(fp, "Unexpected LValue!\n");
4122 }
4123 break;
4124 default:
4125 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4126 break;
4127 }
4128 gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4129}
4130
4131S32 LLScriptLValue::getSize()
4132{
4133 return 0;
4134}
4135
4136void print_asignment(FILE *fp, LLScriptExpression *exp)
4137{
4138 LLScriptLValue *lvalue = (LLScriptLValue *)exp;
4139 LLScriptIdentifier *ident = lvalue->mIdentifier;
4140 if (lvalue->mAccessor)
4141 {
4142 if (ident->mScopeEntry->mIDType == LIT_VARIABLE)
4143 {
4144 fprintf(fp, "%s%d [%s.%s]\n", LSCRIPTTypeLocalStore[ident->mScopeEntry->mType], ident->mScopeEntry->mOffset + lvalue->mOffset, ident->mName, lvalue->mAccessor->mName);
4145 }
4146 else if (ident->mScopeEntry->mIDType == LIT_GLOBAL)
4147 {
4148 fprintf(fp, "%s%d [%s.%s]\n", LSCRIPTTypeGlobalStore[ident->mScopeEntry->mType], ident->mScopeEntry->mOffset + lvalue->mOffset, ident->mName, lvalue->mAccessor->mName);
4149 }
4150 }
4151 else
4152 {
4153 if (ident->mScopeEntry->mIDType == LIT_VARIABLE)
4154 {
4155 fprintf(fp, "%s%d [%s]\n", LSCRIPTTypeLocalStore[ident->mScopeEntry->mType], ident->mScopeEntry->mOffset, ident->mName);
4156 }
4157 else if (ident->mScopeEntry->mIDType == LIT_GLOBAL)
4158 {
4159 fprintf(fp, "%s%d [%s]\n", LSCRIPTTypeGlobalStore[ident->mScopeEntry->mType], ident->mScopeEntry->mOffset, ident->mName);
4160 }
4161 }
4162}
4163
4164void print_cil_asignment(FILE *fp, LLScriptExpression *exp, LLScriptScopeEntry* function_scope)
4165{
4166 LLScriptLValue *lvalue = (LLScriptLValue *) exp;
4167 LLScriptIdentifier *ident = lvalue->mIdentifier;
4168 if (lvalue->mAccessor)
4169 {
4170 // Object address loaded, store in to field.
4171 fprintf(fp, "stfld ");
4172 print_cil_accessor(fp, lvalue);
4173
4174 // Load object address.
4175 print_cil_load_address(fp, exp, function_scope);
4176
4177 // Load field.
4178 fprintf(fp, "ldfld ");
4179 print_cil_accessor(fp, lvalue);
4180 }
4181 else
4182 {
4183 if (ident->mScopeEntry->mIDType == LIT_VARIABLE)
4184 {
4185 // Language semantics require value of assignment to be left on stack.
4186 // TODO: Optimise away redundant dup/pop pairs.
4187 fprintf(fp, "dup\n");
4188 if(is_parameter(ident, function_scope))
4189 {
4190 // Parameter, store by name.
4191 fprintf(fp, "starg.s %s\n", ident->mScopeEntry->mIdentifier);
4192 }
4193 else
4194 {
4195 // Local, store by index.
4196 fprintf(fp, "stloc.s %d\n", ident->mScopeEntry->mCount);
4197 }
4198 }
4199 else if (ident->mScopeEntry->mIDType == LIT_GLOBAL)
4200 {
4201 // Object address loaded, store in to field.
4202 fprintf(fp, "stfld ");
4203 print_cil_member(fp, ident);
4204
4205 // Load object address.
4206 print_cil_load_address(fp, exp, function_scope);
4207
4208 // Load field.
4209 fprintf(fp, "ldfld ");
4210 print_cil_member(fp, ident);
4211 }
4212 }
4213}
4214
4215void print_cast(FILE *fp, LSCRIPTType ret_type, LSCRIPTType right_type)
4216{
4217 if (right_type != ret_type)
4218 {
4219 fprintf(fp, "CAST %s->%s\n", LSCRIPTTypeNames[right_type], LSCRIPTTypeNames[ret_type]);
4220 }
4221}
4222
4223void cast2stack(LLScriptByteCodeChunk *chunk, LSCRIPTType ret_type, LSCRIPTType right_type)
4224{
4225 if (right_type != ret_type)
4226 {
4227 chunk->addByte(LSCRIPTOpCodes[LOPC_CAST]);
4228 U8 castbyte = LSCRIPTTypeByte[right_type] | LSCRIPTTypeHi4Bits[ret_type];
4229 chunk->addByte(castbyte);
4230 }
4231}
4232
4233void operation2stack(LLScriptByteCodeChunk *chunk, LSCRIPTType ret_type, LSCRIPTType right_type)
4234{
4235 U8 typebyte = LSCRIPTTypeByte[right_type] | LSCRIPTTypeHi4Bits[ret_type];
4236 chunk->addByte(typebyte);
4237}
4238
4239void store2stack(LLScriptExpression *exp, LLScriptExpression *lv, LLScriptByteCodeChunk *chunk, LSCRIPTType right_type)
4240{
4241 LLScriptLValue *lvalue = (LLScriptLValue *)lv;
4242 LLScriptIdentifier *ident = lvalue->mIdentifier;
4243 LSCRIPTType rettype = exp->mReturnType;
4244
4245 if (exp->mRightType != LST_NULL)
4246 {
4247 if (legal_binary_expression(rettype, exp->mLeftType, exp->mRightType, exp->mType))
4248 cast2stack(chunk, right_type, exp->mReturnType);
4249 }
4250 switch(exp->mReturnType)
4251 {
4252 case LST_INTEGER:
4253 case LST_FLOATINGPOINT:
4254 if (ident->mScopeEntry->mIDType == LIT_VARIABLE)
4255 {
4256 chunk->addByte(LSCRIPTOpCodes[LOPC_STORE]);
4257 }
4258 else
4259 {
4260 chunk->addByte(LSCRIPTOpCodes[LOPC_STOREG]);
4261 }
4262 break;
4263 case LST_KEY:
4264 case LST_STRING:
4265 if (ident->mScopeEntry->mIDType == LIT_VARIABLE)
4266 {
4267 chunk->addByte(LSCRIPTOpCodes[LOPC_STORES]);
4268 }
4269 else
4270 {
4271 chunk->addByte(LSCRIPTOpCodes[LOPC_STOREGS]);
4272 }
4273 break;
4274 case LST_LIST:
4275 if (ident->mScopeEntry->mIDType == LIT_VARIABLE)
4276 {
4277 chunk->addByte(LSCRIPTOpCodes[LOPC_STOREL]);
4278 }
4279 else
4280 {
4281 chunk->addByte(LSCRIPTOpCodes[LOPC_STOREGL]);
4282 }
4283 break;
4284 case LST_VECTOR:
4285 if (ident->mScopeEntry->mIDType == LIT_VARIABLE)
4286 {
4287 chunk->addByte(LSCRIPTOpCodes[LOPC_STOREV]);
4288 }
4289 else
4290 {
4291 chunk->addByte(LSCRIPTOpCodes[LOPC_STOREGV]);
4292 }
4293 break;
4294 case LST_QUATERNION:
4295 if (ident->mScopeEntry->mIDType == LIT_VARIABLE)
4296 {
4297 chunk->addByte(LSCRIPTOpCodes[LOPC_STOREQ]);
4298 }
4299 else
4300 {
4301 chunk->addByte(LSCRIPTOpCodes[LOPC_STOREGQ]);
4302 }
4303 break;
4304 default:
4305 if (ident->mScopeEntry->mIDType == LIT_VARIABLE)
4306 {
4307 chunk->addByte(LSCRIPTOpCodes[LOPC_STORE]);
4308 }
4309 else
4310 {
4311 chunk->addByte(LSCRIPTOpCodes[LOPC_STOREG]);
4312 }
4313 break;
4314 }
4315 S32 address = ident->mScopeEntry->mOffset + lvalue->mOffset;
4316 chunk->addInteger(address);
4317}
4318
4319void print_cil_numeric_cast(FILE* fp, LSCRIPTType currentArg, LSCRIPTType otherArg)
4320{
4321 if((currentArg == LST_INTEGER) && (otherArg == LST_FLOATINGPOINT))
4322 {
4323 print_cil_cast(fp, LST_INTEGER, LST_FLOATINGPOINT);
4324 }
4325}
4326
4327void LLScriptAssignment::recurse(FILE *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)
4328{
4329 if (gErrorToText.getErrors())
4330 {
4331 return;
4332 }
4333 switch(pass)
4334 {
4335 case LSCP_PRETTY_PRINT:
4336 mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4337 fprintf(fp, " = ");
4338 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4339 break;
4340 case LSCP_EMIT_ASSEMBLY:
4341 {
4342 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4343 print_cast(fp, mReturnType, mRightType);
4344 print_asignment(fp, mLValue);
4345 }
4346 break;
4347 case LSCP_TYPE:
4348 {
4349 mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4350 mLeftType = type;
4351 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4352 mRightType = type;
4353 if (!legal_assignment(mLeftType, mRightType))
4354 {
4355 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
4356 }
4357 type = mReturnType = mLeftType;
4358 }
4359 break;
4360 case LSCP_TO_STACK:
4361 {
4362 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4363 store2stack(this, mLValue, chunk, mRightType);
4364 }
4365 break;
4366 case LSCP_EMIT_CIL_ASSEMBLY:
4367 {
4368 print_cil_load_address(fp, mLValue, entry);
4369 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4370 print_cil_numeric_cast(fp, mRightType, mReturnType);
4371 print_cil_asignment(fp, mLValue, entry);
4372 }
4373 break;
4374 default:
4375 mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4376 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4377 break;
4378 }
4379 gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4380}
4381
4382S32 LLScriptAssignment::getSize()
4383{
4384 return 0;
4385}
4386
4387void print_cil_add(FILE* fp, LSCRIPTType left_type, LSCRIPTType right_type)
4388{
4389 switch(left_type)
4390 {
4391 case LST_INTEGER:
4392 case LST_FLOATINGPOINT:
4393
4394 // Numeric addition.
4395 fprintf(fp, "add\n");
4396 break;
4397
4398 case LST_STRING:
4399 case LST_KEY:
4400
4401 // String concatenation.
4402 fprintf(fp, "call string valuetype [mscorlib]System.String::Concat(string, string)");
4403 break;
4404
4405 case LST_VECTOR:
4406
4407 // Vector addition.
4408 // TODO: Inline (requires temporary variables, which must be identified in earlier pass).
4409 fprintf(fp, "call valuetype [LScriptLibrary]LLVector valuetype [LScriptLibrary]LLVector::'add_vec'(valuetype [LScriptLibrary]LLVector, valuetype [LScriptLibrary]LLVector)\n");
4410 break;
4411
4412 case LST_QUATERNION:
4413
4414 // Rotation addition.
4415 // TODO: Inline (requires temporary variables, which must be identified in earlier pass).
4416 fprintf(fp, "call valuetype [LScriptLibrary]LLQuaternion valuetype [LScriptLibrary]LLQuaternion::'add_quat'(valuetype [LScriptLibrary]LLQuaternion, valuetype [LScriptLibrary]LLQuaternion)\n");
4417 break;
4418
4419 case LST_LIST:
4420 print_cil_box(fp, right_type);
4421 fprintf(fp, "call class [mscorlib]System.Collections.ArrayList class [LScriptLibrary]LScriptInternal::AddReturnList(class [mscorlib]System.Collections.ArrayList, object)\n");
4422 break;
4423
4424 default:
4425 break;
4426 }
4427}
4428
4429void LLScriptAddAssignment::recurse(FILE *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)
4430{
4431 if (gErrorToText.getErrors())
4432 {
4433 return;
4434 }
4435 switch(pass)
4436 {
4437 case LSCP_PRETTY_PRINT:
4438 mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4439 fprintf(fp, " += ");
4440 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4441 break;
4442 case LSCP_EMIT_ASSEMBLY:
4443 {
4444 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4445 mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4446 fprintf(fp, "ADD %s, %s\n", LSCRIPTTypeNames[mRightType], LSCRIPTTypeNames[mLeftType]);
4447 print_asignment(fp, mLValue);
4448 }
4449 break;
4450 case LSCP_TYPE:
4451 {
4452 mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4453 mLeftType = type;
4454 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4455 mRightType = type;
4456 if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
4457 {
4458 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
4459 }
4460 type = mReturnType;
4461 }
4462 break;
4463 case LSCP_TO_STACK:
4464 {
4465 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4466 mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4467 chunk->addByte(LSCRIPTOpCodes[LOPC_ADD]);
4468 operation2stack(chunk, mReturnType, mRightType);
4469 store2stack(this, mLValue, chunk, mReturnType);
4470 }
4471 break;
4472 case LSCP_EMIT_CIL_ASSEMBLY:
4473 {
4474 print_cil_load_address(fp, mLValue, entry);
4475 mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4476 print_cil_numeric_cast(fp, mLValue->mReturnType, mRightSide->mReturnType);
4477 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4478 print_cil_numeric_cast(fp, mRightSide->mReturnType, mLValue->mReturnType);
4479 print_cil_add(fp, mLValue->mReturnType, mRightSide->mReturnType);
4480 print_cil_asignment(fp, mLValue, entry);
4481 }
4482 break;
4483 default:
4484 mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4485 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4486 break;
4487 }
4488 gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4489}
4490
4491S32 LLScriptAddAssignment::getSize()
4492{
4493 return 0;
4494}
4495
4496void print_cil_sub(FILE* fp, LSCRIPTType left_type, LSCRIPTType right_type)
4497{
4498 switch(left_type)
4499 {
4500 case LST_INTEGER:
4501 case LST_FLOATINGPOINT:
4502
4503 // Numeric subtraction.
4504 fprintf(fp, "sub\n");
4505 break;
4506
4507 case LST_VECTOR:
4508
4509 // Vector subtraction.
4510 // TODO: Inline (requires temporary variables, which must be identified in earlier pass).
4511 fprintf(fp, "call valuetype [LScriptLibrary]LLVector valuetype [LScriptLibrary]LLVector::'subtract_vec'(valuetype [LScriptLibrary]LLVector, valuetype [LScriptLibrary]LLVector)\n");
4512 break;
4513
4514 case LST_QUATERNION:
4515
4516 // Rotation subtraction.
4517 // TODO: Inline (requires temporary variables, which must be identified in earlier pass).
4518 fprintf(fp, "call valuetype [LScriptLibrary]LLQuaternion valuetype [LScriptLibrary]LLQuaternion::'subtract_quat'(valuetype [LScriptLibrary]LLQuaternion, valuetype [LScriptLibrary]LLQuaternion)\n");
4519 break;
4520
4521 default:
4522
4523 // Error.
4524 break;
4525 }
4526}
4527
4528void LLScriptSubAssignment::recurse(FILE *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)
4529{
4530 if (gErrorToText.getErrors())
4531 {
4532 return;
4533 }
4534 switch(pass)
4535 {
4536 case LSCP_PRETTY_PRINT:
4537 mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4538 fprintf(fp, " -= ");
4539 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4540 break;
4541 case LSCP_EMIT_ASSEMBLY:
4542 {
4543 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4544 mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4545 fprintf(fp, "SUB %s, %s\n", LSCRIPTTypeNames[mRightType], LSCRIPTTypeNames[mLeftType]);
4546 print_asignment(fp, mLValue);
4547 }
4548 break;
4549 case LSCP_TYPE:
4550 {
4551 mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4552 mLeftType = type;
4553 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4554 mRightType = type;
4555 if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
4556 {
4557 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
4558 }
4559 type = mReturnType;
4560 }
4561 break;
4562 case LSCP_TO_STACK:
4563 {
4564 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4565 mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4566 chunk->addByte(LSCRIPTOpCodes[LOPC_SUB]);
4567 operation2stack(chunk, mReturnType, mRightType);
4568 store2stack(this, mLValue, chunk, mReturnType);
4569 }
4570 break;
4571 case LSCP_EMIT_CIL_ASSEMBLY:
4572 {
4573 print_cil_load_address(fp, mLValue, entry);
4574 mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4575 print_cil_numeric_cast(fp, mLValue->mReturnType, mRightSide->mReturnType);
4576 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4577 print_cil_numeric_cast(fp, mRightSide->mReturnType, mLValue->mReturnType);
4578 print_cil_sub(fp, mLValue->mReturnType, mRightSide->mReturnType);
4579 print_cil_asignment(fp, mLValue, entry);
4580 }
4581 break;
4582 default:
4583 mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4584 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4585 break;
4586 }
4587 gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4588}
4589
4590S32 LLScriptSubAssignment::getSize()
4591{
4592 return 0;
4593}
4594
4595void print_cil_mul(FILE* fp, LSCRIPTType left_type, LSCRIPTType right_type)
4596{
4597 switch(left_type)
4598 {
4599 case LST_INTEGER:
4600 case LST_FLOATINGPOINT:
4601
4602 // Numeric multiplication.
4603 fprintf(fp, "mul\n");
4604 break;
4605
4606 case LST_VECTOR:
4607
4608 switch(right_type)
4609 {
4610 case LST_INTEGER:
4611
4612 print_cil_cast(fp, LST_INTEGER, LST_FLOATINGPOINT);
4613
4614 case LST_FLOATINGPOINT:
4615
4616 // Vector scaling.
4617 fprintf(fp, "call valuetype [LScriptLibrary]LLVector valuetype [LScriptLibrary]LLVector::'multiply_float'(valuetype [LScriptLibrary]LLVector, float32)\n");
4618 break;
4619
4620 case LST_VECTOR:
4621
4622 // Dot product.
4623 fprintf(fp, "call float32 valuetype [LScriptLibrary]LLVector::'multiply_vec'(valuetype [LScriptLibrary]LLVector, valuetype [LScriptLibrary]LLVector)\n");
4624 break;
4625
4626 case LST_QUATERNION:
4627
4628 // Vector rotation.
4629 fprintf(fp, "call valuetype [LScriptLibrary]LLVector valuetype [LScriptLibrary]LLVector::'multiply_quat'(valuetype [LScriptLibrary]LLVector, valuetype [LScriptLibrary]LLQuaternion)\n");
4630 break;
4631
4632 default:
4633 break;
4634 }
4635 break;
4636
4637 case LST_QUATERNION:
4638
4639 // Rotation multiplication.
4640 fprintf(fp, "call valuetype [LScriptLibrary]LLQuaternion valuetype [LScriptLibrary]LLQuaternion::'multiply_quat'(valuetype [LScriptLibrary]LLQuaternion, valuetype [LScriptLibrary]LLQuaternion)\n");
4641 break;
4642
4643 default:
4644
4645 // Error.
4646 break;
4647 }
4648}
4649
4650void LLScriptMulAssignment::recurse(FILE *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)
4651{
4652 if (gErrorToText.getErrors())
4653 {
4654 return;
4655 }
4656 switch(pass)
4657 {
4658 case LSCP_PRETTY_PRINT:
4659 mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4660 fprintf(fp, " *= ");
4661 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4662 break;
4663 case LSCP_EMIT_ASSEMBLY:
4664 {
4665 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4666 mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4667 fprintf(fp, "MUL %s, %s\n", LSCRIPTTypeNames[mRightType], LSCRIPTTypeNames[mLeftType]);
4668 print_asignment(fp, mLValue);
4669 }
4670 break;
4671 case LSCP_TYPE:
4672 {
4673 mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4674 mLeftType = type;
4675 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4676 mRightType = type;
4677 if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
4678 {
4679 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
4680 }
4681 type = mReturnType;
4682 }
4683 break;
4684 case LSCP_TO_STACK:
4685 {
4686 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4687 mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4688 chunk->addByte(LSCRIPTOpCodes[LOPC_MUL]);
4689 operation2stack(chunk, mReturnType, mRightType);
4690 store2stack(this, mLValue, chunk, mReturnType);
4691 }
4692 break;
4693 case LSCP_EMIT_CIL_ASSEMBLY:
4694 {
4695 print_cil_load_address(fp, mLValue, entry);
4696 mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4697 print_cil_numeric_cast(fp, mLValue->mReturnType, mRightSide->mReturnType);
4698 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4699 print_cil_numeric_cast(fp, mRightSide->mReturnType, mLValue->mReturnType);
4700 print_cil_mul(fp, mLValue->mReturnType, mRightSide->mReturnType);
4701 print_cil_asignment(fp, mLValue, entry);
4702 }
4703 break;
4704 default:
4705 mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4706 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4707 break;
4708 }
4709 gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4710}
4711
4712S32 LLScriptMulAssignment::getSize()
4713{
4714 return 0;
4715}
4716
4717void print_cil_div(FILE* fp, LSCRIPTType left_type, LSCRIPTType right_type)
4718{
4719 switch(left_type)
4720 {
4721 case LST_INTEGER:
4722 case LST_FLOATINGPOINT:
4723
4724 // Numeric addition.
4725 fprintf(fp, "div\n");
4726 break;
4727
4728 case LST_VECTOR:
4729
4730 switch(right_type)
4731 {
4732 case LST_INTEGER:
4733
4734 print_cil_cast(fp, LST_INTEGER, LST_FLOATINGPOINT);
4735
4736 case LST_FLOATINGPOINT:
4737
4738 // Scale.
4739 fprintf(fp, "call valuetype [LScriptLibrary]LLVector valuetype [LScriptLibrary]LLVector::'divide_float'(valuetype [LScriptLibrary]LLVector, float32)\n");
4740 break;
4741
4742 case LST_QUATERNION:
4743
4744 // Inverse rotation.
4745 fprintf(fp, "call valuetype [LScriptLibrary]LLVector valuetype [LScriptLibrary]LLVector::'divide_quat'(valuetype [LScriptLibrary]LLVector, valuetype [LScriptLibrary]LLQuaternion)\n");
4746 break;
4747
4748 default:
4749 break;
4750 }
4751 break;
4752
4753 case LST_QUATERNION:
4754
4755 fprintf(fp, "call valuetype [LScriptLibrary]LLQuaternion valuetype [LScriptLibrary]LLQuaternion::'divide_quat'(valuetype [LScriptLibrary]LLQuaternion, valuetype [LScriptLibrary]LLQuaternion)\n");
4756 break;
4757
4758 default:
4759
4760 // Error.
4761 break;
4762 }
4763}
4764
4765void LLScriptDivAssignment::recurse(FILE *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)
4766{
4767 if (gErrorToText.getErrors())
4768 {
4769 return;
4770 }
4771 switch(pass)
4772 {
4773 case LSCP_PRETTY_PRINT:
4774 mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4775 fprintf(fp, " /= ");
4776 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4777 break;
4778 case LSCP_EMIT_ASSEMBLY:
4779 {
4780 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4781 mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4782 fprintf(fp, "DIV %s, %s\n", LSCRIPTTypeNames[mRightType], LSCRIPTTypeNames[mLeftType]);
4783 print_asignment(fp, mLValue);
4784 }
4785 break;
4786 case LSCP_TYPE:
4787 {
4788 mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4789 mLeftType = type;
4790 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4791 mRightType = type;
4792 if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
4793 {
4794 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
4795 }
4796 type = mReturnType;
4797 }
4798 break;
4799 case LSCP_TO_STACK:
4800 {
4801 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4802 mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4803 chunk->addByte(LSCRIPTOpCodes[LOPC_DIV]);
4804 operation2stack(chunk, mReturnType, mRightType);
4805 store2stack(this, mLValue, chunk, mReturnType);
4806 }
4807 break;
4808 case LSCP_EMIT_CIL_ASSEMBLY:
4809 {
4810 print_cil_load_address(fp, mLValue, entry);
4811 mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4812 print_cil_numeric_cast(fp, mLValue->mReturnType, mRightSide->mReturnType);
4813 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4814 print_cil_numeric_cast(fp, mRightSide->mReturnType, mLValue->mReturnType);
4815 print_cil_div(fp, mLValue->mReturnType, mRightSide->mReturnType);
4816 print_cil_asignment(fp, mLValue, entry);
4817 }
4818 break;
4819 default:
4820 mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4821 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4822 break;
4823 }
4824 gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4825}
4826
4827S32 LLScriptDivAssignment::getSize()
4828{
4829 return 0;
4830}
4831
4832void print_cil_mod(FILE* fp, LSCRIPTType left_type, LSCRIPTType right_type)
4833{
4834 switch(left_type)
4835 {
4836 case LST_INTEGER:
4837
4838 // Numeric remainder.
4839 fprintf(fp, "rem\n");
4840 break;
4841
4842 case LST_VECTOR:
4843
4844 // Vector cross product.
4845 fprintf(fp, "call valuetype [LScriptLibrary]LLVector valuetype [LScriptLibrary]LLVector::'mod_vec'(valuetype [LScriptLibrary]LLVector, valuetype [LScriptLibrary]LLVector)\n");
4846 break;
4847
4848 default:
4849
4850 // Error.
4851 break;
4852 }
4853}
4854
4855void LLScriptModAssignment::recurse(FILE *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)
4856{
4857 if (gErrorToText.getErrors())
4858 {
4859 return;
4860 }
4861 switch(pass)
4862 {
4863 case LSCP_PRETTY_PRINT:
4864 mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4865 fprintf(fp, " %%= ");
4866 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4867 break;
4868 case LSCP_EMIT_ASSEMBLY:
4869 {
4870 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4871 mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4872 fprintf(fp, "MOD %s, %s\n", LSCRIPTTypeNames[mRightType], LSCRIPTTypeNames[mLeftType]);
4873 print_asignment(fp, mLValue);
4874 }
4875 break;
4876 case LSCP_TYPE:
4877 {
4878 mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4879 mLeftType = type;
4880 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4881 mRightType = type;
4882 if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
4883 {
4884 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
4885 }
4886 type = mReturnType;
4887 }
4888 break;
4889 case LSCP_TO_STACK:
4890 {
4891 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4892 mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4893 chunk->addByte(LSCRIPTOpCodes[LOPC_MOD]);
4894 operation2stack(chunk, mReturnType, mRightType);
4895 store2stack(this, mLValue, chunk, mReturnType);
4896 }
4897 break;
4898 case LSCP_EMIT_CIL_ASSEMBLY:
4899 {
4900 print_cil_load_address(fp, mLValue, entry);
4901 mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4902 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4903 print_cil_mod(fp, mLValue->mReturnType, mRightSide->mReturnType);
4904 print_cil_asignment(fp, mLValue, entry);
4905 }
4906 break;
4907 default:
4908 mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4909 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4910 break;
4911 }
4912 gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4913}
4914
4915S32 LLScriptModAssignment::getSize()
4916{
4917 return 0;
4918}
4919
4920void print_cil_eq(FILE* fp, LSCRIPTType left_type, LSCRIPTType right_type)
4921{
4922 switch(left_type)
4923 {
4924 case LST_INTEGER:
4925 case LST_FLOATINGPOINT:
4926
4927 // Numeric equality.
4928 fprintf(fp, "ceq\n");
4929 break;
4930
4931 case LST_STRING:
4932 case LST_KEY:
4933
4934 // String equality.
4935 fprintf(fp, "call bool valuetype [mscorlib]System.String::op_Equality(string, string)\n");
4936 break;
4937
4938 case LST_VECTOR:
4939
4940 // Vector equality.
4941 fprintf(fp, "call bool [LScriptLibrary]LLVector::'equals_vec'(valuetype [LScriptLibrary]LLVector, valuetype [LScriptLibrary]LLVector)\n");
4942 break;
4943
4944 case LST_QUATERNION:
4945
4946 // Rotation equality.
4947 fprintf(fp, "call bool [LScriptLibrary]LLQuaternion::'equals_quat'(valuetype [LScriptLibrary]LLQuaternion, valuetype [LScriptLibrary]LLQuaternion)\n");
4948 break;
4949
4950 case LST_LIST:
4951 fprintf(fp, "call bool [LScriptLibrary]LScriptInternal::EqualsList(class [mscorlib]System.Collections.ArrayList, class [mscorlib]System.Collections.ArrayList)\n");
4952 break;
4953
4954 default:
4955
4956 // Error.
4957 break;
4958 }
4959}
4960
4961void LLScriptEquality::recurse(FILE *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)
4962{
4963 if (gErrorToText.getErrors())
4964 {
4965 return;
4966 }
4967 switch(pass)
4968 {
4969 case LSCP_PRETTY_PRINT:
4970 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4971 fprintf(fp, " == ");
4972 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4973 break;
4974 case LSCP_EMIT_ASSEMBLY:
4975 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4976 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4977 fprintf(fp, "EQ %s, %s\n", LSCRIPTTypeNames[mRightType], LSCRIPTTypeNames[mLeftType]);
4978 break;
4979 case LSCP_TYPE:
4980 {
4981 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4982 mLeftType = type;
4983 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4984 mRightType = type;
4985 if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
4986 {
4987 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
4988 }
4989 type = mReturnType;
4990 }
4991 break;
4992 case LSCP_TO_STACK:
4993 {
4994 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4995 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
4996 U8 typebyte = LSCRIPTTypeByte[mRightType] | LSCRIPTTypeHi4Bits[mLeftType];
4997 chunk->addByte(LSCRIPTOpCodes[LOPC_EQ]);
4998 chunk->addByte(typebyte);
4999 }
5000 break;
5001 case LSCP_EMIT_CIL_ASSEMBLY:
5002 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5003 print_cil_numeric_cast(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
5004 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5005 print_cil_numeric_cast(fp, mRightSide->mReturnType, mLeftSide->mReturnType);
5006 print_cil_eq(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
5007 break;
5008 default:
5009 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5010 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5011 break;
5012 }
5013 gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5014}
5015
5016S32 LLScriptEquality::getSize()
5017{
5018 return 0;
5019}
5020
5021void LLScriptNotEquals::recurse(FILE *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)
5022{
5023 if (gErrorToText.getErrors())
5024 {
5025 return;
5026 }
5027 switch(pass)
5028 {
5029 case LSCP_PRETTY_PRINT:
5030 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5031 fprintf(fp, " != ");
5032 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5033 break;
5034 case LSCP_EMIT_ASSEMBLY:
5035 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5036 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5037 fprintf(fp, "NEQ %s, %s\n", LSCRIPTTypeNames[mRightType], LSCRIPTTypeNames[mLeftType]);
5038 break;
5039 case LSCP_TYPE:
5040 {
5041 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5042 mLeftType = type;
5043 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5044 mRightType = type;
5045 if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
5046 {
5047 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
5048 }
5049 type = mReturnType;
5050 }
5051 break;
5052 case LSCP_TO_STACK:
5053 {
5054 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5055 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5056 U8 typebyte = LSCRIPTTypeByte[mRightType] | LSCRIPTTypeHi4Bits[mLeftType];
5057 chunk->addByte(LSCRIPTOpCodes[LOPC_NEQ]);
5058 chunk->addByte(typebyte);
5059 }
5060 break;
5061 case LSCP_EMIT_CIL_ASSEMBLY:
5062 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5063 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5064 fprintf(fp, "ceq\n");
5065 fprintf(fp, "ldc.i4.0\n");
5066 fprintf(fp, "ceq\n"); // Compare result of first compare equal with 0 to get compare not equal.
5067 break;
5068 default:
5069 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5070 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5071 break;
5072 }
5073 gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5074}
5075
5076S32 LLScriptNotEquals::getSize()
5077{
5078 return 0;
5079}
5080
5081void LLScriptLessEquals::recurse(FILE *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)
5082{
5083 if (gErrorToText.getErrors())
5084 {
5085 return;
5086 }
5087 switch(pass)
5088 {
5089 case LSCP_PRETTY_PRINT:
5090 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5091 fprintf(fp, " <= ");
5092 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5093 break;
5094 case LSCP_EMIT_ASSEMBLY:
5095 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5096 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5097 fprintf(fp, "LEQ %s, %s\n", LSCRIPTTypeNames[mRightType], LSCRIPTTypeNames[mLeftType]);
5098 break;
5099 case LSCP_TYPE:
5100 {
5101 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5102 mLeftType = type;
5103 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5104 mRightType = type;
5105 if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
5106 {
5107 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
5108 }
5109 type = mReturnType;
5110 }
5111 break;
5112 case LSCP_TO_STACK:
5113 {
5114 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5115 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5116 U8 typebyte = LSCRIPTTypeByte[mRightType] | LSCRIPTTypeHi4Bits[mLeftType];
5117 chunk->addByte(LSCRIPTOpCodes[LOPC_LEQ]);
5118 chunk->addByte(typebyte);
5119 }
5120 break;
5121 case LSCP_EMIT_CIL_ASSEMBLY:
5122 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5123 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5124 fprintf(fp, "cgt\n"); // Test greater than.
5125 fprintf(fp, "ldc.i4.0\n"); // Use (b == 0) implementation of boolean not.
5126 fprintf(fp, "ceq\n"); // Apply boolean not to greater than. If not greater than, then less or equal.
5127 break;
5128 default:
5129 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5130 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5131 break;
5132 }
5133 gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5134}
5135
5136S32 LLScriptLessEquals::getSize()
5137{
5138 return 0;
5139}
5140
5141void LLScriptGreaterEquals::recurse(FILE *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)
5142{
5143 if (gErrorToText.getErrors())
5144 {
5145 return;
5146 }
5147 switch(pass)
5148 {
5149 case LSCP_PRETTY_PRINT:
5150 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5151 fprintf(fp, " >= ");
5152 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5153 break;
5154 case LSCP_EMIT_ASSEMBLY:
5155 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5156 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5157 fprintf(fp, "GEQ %s, %s\n", LSCRIPTTypeNames[mRightType], LSCRIPTTypeNames[mLeftType]);
5158 break;
5159 case LSCP_TYPE:
5160 {
5161 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5162 mLeftType = type;
5163 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5164 mRightType = type;
5165 if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
5166 {
5167 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
5168 }
5169 type = mReturnType;
5170 }
5171 break;
5172 case LSCP_TO_STACK:
5173 {
5174 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5175 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5176 U8 typebyte = LSCRIPTTypeByte[mRightType] | LSCRIPTTypeHi4Bits[mLeftType];
5177 chunk->addByte(LSCRIPTOpCodes[LOPC_GEQ]);
5178 chunk->addByte(typebyte);
5179 }
5180 break;
5181 case LSCP_EMIT_CIL_ASSEMBLY:
5182 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5183 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5184 fprintf(fp, "clt\n"); // Test less than.
5185 fprintf(fp, "ldc.i4.0\n"); // Use (b == 0) implementation of boolean not.
5186 fprintf(fp, "ceq\n"); // Apply boolean not to less than. If not less than, then greater or equal.
5187 break;
5188 default:
5189 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5190 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5191 break;
5192 }
5193 gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5194}
5195
5196S32 LLScriptGreaterEquals::getSize()
5197{
5198 return 0;
5199}
5200
5201void LLScriptLessThan::recurse(FILE *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)
5202{
5203 if (gErrorToText.getErrors())
5204 {
5205 return;
5206 }
5207 switch(pass)
5208 {
5209 case LSCP_PRETTY_PRINT:
5210 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5211 fprintf(fp, " < ");
5212 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5213 break;
5214 case LSCP_EMIT_ASSEMBLY:
5215 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5216 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5217 fprintf(fp, "LESS %s, %s\n", LSCRIPTTypeNames[mRightType], LSCRIPTTypeNames[mLeftType]);
5218 break;
5219 case LSCP_TYPE:
5220 {
5221 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5222 mLeftType = type;
5223 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5224 mRightType = type;
5225 if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
5226 {
5227 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
5228 }
5229 type = mReturnType;
5230 }
5231 break;
5232 case LSCP_TO_STACK:
5233 {
5234 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5235 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5236 U8 typebyte = LSCRIPTTypeByte[mRightType] | LSCRIPTTypeHi4Bits[mLeftType];
5237 chunk->addByte(LSCRIPTOpCodes[LOPC_LESS]);
5238 chunk->addByte(typebyte);
5239 }
5240 break;
5241 case LSCP_EMIT_CIL_ASSEMBLY:
5242 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5243 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5244 fprintf(fp, "clt\n");
5245 break;
5246 default:
5247 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5248 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5249 break;
5250 }
5251 gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5252}
5253
5254S32 LLScriptLessThan::getSize()
5255{
5256 return 0;
5257}
5258
5259void LLScriptGreaterThan::recurse(FILE *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)
5260{
5261 if (gErrorToText.getErrors())
5262 {
5263 return;
5264 }
5265 switch(pass)
5266 {
5267 case LSCP_PRETTY_PRINT:
5268 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5269 fprintf(fp, " > ");
5270 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5271 break;
5272 case LSCP_EMIT_ASSEMBLY:
5273 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5274 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5275 fprintf(fp, "GREATER %s, %s\n", LSCRIPTTypeNames[mRightType], LSCRIPTTypeNames[mLeftType]);
5276 break;
5277 case LSCP_TYPE:
5278 {
5279 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5280 mLeftType = type;
5281 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5282 mRightType = type;
5283 if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
5284 {
5285 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
5286 }
5287 type = mReturnType;
5288 }
5289 break;
5290 case LSCP_TO_STACK:
5291 {
5292 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5293 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5294 U8 typebyte = LSCRIPTTypeByte[mRightType] | LSCRIPTTypeHi4Bits[mLeftType];
5295 chunk->addByte(LSCRIPTOpCodes[LOPC_GREATER]);
5296 chunk->addByte(typebyte);
5297 }
5298 break;
5299 case LSCP_EMIT_CIL_ASSEMBLY:
5300 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5301 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5302 fprintf(fp, "cgt\n");
5303 break;
5304 default:
5305 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5306 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5307 break;
5308 }
5309 gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5310}
5311
5312S32 LLScriptGreaterThan::getSize()
5313{
5314 return 0;
5315}
5316
5317void LLScriptPlus::recurse(FILE *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)
5318{
5319 if (gErrorToText.getErrors())
5320 {
5321 return;
5322 }
5323 switch(pass)
5324 {
5325 case LSCP_PRETTY_PRINT:
5326 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5327 fprintf(fp, " + ");
5328 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5329 break;
5330 case LSCP_EMIT_ASSEMBLY:
5331 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5332 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5333 fprintf(fp, "ADD %s, %s\n", LSCRIPTTypeNames[mRightType], LSCRIPTTypeNames[mLeftType]);
5334 break;
5335 case LSCP_TYPE:
5336 {
5337 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5338 mLeftType = type;
5339 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5340 mRightType = type;
5341 if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
5342 {
5343 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
5344 }
5345 type = mReturnType;
5346 }
5347 break;
5348 case LSCP_TO_STACK:
5349 {
5350 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5351 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5352 U8 typebyte = LSCRIPTTypeByte[mRightType] | LSCRIPTTypeHi4Bits[mLeftType];
5353 chunk->addByte(LSCRIPTOpCodes[LOPC_ADD]);
5354 chunk->addByte(typebyte);
5355 }
5356 break;
5357 case LSCP_EMIT_CIL_ASSEMBLY:
5358 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5359 print_cil_numeric_cast(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
5360 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5361 print_cil_numeric_cast(fp, mRightSide->mReturnType, mLeftSide->mReturnType);
5362 print_cil_add(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
5363 break;
5364 default:
5365 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5366 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5367 break;
5368 }
5369 gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5370}
5371
5372S32 LLScriptPlus::getSize()
5373{
5374 return 0;
5375}
5376
5377void LLScriptMinus::recurse(FILE *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)
5378{
5379 if (gErrorToText.getErrors())
5380 {
5381 return;
5382 }
5383 switch(pass)
5384 {
5385 case LSCP_PRETTY_PRINT:
5386 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5387 fprintf(fp, " - ");
5388 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5389 break;
5390 case LSCP_EMIT_ASSEMBLY:
5391 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5392 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5393 fprintf(fp, "SUB %s, %s\n", LSCRIPTTypeNames[mRightType], LSCRIPTTypeNames[mLeftType]);
5394 break;
5395 case LSCP_TYPE:
5396 {
5397 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5398 mLeftType = type;
5399 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5400 mRightType = type;
5401 if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
5402 {
5403 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
5404 }
5405 type = mReturnType;
5406 }
5407 break;
5408 case LSCP_TO_STACK:
5409 {
5410 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5411 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5412 U8 typebyte = LSCRIPTTypeByte[mRightType] | LSCRIPTTypeHi4Bits[mLeftType];
5413 chunk->addByte(LSCRIPTOpCodes[LOPC_SUB]);
5414 chunk->addByte(typebyte);
5415 }
5416 break;
5417 case LSCP_EMIT_CIL_ASSEMBLY:
5418 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5419 print_cil_numeric_cast(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
5420 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5421 print_cil_numeric_cast(fp, mRightSide->mReturnType, mLeftSide->mReturnType);
5422 print_cil_sub(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
5423 break;
5424 default:
5425 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5426 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5427 break;
5428 }
5429 gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5430}
5431
5432S32 LLScriptMinus::getSize()
5433{
5434 return 0;
5435}
5436
5437void LLScriptTimes::recurse(FILE *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)
5438{
5439 if (gErrorToText.getErrors())
5440 {
5441 return;
5442 }
5443 switch(pass)
5444 {
5445 case LSCP_PRETTY_PRINT:
5446 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5447 fprintf(fp, " * ");
5448 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5449 break;
5450 case LSCP_EMIT_ASSEMBLY:
5451 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5452 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5453 fprintf(fp, "MUL %s, %s\n", LSCRIPTTypeNames[mRightType], LSCRIPTTypeNames[mLeftType]);
5454 break;
5455 case LSCP_TYPE:
5456 {
5457 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5458 mLeftType = type;
5459 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5460 mRightType = type;
5461 if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
5462 {
5463 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
5464 }
5465 type = mReturnType;
5466 }
5467 break;
5468 case LSCP_TO_STACK:
5469 {
5470 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5471 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5472 U8 typebyte = LSCRIPTTypeByte[mRightType] | LSCRIPTTypeHi4Bits[mLeftType];
5473 chunk->addByte(LSCRIPTOpCodes[LOPC_MUL]);
5474 chunk->addByte(typebyte);
5475 }
5476 break;
5477 case LSCP_EMIT_CIL_ASSEMBLY:
5478 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5479 print_cil_numeric_cast(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
5480 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5481 print_cil_numeric_cast(fp, mRightSide->mReturnType, mLeftSide->mReturnType);
5482 print_cil_mul(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
5483 break;
5484 default:
5485 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5486 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5487 break;
5488 }
5489 gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5490}
5491
5492S32 LLScriptTimes::getSize()
5493{
5494 return 0;
5495}
5496
5497void LLScriptDivide::recurse(FILE *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)
5498{
5499 if (gErrorToText.getErrors())
5500 {
5501 return;
5502 }
5503 switch(pass)
5504 {
5505 case LSCP_PRETTY_PRINT:
5506 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5507 fprintf(fp, " / ");
5508 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5509 break;
5510 case LSCP_EMIT_ASSEMBLY:
5511 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5512 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5513 fprintf(fp, "DIV %s, %s\n", LSCRIPTTypeNames[mRightType], LSCRIPTTypeNames[mLeftType]);
5514 break;
5515 case LSCP_TYPE:
5516 {
5517 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5518 mLeftType = type;
5519 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5520 mRightType = type;
5521 if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
5522 {
5523 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
5524 }
5525 type = mReturnType;
5526 }
5527 break;
5528 case LSCP_TO_STACK:
5529 {
5530 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5531 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5532 U8 typebyte = LSCRIPTTypeByte[mRightType] | LSCRIPTTypeHi4Bits[mLeftType];
5533 chunk->addByte(LSCRIPTOpCodes[LOPC_DIV]);
5534 chunk->addByte(typebyte);
5535 }
5536 break;
5537 case LSCP_EMIT_CIL_ASSEMBLY:
5538 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5539 print_cil_numeric_cast(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
5540 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5541 print_cil_numeric_cast(fp, mRightSide->mReturnType, mLeftSide->mReturnType);
5542 print_cil_div(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
5543 break;
5544 default:
5545 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5546 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5547 break;
5548 }
5549 gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5550}
5551
5552S32 LLScriptDivide::getSize()
5553{
5554 return 0;
5555}
5556
5557void LLScriptMod::recurse(FILE *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)
5558{
5559 if (gErrorToText.getErrors())
5560 {
5561 return;
5562 }
5563 switch(pass)
5564 {
5565 case LSCP_PRETTY_PRINT:
5566 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5567 fprintf(fp, " %% ");
5568 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5569 break;
5570 case LSCP_EMIT_ASSEMBLY:
5571 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5572 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5573 fprintf(fp, "MOD %s, %s\n", LSCRIPTTypeNames[mRightType], LSCRIPTTypeNames[mLeftType]);
5574 break;
5575 case LSCP_TYPE:
5576 {
5577 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5578 mLeftType = type;
5579 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5580 mRightType = type;
5581 if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
5582 {
5583 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
5584 }
5585 type = mReturnType;
5586 }
5587 break;
5588 case LSCP_TO_STACK:
5589 {
5590 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5591 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5592 U8 typebyte = LSCRIPTTypeByte[mRightType] | LSCRIPTTypeHi4Bits[mLeftType];
5593 chunk->addByte(LSCRIPTOpCodes[LOPC_MOD]);
5594 chunk->addByte(typebyte);
5595 }
5596 break;
5597 case LSCP_EMIT_CIL_ASSEMBLY:
5598 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5599 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5600 print_cil_mod(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
5601 break;
5602 default:
5603 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5604 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5605 break;
5606 }
5607 gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5608}
5609
5610S32 LLScriptMod::getSize()
5611{
5612 return 0;
5613}
5614
5615void LLScriptBitAnd::recurse(FILE *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)
5616{
5617 if (gErrorToText.getErrors())
5618 {
5619 return;
5620 }
5621 switch(pass)
5622 {
5623 case LSCP_PRETTY_PRINT:
5624 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5625 fprintf(fp, " & ");
5626 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5627 break;
5628 case LSCP_EMIT_ASSEMBLY:
5629 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5630 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5631 fprintf(fp, "BITAND\n");
5632 break;
5633 case LSCP_TYPE:
5634 {
5635 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5636 mLeftType = type;
5637 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5638 mRightType = type;
5639 if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
5640 {
5641 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
5642 }
5643 type = mReturnType;
5644 }
5645 break;
5646 case LSCP_TO_STACK:
5647 {
5648 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5649 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5650 chunk->addByte(LSCRIPTOpCodes[LOPC_BITAND]);
5651 }
5652 break;
5653 case LSCP_EMIT_CIL_ASSEMBLY:
5654 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5655 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5656 fprintf(fp, "and\n");
5657 break;
5658 default:
5659 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5660 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5661 break;
5662 }
5663 gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5664}
5665
5666S32 LLScriptBitAnd::getSize()
5667{
5668 return 0;
5669}
5670
5671void LLScriptBitOr::recurse(FILE *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)
5672{
5673 if (gErrorToText.getErrors())
5674 {
5675 return;
5676 }
5677 switch(pass)
5678 {
5679 case LSCP_PRETTY_PRINT:
5680 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5681 fprintf(fp, " | ");
5682 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5683 break;
5684 case LSCP_EMIT_ASSEMBLY:
5685 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5686 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5687 fprintf(fp, "BITOR\n");
5688 break;
5689 case LSCP_TYPE:
5690 {
5691 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5692 mLeftType = type;
5693 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5694 mRightType = type;
5695 if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
5696 {
5697 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
5698 }
5699 type = mReturnType;
5700 }
5701 break;
5702 case LSCP_TO_STACK:
5703 {
5704 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5705 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5706 chunk->addByte(LSCRIPTOpCodes[LOPC_BITOR]);
5707 }
5708 break;
5709 case LSCP_EMIT_CIL_ASSEMBLY:
5710 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5711 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5712 fprintf(fp, "or\n");
5713 break;
5714 default:
5715 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5716 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5717 break;
5718 }
5719 gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5720}
5721
5722S32 LLScriptBitOr::getSize()
5723{
5724 return 0;
5725}
5726
5727void LLScriptBitXor::recurse(FILE *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)
5728{
5729 if (gErrorToText.getErrors())
5730 {
5731 return;
5732 }
5733 switch(pass)
5734 {
5735 case LSCP_PRETTY_PRINT:
5736 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5737 fprintf(fp, " ^ ");
5738 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5739 break;
5740 case LSCP_EMIT_ASSEMBLY:
5741 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5742 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5743 fprintf(fp, "BITXOR\n");
5744 break;
5745 case LSCP_TYPE:
5746 {
5747 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5748 mLeftType = type;
5749 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5750 mRightType = type;
5751 if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
5752 {
5753 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
5754 }
5755 type = mReturnType;
5756 }
5757 break;
5758 case LSCP_TO_STACK:
5759 {
5760 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5761 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5762 chunk->addByte(LSCRIPTOpCodes[LOPC_BITXOR]);
5763 }
5764 break;
5765 case LSCP_EMIT_CIL_ASSEMBLY:
5766 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5767 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5768 fprintf(fp, "xor\n");
5769 break;
5770 default:
5771 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5772 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5773 break;
5774 }
5775 gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5776}
5777
5778S32 LLScriptBitXor::getSize()
5779{
5780 return 0;
5781}
5782
5783void LLScriptBooleanAnd::recurse(FILE *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)
5784{
5785 if (gErrorToText.getErrors())
5786 {
5787 return;
5788 }
5789 switch(pass)
5790 {
5791 case LSCP_PRETTY_PRINT:
5792 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5793 fprintf(fp, " && ");
5794 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5795 break;
5796 case LSCP_EMIT_ASSEMBLY:
5797 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5798 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5799 fprintf(fp, "BOOLAND\n");
5800 break;
5801 case LSCP_TYPE:
5802 {
5803 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5804 mLeftType = type;
5805 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5806 mRightType = type;
5807 if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
5808 {
5809 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
5810 }
5811 type = mReturnType;
5812 }
5813 break;
5814 case LSCP_TO_STACK:
5815 {
5816 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5817 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5818 chunk->addByte(LSCRIPTOpCodes[LOPC_BOOLAND]);
5819 }
5820 break;
5821 case LSCP_EMIT_CIL_ASSEMBLY:
5822 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5823 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5824 fprintf(fp, "and\n");
5825 break;
5826 default:
5827 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5828 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5829 break;
5830 }
5831 gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5832}
5833
5834S32 LLScriptBooleanAnd::getSize()
5835{
5836 return 0;
5837}
5838
5839void LLScriptBooleanOr::recurse(FILE *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)
5840{
5841 if (gErrorToText.getErrors())
5842 {
5843 return;
5844 }
5845 switch(pass)
5846 {
5847 case LSCP_PRETTY_PRINT:
5848 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5849 fprintf(fp, " || ");
5850 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5851 break;
5852 case LSCP_EMIT_ASSEMBLY:
5853 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5854 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5855 fprintf(fp, "BOOLOR\n");
5856 break;
5857 case LSCP_TYPE:
5858 {
5859 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5860 mLeftType = type;
5861 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5862 mRightType = type;
5863 if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
5864 {
5865 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
5866 }
5867 type = mReturnType;
5868 }
5869 break;
5870 case LSCP_TO_STACK:
5871 {
5872 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5873 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5874 chunk->addByte(LSCRIPTOpCodes[LOPC_BOOLOR]);
5875 }
5876 break;
5877 case LSCP_EMIT_CIL_ASSEMBLY:
5878 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5879 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5880 fprintf(fp, "or\n");
5881 break;
5882 default:
5883 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5884 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5885 break;
5886 }
5887 gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5888}
5889
5890S32 LLScriptBooleanOr::getSize()
5891{
5892 return 0;
5893}
5894
5895void LLScriptShiftLeft::recurse(FILE *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)
5896{
5897 if (gErrorToText.getErrors())
5898 {
5899 return;
5900 }
5901 switch(pass)
5902 {
5903 case LSCP_PRETTY_PRINT:
5904 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5905 fprintf(fp, " << ");
5906 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5907 break;
5908 case LSCP_EMIT_ASSEMBLY:
5909 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5910 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5911 fprintf(fp, "SHL\n");
5912 break;
5913 case LSCP_TYPE:
5914 {
5915 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5916 mLeftType = type;
5917 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5918 mRightType = type;
5919 if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
5920 {
5921 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
5922 }
5923 type = mReturnType;
5924 }
5925 break;
5926 case LSCP_TO_STACK:
5927 {
5928 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5929 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5930 chunk->addByte(LSCRIPTOpCodes[LOPC_SHL]);
5931 }
5932 break;
5933 case LSCP_EMIT_CIL_ASSEMBLY:
5934 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5935 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5936 fprintf(fp, "shl\n");
5937 break;
5938 default:
5939 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5940 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5941 break;
5942 }
5943 gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5944}
5945
5946S32 LLScriptShiftLeft::getSize()
5947{
5948 return 0;
5949}
5950
5951
5952void LLScriptShiftRight::recurse(FILE *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)
5953{
5954 if (gErrorToText.getErrors())
5955 {
5956 return;
5957 }
5958 switch(pass)
5959 {
5960 case LSCP_PRETTY_PRINT:
5961 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5962 fprintf(fp, " >> ");
5963 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5964 break;
5965 case LSCP_EMIT_ASSEMBLY:
5966 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5967 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5968 fprintf(fp, "SHR\n");
5969 break;
5970 case LSCP_TYPE:
5971 {
5972 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5973 mLeftType = type;
5974 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5975 mRightType = type;
5976 if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
5977 {
5978 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
5979 }
5980 type = mReturnType;
5981 }
5982 break;
5983 case LSCP_TO_STACK:
5984 {
5985 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5986 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5987 chunk->addByte(LSCRIPTOpCodes[LOPC_SHR]);
5988 }
5989 break;
5990 case LSCP_EMIT_CIL_ASSEMBLY:
5991 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5992 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5993 fprintf(fp, "shr\n");
5994 break;
5995 default:
5996 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5997 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
5998 break;
5999 }
6000 gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6001}
6002
6003S32 LLScriptShiftRight::getSize()
6004{
6005 return 0;
6006}
6007
6008void LLScriptParenthesis::recurse(FILE *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)
6009{
6010 if (gErrorToText.getErrors())
6011 {
6012 return;
6013 }
6014 switch(pass)
6015 {
6016 case LSCP_PRETTY_PRINT:
6017 fprintf(fp, "( ");
6018 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6019 fprintf(fp, " )");
6020 break;
6021 case LSCP_TYPE:
6022 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6023 mReturnType = mLeftType = type;
6024 break;
6025 case LSCP_EMIT_ASSEMBLY:
6026 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6027 mReturnType = mLeftType = type;
6028 break;
6029 default:
6030 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6031 break;
6032 }
6033 gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6034}
6035
6036S32 LLScriptParenthesis::getSize()
6037{
6038 return 0;
6039}
6040
6041void LLScriptUnaryMinus::recurse(FILE *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)
6042{
6043 if (gErrorToText.getErrors())
6044 {
6045 return;
6046 }
6047 switch(pass)
6048 {
6049 case LSCP_PRETTY_PRINT:
6050 fprintf(fp, "-");
6051 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6052 break;
6053 case LSCP_EMIT_ASSEMBLY:
6054 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6055 fprintf(fp, "NEG %s\n", LSCRIPTTypeNames[mLeftType]);
6056 break;
6057 case LSCP_TYPE:
6058 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6059 if (!legal_unary_expression(type, type, mType))
6060 {
6061 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
6062 }
6063 else
6064 {
6065 mReturnType = mLeftType = type;
6066 }
6067 break;
6068 case LSCP_TO_STACK:
6069 {
6070 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6071 U8 typebyte = LSCRIPTTypeByte[mLeftType];
6072 chunk->addByte(LSCRIPTOpCodes[LOPC_NEG]);
6073 chunk->addByte(typebyte);
6074 }
6075 break;
6076 default:
6077 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6078 break;
6079 }
6080 gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6081}
6082
6083S32 LLScriptUnaryMinus::getSize()
6084{
6085 return 0;
6086}
6087
6088void LLScriptBooleanNot::recurse(FILE *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)
6089{
6090 if (gErrorToText.getErrors())
6091 {
6092 return;
6093 }
6094 switch(pass)
6095 {
6096 case LSCP_PRETTY_PRINT:
6097 fprintf(fp, "!");
6098 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6099 break;
6100 case LSCP_EMIT_ASSEMBLY:
6101 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6102 fprintf(fp, "BOOLNOT\n");
6103 break;
6104 case LSCP_TYPE:
6105 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6106 if (!legal_unary_expression(type, type, mType))
6107 {
6108 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
6109 }
6110 else
6111 {
6112 mReturnType = mLeftType = type;
6113 }
6114 break;
6115 case LSCP_TO_STACK:
6116 {
6117 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6118 chunk->addByte(LSCRIPTOpCodes[LOPC_BOOLNOT]);
6119 }
6120 break;
6121 case LSCP_EMIT_CIL_ASSEMBLY:
6122 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6123 fprintf(fp, "ldc.i4.0\n");
6124 fprintf(fp, "ceq\n"); // If f(e) is (e == 0), f(e) returns 1 if e is 0 and 0 otherwise, therefore f(e) implements boolean not.
6125 break;
6126 default:
6127 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6128 break;
6129 }
6130 gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6131}
6132
6133S32 LLScriptBooleanNot::getSize()
6134{
6135 return 0;
6136}
6137
6138void LLScriptBitNot::recurse(FILE *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)
6139{
6140 if (gErrorToText.getErrors())
6141 {
6142 return;
6143 }
6144 switch(pass)
6145 {
6146 case LSCP_PRETTY_PRINT:
6147 fprintf(fp, "~");
6148 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6149 break;
6150 case LSCP_EMIT_ASSEMBLY:
6151 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6152 fprintf(fp, "BITNOT\n");
6153 break;
6154 case LSCP_TYPE:
6155 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6156 if (!legal_unary_expression(type, type, mType))
6157 {
6158 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
6159 }
6160 else
6161 {
6162 mReturnType = mLeftType = type;
6163 }
6164 break;
6165 case LSCP_TO_STACK:
6166 {
6167 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6168 chunk->addByte(LSCRIPTOpCodes[LOPC_BITNOT]);
6169 }
6170 break;
6171 case LSCP_EMIT_CIL_ASSEMBLY:
6172 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6173 fprintf(fp, "not\n");
6174 break;
6175 default:
6176 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6177 break;
6178 }
6179 gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6180}
6181
6182S32 LLScriptBitNot::getSize()
6183{
6184 return 0;
6185}
6186
6187void LLScriptPreIncrement::recurse(FILE *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)
6188{
6189 if (gErrorToText.getErrors())
6190 {
6191 return;
6192 }
6193 switch(pass)
6194 {
6195 case LSCP_PRETTY_PRINT:
6196 fprintf(fp, "++");
6197 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6198 break;
6199 case LSCP_EMIT_ASSEMBLY:
6200 {
6201 if (mReturnType == LST_INTEGER)
6202 {
6203 fprintf(fp, "PUSHARGI 1\n");
6204 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6205 fprintf(fp, "\n");
6206 fprintf(fp, "ADD integer, integer\n");
6207 }
6208 else if (mReturnType == LST_FLOATINGPOINT)
6209 {
6210 fprintf(fp, "PUSHARGF 1\n");
6211 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6212 fprintf(fp, "\n");
6213 fprintf(fp, "ADD float, float\n");
6214 }
6215 else
6216 {
6217 fprintf(fp, "Unexpected Type\n");
6218 }
6219 print_asignment(fp, mExpression);
6220 }
6221 break;
6222 case LSCP_TYPE:
6223 if (mExpression->mType != LET_LVALUE)
6224 {
6225 gErrorToText.writeError(fp, this, LSERROR_EXPRESSION_ON_LVALUE);
6226 }
6227 else
6228 {
6229 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6230 if (!legal_unary_expression(type, type, mType))
6231 {
6232 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
6233 }
6234 else
6235 {
6236 mReturnType = mLeftType = type;
6237 }
6238 }
6239 break;
6240 case LSCP_TO_STACK:
6241 {
6242 if (mReturnType == LST_INTEGER)
6243 {
6244 chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGI]);
6245 chunk->addInteger(1);
6246 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6247 chunk->addByte(LSCRIPTOpCodes[LOPC_ADD]);
6248 chunk->addByte(LSCRIPTTypeByte[LST_INTEGER] | LSCRIPTTypeHi4Bits[LST_INTEGER]);
6249 }
6250 else if (mReturnType == LST_FLOATINGPOINT)
6251 {
6252 chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGF]);
6253 chunk->addFloat(1.f);
6254 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6255 chunk->addByte(LSCRIPTOpCodes[LOPC_ADD]);
6256 chunk->addByte(LSCRIPTTypeByte[LST_FLOATINGPOINT] | LSCRIPTTypeHi4Bits[LST_FLOATINGPOINT]);
6257 }
6258 store2stack(this, mExpression, chunk, mReturnType);
6259 }
6260 break;
6261 case LSCP_EMIT_CIL_ASSEMBLY:
6262 {
6263 print_cil_load_address(fp, mExpression, entry);
6264 if (mReturnType == LST_INTEGER)
6265 {
6266 fprintf(fp, "ldc.i4.1\n");
6267 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6268 fprintf(fp, "add\n");
6269 }
6270 else if (mReturnType == LST_FLOATINGPOINT)
6271 {
6272 fprintf(fp, "ldc.r8.1\n");
6273 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6274 fprintf(fp, "add\n");
6275 }
6276 else
6277 {
6278 fprintf(fp, "Unexpected Type\n");
6279 }
6280 print_cil_asignment(fp, mExpression, entry);
6281 }
6282 break;
6283 default:
6284 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6285 break;
6286 }
6287 gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6288}
6289
6290S32 LLScriptPreIncrement::getSize()
6291{
6292 return 0;
6293}
6294
6295void LLScriptPreDecrement::recurse(FILE *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)
6296{
6297 if (gErrorToText.getErrors())
6298 {
6299 return;
6300 }
6301 switch(pass)
6302 {
6303 case LSCP_PRETTY_PRINT:
6304 fprintf(fp, "--");
6305 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6306 break;
6307 case LSCP_EMIT_ASSEMBLY:
6308 {
6309 if (mReturnType == LST_INTEGER)
6310 {
6311 fprintf(fp, "PUSHARGI 1\n");
6312 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6313 fprintf(fp, "\n");
6314 fprintf(fp, "SUB integer, integer\n");
6315 }
6316 else if (mReturnType == LST_FLOATINGPOINT)
6317 {
6318 fprintf(fp, "PUSHARGF 1\n");
6319 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6320 fprintf(fp, "\n");
6321 fprintf(fp, "SUB float, float\n");
6322 }
6323 else
6324 {
6325 fprintf(fp, "Unexpected Type\n");
6326 }
6327 print_asignment(fp, mExpression);
6328 }
6329 break;
6330 case LSCP_TYPE:
6331 if (mExpression->mType != LET_LVALUE)
6332 {
6333 gErrorToText.writeError(fp, this, LSERROR_EXPRESSION_ON_LVALUE);
6334 }
6335 else
6336 {
6337 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6338 if (!legal_unary_expression(type, type, mType))
6339 {
6340 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
6341 }
6342 else
6343 {
6344 mReturnType = mLeftType = type;
6345 }
6346 }
6347 break;
6348 case LSCP_TO_STACK:
6349 {
6350 if (mReturnType == LST_INTEGER)
6351 {
6352 chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGI]);
6353 chunk->addInteger(1);
6354 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6355 chunk->addByte(LSCRIPTOpCodes[LOPC_SUB]);
6356 chunk->addByte(LSCRIPTTypeByte[LST_INTEGER] | LSCRIPTTypeHi4Bits[LST_INTEGER]);
6357 }
6358 else if (mReturnType == LST_FLOATINGPOINT)
6359 {
6360 chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGF]);
6361 chunk->addFloat(1.f);
6362 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6363 chunk->addByte(LSCRIPTOpCodes[LOPC_SUB]);
6364 chunk->addByte(LSCRIPTTypeByte[LST_FLOATINGPOINT] | LSCRIPTTypeHi4Bits[LST_FLOATINGPOINT]);
6365 }
6366 store2stack(this, mExpression, chunk, mReturnType);
6367 }
6368 break;
6369 case LSCP_EMIT_CIL_ASSEMBLY:
6370 {
6371 print_cil_load_address(fp, mExpression, entry);
6372 if (mReturnType == LST_INTEGER)
6373 {
6374 fprintf(fp, "ldc.i4.1\n");
6375 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6376 fprintf(fp, "sub\n");
6377 }
6378 else if (mReturnType == LST_FLOATINGPOINT)
6379 {
6380 fprintf(fp, "ldc.r8.1\n");
6381 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6382 fprintf(fp, "sub\n");
6383 }
6384 else
6385 {
6386 fprintf(fp, "Unexpected Type\n");
6387 }
6388 print_cil_asignment(fp, mExpression, entry);
6389 }
6390 break;
6391 default:
6392 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6393 break;
6394 }
6395 gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6396}
6397
6398S32 LLScriptPreDecrement::getSize()
6399{
6400 return 0;
6401}
6402
6403void LLScriptTypeCast::recurse(FILE *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)
6404{
6405 if (gErrorToText.getErrors())
6406 {
6407 return;
6408 }
6409 switch(pass)
6410 {
6411 case LSCP_PRETTY_PRINT:
6412 fprintf(fp, "( ");
6413 mType->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6414 fprintf(fp, ") ");
6415 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6416 break;
6417 case LSCP_EMIT_ASSEMBLY:
6418 fprintf(fp, "CAST %s->%s\n", LSCRIPTTypeNames[mRightType], LSCRIPTTypeNames[mType->mType]);
6419 break;
6420 case LSCP_TYPE:
6421 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6422 mRightType = type;
6423 if (!legal_casts(mType->mType, type))
6424 {
6425 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
6426 }
6427 type = mType->mType;
6428 mReturnType = mLeftType = type;
6429 break;
6430 case LSCP_TO_STACK:
6431 {
6432 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6433 chunk->addByte(LSCRIPTOpCodes[LOPC_CAST]);
6434 U8 castbyte = LSCRIPTTypeByte[mType->mType] | LSCRIPTTypeHi4Bits[mRightType];
6435 chunk->addByte(castbyte);
6436 }
6437 break;
6438 case LSCP_EMIT_CIL_ASSEMBLY:
6439 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6440 print_cil_cast(fp, mRightType, mType->mType);
6441 break;
6442 default:
6443 mType->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6444 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6445 break;
6446 }
6447 gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6448}
6449
6450S32 LLScriptTypeCast::getSize()
6451{
6452 return 0;
6453}
6454
6455void LLScriptVectorInitializer::recurse(FILE *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)
6456{
6457 if (gErrorToText.getErrors())
6458 {
6459 return;
6460 }
6461 switch(pass)
6462 {
6463 case LSCP_PRETTY_PRINT:
6464 fprintf(fp, "< ");
6465 mExpression1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6466 fprintf(fp, ", ");
6467 mExpression2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6468 fprintf(fp, ", ");
6469 mExpression3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6470 fprintf(fp, " >");
6471 break;
6472 case LSCP_EMIT_ASSEMBLY:
6473 mExpression1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6474 if (mExpression1->mReturnType != LST_FLOATINGPOINT)
6475 {
6476 fprintf(fp, "CAST %s->%s\n", LSCRIPTTypeNames[mExpression1->mReturnType], LSCRIPTTypeNames[LST_FLOATINGPOINT]);
6477 }
6478 mExpression2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6479 if (mExpression2->mReturnType != LST_FLOATINGPOINT)
6480 {
6481 fprintf(fp, "CAST %s->%s\n", LSCRIPTTypeNames[mExpression2->mReturnType], LSCRIPTTypeNames[LST_FLOATINGPOINT]);
6482 }
6483 mExpression3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6484 if (mExpression3->mReturnType != LST_FLOATINGPOINT)
6485 {
6486 fprintf(fp, "CAST %s->%s\n", LSCRIPTTypeNames[mExpression3->mReturnType], LSCRIPTTypeNames[LST_FLOATINGPOINT]);
6487 }
6488 break;
6489 case LSCP_TYPE:
6490 // vector's take floats
6491 mExpression1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6492 if (!legal_assignment(LST_FLOATINGPOINT, type))
6493 {
6494 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
6495 }
6496 mExpression2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6497 if (!legal_assignment(LST_FLOATINGPOINT, type))
6498 {
6499 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
6500 }
6501 mExpression3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6502 if (!legal_assignment(LST_FLOATINGPOINT, type))
6503 {
6504 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
6505 }
6506 mReturnType = type = LST_VECTOR;
6507 if (mNextp)
6508 {
6509 mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6510 }
6511 break;
6512 case LSCP_TO_STACK:
6513 pass = LSCP_TO_STACK;
6514 mExpression1->recurse(fp, tabs, tabsize, LSCP_TO_STACK, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6515 if (mExpression1->mReturnType != LST_FLOATINGPOINT)
6516 {
6517 chunk->addByte(LSCRIPTOpCodes[LOPC_CAST]);
6518 U8 castbyte = LSCRIPTTypeByte[LST_FLOATINGPOINT] | LSCRIPTTypeHi4Bits[mExpression1->mReturnType];
6519 chunk->addByte(castbyte);
6520 }
6521 mExpression2->recurse(fp, tabs, tabsize, LSCP_TO_STACK, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6522 if (mExpression2->mReturnType != LST_FLOATINGPOINT)
6523 {
6524 chunk->addByte(LSCRIPTOpCodes[LOPC_CAST]);
6525 U8 castbyte = LSCRIPTTypeByte[LST_FLOATINGPOINT] | LSCRIPTTypeHi4Bits[mExpression2->mReturnType];
6526 chunk->addByte(castbyte);
6527 }
6528 mExpression3->recurse(fp, tabs, tabsize, LSCP_TO_STACK, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6529 if (mExpression3->mReturnType != LST_FLOATINGPOINT)
6530 {
6531 chunk->addByte(LSCRIPTOpCodes[LOPC_CAST]);
6532 U8 castbyte = LSCRIPTTypeByte[LST_FLOATINGPOINT] | LSCRIPTTypeHi4Bits[mExpression3->mReturnType];
6533 chunk->addByte(castbyte);
6534 }
6535 break;
6536 case LSCP_EMIT_CIL_ASSEMBLY:
6537
6538 // Load arguments.
6539 mExpression1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6540 if (mExpression1->mReturnType != LST_FLOATINGPOINT)
6541 {
6542 print_cil_cast(fp, mExpression1->mReturnType, LST_FLOATINGPOINT);
6543 }
6544 mExpression2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6545 if (mExpression2->mReturnType != LST_FLOATINGPOINT)
6546 {
6547 print_cil_cast(fp, mExpression2->mReturnType, LST_FLOATINGPOINT);
6548 }
6549 mExpression3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6550 if (mExpression3->mReturnType != LST_FLOATINGPOINT)
6551 {
6552 print_cil_cast(fp, mExpression3->mReturnType, LST_FLOATINGPOINT);
6553 }
6554 // Call named ctor, which leaves new Vector on stack, so it can be saved in to local or argument just like a primitive type.
6555 fprintf(fp, "call valuetype [LScriptLibrary]LLVector valuetype [LScriptLibrary]LLVector::'create'(float32, float32, float32)\n");
6556 break;
6557 default:
6558 mExpression1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6559 mExpression2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6560 mExpression3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6561 break;
6562 }
6563 gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6564}
6565
6566S32 LLScriptVectorInitializer::getSize()
6567{
6568 return 0;
6569}
6570
6571void LLScriptQuaternionInitializer::recurse(FILE *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)
6572{
6573 if (gErrorToText.getErrors())
6574 {
6575 return;
6576 }
6577 switch(pass)
6578 {
6579 case LSCP_PRETTY_PRINT:
6580 fprintf(fp, "< ");
6581 mExpression1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6582 fprintf(fp, ", ");
6583 mExpression2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6584 fprintf(fp, ", ");
6585 mExpression3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6586 fprintf(fp, ", ");
6587 mExpression4->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6588 fprintf(fp, " >");
6589 break;
6590 case LSCP_EMIT_ASSEMBLY:
6591 mExpression1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6592 if (mExpression1->mReturnType != LST_FLOATINGPOINT)
6593 {
6594 fprintf(fp, "CAST %s->%s\n", LSCRIPTTypeNames[mExpression1->mReturnType], LSCRIPTTypeNames[LST_FLOATINGPOINT]);
6595 }
6596 mExpression2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6597 if (mExpression2->mReturnType != LST_FLOATINGPOINT)
6598 {
6599 fprintf(fp, "CAST %s->%s\n", LSCRIPTTypeNames[mExpression2->mReturnType], LSCRIPTTypeNames[LST_FLOATINGPOINT]);
6600 }
6601 mExpression3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6602 if (mExpression3->mReturnType != LST_FLOATINGPOINT)
6603 {
6604 fprintf(fp, "CAST %s->%s\n", LSCRIPTTypeNames[mExpression3->mReturnType], LSCRIPTTypeNames[LST_FLOATINGPOINT]);
6605 }
6606 mExpression4->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6607 if (mExpression4->mReturnType != LST_FLOATINGPOINT)
6608 {
6609 fprintf(fp, "CAST %s->%s\n", LSCRIPTTypeNames[mExpression4->mReturnType], LSCRIPTTypeNames[LST_FLOATINGPOINT]);
6610 }
6611 break;
6612 case LSCP_TYPE:
6613 // vector's take floats
6614 mExpression1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6615 if (!legal_assignment(LST_FLOATINGPOINT, type))
6616 {
6617 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
6618 }
6619 mExpression2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6620 if (!legal_assignment(LST_FLOATINGPOINT, type))
6621 {
6622 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
6623 }
6624 mExpression3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6625 if (!legal_assignment(LST_FLOATINGPOINT, type))
6626 {
6627 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
6628 }
6629 mExpression4->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6630 if (!legal_assignment(LST_FLOATINGPOINT, type))
6631 {
6632 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
6633 }
6634 mReturnType = type = LST_QUATERNION;
6635 if (mNextp)
6636 {
6637 mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6638 }
6639 break;
6640 case LSCP_TO_STACK:
6641 pass = LSCP_TO_STACK;
6642 mExpression1->recurse(fp, tabs, tabsize, LSCP_TO_STACK, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6643 if (mExpression1->mReturnType != LST_FLOATINGPOINT)
6644 {
6645 chunk->addByte(LSCRIPTOpCodes[LOPC_CAST]);
6646 U8 castbyte = LSCRIPTTypeByte[LST_FLOATINGPOINT] | LSCRIPTTypeHi4Bits[mExpression1->mReturnType];
6647 chunk->addByte(castbyte);
6648 }
6649 mExpression2->recurse(fp, tabs, tabsize, LSCP_TO_STACK, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6650 if (mExpression2->mReturnType != LST_FLOATINGPOINT)
6651 {
6652 chunk->addByte(LSCRIPTOpCodes[LOPC_CAST]);
6653 U8 castbyte = LSCRIPTTypeByte[LST_FLOATINGPOINT] | LSCRIPTTypeHi4Bits[mExpression2->mReturnType];
6654 chunk->addByte(castbyte);
6655 }
6656 mExpression3->recurse(fp, tabs, tabsize, LSCP_TO_STACK, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6657 if (mExpression3->mReturnType != LST_FLOATINGPOINT)
6658 {
6659 chunk->addByte(LSCRIPTOpCodes[LOPC_CAST]);
6660 U8 castbyte = LSCRIPTTypeByte[LST_FLOATINGPOINT] | LSCRIPTTypeHi4Bits[mExpression3->mReturnType];
6661 chunk->addByte(castbyte);
6662 }
6663 mExpression4->recurse(fp, tabs, tabsize, LSCP_TO_STACK, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6664 if (mExpression4->mReturnType != LST_FLOATINGPOINT)
6665 {
6666 chunk->addByte(LSCRIPTOpCodes[LOPC_CAST]);
6667 U8 castbyte = LSCRIPTTypeByte[LST_FLOATINGPOINT] | LSCRIPTTypeHi4Bits[mExpression4->mReturnType];
6668 chunk->addByte(castbyte);
6669 }
6670 break;
6671 case LSCP_EMIT_CIL_ASSEMBLY:
6672
6673 // Load arguments.
6674 mExpression1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6675 if (mExpression1->mReturnType != LST_FLOATINGPOINT)
6676 {
6677 print_cil_cast(fp, mExpression1->mReturnType, LST_FLOATINGPOINT);
6678 }
6679 mExpression2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6680 if (mExpression2->mReturnType != LST_FLOATINGPOINT)
6681 {
6682 print_cil_cast(fp, mExpression2->mReturnType, LST_FLOATINGPOINT);
6683 }
6684 mExpression3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6685 if (mExpression3->mReturnType != LST_FLOATINGPOINT)
6686 {
6687 print_cil_cast(fp, mExpression3->mReturnType, LST_FLOATINGPOINT);
6688 }
6689 mExpression4->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6690 if (mExpression4->mReturnType != LST_FLOATINGPOINT)
6691 {
6692 print_cil_cast(fp, mExpression4->mReturnType, LST_FLOATINGPOINT);
6693 }
6694
6695 // Call named ctor, which leaves new Vector on stack, so it can be saved in to local or argument just like a primitive type.
6696 fprintf(fp, "call valuetype [LScriptLibrary]LLQuaternion valuetype [LScriptLibrary]LLQuaternion::'create'(float32, float32, float32, float32)\n");
6697 break;
6698 default:
6699 mExpression1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6700 mExpression2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6701 mExpression3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6702 mExpression4->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6703 break;
6704 }
6705 gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6706}
6707
6708S32 LLScriptQuaternionInitializer::getSize()
6709{
6710 return 0;
6711}
6712
6713void LLScriptListInitializer::recurse(FILE *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)
6714{
6715 if (gErrorToText.getErrors())
6716 {
6717 return;
6718 }
6719 switch(pass)
6720 {
6721 case LSCP_PRETTY_PRINT:
6722 fprintf(fp, "[ ");
6723 mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6724 fprintf(fp, " ]");
6725 break;
6726 case LSCP_EMIT_ASSEMBLY:
6727 count = 0;
6728 if (mExpressionList)
6729 {
6730 mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6731 fprintf(fp, "STACKTOL %llu\n", count);
6732 }
6733 break;
6734 case LSCP_TYPE:
6735 if (mExpressionList)
6736 {
6737 mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6738 mReturnType = type = LST_LIST;
6739 }
6740 mReturnType = type = LST_LIST;
6741 break;
6742 case LSCP_TO_STACK:
6743 if (mExpressionList)
6744 {
6745 pass = LSCP_TO_STACK;
6746 count = 0;
6747 mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6748 chunk->addByte(LSCRIPTOpCodes[LOPC_STACKTOL]);
6749 chunk->addInteger((S32)count);
6750 count = 0;
6751 }
6752 else
6753 {
6754 chunk->addByte(LSCRIPTOpCodes[LOPC_STACKTOL]);
6755 chunk->addInteger(0);
6756 }
6757 break;
6758 case LSCP_EMIT_CIL_ASSEMBLY:
6759
6760 // Push boxed elements on stack.
6761 count = 0;
6762 if (mExpressionList)
6763 {
6764 mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6765 }
6766
6767 // Create list on stack, consuming first boxed element.
6768 fprintf(fp, "call class [mscorlib]System.Collections.ArrayList class [LScriptLibrary]LScriptInternal::CreateList()\n");
6769
6770 // Call AddReturnList to add remaining boxed expressions.
6771 for(U64 i = 0; i < count; i++)
6772 {
6773 fprintf(fp, "call class [mscorlib]System.Collections.ArrayList class [LScriptLibrary]LScriptInternal::AddReturnList(object, class [mscorlib]System.Collections.ArrayList)\n");
6774 }
6775 count = 0;
6776
6777 break;
6778 default:
6779 if (mExpressionList)
6780 {
6781 mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6782 }
6783 break;
6784 }
6785 gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6786}
6787
6788S32 LLScriptListInitializer::getSize()
6789{
6790 return 0;
6791}
6792
6793void LLScriptPostIncrement::recurse(FILE *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)
6794{
6795 if (gErrorToText.getErrors())
6796 {
6797 return;
6798 }
6799 switch(pass)
6800 {
6801 case LSCP_PRETTY_PRINT:
6802 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6803 fprintf(fp, "++");
6804 break;
6805 case LSCP_EMIT_ASSEMBLY:
6806 {
6807 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6808 if (mReturnType == LST_INTEGER)
6809 {
6810 fprintf(fp, "PUSHARGI 1\n");
6811 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6812 fprintf(fp, "ADD integer, integer\n");
6813 }
6814 else if (mReturnType == LST_FLOATINGPOINT)
6815 {
6816 fprintf(fp, "PUSHARGF 1\n");
6817 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6818 fprintf(fp, "ADD float, float\n");
6819 }
6820 else
6821 {
6822 fprintf(fp, "Unexpected Type\n");
6823 }
6824 print_asignment(fp, mExpression);
6825 fprintf(fp, "%s\n", LSCRIPTTypePop[mReturnType]);
6826 }
6827 break;
6828 case LSCP_TYPE:
6829 if (mExpression->mType != LET_LVALUE)
6830 {
6831 gErrorToText.writeError(fp, this, LSERROR_EXPRESSION_ON_LVALUE);
6832 }
6833 else
6834 {
6835 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6836 if (!legal_unary_expression(type, type, mType))
6837 {
6838 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
6839 }
6840 else
6841 {
6842 mReturnType = mLeftType = type;
6843 }
6844 }
6845 break;
6846 case LSCP_TO_STACK:
6847 {
6848 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6849 if (mReturnType == LST_INTEGER)
6850 {
6851 chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGI]);
6852 chunk->addInteger(1);
6853 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6854 chunk->addByte(LSCRIPTOpCodes[LOPC_ADD]);
6855 chunk->addByte(LSCRIPTTypeByte[LST_INTEGER] | LSCRIPTTypeHi4Bits[LST_INTEGER]);
6856 }
6857 else if (mReturnType == LST_FLOATINGPOINT)
6858 {
6859 chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGF]);
6860 chunk->addFloat(1.f);
6861 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6862 chunk->addByte(LSCRIPTOpCodes[LOPC_ADD]);
6863 chunk->addByte(LSCRIPTTypeByte[LST_FLOATINGPOINT] | LSCRIPTTypeHi4Bits[LST_FLOATINGPOINT]);
6864 }
6865 store2stack(this, mExpression, chunk, mReturnType);
6866 switch(mReturnType)
6867 {
6868 case LST_INTEGER:
6869 case LST_FLOATINGPOINT:
6870 chunk->addByte(LSCRIPTOpCodes[LOPC_POP]);
6871 break;
6872 case LST_KEY:
6873 case LST_STRING:
6874 chunk->addByte(LSCRIPTOpCodes[LOPC_POPS]);
6875 break;
6876 case LST_LIST:
6877 chunk->addByte(LSCRIPTOpCodes[LOPC_POPL]);
6878 break;
6879 case LST_VECTOR:
6880 chunk->addByte(LSCRIPTOpCodes[LOPC_POPV]);
6881 break;
6882 case LST_QUATERNION:
6883 chunk->addByte(LSCRIPTOpCodes[LOPC_POPQ]);
6884 break;
6885 default:
6886 chunk->addByte(LSCRIPTOpCodes[LOPC_POP]);
6887 break;
6888 }
6889 }
6890 break;
6891 case LSCP_EMIT_CIL_ASSEMBLY:
6892 {
6893 print_cil_load_address(fp, mExpression, entry);
6894 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6895 fprintf(fp,"dup\n"); // Copy expression result to use as increment operand.
6896 if (mReturnType == LST_INTEGER)
6897 {
6898 fprintf(fp, "ldc.i4.1\n");
6899 }
6900 else if (mReturnType == LST_FLOATINGPOINT)
6901 {
6902 fprintf(fp, "ldc.r8.1\n");
6903 }
6904 else
6905 {
6906 fprintf(fp, "Unexpected Type\n");
6907 }
6908 fprintf(fp, "add\n");
6909 print_cil_asignment(fp, mExpression, entry);
6910 fprintf(fp, "pop\n"); // Pop assignment result to leave original expression result on stack. TODO: Optimise away redundant pop/dup pairs.
6911 }
6912 break;
6913 default:
6914 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6915 break;
6916 }
6917 gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6918}
6919
6920S32 LLScriptPostIncrement::getSize()
6921{
6922 return 0;
6923}
6924
6925void LLScriptPostDecrement::recurse(FILE *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)
6926{
6927 if (gErrorToText.getErrors())
6928 {
6929 return;
6930 }
6931 switch(pass)
6932 {
6933 case LSCP_PRETTY_PRINT:
6934 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6935 fprintf(fp, "--");
6936 break;
6937 case LSCP_EMIT_ASSEMBLY:
6938 {
6939 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6940 if (mReturnType == LST_INTEGER)
6941 {
6942 fprintf(fp, "PUSHARGI 1\n");
6943 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6944 fprintf(fp, "SUB integer, integer\n");
6945 }
6946 else if (mReturnType == LST_FLOATINGPOINT)
6947 {
6948 fprintf(fp, "PUSHARGF 1\n");
6949 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6950 fprintf(fp, "SUB float, float\n");
6951 }
6952 else
6953 {
6954 fprintf(fp, "Unexpected Type\n");
6955 }
6956 print_asignment(fp, mExpression);
6957 fprintf(fp, "%s\n", LSCRIPTTypePop[mReturnType]);
6958 }
6959 break;
6960 case LSCP_TYPE:
6961 if (mExpression->mType != LET_LVALUE)
6962 {
6963 gErrorToText.writeError(fp, this, LSERROR_EXPRESSION_ON_LVALUE);
6964 }
6965 else
6966 {
6967 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6968 if (!legal_unary_expression(type, type, mType))
6969 {
6970 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
6971 }
6972 else
6973 {
6974 mReturnType = mLeftType = type;
6975 }
6976 }
6977 break;
6978 case LSCP_TO_STACK:
6979 {
6980 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6981 if (mReturnType == LST_INTEGER)
6982 {
6983 chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGI]);
6984 chunk->addInteger(1);
6985 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6986 chunk->addByte(LSCRIPTOpCodes[LOPC_SUB]);
6987 chunk->addByte(LSCRIPTTypeByte[LST_INTEGER] | LSCRIPTTypeHi4Bits[LST_INTEGER]);
6988 }
6989 else if (mReturnType == LST_FLOATINGPOINT)
6990 {
6991 chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGF]);
6992 chunk->addFloat(1.f);
6993 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
6994 chunk->addByte(LSCRIPTOpCodes[LOPC_SUB]);
6995 chunk->addByte(LSCRIPTTypeByte[LST_FLOATINGPOINT] | LSCRIPTTypeHi4Bits[LST_FLOATINGPOINT]);
6996 }
6997 store2stack(this, mExpression, chunk, mReturnType);
6998 switch(mReturnType)
6999 {
7000 case LST_INTEGER:
7001 case LST_FLOATINGPOINT:
7002 chunk->addByte(LSCRIPTOpCodes[LOPC_POP]);
7003 break;
7004 case LST_KEY:
7005 case LST_STRING:
7006 chunk->addByte(LSCRIPTOpCodes[LOPC_POPS]);
7007 break;
7008 case LST_LIST:
7009 chunk->addByte(LSCRIPTOpCodes[LOPC_POPL]);
7010 break;
7011 case LST_VECTOR:
7012 chunk->addByte(LSCRIPTOpCodes[LOPC_POPV]);
7013 break;
7014 case LST_QUATERNION:
7015 chunk->addByte(LSCRIPTOpCodes[LOPC_POPQ]);
7016 break;
7017 default:
7018 chunk->addByte(LSCRIPTOpCodes[LOPC_POP]);
7019 break;
7020 }
7021 }
7022 break;
7023 case LSCP_EMIT_CIL_ASSEMBLY:
7024 {
7025 print_cil_load_address(fp, mExpression, entry);
7026 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7027 fprintf(fp,"dup\n"); // Copy expression result to use as decrement operand.
7028 if (mReturnType == LST_INTEGER)
7029 {
7030 fprintf(fp, "ldc.i4.1\n");
7031 }
7032 else if (mReturnType == LST_FLOATINGPOINT)
7033 {
7034 fprintf(fp, "ldc.r8.1\n");
7035 }
7036 else
7037 {
7038 fprintf(fp, "Unexpected Type\n");
7039 }
7040 fprintf(fp, "sub\n");
7041 print_cil_asignment(fp, mExpression, entry);
7042 fprintf(fp, "pop\n"); // Pop assignment result to leave original expression result on stack. TODO: Optimise away redundant pop/dup pairs.
7043 }
7044 break;
7045 default:
7046 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7047 break;
7048 }
7049 gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7050}
7051
7052S32 LLScriptPostDecrement::getSize()
7053{
7054 return 0;
7055}
7056
7057// Generate arg list.
7058void print_cil_arg_list(FILE *fp, LLScriptFuncExpressionList* exp_list)
7059{
7060 // Print first argument.
7061 print_cil_type(fp, exp_list->mFirstp->mReturnType);
7062
7063 // Recursively print next arguments.
7064 if(exp_list->mSecondp != NULL)
7065 {
7066 fprintf(fp, ", ");
7067 print_cil_arg_list(fp, (LLScriptFuncExpressionList*) exp_list->mSecondp);
7068 }
7069}
7070
7071void LLScriptFunctionCall::recurse(FILE *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)
7072{
7073 if (gErrorToText.getErrors())
7074 {
7075 return;
7076 }
7077 switch(pass)
7078 {
7079 case LSCP_PRETTY_PRINT:
7080 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7081 fprintf(fp, "( ");
7082 if (mExpressionList)
7083 mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7084 fprintf(fp, " )");
7085 break;
7086 case LSCP_EMIT_ASSEMBLY:
7087 if (mIdentifier->mScopeEntry->mType)
7088 fprintf(fp, "%s\n", LSCRIPTTypePush[mIdentifier->mScopeEntry->mType]);
7089 fprintf(fp,"PUSHE\n");
7090 fprintf(fp, "PUSHBP\n");
7091 if (mExpressionList)
7092 mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, mIdentifier->mScopeEntry, 0, NULL);
7093 fprintf(fp, "PUSHARGE %d\n", mIdentifier->mScopeEntry->mSize - mIdentifier->mScopeEntry->mOffset);
7094 fprintf(fp, "PUSHSP\n");
7095 fprintf(fp, "PUSHARGI %d\n", mIdentifier->mScopeEntry->mSize);
7096 fprintf(fp, "ADD integer, integer\n");
7097 fprintf(fp, "POPBP\n");
7098 if (mIdentifier->mScopeEntry->mIDType != LIT_LIBRARY_FUNCTION)
7099 {
7100 fprintf(fp, "CALL ");
7101 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7102 }
7103 else
7104 {
7105 fprintf(fp, "CALLLID ");
7106 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7107 fprintf(fp, ", %d", (U32)mIdentifier->mScopeEntry->mLibraryNumber);
7108 }
7109 fprintf(fp, "\n");
7110 fprintf(fp, "POPBP\n");
7111 break;
7112 case LSCP_SCOPE_PASS1:
7113 if (mExpressionList)
7114 mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7115 break;
7116 case LSCP_SCOPE_PASS2:
7117 {
7118 LLScriptScopeEntry *entry = scope->findEntryTyped(mIdentifier->mName, LIT_FUNCTION);
7119 if (!entry)
7120 {
7121 gErrorToText.writeError(fp, this, LSERROR_UNDEFINED_NAME);
7122 }
7123 else
7124 {
7125 // if we did find it, make sure this identifier is associated with the correct scope entry
7126 mIdentifier->mScopeEntry = entry;
7127 }
7128 if (mExpressionList)
7129 mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7130 }
7131 break;
7132 case LSCP_TYPE:
7133 if (mIdentifier->mScopeEntry)
7134 {
7135 U64 argcount = 0;
7136 if (mExpressionList)
7137 mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, argcount, chunk, heap, stacksize, mIdentifier->mScopeEntry, 0, NULL);
7138
7139 if (!mIdentifier->mScopeEntry->mFunctionArgs.mString)
7140 {
7141 if (argcount)
7142 {
7143 gErrorToText.writeError(fp, this, LSERROR_FUNCTION_TYPE_ERROR);
7144 }
7145 }
7146 else if (argcount != strlen(mIdentifier->mScopeEntry->mFunctionArgs.mString))
7147 {
7148 gErrorToText.writeError(fp, this, LSERROR_FUNCTION_TYPE_ERROR);
7149 }
7150 }
7151
7152 if (mIdentifier->mScopeEntry)
7153 type = mIdentifier->mScopeEntry->mType;
7154 else
7155 type = LST_NULL;
7156 mReturnType = type;
7157 break;
7158 case LSCP_TO_STACK:
7159 switch(mIdentifier->mScopeEntry->mType)
7160 {
7161 case LST_INTEGER:
7162 case LST_FLOATINGPOINT:
7163 case LST_STRING:
7164 case LST_KEY:
7165 case LST_LIST:
7166 chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHE]);
7167 break;
7168 case LST_VECTOR:
7169 chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHEV]);
7170 break;
7171 case LST_QUATERNION:
7172 chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHEQ]);
7173 break;
7174 default:
7175 break;
7176 }
7177 chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHE]);
7178 chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHBP]);
7179 if (mExpressionList)
7180 {
7181 // Don't let this change the count.
7182 U64 dummy_count = 0;
7183 mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, dummy_count, chunk, heap, stacksize, mIdentifier->mScopeEntry, 0, NULL);
7184 //mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, mIdentifier->mScopeEntry, 0, NULL);
7185 }
7186 chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGE]);
7187 chunk->addInteger(mIdentifier->mScopeEntry->mSize - mIdentifier->mScopeEntry->mOffset);
7188 chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHSP]);
7189 chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGI]);
7190 chunk->addInteger(mIdentifier->mScopeEntry->mSize);
7191 chunk->addByte(LSCRIPTOpCodes[LOPC_ADD]);
7192 chunk->addByte(LSCRIPTTypeByte[LST_INTEGER] | LSCRIPTTypeHi4Bits[LST_INTEGER]);
7193 chunk->addByte(LSCRIPTOpCodes[LOPC_POPBP]);
7194 if (mIdentifier->mScopeEntry->mIDType != LIT_LIBRARY_FUNCTION)
7195 {
7196 chunk->addByte(LSCRIPTOpCodes[LOPC_CALL]);
7197 chunk->addInteger(mIdentifier->mScopeEntry->mCount);
7198 }
7199 else
7200 {
7201 chunk->addByte(LSCRIPTOpCodes[LOPC_CALLLIB_TWO_BYTE]);
7202 chunk->addU16(mIdentifier->mScopeEntry->mLibraryNumber);
7203 }
7204 break;
7205 case LSCP_EMIT_CIL_ASSEMBLY:
7206 {
7207 bool library_call = (mIdentifier->mScopeEntry->mIDType == LIT_LIBRARY_FUNCTION);
7208 if(! library_call)
7209 {
7210 // Load this pointer.
7211 fprintf(fp, "ldarg.0\n");
7212 }
7213
7214 // Load args on to stack.
7215 if (mExpressionList)
7216 {
7217 mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry /* Needed for is_parameter calls */, 0, NULL);
7218 }
7219
7220 // Make call.
7221 if (! library_call)
7222 {
7223 fprintf(fp, "callvirt instance ");
7224 }
7225 else
7226 {
7227 fprintf(fp, "call ");
7228 }
7229 print_cil_type(fp, mIdentifier->mScopeEntry->mType);
7230 fprintf(fp, " class ");
7231 if (library_call)
7232 {
7233 fprintf(fp, "[LScriptLibrary]LScriptLibrary");
7234 }
7235 else
7236 {
7237 fprintf(fp, "LSL");
7238 }
7239 fprintf(fp, "::");
7240 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7241 fprintf(fp, "(");
7242 if (mExpressionList) {print_cil_arg_list(fp, (LLScriptFuncExpressionList*) mExpressionList);}
7243 fprintf(fp, ")\n");
7244 }
7245 break;
7246 default:
7247 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7248 if (mExpressionList)
7249 mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7250 break;
7251 }
7252 gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7253}
7254
7255S32 LLScriptFunctionCall::getSize()
7256{
7257 return 0;
7258}
7259
7260void LLScriptPrint::recurse(FILE *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)
7261{
7262 if (gErrorToText.getErrors())
7263 {
7264 return;
7265 }
7266 switch(pass)
7267 {
7268 case LSCP_PRETTY_PRINT:
7269 fprintf(fp, " PRINT ( ");
7270 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7271 fprintf(fp, " )");
7272 break;
7273 case LSCP_EMIT_ASSEMBLY:
7274 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7275 fprintf(fp, "PRINT %s\n", LSCRIPTTypeNames[mLeftType]);
7276 break;
7277 case LSCP_TYPE:
7278 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7279 mLeftType = type;
7280 mReturnType = LST_NULL;
7281 break;
7282 case LSCP_TO_STACK:
7283 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7284 chunk->addByte(LSCRIPTOpCodes[LOPC_PRINT]);
7285 chunk->addByte(LSCRIPTTypeByte[mLeftType]);
7286 break;
7287 default:
7288 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7289 break;
7290 }
7291 gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7292}
7293
7294S32 LLScriptPrint::getSize()
7295{
7296 return 0;
7297}
7298
7299void LLScriptConstantExpression::recurse(FILE *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)
7300{
7301 if (gErrorToText.getErrors())
7302 {
7303 return;
7304 }
7305 switch(pass)
7306 {
7307 case LSCP_PRETTY_PRINT:
7308 mConstant->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7309 break;
7310 case LSCP_TYPE:
7311 mConstant->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7312 mReturnType = type;
7313 break;
7314 case LSCP_TO_STACK:
7315 mConstant->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7316 break;
7317 default:
7318 mConstant->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7319 break;
7320 }
7321 gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7322}
7323
7324S32 LLScriptConstantExpression::getSize()
7325{
7326 return 0;
7327}
7328
7329void LLScriptStatement::addStatement(LLScriptStatement *event)
7330{
7331 if (mNextp)
7332 {
7333 event->mNextp = mNextp;
7334 }
7335 mNextp = event;
7336}
7337
7338void LLScriptStatement::recurse(FILE *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)
7339{
7340 fprintf(fp, "Statement Base Class -- should never get here!\n");
7341}
7342
7343S32 LLScriptStatement::getSize()
7344{
7345 printf("Statement Base Class -- should never get here!\n");
7346 return 0;
7347}
7348
7349void LLScriptStatement::gonext(FILE *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)
7350{
7351 if (gErrorToText.getErrors())
7352 {
7353 return;
7354 }
7355 switch(pass)
7356 {
7357 case LSCP_PRETTY_PRINT:
7358 if (mNextp)
7359 {
7360 fprintf(fp, ", ");
7361 mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7362 }
7363 break;
7364 case LSCP_EMIT_ASSEMBLY:
7365 if (mNextp)
7366 {
7367 mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7368 }
7369 break;
7370 default:
7371 if (mNextp)
7372 {
7373 mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7374 }
7375 break;
7376 }
7377}
7378
7379S32 LLScriptStatementSequence::getSize()
7380{
7381 return 0;
7382}
7383
7384void LLScriptStatementSequence::recurse(FILE *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)
7385{
7386 if (gErrorToText.getErrors())
7387 {
7388 return;
7389 }
7390 switch(pass)
7391 {
7392 case LSCP_PRETTY_PRINT:
7393 mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7394 mSecondp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7395 break;
7396 case LSCP_EMIT_ASSEMBLY:
7397 mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7398 mSecondp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7399 break;
7400 case LSCP_PRUNE:
7401 mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7402 if (prunearg)
7403 {
7404 ptype = LSPRUNE_DEAD_CODE;
7405 gErrorToText.writeWarning(fp, this, LSWARN_DEAD_CODE);
7406 }
7407 mSecondp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7408 break;
7409 case LSCP_TYPE:
7410 // pass the return type into all statements so we can check returns
7411 {
7412 LSCRIPTType return_type = type;
7413 mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, return_type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7414 return_type = type;
7415 mSecondp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, return_type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7416 }
7417 break;
7418 default:
7419 mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7420 mSecondp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7421 break;
7422 }
7423 gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7424}
7425
7426S32 LLScriptNOOP::getSize()
7427{
7428 return 0;
7429}
7430
7431void LLScriptNOOP::recurse(FILE *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)
7432{
7433 if (gErrorToText.getErrors())
7434 {
7435 return;
7436 }
7437 switch(pass)
7438 {
7439 case LSCP_PRETTY_PRINT:
7440 fdotabs(fp, tabs, tabsize);
7441 fprintf(fp, ";\n");
7442 break;
7443 case LSCP_PRUNE:
7444 if (ptype == LSPRUNE_DEAD_CODE)
7445 prunearg = TRUE;
7446 else
7447 prunearg = FALSE;
7448 break;
7449 default:
7450 break;
7451 }
7452 gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7453}
7454
7455void add_exit_pops(LLScriptByteCodeChunk *chunk, LLScriptScopeEntry *entry)
7456{
7457 // remember that we need to pop in reverse order
7458 S32 number, i;
7459
7460 if (entry->mLocals.mString)
7461 {
7462 number = (S32)strlen(entry->mLocals.mString);
7463 for (i = number - 1; i >= 0; i--)
7464 {
7465 switch(entry->mLocals.getType(i))
7466 {
7467 case LST_INTEGER:
7468 chunk->addByte(LSCRIPTOpCodes[LOPC_POP]);
7469 break;
7470 case LST_FLOATINGPOINT:
7471 chunk->addByte(LSCRIPTOpCodes[LOPC_POP]);
7472 break;
7473 case LST_STRING:
7474 case LST_KEY:
7475 chunk->addByte(LSCRIPTOpCodes[LOPC_POPS]);
7476 break;
7477 case LST_VECTOR:
7478 chunk->addByte(LSCRIPTOpCodes[LOPC_POPV]);
7479 break;
7480 case LST_QUATERNION:
7481 chunk->addByte(LSCRIPTOpCodes[LOPC_POPQ]);
7482 break;
7483 case LST_LIST:
7484 chunk->addByte(LSCRIPTOpCodes[LOPC_POPL]);
7485 break;
7486
7487 default:
7488 break;
7489 }
7490 }
7491 }
7492
7493 if (entry->mFunctionArgs.mString)
7494 {
7495 number = (S32)strlen(entry->mFunctionArgs.mString);
7496 for (i = number - 1; i >= 0; i--)
7497 {
7498 switch(entry->mFunctionArgs.getType(i))
7499 {
7500 case LST_INTEGER:
7501 chunk->addByte(LSCRIPTOpCodes[LOPC_POP]);
7502 break;
7503 case LST_FLOATINGPOINT:
7504 chunk->addByte(LSCRIPTOpCodes[LOPC_POP]);
7505 break;
7506 case LST_STRING:
7507 case LST_KEY:
7508 chunk->addByte(LSCRIPTOpCodes[LOPC_POPS]);
7509 break;
7510 case LST_VECTOR:
7511 chunk->addByte(LSCRIPTOpCodes[LOPC_POPV]);
7512 break;
7513 case LST_QUATERNION:
7514 chunk->addByte(LSCRIPTOpCodes[LOPC_POPQ]);
7515 break;
7516 case LST_LIST:
7517 chunk->addByte(LSCRIPTOpCodes[LOPC_POPL]);
7518 break;
7519
7520 default:
7521 break;
7522 }
7523 }
7524 }
7525}
7526
7527void print_exit_pops(FILE *fp, LLScriptScopeEntry *entry)
7528{
7529 // remember that we need to pop in reverse order
7530 S32 number, i;
7531
7532 if (entry->mLocals.mString)
7533 {
7534 number = (S32)strlen(entry->mLocals.mString);
7535 for (i = number - 1; i >= 0; i--)
7536 {
7537 fprintf(fp, "%s", LSCRIPTTypePop[entry->mLocals.getType(i)]);
7538 }
7539 }
7540
7541 if (entry->mFunctionArgs.mString)
7542 {
7543 number = (S32)strlen(entry->mFunctionArgs.mString);
7544 for (i = number - 1; i >= 0; i--)
7545 {
7546 fprintf(fp, "%s", LSCRIPTTypePop[entry->mFunctionArgs.getType(i)]);
7547 }
7548 }
7549}
7550
7551
7552S32 LLScriptStateChange::getSize()
7553{
7554 return 0;
7555}
7556
7557void LLScriptStateChange::recurse(FILE *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)
7558{
7559 if (gErrorToText.getErrors())
7560 {
7561 return;
7562 }
7563 switch(pass)
7564 {
7565 case LSCP_PRETTY_PRINT:
7566 fdotabs(fp, tabs, tabsize);
7567 fprintf(fp, "state ");
7568 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7569 fprintf(fp, ";\n");
7570 break;
7571 case LSCP_EMIT_ASSEMBLY:
7572 print_exit_pops(fp, entry);
7573 fprintf(fp, "STATE ");
7574 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7575 fprintf(fp, "\n");
7576 break;
7577 case LSCP_PRUNE:
7578 if ( (ptype == LSPRUNE_GLOBAL_VOIDS)
7579 ||(ptype == LSPRUNE_GLOBAL_NON_VOIDS))
7580 {
7581 gErrorToText.writeError(fp, this, LSERROR_STATE_CHANGE_IN_GLOBAL);
7582 }
7583 if (ptype == LSPRUNE_DEAD_CODE)
7584 prunearg = TRUE;
7585 else
7586 prunearg = FALSE;
7587 break;
7588 case LSCP_SCOPE_PASS2:
7589 {
7590 LLScriptScopeEntry *entry = scope->findEntryTyped(mIdentifier->mName, LIT_STATE);
7591 if (!entry)
7592 {
7593 gErrorToText.writeError(fp, this, LSERROR_UNDEFINED_NAME);
7594 }
7595 else
7596 {
7597 // if we did find it, make sure this identifier is associated with the correct scope entry
7598 mIdentifier->mScopeEntry = entry;
7599 }
7600 }
7601 break;
7602 case LSCP_EMIT_BYTE_CODE:
7603 {
7604 add_exit_pops(chunk, entry);
7605 chunk->addByte(LSCRIPTOpCodes[LOPC_STATE]);
7606 chunk->addInteger(mIdentifier->mScopeEntry->mCount);
7607 }
7608 break;
7609 case LSCP_EMIT_CIL_ASSEMBLY:
7610 fprintf(fp, "ldstr \"");
7611 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7612 fprintf(fp, "\"\n");
7613 fprintf(fp, "call void class [LScriptLibrary]LScriptInternal::change_state(string)\n");
7614 break;
7615 default:
7616 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7617 break;
7618 }
7619 gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7620}
7621
7622S32 LLScriptJump::getSize()
7623{
7624 return 0;
7625}
7626
7627void LLScriptJump::recurse(FILE *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)
7628{
7629 if (gErrorToText.getErrors())
7630 {
7631 return;
7632 }
7633 switch(pass)
7634 {
7635 case LSCP_PRETTY_PRINT:
7636 fdotabs(fp, tabs, tabsize);
7637 fprintf(fp, "jump ");
7638 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7639 fprintf(fp, ";\n");
7640 break;
7641 case LSCP_EMIT_ASSEMBLY:
7642 fprintf(fp, "JUMP ");
7643 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7644 fprintf(fp, "\n");
7645 break;
7646 case LSCP_PRUNE:
7647 if (ptype == LSPRUNE_DEAD_CODE)
7648 prunearg = TRUE;
7649 else
7650 prunearg = FALSE;
7651 break;
7652 case LSCP_SCOPE_PASS2:
7653 {
7654 LLScriptScopeEntry *entry = scope->findEntryTyped(mIdentifier->mName, LIT_LABEL);
7655 if (!entry)
7656 {
7657 gErrorToText.writeError(fp, this, LSERROR_UNDEFINED_NAME);
7658 }
7659 else
7660 {
7661 // if we did find it, make sure this identifier is associated with the correct scope entry
7662 mIdentifier->mScopeEntry = entry;
7663 }
7664 }
7665 break;
7666 case LSCP_EMIT_BYTE_CODE:
7667 {
7668 chunk->addByte(LSCRIPTOpCodes[LOPC_JUMP]);
7669 chunk->addBytes(LSCRIPTDataSize[LST_INTEGER]);
7670 chunk->addJump(mIdentifier->mName);
7671 }
7672 break;
7673 case LSCP_EMIT_CIL_ASSEMBLY:
7674 fprintf(fp, "br ");
7675 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7676 fprintf(fp, "\n");
7677 break;
7678 default:
7679 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7680 break;
7681 }
7682 gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7683}
7684
7685S32 LLScriptLabel::getSize()
7686{
7687 return 0;
7688}
7689
7690void LLScriptLabel::recurse(FILE *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)
7691{
7692 if (gErrorToText.getErrors())
7693 {
7694 return;
7695 }
7696 switch(pass)
7697 {
7698 case LSCP_PRETTY_PRINT:
7699 fdotabs(fp, tabs, tabsize);
7700 fprintf(fp, "@");
7701 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7702 fprintf(fp, ";\n");
7703 break;
7704 case LSCP_EMIT_ASSEMBLY:
7705 fprintf(fp, "LABEL ");
7706 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7707 fprintf(fp, "\n");
7708 break;
7709 case LSCP_PRUNE:
7710 // Always clear this flag, to stop pruning after return statements. A jump
7711 // might start up code at this label, so we need to stop pruning.
7712 prunearg = FALSE;
7713 break;
7714 case LSCP_SCOPE_PASS1:
7715 // add labels to scope
7716 if (scope->checkEntry(mIdentifier->mName))
7717 {
7718 gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
7719 }
7720 else
7721 {
7722 mIdentifier->mScopeEntry = scope->addEntry(mIdentifier->mName, LIT_LABEL, LST_NULL);
7723 }
7724 break;
7725 case LSCP_EMIT_BYTE_CODE:
7726 {
7727 chunk->addLabel(mIdentifier->mName);
7728 }
7729 break;
7730 case LSCP_EMIT_CIL_ASSEMBLY:
7731 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7732 fprintf(fp, ":\n");
7733 break;
7734 default:
7735 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7736 break;
7737 }
7738 gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7739}
7740
7741void add_return(LLScriptByteCodeChunk *chunk, LLScriptScopeEntry *entry)
7742{
7743 add_exit_pops(chunk, entry);
7744 chunk->addByte(LSCRIPTOpCodes[LOPC_RETURN]);
7745}
7746
7747void print_return(FILE *fp, LLScriptScopeEntry *entry)
7748{
7749 print_exit_pops(fp, entry);
7750 fprintf(fp, "RETURN\n");
7751}
7752
7753
7754S32 LLScriptReturn::getSize()
7755{
7756 return 0;
7757}
7758
7759void LLScriptReturn::recurse(FILE *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)
7760{
7761 if (gErrorToText.getErrors())
7762 {
7763 return;
7764 }
7765 switch(pass)
7766 {
7767 case LSCP_PRETTY_PRINT:
7768 if (mExpression)
7769 {
7770 fdotabs(fp, tabs, tabsize);
7771 fprintf(fp, "return ");
7772 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7773 fprintf(fp, ";\n");
7774 }
7775 else
7776 {
7777 fdotabs(fp, tabs, tabsize);
7778 fprintf(fp, "return;\n");
7779 }
7780 break;
7781 case LSCP_EMIT_ASSEMBLY:
7782 if (mExpression)
7783 {
7784 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7785 fprintf(fp, "%s\n", LSCRIPTTypeReturn[mType]);
7786 }
7787 print_return(fp, entry);
7788 break;
7789 case LSCP_PRUNE:
7790 if ( (ptype == LSPRUNE_GLOBAL_VOIDS)
7791 ||(ptype == LSPRUNE_EVENTS))
7792 {
7793 if (mExpression)
7794 {
7795 gErrorToText.writeError(fp, this, LSERROR_INVALID_RETURN);
7796 }
7797 }
7798 else if (ptype == LSPRUNE_GLOBAL_NON_VOIDS)
7799 {
7800 if (!mExpression)
7801 {
7802 gErrorToText.writeError(fp, this, LSERROR_INVALID_VOID_RETURN);
7803 }
7804 }
7805 prunearg = TRUE;
7806 case LSCP_TYPE:
7807 // if there is a return expression, it must be promotable to the return type of the function
7808 if (mExpression)
7809 {
7810 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7811 if (!legal_assignment(basetype, type))
7812 {
7813 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
7814 }
7815 else
7816 {
7817 mType = basetype;
7818 }
7819 }
7820 break;
7821 case LSCP_EMIT_BYTE_CODE:
7822 if (mExpression)
7823 {
7824 mExpression->recurse(fp, tabs, tabsize, LSCP_TO_STACK, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7825 switch(mType)
7826 {
7827 case LST_INTEGER:
7828 case LST_FLOATINGPOINT:
7829 chunk->addByte(LSCRIPTOpCodes[LOPC_LOADP]);
7830 chunk->addInteger(-12);
7831 break;
7832 case LST_STRING:
7833 case LST_KEY:
7834 // use normal store for reference counted types
7835 chunk->addByte(LSCRIPTOpCodes[LOPC_LOADSP]);
7836 chunk->addInteger(-12);
7837 break;
7838 case LST_LIST:
7839 // use normal store for reference counted types
7840 chunk->addByte(LSCRIPTOpCodes[LOPC_LOADLP]);
7841 chunk->addInteger(-12);
7842 break;
7843 case LST_VECTOR:
7844 chunk->addByte(LSCRIPTOpCodes[LOPC_LOADVP]);
7845 chunk->addInteger(-20);
7846 break;
7847 case LST_QUATERNION:
7848 chunk->addByte(LSCRIPTOpCodes[LOPC_LOADQP]);
7849 chunk->addInteger(-24);
7850 break;
7851 default:
7852 chunk->addByte(LSCRIPTOpCodes[LOPC_LOADP]);
7853 chunk->addInteger(-12);
7854 break;
7855 }
7856 }
7857 add_return(chunk, entry);
7858 break;
7859 case LSCP_EMIT_CIL_ASSEMBLY:
7860 if (mExpression)
7861 {
7862 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7863 }
7864 fprintf(fp, "ret\n");
7865 break;
7866 default:
7867 if (mExpression)
7868 {
7869 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7870 }
7871 break;
7872 }
7873 gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7874}
7875
7876S32 LLScriptExpressionStatement::getSize()
7877{
7878 return 0;
7879}
7880
7881void LLScriptExpressionStatement::recurse(FILE *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)
7882{
7883 if (gErrorToText.getErrors())
7884 {
7885 return;
7886 }
7887 switch(pass)
7888 {
7889 case LSCP_PRETTY_PRINT:
7890 fdotabs(fp, tabs, tabsize);
7891 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7892 fprintf(fp, ";\n");
7893 break;
7894 case LSCP_EMIT_ASSEMBLY:
7895 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7896 if (mExpression->mReturnType)
7897 {
7898 fprintf(fp, "%s\n", LSCRIPTTypePop[mExpression->mReturnType]);
7899 }
7900 break;
7901 case LSCP_PRUNE:
7902 if (ptype == LSPRUNE_DEAD_CODE)
7903 prunearg = TRUE;
7904 else
7905 prunearg = FALSE;
7906 break;
7907 case LSCP_EMIT_BYTE_CODE:
7908 mExpression->recurse(fp, tabs, tabsize, LSCP_TO_STACK, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7909 switch(mExpression->mReturnType)
7910 {
7911 case LST_INTEGER:
7912 case LST_FLOATINGPOINT:
7913 chunk->addByte(LSCRIPTOpCodes[LOPC_POP]);
7914 break;
7915 case LST_STRING:
7916 case LST_KEY:
7917 chunk->addByte(LSCRIPTOpCodes[LOPC_POPS]);
7918 break;
7919 case LST_LIST:
7920 chunk->addByte(LSCRIPTOpCodes[LOPC_POPL]);
7921 break;
7922 case LST_VECTOR:
7923 chunk->addByte(LSCRIPTOpCodes[LOPC_POPV]);
7924 break;
7925 case LST_QUATERNION:
7926 chunk->addByte(LSCRIPTOpCodes[LOPC_POPQ]);
7927 break;
7928 default:
7929 break;
7930 }
7931 break;
7932 case LSCP_EMIT_CIL_ASSEMBLY:
7933 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7934 if(mExpression->mReturnType)
7935 {
7936 fprintf(fp, "pop\n");
7937 }
7938 break;
7939 default:
7940 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7941 break;
7942 }
7943 gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7944}
7945
7946S32 LLScriptIf::getSize()
7947{
7948 return 0;
7949}
7950
7951void LLScriptIf::recurse(FILE *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)
7952{
7953 if (gErrorToText.getErrors())
7954 {
7955 return;
7956 }
7957 switch(pass)
7958 {
7959 case LSCP_PRETTY_PRINT:
7960 fdotabs(fp, tabs, tabsize);
7961 fprintf(fp, "if ( ");
7962 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7963 fprintf(fp, " )\n");
7964 mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7965 break;
7966 case LSCP_EMIT_ASSEMBLY:
7967 {
7968 S32 tjump = gTempJumpCount++;
7969 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7970 fprintf(fp, "JUMPNIF ##Temp Jump %d##\n", tjump);
7971 mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7972 fprintf(fp, "LABEL ##Temp Jump %d##\n", tjump);
7973 }
7974 break;
7975 case LSCP_PRUNE:
7976 if (ptype == LSPRUNE_DEAD_CODE)
7977 prunearg = TRUE;
7978 else
7979 prunearg = FALSE;
7980 break;
7981 case LSCP_TYPE:
7982 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7983 mType = type;
7984 mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7985 break;
7986 case LSCP_EMIT_BYTE_CODE:
7987 {
7988 char jumpname[32];
7989 sprintf(jumpname, "##Temp Jump %d##", gTempJumpCount++);
7990
7991 mExpression->recurse(fp, tabs, tabsize, LSCP_TO_STACK, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7992 chunk->addByte(LSCRIPTOpCodes[LOPC_JUMPNIF]);
7993 chunk->addByte(LSCRIPTTypeByte[mType]);
7994 chunk->addBytes(LSCRIPTDataSize[LST_INTEGER]);
7995 chunk->addJump(jumpname);
7996 mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
7997 chunk->addLabel(jumpname);
7998 }
7999 break;
8000 case LSCP_EMIT_CIL_ASSEMBLY:
8001 {
8002 S32 tjump = gTempJumpCount++;
8003 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8004 fprintf(fp, "brfalse LabelTempJump%d\n", tjump);
8005 mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8006 fprintf(fp, "LabelTempJump%d:\n", tjump);
8007 }
8008 break;
8009 default:
8010 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8011 mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8012 break;
8013 }
8014 gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8015}
8016
8017S32 LLScriptIfElse::getSize()
8018{
8019 return 0;
8020}
8021
8022void LLScriptIfElse::recurse(FILE *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)
8023{
8024 if (gErrorToText.getErrors())
8025 {
8026 return;
8027 }
8028 switch(pass)
8029 {
8030 case LSCP_PRETTY_PRINT:
8031 fdotabs(fp, tabs, tabsize);
8032 fprintf(fp, "if ( ");
8033 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8034 fprintf(fp, " )\n");
8035 mStatement1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8036 fdotabs(fp, tabs, tabsize);
8037 fprintf(fp, "else\n");
8038 mStatement2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8039 break;
8040 case LSCP_EMIT_ASSEMBLY:
8041 {
8042 S32 tjump1 = gTempJumpCount++;
8043 S32 tjump2 = gTempJumpCount++;
8044 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8045 fprintf(fp, "JUMPNIF ##Temp Jump %d##\n", tjump1);
8046 mStatement1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8047 fprintf(fp, "JUMP ##Temp Jump %d##\n", tjump2);
8048 fprintf(fp, "LABEL ##Temp Jump %d##\n", tjump1);
8049 mStatement2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8050 fprintf(fp, "LABEL ##Temp Jump %d##\n", tjump2);
8051 }
8052 break;
8053 case LSCP_PRUNE:
8054 {
8055 BOOL arg1 = TRUE, arg2 = TRUE;
8056 mStatement1->recurse(fp, tabs, tabsize, pass, ptype, arg1, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8057 mStatement2->recurse(fp, tabs, tabsize, pass, ptype, arg2, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8058 prunearg = arg1 && arg2;
8059 }
8060 break;
8061 case LSCP_TYPE:
8062 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8063 mType = type;
8064 mStatement1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8065 mStatement2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8066 break;
8067 case LSCP_EMIT_BYTE_CODE:
8068 {
8069 char jumpname1[32];
8070 sprintf(jumpname1, "##Temp Jump %d##", gTempJumpCount++);
8071 char jumpname2[32];
8072 sprintf(jumpname2, "##Temp Jump %d##", gTempJumpCount++);
8073
8074 mExpression->recurse(fp, tabs, tabsize, LSCP_TO_STACK, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8075 chunk->addByte(LSCRIPTOpCodes[LOPC_JUMPNIF]);
8076 chunk->addByte(LSCRIPTTypeByte[mType]);
8077 chunk->addBytes(LSCRIPTDataSize[LST_INTEGER]);
8078 chunk->addJump(jumpname1);
8079 mStatement1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8080 chunk->addByte(LSCRIPTOpCodes[LOPC_JUMP]);
8081 chunk->addBytes(LSCRIPTDataSize[LST_INTEGER]);
8082 chunk->addJump(jumpname2);
8083 chunk->addLabel(jumpname1);
8084 mStatement2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8085 chunk->addLabel(jumpname2);
8086 }
8087 break;
8088 case LSCP_EMIT_CIL_ASSEMBLY:
8089 {
8090 S32 tjump1 = gTempJumpCount++;
8091 S32 tjump2 = gTempJumpCount++;
8092 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8093 fprintf(fp, "brfalse LabelTempJump%d\n", tjump1);
8094 mStatement1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8095 fprintf(fp, "br LabelTempJump%d\n", tjump2);
8096 fprintf(fp, "LabelTempJump%d:\n", tjump1);
8097 mStatement2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8098 fprintf(fp, "LabelTempJump%d:\n", tjump2);
8099 }
8100 break;
8101 default:
8102 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8103 mStatement1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8104 mStatement2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8105 break;
8106 };
8107 gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8108}
8109
8110S32 LLScriptFor::getSize()
8111{
8112 return 0;
8113}
8114
8115void LLScriptFor::recurse(FILE *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)
8116{
8117 if (gErrorToText.getErrors())
8118 {
8119 return;
8120 }
8121 switch(pass)
8122 {
8123 case LSCP_PRETTY_PRINT:
8124 fdotabs(fp, tabs, tabsize);
8125 fprintf(fp, "for ( ");
8126 if(mSequence)
8127 mSequence->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8128 fprintf(fp, " ; ");
8129 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8130 fprintf(fp, " ; ");
8131 if(mExpressionList)
8132 mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8133 fprintf(fp, " )\n");
8134 if(mStatement)
8135 mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8136 break;
8137 case LSCP_EMIT_ASSEMBLY:
8138 {
8139 S32 tjump1 = gTempJumpCount++;
8140 S32 tjump2 = gTempJumpCount++;
8141 if(mSequence)
8142 mSequence->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8143 fprintf(fp, "LABEL ##Temp Jump %d##\n", tjump1);
8144 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8145 fprintf(fp, "JUMPNIF ##Temp Jump %d##\n", tjump2);
8146 if(mStatement)
8147 mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8148 if(mExpressionList)
8149 mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8150 fprintf(fp, "JUMP ##Temp Jump %d##\n", tjump1);
8151 fprintf(fp, "LABEL ##Temp Jump %d##\n", tjump2);
8152 }
8153 break;
8154 case LSCP_PRUNE:
8155 if (ptype == LSPRUNE_DEAD_CODE)
8156 prunearg = TRUE;
8157 else
8158 prunearg = FALSE;
8159 break;
8160 case LSCP_TYPE:
8161 if(mSequence)
8162 mSequence->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8163 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8164 mType = type;
8165 if(mExpressionList)
8166 mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8167 if(mStatement)
8168 mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8169 break;
8170 case LSCP_EMIT_BYTE_CODE:
8171 {
8172 char jumpname1[32];
8173 sprintf(jumpname1, "##Temp Jump %d##", gTempJumpCount++);
8174 char jumpname2[32];
8175 sprintf(jumpname2, "##Temp Jump %d##", gTempJumpCount++);
8176
8177 if(mSequence)
8178 mSequence->recurse(fp, tabs, tabsize, LSCP_TO_STACK, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8179 chunk->addLabel(jumpname1);
8180 mExpression->recurse(fp, tabs, tabsize, LSCP_TO_STACK, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8181 chunk->addByte(LSCRIPTOpCodes[LOPC_JUMPNIF]);
8182 chunk->addByte(LSCRIPTTypeByte[mType]);
8183 chunk->addBytes(LSCRIPTDataSize[LST_INTEGER]);
8184 chunk->addJump(jumpname2);
8185 if(mStatement)
8186 mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8187 if(mExpressionList)
8188 mExpressionList->recurse(fp, tabs, tabsize, LSCP_TO_STACK, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8189 chunk->addByte(LSCRIPTOpCodes[LOPC_JUMP]);
8190 chunk->addBytes(LSCRIPTDataSize[LST_INTEGER]);
8191 chunk->addJump(jumpname1);
8192 chunk->addLabel(jumpname2);
8193 }
8194 break;
8195 case LSCP_EMIT_CIL_ASSEMBLY:
8196 {
8197 S32 tjump1 = gTempJumpCount++;
8198 S32 tjump2 = gTempJumpCount++;
8199 if(mSequence)
8200 mSequence->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8201 fprintf(fp, "LabelTempJump%d:\n", tjump1);
8202 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8203 fprintf(fp, "brfalse LabelTempJump%d\n", tjump2);
8204 if(mStatement)
8205 mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8206 if(mExpressionList)
8207 mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8208 fprintf(fp, "br LabelTempJump%d\n", tjump1);
8209 fprintf(fp, "LabelTempJump%d:\n", tjump2);
8210 }
8211 break;
8212 default:
8213 if(mSequence)
8214 mSequence->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8215 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8216 if(mExpressionList)
8217 mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8218 if(mStatement)
8219 mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8220 break;
8221 }
8222 gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8223}
8224
8225S32 LLScriptDoWhile::getSize()
8226{
8227 return 0;
8228}
8229
8230void LLScriptDoWhile::recurse(FILE *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)
8231{
8232 if (gErrorToText.getErrors())
8233 {
8234 return;
8235 }
8236 switch(pass)
8237 {
8238 case LSCP_PRETTY_PRINT:
8239 fdotabs(fp, tabs, tabsize);
8240 fprintf(fp, "do\n");
8241 mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8242 fdotabs(fp, tabs, tabsize);
8243 fprintf(fp, "while( ");
8244 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8245 fprintf(fp, " );\n");
8246 break;
8247 case LSCP_EMIT_ASSEMBLY:
8248 {
8249 S32 tjump1 = gTempJumpCount++;
8250 fprintf(fp, "LABEL ##Temp Jump %d##\n", tjump1);
8251 mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8252 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8253 fprintf(fp, "JUMPIF ##Temp Jump %d##\n", tjump1);
8254 }
8255 break;
8256 case LSCP_PRUNE:
8257 if (ptype == LSPRUNE_DEAD_CODE)
8258 prunearg = TRUE;
8259 else
8260 prunearg = FALSE;
8261 break;
8262 case LSCP_TYPE:
8263 mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8264 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8265 mType = type;
8266 break;
8267 case LSCP_EMIT_BYTE_CODE:
8268 {
8269 char jumpname1[32];
8270 sprintf(jumpname1, "##Temp Jump %d##", gTempJumpCount++);
8271
8272 chunk->addLabel(jumpname1);
8273 mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8274 mExpression->recurse(fp, tabs, tabsize, LSCP_TO_STACK, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8275 chunk->addByte(LSCRIPTOpCodes[LOPC_JUMPIF]);
8276 chunk->addByte(LSCRIPTTypeByte[mType]);
8277 chunk->addBytes(LSCRIPTDataSize[LST_INTEGER]);
8278 chunk->addJump(jumpname1);
8279 }
8280 break;
8281 case LSCP_EMIT_CIL_ASSEMBLY:
8282 {
8283 S32 tjump1 = gTempJumpCount++;
8284 fprintf(fp, "LabelTempJump%d:\n", tjump1);
8285 mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8286 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8287 fprintf(fp, "brtrue LabelTempJump%d\n", tjump1);
8288 }
8289 break;
8290 default:
8291 mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8292 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8293 break;
8294 }
8295 gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8296}
8297
8298S32 LLScriptWhile::getSize()
8299{
8300 return 0;
8301}
8302
8303void LLScriptWhile::recurse(FILE *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)
8304{
8305 if (gErrorToText.getErrors())
8306 {
8307 return;
8308 }
8309 switch(pass)
8310 {
8311 case LSCP_PRETTY_PRINT:
8312 fdotabs(fp, tabs, tabsize);
8313 fprintf(fp, "while( ");
8314 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8315 fprintf(fp, " )\n");
8316 mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8317 break;
8318 case LSCP_EMIT_ASSEMBLY:
8319 {
8320 S32 tjump1 = gTempJumpCount++;
8321 S32 tjump2 = gTempJumpCount++;
8322 fprintf(fp, "LABEL ##Temp Jump %d##\n", tjump1);
8323 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8324 fprintf(fp, "JUMPNIF ##Temp Jump %d##\n", tjump2);
8325 mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8326 fprintf(fp, "JUMP ##Temp Jump %d##\n", tjump1);
8327 fprintf(fp, "LABEL ##Temp Jump %d##\n", tjump2);
8328 }
8329 break;
8330 case LSCP_PRUNE:
8331 if (ptype == LSPRUNE_DEAD_CODE)
8332 prunearg = TRUE;
8333 else
8334 prunearg = FALSE;
8335 break;
8336 case LSCP_TYPE:
8337 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8338 mType = type;
8339 mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8340 break;
8341 case LSCP_EMIT_BYTE_CODE:
8342 {
8343 char jumpname1[32];
8344 sprintf(jumpname1, "##Temp Jump %d##", gTempJumpCount++);
8345 char jumpname2[32];
8346 sprintf(jumpname2, "##Temp Jump %d##", gTempJumpCount++);
8347
8348 chunk->addLabel(jumpname1);
8349 mExpression->recurse(fp, tabs, tabsize, LSCP_TO_STACK, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8350 chunk->addByte(LSCRIPTOpCodes[LOPC_JUMPNIF]);
8351 chunk->addByte(LSCRIPTTypeByte[mType]);
8352 chunk->addBytes(LSCRIPTDataSize[LST_INTEGER]);
8353 chunk->addJump(jumpname2);
8354 mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8355 chunk->addByte(LSCRIPTOpCodes[LOPC_JUMP]);
8356 chunk->addBytes(LSCRIPTDataSize[LST_INTEGER]);
8357 chunk->addJump(jumpname1);
8358 chunk->addLabel(jumpname2);
8359 }
8360 break;
8361 case LSCP_EMIT_CIL_ASSEMBLY:
8362 {
8363 S32 tjump1 = gTempJumpCount++;
8364 S32 tjump2 = gTempJumpCount++;
8365 fprintf(fp, "LabelTempJump%d:\n", tjump1);
8366 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8367 fprintf(fp, "brfalse LabelTempJump%d\n", tjump2);
8368 mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8369 fprintf(fp, "br LabelTempJump%d\n", tjump1);
8370 fprintf(fp, "LabelTempJump%d:\n", tjump2);
8371 }
8372 break;
8373 default:
8374 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8375 mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8376 break;
8377 }
8378 gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8379}
8380
8381S32 LLScriptDeclaration::getSize()
8382{
8383 return mType->getSize();
8384}
8385
8386void LLScriptDeclaration::recurse(FILE *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)
8387{
8388 if (gErrorToText.getErrors())
8389 {
8390 return;
8391 }
8392 switch(pass)
8393 {
8394 case LSCP_PRETTY_PRINT:
8395 if (mExpression)
8396 {
8397 fdotabs(fp, tabs, tabsize);
8398 mType->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8399 fprintf(fp, "\t");
8400 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8401 fprintf(fp, " = ");
8402 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8403 fprintf(fp, ";\n");
8404 }
8405 else
8406 {
8407 fdotabs(fp, tabs, tabsize);
8408 mType->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8409 fprintf(fp, "\t");
8410 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8411 fprintf(fp, ";\n");
8412 }
8413 break;
8414 case LSCP_EMIT_ASSEMBLY:
8415 if (mExpression)
8416 {
8417 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8418 if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
8419 {
8420 fprintf(fp, "%s%d [%s]\n", LSCRIPTTypeLocalDeclaration[mIdentifier->mScopeEntry->mType], mIdentifier->mScopeEntry->mOffset, mIdentifier->mName);
8421 }
8422 else if (mIdentifier->mScopeEntry->mIDType == LIT_GLOBAL)
8423 {
8424 gErrorToText.writeError(fp, this, LSERROR_UNDEFINED_NAME);
8425 }
8426 }
8427 break;
8428 case LSCP_PRUNE:
8429 if (ptype == LSPRUNE_DEAD_CODE)
8430 prunearg = TRUE;
8431 else
8432 prunearg = FALSE;
8433 break;
8434 case LSCP_SCOPE_PASS1:
8435 // Check to see if a declaration is valid here.
8436 if (!mAllowDeclarations)
8437 {
8438 gErrorToText.writeError(fp, this, LSERROR_NEED_NEW_SCOPE);
8439 }
8440 // add labels to scope
8441 else if (scope->checkEntry(mIdentifier->mName))
8442 {
8443 gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
8444 }
8445 else
8446 {
8447 if (mExpression)
8448 {
8449 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8450 }
8451 // this needs to go after expression decent to make sure that we don't add ourselves or something silly
8452 // check expression if it exists
8453 mIdentifier->mScopeEntry = scope->addEntry(mIdentifier->mName, LIT_VARIABLE, mType->mType);
8454 }
8455 break;
8456 case LSCP_TYPE:
8457 // if there is an expression, it must be promotable to variable type
8458 if (mExpression && mIdentifier->mScopeEntry)
8459 {
8460 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8461 if (!legal_assignment(mIdentifier->mScopeEntry->mType, type))
8462 {
8463 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
8464 }
8465 }
8466 break;
8467 case LSCP_RESOURCE:
8468 {
8469 mIdentifier->mScopeEntry->mOffset = (S32)count;
8470 mIdentifier->mScopeEntry->mSize = mType->getSize();
8471 count += mIdentifier->mScopeEntry->mSize;
8472 // Index into locals is current number of locals. Stored in mCount member of mScopeEntry.
8473 mIdentifier->mScopeEntry->mCount = entry->mLocals.getNumber();
8474 entry->mLocals.addType(mType->mType);
8475 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8476 }
8477 break;
8478 case LSCP_EMIT_BYTE_CODE:
8479 if (mExpression)
8480 {
8481 mExpression->recurse(fp, tabs, tabsize, LSCP_TO_STACK, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8482 if (mExpression->mReturnType != mIdentifier->mScopeEntry->mType)
8483 {
8484 cast2stack(chunk, mExpression->mReturnType, mIdentifier->mScopeEntry->mType);
8485 }
8486 switch(mExpression->mReturnType)
8487 {
8488 case LST_INTEGER:
8489 case LST_FLOATINGPOINT:
8490 if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
8491 {
8492 chunk->addByte(LSCRIPTOpCodes[LOPC_LOADP]);
8493 }
8494 break;
8495 case LST_STRING:
8496 case LST_KEY:
8497 if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
8498 {
8499 chunk->addByte(LSCRIPTOpCodes[LOPC_LOADSP]);
8500 }
8501 break;
8502 case LST_LIST:
8503 if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
8504 {
8505 chunk->addByte(LSCRIPTOpCodes[LOPC_LOADLP]);
8506 }
8507 break;
8508 case LST_VECTOR:
8509 if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
8510 {
8511 chunk->addByte(LSCRIPTOpCodes[LOPC_LOADVP]);
8512 }
8513 break;
8514 case LST_QUATERNION:
8515 if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
8516 {
8517 chunk->addByte(LSCRIPTOpCodes[LOPC_LOADQP]);
8518 }
8519 break;
8520 default:
8521 if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
8522 {
8523 chunk->addByte(LSCRIPTOpCodes[LOPC_LOADP]);
8524 }
8525 break;
8526 }
8527 if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
8528 {
8529 S32 address = mIdentifier->mScopeEntry->mOffset;
8530 chunk->addInteger(address);
8531 }
8532 }
8533 else
8534 {
8535 switch(mIdentifier->mScopeEntry->mType)
8536 {
8537 case LST_INTEGER:
8538 case LST_FLOATINGPOINT:
8539 if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
8540 {
8541 chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGI]);
8542 chunk->addInteger(0);
8543 chunk->addByte(LSCRIPTOpCodes[LOPC_LOADP]);
8544 }
8545 break;
8546 case LST_STRING:
8547 case LST_KEY:
8548 if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
8549 {
8550 chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGS]);
8551 chunk->addBytes("", 1);
8552 chunk->addByte(LSCRIPTOpCodes[LOPC_LOADSP]);
8553 }
8554 break;
8555 case LST_LIST:
8556 if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
8557 {
8558 chunk->addByte(LSCRIPTOpCodes[LOPC_STACKTOL]);
8559 chunk->addInteger(0);
8560 chunk->addByte(LSCRIPTOpCodes[LOPC_LOADLP]);
8561 }
8562 break;
8563 case LST_VECTOR:
8564 if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
8565 {
8566 chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGV]);
8567 chunk->addFloat(0);
8568 chunk->addFloat(0);
8569 chunk->addFloat(0);
8570 chunk->addByte(LSCRIPTOpCodes[LOPC_LOADVP]);
8571 }
8572 break;
8573 case LST_QUATERNION:
8574 if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
8575 {
8576 chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGQ]);
8577 chunk->addFloat(1);
8578 chunk->addFloat(0);
8579 chunk->addFloat(0);
8580 chunk->addFloat(0);
8581 chunk->addByte(LSCRIPTOpCodes[LOPC_LOADQP]);
8582 }
8583 break;
8584 default:
8585 if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
8586 {
8587 chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGI]);
8588 chunk->addInteger(0);
8589 chunk->addByte(LSCRIPTOpCodes[LOPC_LOADP]);
8590 }
8591 break;
8592 }
8593 if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
8594 {
8595 S32 address = mIdentifier->mScopeEntry->mOffset;
8596 chunk->addInteger(address);
8597 }
8598 }
8599 break;
8600 case LSCP_EMIT_CIL_ASSEMBLY:
8601 if (mExpression)
8602 {
8603 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8604 if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
8605 {
8606 if(is_parameter(mIdentifier, entry))
8607 {
8608 // Parameter, store by name.
8609 fprintf(fp, "starg.s %s\n", mIdentifier->mScopeEntry->mIdentifier);
8610 }
8611 else
8612 {
8613 // Local, store by index.
8614 fprintf(fp, "stloc.s %d\n", mIdentifier->mScopeEntry->mCount);
8615 }
8616 }
8617 else if (mIdentifier->mScopeEntry->mIDType == LIT_GLOBAL)
8618 {
8619 gErrorToText.writeError(fp, this, LSERROR_UNDEFINED_NAME);
8620 }
8621 }
8622 break;
8623 default:
8624 if (mExpression)
8625 {
8626 mType->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8627 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8628 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8629 }
8630 else
8631 {
8632 mType->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8633 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8634 }
8635 break;
8636 }
8637 gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8638}
8639
8640S32 LLScriptCompoundStatement::getSize()
8641{
8642 return 0;
8643}
8644
8645void LLScriptCompoundStatement::recurse(FILE *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)
8646{
8647 if (gErrorToText.getErrors())
8648 {
8649 return;
8650 }
8651 switch(pass)
8652 {
8653 case LSCP_PRETTY_PRINT:
8654 if (mStatement)
8655 {
8656 fdotabs(fp, tabs, tabsize);
8657 fprintf(fp, "{\n");
8658 mStatement->recurse(fp, tabs + 1, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8659 fdotabs(fp, tabs, tabsize);
8660 fprintf(fp, "}\n");
8661 }
8662 else
8663 {
8664 fdotabs(fp, tabs, tabsize);
8665 fprintf(fp, "{\n");
8666 fdotabs(fp, tabs, tabsize);
8667 fprintf(fp, "}\n");
8668 }
8669 break;
8670 case LSCP_EMIT_ASSEMBLY:
8671 if (mStatement)
8672 {
8673 mStatement->recurse(fp, tabs + 1, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8674 }
8675 break;
8676 case LSCP_PRUNE:
8677 if (mStatement)
8678 {
8679 mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8680 }
8681 else
8682 {
8683 prunearg = FALSE;
8684 }
8685 break;
8686 case LSCP_SCOPE_PASS1:
8687 // compound statements create a new scope
8688 if (mStatement)
8689 {
8690 mStatementScope = new LLScriptScope(gScopeStringTable);
8691 mStatementScope->addParentScope(scope);
8692 mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, mStatementScope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8693 }
8694 break;
8695 case LSCP_SCOPE_PASS2:
8696 // compound statements create a new scope
8697 if (mStatement)
8698 {
8699 mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, mStatementScope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8700 }
8701 break;
8702 default:
8703 if (mStatement)
8704 {
8705 mStatement->recurse(fp, tabs + 1, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8706 }
8707 break;
8708 }
8709 gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8710}
8711
8712void LLScriptEventHandler::addEvent(LLScriptEventHandler *event)
8713{
8714 if (mNextp)
8715 {
8716 event->mNextp = mNextp;
8717 }
8718 mNextp = event;
8719}
8720
8721void LLScriptEventHandler::gonext(FILE *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)
8722{
8723 if (gErrorToText.getErrors())
8724 {
8725 return;
8726 }
8727 switch(pass)
8728 {
8729 case LSCP_PRETTY_PRINT:
8730 if (mNextp)
8731 {
8732 mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8733 }
8734 break;
8735 default:
8736 if (mNextp)
8737 {
8738 mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8739 }
8740 break;
8741 }
8742}
8743
8744S32 LLScriptEventHandler::getSize()
8745{
8746 return mStackSpace;
8747}
8748
8749U64 gCurrentHandler = 0;
8750
8751void print_cil_local_init(FILE* fp, LLScriptScopeEntry* scopeEntry)
8752{
8753 if(scopeEntry->mLocals.getNumber() > 0)
8754 {
8755 fprintf(fp, ".locals init (");
8756 for(int local = 0; local < scopeEntry->mLocals.getNumber(); ++local)
8757 {
8758 if(local > 0)
8759 {
8760 fprintf(fp, ", ");
8761 }
8762 print_cil_type(fp, scopeEntry->mLocals.getType(local));
8763 }
8764 fprintf(fp, ")\n");
8765 }
8766}
8767
8768void LLScriptEventHandler::recurse(FILE *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)
8769{
8770 if (gErrorToText.getErrors())
8771 {
8772 return;
8773 }
8774 switch(pass)
8775 {
8776 case LSCP_PRETTY_PRINT:
8777 mEventp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8778 if (mStatement)
8779 {
8780 mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8781 }
8782 else
8783 {
8784 fdotabs(fp, tabs, tabsize);
8785 fprintf(fp, "{\n");
8786 fdotabs(fp, tabs, tabsize);
8787 fprintf(fp, "}\n");
8788 }
8789 break;
8790 case LSCP_EMIT_ASSEMBLY:
8791 mEventp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8792 if (mStatement)
8793 {
8794 mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, getSize(), mScopeEntry, entrycount, NULL);
8795 }
8796 if (mbNeedTrailingReturn)
8797 {
8798 print_return(fp, mScopeEntry);
8799 }
8800 fprintf(fp, "\n");
8801 break;
8802 case LSCP_PRUNE:
8803 mbNeedTrailingReturn = FALSE;
8804 prunearg = TRUE;
8805 mStatement->recurse(fp, tabs, tabsize, pass, LSPRUNE_EVENTS, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8806 if (!prunearg)
8807 {
8808 // this means that we didn't end with a return statement, need to add one
8809 mbNeedTrailingReturn = TRUE;
8810 }
8811 break;
8812 case LSCP_SCOPE_PASS1:
8813 // create event level scope
8814 mEventScope = new LLScriptScope(gScopeStringTable);
8815 mEventScope->addParentScope(scope);
8816
8817 // add event parameters
8818 mEventp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, mEventScope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8819
8820 mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, mEventScope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8821 break;
8822 case LSCP_SCOPE_PASS2:
8823 mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, mEventScope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8824 break;
8825 case LSCP_TYPE:
8826 mScopeEntry = new LLScriptScopeEntry("Event", LIT_HANDLER, LST_NULL);
8827 switch(mEventp->mType)
8828 {
8829 case LSTT_STATE_ENTRY:
8830 break;
8831 case LSTT_STATE_EXIT:
8832 break;
8833 case LSTT_TOUCH_START:
8834 mScopeEntry->mFunctionArgs.addType(LST_INTEGER);
8835 break;
8836 case LSTT_TOUCH:
8837 mScopeEntry->mFunctionArgs.addType(LST_INTEGER);
8838 break;
8839 case LSTT_TOUCH_END:
8840 mScopeEntry->mFunctionArgs.addType(LST_INTEGER);
8841 break;
8842 case LSTT_COLLISION_START:
8843 mScopeEntry->mFunctionArgs.addType(LST_INTEGER);
8844 break;
8845 case LSTT_COLLISION:
8846 mScopeEntry->mFunctionArgs.addType(LST_INTEGER);
8847 break;
8848 case LSTT_COLLISION_END:
8849 mScopeEntry->mFunctionArgs.addType(LST_INTEGER);
8850 break;
8851 case LSTT_LAND_COLLISION_START:
8852 mScopeEntry->mFunctionArgs.addType(LST_VECTOR);
8853 break;
8854 case LSTT_LAND_COLLISION:
8855 mScopeEntry->mFunctionArgs.addType(LST_VECTOR);
8856 break;
8857 case LSTT_LAND_COLLISION_END:
8858 mScopeEntry->mFunctionArgs.addType(LST_VECTOR);
8859 break;
8860 case LSTT_INVENTORY:
8861 mScopeEntry->mFunctionArgs.addType(LST_INTEGER);
8862 break;
8863 case LSTT_ATTACH:
8864 mScopeEntry->mFunctionArgs.addType(LST_KEY);
8865 break;
8866 case LSTT_DATASERVER:
8867 mScopeEntry->mFunctionArgs.addType(LST_KEY);
8868 mScopeEntry->mFunctionArgs.addType(LST_STRING);
8869 break;
8870 case LSTT_TIMER:
8871 break;
8872 case LSTT_MOVING_START:
8873 break;
8874 case LSTT_MOVING_END:
8875 break;
8876 case LSTT_OBJECT_REZ:
8877 mScopeEntry->mFunctionArgs.addType(LST_KEY);
8878 break;
8879 case LSTT_REMOTE_DATA:
8880 mScopeEntry->mFunctionArgs.addType(LST_INTEGER);
8881 mScopeEntry->mFunctionArgs.addType(LST_KEY);
8882 mScopeEntry->mFunctionArgs.addType(LST_KEY);
8883 mScopeEntry->mFunctionArgs.addType(LST_STRING);
8884 mScopeEntry->mFunctionArgs.addType(LST_INTEGER);
8885 mScopeEntry->mFunctionArgs.addType(LST_STRING);
8886 break;
8887 case LSTT_CHAT:
8888 mScopeEntry->mFunctionArgs.addType(LST_INTEGER);
8889 mScopeEntry->mFunctionArgs.addType(LST_STRING);
8890 mScopeEntry->mFunctionArgs.addType(LST_KEY);
8891 mScopeEntry->mFunctionArgs.addType(LST_STRING);
8892 break;
8893 case LSTT_SENSOR:
8894 mScopeEntry->mFunctionArgs.addType(LST_INTEGER);
8895 break;
8896 case LSTT_CONTROL:
8897 mScopeEntry->mFunctionArgs.addType(LST_KEY);
8898 mScopeEntry->mFunctionArgs.addType(LST_INTEGER);
8899 mScopeEntry->mFunctionArgs.addType(LST_INTEGER);
8900 break;
8901 case LSTT_LINK_MESSAGE:
8902 mScopeEntry->mFunctionArgs.addType(LST_INTEGER);
8903 mScopeEntry->mFunctionArgs.addType(LST_INTEGER);
8904 mScopeEntry->mFunctionArgs.addType(LST_STRING);
8905 mScopeEntry->mFunctionArgs.addType(LST_KEY);
8906 break;
8907 case LSTT_MONEY:
8908 mScopeEntry->mFunctionArgs.addType(LST_KEY);
8909 mScopeEntry->mFunctionArgs.addType(LST_INTEGER);
8910 break;
8911 case LSTT_EMAIL:
8912 mScopeEntry->mFunctionArgs.addType(LST_STRING);
8913 mScopeEntry->mFunctionArgs.addType(LST_STRING);
8914 mScopeEntry->mFunctionArgs.addType(LST_STRING);
8915 mScopeEntry->mFunctionArgs.addType(LST_STRING);
8916 mScopeEntry->mFunctionArgs.addType(LST_INTEGER);
8917 break;
8918 case LSTT_REZ:
8919 mScopeEntry->mFunctionArgs.addType(LST_INTEGER);
8920 break;
8921 case LSTT_NO_SENSOR:
8922 break;
8923 case LSTT_AT_TARGET:
8924 mScopeEntry->mFunctionArgs.addType(LST_INTEGER);
8925 mScopeEntry->mFunctionArgs.addType(LST_VECTOR);
8926 mScopeEntry->mFunctionArgs.addType(LST_VECTOR);
8927 break;
8928 case LSTT_NOT_AT_TARGET:
8929 break;
8930 case LSTT_AT_ROT_TARGET:
8931 mScopeEntry->mFunctionArgs.addType(LST_INTEGER);
8932 mScopeEntry->mFunctionArgs.addType(LST_QUATERNION);
8933 mScopeEntry->mFunctionArgs.addType(LST_QUATERNION);
8934 break;
8935 case LSTT_NOT_AT_ROT_TARGET:
8936 break;
8937 case LSTT_RTPERMISSIONS:
8938 mScopeEntry->mFunctionArgs.addType(LST_INTEGER);
8939 break;
8940 case LSTT_HTTP_RESPONSE:
8941 mScopeEntry->mFunctionArgs.addType(LST_KEY);
8942 mScopeEntry->mFunctionArgs.addType(LST_INTEGER);
8943 mScopeEntry->mFunctionArgs.addType(LST_LIST);
8944 mScopeEntry->mFunctionArgs.addType(LST_STRING);
8945 break;
8946
8947 default:
8948 break;
8949 }
8950 mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8951 break;
8952 case LSCP_RESOURCE:
8953 // first determine resource counts for globals
8954 count = 0;
8955 mEventp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
8956 if (mStatement)
8957 {
8958 entrycount = 0;
8959 mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, mScopeEntry, entrycount, NULL);
8960 fprintf(fp, "Function Args: %s\n", mScopeEntry->mFunctionArgs.mString);
8961 fprintf(fp, "Local List: %s\n", mScopeEntry->mLocals.mString);
8962 }
8963 mStackSpace = (S32)count;
8964 break;
8965 case LSCP_DETERMINE_HANDLERS:
8966 count |= LSCRIPTStateBitField[mEventp->mType];
8967 break;
8968 case LSCP_EMIT_BYTE_CODE:
8969 {
8970 // order for event handler
8971 // set jump table value
8972 S32 jumpoffset;
8973 jumpoffset = LSCRIPTDataSize[LST_INTEGER]*get_event_handler_jump_position(gCurrentHandler, mEventp->mType)*2;
8974
8975 integer2bytestream(chunk->mCodeChunk, jumpoffset, chunk->mCurrentOffset);
8976
8977 // 0 - 3: offset to actual data
8978 S32 offsetoffset = chunk->mCurrentOffset;
8979 S32 offsetdelta = 0;
8980 chunk->addBytes(4);
8981
8982 // null terminated event name and null terminated parameters
8983 if (mEventp)
8984 {
8985 LLScriptByteCodeChunk *event = new LLScriptByteCodeChunk(FALSE);
8986 mEventp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, event, heap, stacksize, entry, entrycount, NULL);
8987 chunk->addBytes(event->mCodeChunk, event->mCurrentOffset);
8988 delete event;
8989 }
8990 chunk->addBytes(1);
8991
8992 // now we're at the first opcode
8993 offsetdelta = chunk->mCurrentOffset - offsetoffset;
8994 integer2bytestream(chunk->mCodeChunk, offsetoffset, offsetdelta);
8995
8996 // get ready to compute the number of bytes of opcode
8997 offsetdelta = chunk->mCurrentOffset;
8998
8999 if (mStatement)
9000 {
9001 LLScriptByteCodeChunk *statements = new LLScriptByteCodeChunk(TRUE);
9002 mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, statements, heap, getSize(), mScopeEntry, entrycount, NULL);
9003 statements->connectJumps();
9004 chunk->addBytes(statements->mCodeChunk, statements->mCurrentOffset);
9005 delete statements;
9006 }
9007 if (mbNeedTrailingReturn)
9008 {
9009 add_return(chunk, mScopeEntry);
9010 }
9011 // now stuff in the number of bytes of stack space that this routine needs
9012 integer2bytestream(chunk->mCodeChunk, jumpoffset, getSize());
9013 }
9014 break;
9015 case LSCP_EMIT_CIL_ASSEMBLY:
9016
9017 // Method signature prefix.
9018 fprintf(fp, ".method public hidebysig instance default void ");
9019
9020 // Mangle event handler name by prefixing it with state name. Allows state changing by finding handlers prefixed with new state name.
9021 fprintf(fp, entry->mIdentifier);
9022
9023 // Handler name and arguments.
9024 mEventp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9025
9026 // Method signature postfix.
9027 fprintf(fp, " cil managed\n");
9028
9029 // Function header.
9030 fprintf(fp,"{\n");
9031 fprintf(fp, ".maxstack 500\n"); // TODO: Calculated stack size...
9032
9033 // Allocate space for locals.
9034 print_cil_local_init(fp, mScopeEntry);
9035
9036 if (mStatement)
9037 {
9038 // Pass scope so identifiers can determine parameter or local.
9039 mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, mScopeEntry, entrycount, NULL);
9040 }
9041
9042 // Function footer.
9043 fprintf(fp, "\nret\n"); // TODO: Check whether return needed?
9044 fprintf(fp, "}\n");
9045
9046 break;
9047 default:
9048 mEventp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9049 if (mStatement)
9050 {
9051 mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9052 }
9053 break;
9054 }
9055 gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9056}
9057
9058void LLScriptFunctionDec::addFunctionParameter(LLScriptFunctionDec *dec)
9059{
9060 if (mNextp)
9061 {
9062 dec->mNextp = mNextp;
9063 }
9064 mNextp = dec;
9065}
9066
9067void LLScriptFunctionDec::gonext(FILE *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)
9068{
9069 if (gErrorToText.getErrors())
9070 {
9071 return;
9072 }
9073 switch(pass)
9074 {
9075 case LSCP_PRETTY_PRINT:
9076 if (mNextp)
9077 {
9078 fprintf(fp, ", ");
9079 mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9080 }
9081 break;
9082 case LSCP_EMIT_ASSEMBLY:
9083 if (mNextp)
9084 {
9085 fprintf(fp, ", ");
9086 mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9087 }
9088 break;
9089 default:
9090 if (mNextp)
9091 {
9092 mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9093 }
9094 break;
9095 }
9096
9097}
9098
9099S32 LLScriptFunctionDec::getSize()
9100{
9101 return 0;
9102}
9103
9104void LLScriptFunctionDec::recurse(FILE *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)
9105{
9106 if (gErrorToText.getErrors())
9107 {
9108 return;
9109 }
9110 switch(pass)
9111 {
9112 case LSCP_PRETTY_PRINT:
9113 fdotabs(fp, tabs, tabsize);
9114 mType->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9115 fprintf(fp, " ");
9116 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9117 break;
9118 case LSCP_EMIT_ASSEMBLY:
9119 mType->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9120 fprintf(fp, " ");
9121 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9122 break;
9123 case LSCP_SCOPE_PASS1:
9124 // add function names into global scope
9125 if (scope->checkEntry(mIdentifier->mName))
9126 {
9127 gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
9128 }
9129 else
9130 {
9131 mIdentifier->mScopeEntry = scope->addEntry(mIdentifier->mName, LIT_VARIABLE, mType->mType);
9132 }
9133 break;
9134 case LSCP_RESOURCE:
9135 {
9136 // we're just tryng to determine how much space the variable needs
9137 mIdentifier->mScopeEntry->mOffset = (S32)count;
9138 mIdentifier->mScopeEntry->mSize = mType->getSize();
9139 count += mIdentifier->mScopeEntry->mSize;
9140 }
9141 break;
9142 case LSCP_EMIT_BYTE_CODE:
9143 {
9144 // return type
9145 char typereturn;
9146 if (mType)
9147 {
9148 typereturn = LSCRIPTTypeByte[mType->mType];
9149 }
9150 else
9151 {
9152 typereturn = LSCRIPTTypeByte[LST_NULL];
9153 }
9154 chunk->addBytes(&typereturn, 1);
9155 // name
9156#ifdef LSL_INCLUDE_DEBUG_INFO
9157 chunk->addBytes(mIdentifier->mName, strlen(mIdentifier->mName) + 1);
9158#else
9159 chunk->addBytes(1);
9160#endif
9161 }
9162 break;
9163 case LSCP_BUILD_FUNCTION_ARGS:
9164 {
9165 entry->mFunctionArgs.addType(mType->mType);
9166 }
9167 break;
9168 case LSCP_EMIT_CIL_ASSEMBLY:
9169 mType->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9170 fprintf(fp, " ");
9171 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9172 break;
9173 default:
9174 mType->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9175 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9176 break;
9177 }
9178 gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9179}
9180
9181void LLScriptGlobalFunctions::addGlobalFunction(LLScriptGlobalFunctions *global)
9182{
9183 if (mNextp)
9184 {
9185 global->mNextp = mNextp;
9186 }
9187 mNextp = global;
9188}
9189
9190void LLScriptGlobalFunctions::gonext(FILE *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)
9191{
9192 if (gErrorToText.getErrors())
9193 {
9194 return;
9195 }
9196 switch(pass)
9197 {
9198 case LSCP_PRETTY_PRINT:
9199 if (mNextp)
9200 {
9201 mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9202 }
9203 break;
9204 default:
9205 if (mNextp)
9206 {
9207 mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9208 }
9209 break;
9210 }
9211}
9212
9213S32 LLScriptGlobalFunctions::getSize()
9214{
9215 return 0;
9216}
9217
9218void LLScriptGlobalFunctions::recurse(FILE *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)
9219{
9220 if (gErrorToText.getErrors())
9221 {
9222 return;
9223 }
9224 switch(pass)
9225 {
9226 case LSCP_PRETTY_PRINT:
9227 fdotabs(fp, tabs, tabsize);
9228 if (mType)
9229 {
9230 mType->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9231 fprintf(fp, "\t");
9232 }
9233 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9234 if (mParameters)
9235 {
9236 fprintf(fp, "( ");
9237 mParameters->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9238 fprintf(fp, " )\n");
9239 }
9240 else
9241 {
9242 fprintf(fp, "()\n");
9243 }
9244 if (mStatements)
9245 {
9246 fdotabs(fp, tabs, tabsize);
9247 mStatements->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, mIdentifier->mScopeEntry, entrycount, NULL);
9248 }
9249 else
9250 {
9251 fdotabs(fp, tabs, tabsize);
9252 fprintf(fp, "{\n");
9253 fdotabs(fp, tabs, tabsize);
9254 fprintf(fp, "}\n");
9255 }
9256 break;
9257 case LSCP_EMIT_ASSEMBLY:
9258 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9259 if (mParameters)
9260 {
9261 fprintf(fp, "( ");
9262 mParameters->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9263 fprintf(fp, " )\n");
9264 }
9265 else
9266 {
9267 fprintf(fp, "()\n");
9268 }
9269 if (mStatements)
9270 {
9271 mStatements->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, mIdentifier->mScopeEntry->mSize, mIdentifier->mScopeEntry, entrycount, NULL);
9272 }
9273 if (mbNeedTrailingReturn)
9274 {
9275 print_return(fp, mIdentifier->mScopeEntry);
9276 }
9277 fprintf(fp, "\n");
9278 break;
9279 case LSCP_PRUNE:
9280 mbNeedTrailingReturn = FALSE;
9281 if (mType)
9282 {
9283 prunearg = TRUE;
9284 mStatements->recurse(fp, tabs, tabsize, pass, LSPRUNE_GLOBAL_NON_VOIDS, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9285 if (!prunearg)
9286 {
9287 gErrorToText.writeError(fp, this, LSERROR_NO_RETURN);
9288 }
9289 }
9290 else
9291 {
9292 prunearg = TRUE;
9293 mStatements->recurse(fp, tabs, tabsize, pass, LSPRUNE_GLOBAL_VOIDS, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9294 if (!prunearg)
9295 {
9296 // this means that we didn't end with a return statement, need to add one
9297 mbNeedTrailingReturn = TRUE;
9298 }
9299 }
9300 break;
9301 case LSCP_SCOPE_PASS1:
9302 // add function names into global scope
9303 if (scope->checkEntry(mIdentifier->mName))
9304 {
9305 gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
9306 }
9307 else
9308 {
9309 if (mType)
9310 {
9311 mIdentifier->mScopeEntry = scope->addEntry(mIdentifier->mName, LIT_FUNCTION, mType->mType);
9312 }
9313 else
9314 {
9315 mIdentifier->mScopeEntry = scope->addEntry(mIdentifier->mName, LIT_FUNCTION, LST_NULL);
9316 }
9317 }
9318
9319 // create function level scope
9320 mFunctionScope = new LLScriptScope(gScopeStringTable);
9321 mFunctionScope->addParentScope(scope);
9322
9323 // function parameters
9324 if (mParameters)
9325 {
9326 mParameters->recurse(fp, tabs, tabsize, pass, ptype, prunearg, mFunctionScope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9327 }
9328
9329 mStatements->recurse(fp, tabs, tabsize, pass, ptype, prunearg, mFunctionScope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9330 break;
9331 case LSCP_SCOPE_PASS2:
9332 mStatements->recurse(fp, tabs, tabsize, pass, ptype, prunearg, mFunctionScope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9333
9334 if (mParameters)
9335 {
9336 if (mIdentifier->mScopeEntry)
9337 {
9338 mParameters->recurse(fp, tabs, tabsize, LSCP_BUILD_FUNCTION_ARGS, ptype, prunearg, mFunctionScope, type, basetype, count, chunk, heap, stacksize, mIdentifier->mScopeEntry, 0, NULL);
9339 }
9340 }
9341 break;
9342 case LSCP_TYPE:
9343 if (mType)
9344 {
9345 mStatements->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, mType->mType, count, chunk, heap, stacksize, entry, entrycount, NULL);
9346 }
9347 else
9348 {
9349 type = LST_NULL;
9350 mStatements->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9351 }
9352 break;
9353 case LSCP_RESOURCE:
9354 // first determine resource counts for globals
9355 count = 0;
9356
9357 if (mParameters)
9358 {
9359 mParameters->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9360 }
9361
9362 if (mIdentifier->mScopeEntry)
9363 {
9364 // this isn't a bug . . . Offset is used to determine how much is params vs locals
9365 mIdentifier->mScopeEntry->mOffset = (S32)count;
9366 }
9367
9368 if (mStatements)
9369 {
9370 entrycount = 0;
9371 mStatements->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, mIdentifier->mScopeEntry, entrycount, NULL);
9372 fprintf(fp, "Function Args: %s\n", mIdentifier->mScopeEntry->mFunctionArgs.mString);
9373 fprintf(fp, "Local List: %s\n", mIdentifier->mScopeEntry->mLocals.mString);
9374 if (mIdentifier->mScopeEntry)
9375 {
9376 mIdentifier->mScopeEntry->mSize = (S32)count;
9377 }
9378 }
9379 break;
9380 case LSCP_EMIT_BYTE_CODE:
9381 {
9382 // order for global functions
9383 // set jump table value
9384 S32 jumpoffset = LSCRIPTDataSize[LST_INTEGER]*mIdentifier->mScopeEntry->mCount + LSCRIPTDataSize[LST_INTEGER];
9385 integer2bytestream(chunk->mCodeChunk, jumpoffset, chunk->mCurrentOffset);
9386
9387 // 0 - 3: offset to actual data
9388 S32 offsetoffset = chunk->mCurrentOffset;
9389 S32 offsetdelta = 0;
9390 chunk->addBytes(4);
9391
9392 // null terminated function name
9393#ifdef LSL_INCLUDE_DEBUG_INFO
9394 chunk->addBytes(mIdentifier->mName, strlen(mIdentifier->mName) + 1);
9395#else
9396 chunk->addBytes(1);
9397#endif
9398 // return type
9399 char typereturn;
9400 if (mType)
9401 {
9402 typereturn = LSCRIPTTypeByte[mType->mType];
9403 }
9404 else
9405 {
9406 typereturn = LSCRIPTTypeByte[LST_NULL];
9407 }
9408 chunk->addBytes(&typereturn, 1);
9409
9410 // null terminated parameters, followed by type
9411 if (mParameters)
9412 {
9413 LLScriptByteCodeChunk *params = new LLScriptByteCodeChunk(FALSE);
9414 mParameters->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, params, heap, stacksize, entry, entrycount, NULL);
9415 chunk->addBytes(params->mCodeChunk, params->mCurrentOffset);
9416 delete params;
9417 }
9418 chunk->addBytes(1);
9419
9420 // now we're at the first opcode
9421 offsetdelta = chunk->mCurrentOffset - offsetoffset;
9422 integer2bytestream(chunk->mCodeChunk, offsetoffset, offsetdelta);
9423
9424 if (mStatements)
9425 {
9426 LLScriptByteCodeChunk *statements = new LLScriptByteCodeChunk(TRUE);
9427 mStatements->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, statements, heap, mIdentifier->mScopeEntry->mSize, mIdentifier->mScopeEntry, entrycount, NULL);
9428 statements->connectJumps();
9429 chunk->addBytes(statements->mCodeChunk, statements->mCurrentOffset);
9430 delete statements;
9431 }
9432 if (mbNeedTrailingReturn)
9433 {
9434 add_return(chunk, mIdentifier->mScopeEntry);
9435 }
9436 }
9437 break;
9438 case LSCP_EMIT_CIL_ASSEMBLY:
9439 {
9440 // Function header.
9441 fprintf(fp, ".method public hidebysig instance default ");
9442 print_cil_type(fp, mType ? mType->mType : LST_NULL);
9443 fprintf(fp, " ");
9444 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9445 if (mParameters)
9446 {
9447 fprintf(fp, "( ");
9448 mParameters->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9449 fprintf(fp, " )");
9450 }
9451 else
9452 {
9453 fprintf(fp, "()");
9454 }
9455 fprintf(fp, " cil managed\n{\n");
9456 fprintf(fp, ".maxstack 500\n"); // TODO: Calculated stack size...
9457
9458 // Allocate space for locals.
9459 print_cil_local_init(fp, mIdentifier->mScopeEntry);
9460
9461 if (mStatements)
9462 {
9463 mStatements->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, mIdentifier->mScopeEntry->mSize, mIdentifier->mScopeEntry, entrycount, NULL);
9464 }
9465
9466 // Function footer.
9467 if (mbNeedTrailingReturn)
9468 {
9469 fprintf(fp, "ret\n");
9470 }
9471 fprintf(fp, "}\n");
9472 fprintf(fp, "\n");
9473 }
9474 break;
9475 default:
9476 if (mType)
9477 {
9478 mType->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9479 }
9480 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9481 if (mParameters)
9482 {
9483 mParameters->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9484 }
9485 if (mStatements)
9486 {
9487 mStatements->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9488 }
9489 break;
9490 }
9491 gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9492}
9493
9494void LLScriptState::addState(LLScriptState *state)
9495{
9496 if (mNextp)
9497 {
9498 state->mNextp = mNextp;
9499 }
9500 mNextp = state;
9501}
9502
9503void LLScriptState::gonext(FILE *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)
9504{
9505 if (gErrorToText.getErrors())
9506 {
9507 return;
9508 }
9509 switch(pass)
9510 {
9511 case LSCP_PRETTY_PRINT:
9512 if (mNextp)
9513 {
9514 mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9515 }
9516 break;
9517 default:
9518 if (mNextp)
9519 {
9520 mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9521 }
9522 break;
9523 }
9524}
9525
9526S32 LLScriptState::getSize()
9527{
9528 return 0;
9529}
9530
9531void LLScriptState::recurse(FILE *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)
9532{
9533 if (gErrorToText.getErrors())
9534 {
9535 return;
9536 }
9537 switch(pass)
9538 {
9539 case LSCP_PRETTY_PRINT:
9540 fdotabs(fp, tabs, tabsize);
9541 if (mType == LSSTYPE_DEFAULT)
9542 {
9543 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9544 fprintf(fp, "\n");
9545 fdotabs(fp, tabs, tabsize);
9546 fprintf(fp, "{\n");
9547 }
9548 else
9549 {
9550 fprintf(fp, "state ");
9551 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9552 fprintf(fp, "\n");
9553 fdotabs(fp, tabs, tabsize);
9554 fprintf(fp, "{\n");
9555 }
9556 if (mEvent)
9557 {
9558 mEvent->recurse(fp, tabs + 1, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9559 }
9560 fdotabs(fp, tabs, tabsize);
9561 fprintf(fp, "}\n");
9562 break;
9563 case LSCP_EMIT_ASSEMBLY:
9564 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9565 fprintf(fp, ":\n");
9566 if (mEvent)
9567 {
9568 fprintf(fp, "EVENTS\n");
9569 mEvent->recurse(fp, tabs + 1, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9570 fprintf(fp, "\n");
9571 }
9572 break;
9573 case LSCP_SCOPE_PASS1:
9574 // add state name
9575 if (scope->checkEntry(mIdentifier->mName))
9576 {
9577 gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
9578 }
9579 else
9580 {
9581 mIdentifier->mScopeEntry = scope->addEntry(mIdentifier->mName, LIT_STATE, LST_NULL);
9582 }
9583 // now do the events
9584 if (mEvent)
9585 {
9586 mEvent->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9587 }
9588 break;
9589 case LSCP_SCOPE_PASS2:
9590 if (mEvent)
9591 {
9592 mEvent->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9593 }
9594 break;
9595 case LSCP_TYPE:
9596 if (mEvent)
9597 {
9598 mEvent->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9599 }
9600 break;
9601 case LSCP_EMIT_BYTE_CODE:
9602 {
9603 // order for states
9604 // set jump table value
9605
9606 S32 jumpoffset;
9607 if (LSL2_CURRENT_MAJOR_VERSION == LSL2_MAJOR_VERSION_TWO)
9608 {
9609 jumpoffset = LSCRIPTDataSize[LST_INTEGER]*3*mIdentifier->mScopeEntry->mCount + LSCRIPTDataSize[LST_INTEGER];
9610 }
9611 else
9612 {
9613 jumpoffset = LSCRIPTDataSize[LST_INTEGER]*2*mIdentifier->mScopeEntry->mCount + LSCRIPTDataSize[LST_INTEGER];
9614 }
9615 integer2bytestream(chunk->mCodeChunk, jumpoffset, chunk->mCurrentOffset);
9616
9617 // need to figure out what handlers this state has registered
9618 // we'll use to count to find it
9619 count = 0;
9620
9621 if (mEvent)
9622 {
9623 mEvent->recurse(fp, tabs, tabsize, LSCP_DETERMINE_HANDLERS, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9624 gCurrentHandler = count;
9625 }
9626
9627 // add description word into chunk
9628 if (LSL2_CURRENT_MAJOR_VERSION == LSL2_MAJOR_VERSION_TWO)
9629 {
9630 u642bytestream(chunk->mCodeChunk, jumpoffset, gCurrentHandler);
9631 }
9632 else
9633 {
9634 integer2bytestream(chunk->mCodeChunk, jumpoffset, (S32)gCurrentHandler);
9635 }
9636
9637
9638 // 0 - 3: offset to event jump table
9639 S32 offsetoffset = chunk->mCurrentOffset;
9640 S32 offsetdelta = 0;
9641 chunk->addBytes(4);
9642
9643 // null terminated state name
9644#ifdef LSL_INCLUDE_DEBUG_INFO
9645 chunk->addBytes(mIdentifier->mName, strlen(mIdentifier->mName) + 1);
9646#else
9647 chunk->addBytes(1);
9648#endif
9649 // now we're at the jump table
9650 offsetdelta = chunk->mCurrentOffset - offsetoffset;
9651 integer2bytestream(chunk->mCodeChunk, offsetoffset, offsetdelta);
9652
9653 // add the events themselves
9654 if (mEvent)
9655 {
9656 LLScriptByteCodeChunk *events = new LLScriptByteCodeChunk(FALSE);
9657 // make space for event jump table
9658 events->addBytes(LSCRIPTDataSize[LST_INTEGER]*get_number_of_event_handlers(gCurrentHandler)*2);
9659 mEvent->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, events, heap, stacksize, entry, entrycount, NULL);
9660 chunk->addBytes(events->mCodeChunk, events->mCurrentOffset);
9661 delete events;
9662 }
9663 }
9664 break;
9665 case LSCP_EMIT_CIL_ASSEMBLY:
9666 if (mEvent)
9667 {
9668 // Entry not used at this level, so pass state scope as entry parameter, to allow event handlers to do name mangling.
9669 mEvent->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, mIdentifier->mScopeEntry, entrycount, NULL);
9670 }
9671 break;
9672 default:
9673 if (mType == LSSTYPE_DEFAULT)
9674 {
9675 }
9676 else
9677 {
9678 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9679 }
9680 if (mEvent)
9681 {
9682 mEvent->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9683 }
9684 break;
9685 }
9686 gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9687}
9688
9689S32 LLScriptScript::getSize()
9690{
9691 return 0;
9692}
9693
9694LLScriptScript::LLScriptScript(LLScritpGlobalStorage *globals,
9695 LLScriptState *states) :
9696 LLScriptFilePosition(0, 0),
9697 mStates(states), mGlobalScope(NULL), mGlobals(NULL), mGlobalFunctions(NULL), mGodLike(FALSE)
9698{
9699 const char DEFAULT_BYTECODE_FILENAME[] = "lscript.lso";
9700 strcpy(mBytecodeDest, DEFAULT_BYTECODE_FILENAME);
9701
9702 LLScriptGlobalVariable *tvar;
9703 LLScriptGlobalFunctions *tfunc;
9704 LLScritpGlobalStorage *temp;
9705
9706 temp = globals;
9707 while(temp)
9708 {
9709 if (temp->mbGlobalFunction)
9710 {
9711 if (!mGlobalFunctions)
9712 {
9713 mGlobalFunctions = (LLScriptGlobalFunctions *)temp->mGlobal;
9714 }
9715 else
9716 {
9717 tfunc = mGlobalFunctions;
9718 while(tfunc->mNextp)
9719 {
9720 tfunc = tfunc->mNextp;
9721 }
9722 tfunc->mNextp = (LLScriptGlobalFunctions *)temp->mGlobal;
9723 }
9724 }
9725 else
9726 {
9727 if (!mGlobals)
9728 {
9729 mGlobals = (LLScriptGlobalVariable *)temp->mGlobal;
9730 }
9731 else
9732 {
9733 tvar = mGlobals;
9734 while(tvar->mNextp)
9735 {
9736 tvar = tvar->mNextp;
9737 }
9738 tvar->mNextp = (LLScriptGlobalVariable *)temp->mGlobal;
9739 }
9740 }
9741 temp = temp->mNextp;
9742 }
9743}
9744
9745void LLScriptScript::setBytecodeDest(const char* dst_filename)
9746{
9747 strncpy(mBytecodeDest, dst_filename, MAX_STRING);
9748 mBytecodeDest[MAX_STRING-1] = '\0';
9749}
9750
9751void print_cil_globals(FILE* fp, LLScriptGlobalVariable* global)
9752{
9753 fprintf(fp, ".field private ");
9754 print_cil_type(fp, global->mType->mType);
9755 fprintf(fp, " ");
9756 fprintf(fp, global->mIdentifier->mName);
9757 fprintf(fp, "\n");
9758 if(NULL != global->mNextp)
9759 {
9760 print_cil_globals(fp, global->mNextp);
9761 }
9762}
9763
9764void LLScriptScript::recurse(FILE *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)
9765{
9766 if (gErrorToText.getErrors())
9767 {
9768 return;
9769 }
9770 switch(pass)
9771 {
9772 case LSCP_PRETTY_PRINT:
9773 if (mGlobals)
9774 {
9775 fdotabs(fp, tabs, tabsize);
9776 mGlobals->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9777 }
9778
9779 if (mGlobalFunctions)
9780 {
9781 fdotabs(fp, tabs, tabsize);
9782 mGlobalFunctions->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9783 }
9784
9785 fdotabs(fp, tabs, tabsize);
9786 mStates->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9787 break;
9788 case LSCP_PRUNE:
9789 if (mGlobalFunctions)
9790 {
9791 mGlobalFunctions->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9792 }
9793 mStates->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9794 break;
9795 case LSCP_SCOPE_PASS1:
9796 {
9797 mGlobalScope = new LLScriptScope(gScopeStringTable);
9798 // zeroth, add library functions to global scope
9799 S32 i;
9800 char *arg;
9801 LLScriptScopeEntry *sentry;
9802 for (i = 0; i < gScriptLibrary.mNextNumber; i++)
9803 {
9804 // First, check to make sure this isn't a god only function, or that the viewer's agent is a god.
9805 if (!gScriptLibrary.mFunctions[i]->mGodOnly || mGodLike)
9806 {
9807 if (gScriptLibrary.mFunctions[i]->mReturnType)
9808 sentry = mGlobalScope->addEntry(gScriptLibrary.mFunctions[i]->mName, LIT_LIBRARY_FUNCTION, char2type(*gScriptLibrary.mFunctions[i]->mReturnType));
9809 else
9810 sentry = mGlobalScope->addEntry(gScriptLibrary.mFunctions[i]->mName, LIT_LIBRARY_FUNCTION, LST_NULL);
9811 sentry->mLibraryNumber = i;
9812 arg = gScriptLibrary.mFunctions[i]->mArgs;
9813 if (arg)
9814 {
9815 while (*arg)
9816 {
9817 sentry->mFunctionArgs.addType(char2type(*arg));
9818 sentry->mSize += LSCRIPTDataSize[char2type(*arg)];
9819 sentry->mOffset += LSCRIPTDataSize[char2type(*arg)];
9820 arg++;
9821 }
9822 }
9823 }
9824 }
9825 // first go and collect all the global variables
9826 if (mGlobals)
9827 mGlobals->recurse(fp, tabs, tabsize, pass, ptype, prunearg, mGlobalScope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9828 // second, do the global functions
9829 if (mGlobalFunctions)
9830 mGlobalFunctions->recurse(fp, tabs, tabsize, pass, ptype, prunearg, mGlobalScope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9831 // now do states
9832 mStates->recurse(fp, tabs, tabsize, pass, ptype, prunearg, mGlobalScope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9833 break;
9834 }
9835 case LSCP_SCOPE_PASS2:
9836 // now we're checking jumps, function calls, and state transitions
9837 if (mGlobalFunctions)
9838 mGlobalFunctions->recurse(fp, tabs, tabsize, pass, ptype, prunearg, mGlobalScope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9839 mStates->recurse(fp, tabs, tabsize, pass, ptype, prunearg, mGlobalScope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9840 break;
9841 case LSCP_TYPE:
9842 // first we need to check global variables
9843 if (mGlobals)
9844 mGlobals->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9845 // now do global functions and states
9846 if (mGlobalFunctions)
9847 mGlobalFunctions->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9848 mStates->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9849 break;
9850 case LSCP_RESOURCE:
9851 // first determine resource counts for globals
9852 count = 0;
9853 if (mGlobals)
9854 mGlobals->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9855 // now do locals
9856 if (mGlobalFunctions)
9857 mGlobalFunctions->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9858 mStates->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9859 break;
9860 case LSCP_EMIT_ASSEMBLY:
9861
9862 if (mGlobals)
9863 {
9864 fprintf(fp, "GLOBALS\n");
9865 fdotabs(fp, tabs, tabsize);
9866 mGlobals->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9867 fprintf(fp, "\n");
9868 }
9869
9870 if (mGlobalFunctions)
9871 {
9872 fprintf(fp, "GLOBAL FUNCTIONS\n");
9873 fdotabs(fp, tabs, tabsize);
9874 mGlobalFunctions->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9875 fprintf(fp, "\n");
9876 }
9877
9878 fprintf(fp, "STATES\n");
9879 fdotabs(fp, tabs, tabsize);
9880 mStates->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9881 fprintf(fp, "\n");
9882 break;
9883 case LSCP_EMIT_BYTE_CODE:
9884 {
9885 // first, create data structure to hold the whole shebang
9886 LLScriptScriptCodeChunk *code = new LLScriptScriptCodeChunk(TOP_OF_MEMORY);
9887
9888 // ok, let's add the registers, all zeroes for now
9889 S32 i;
9890 S32 nooffset = 0;
9891
9892 for (i = LREG_IP; i < LREG_EOF; i++)
9893 {
9894 if (i < LREG_NCE)
9895 code->mRegisters->addBytes(4);
9896 else if (LSL2_CURRENT_MAJOR_VERSION == LSL2_MAJOR_VERSION_TWO)
9897 code->mRegisters->addBytes(8);
9898 }
9899 // global variables
9900 if (mGlobals)
9901 mGlobals->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, code->mGlobalVariables, code->mHeap, stacksize, entry, entrycount, NULL);
9902
9903 // put the ending heap block onto the heap
9904 U8 *temp;
9905 S32 size = lsa_create_data_block(&temp, NULL, 0);
9906 code->mHeap->addBytes(temp, size);
9907 delete [] temp;
9908
9909 // global functions
9910 // make space for global function jump table
9911 if (mGlobalFunctions)
9912 {
9913 code->mGlobalFunctions->addBytes(LSCRIPTDataSize[LST_INTEGER]*mGlobalScope->mFunctionCount + LSCRIPTDataSize[LST_INTEGER]);
9914 integer2bytestream(code->mGlobalFunctions->mCodeChunk, nooffset, mGlobalScope->mFunctionCount);
9915 mGlobalFunctions->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, code->mGlobalFunctions, NULL, stacksize, entry, entrycount, NULL);
9916 }
9917
9918
9919 nooffset = 0;
9920 // states
9921 // make space for state jump/info table
9922 if (LSL2_CURRENT_MAJOR_VERSION == LSL2_MAJOR_VERSION_TWO)
9923 {
9924 code->mStates->addBytes(LSCRIPTDataSize[LST_INTEGER]*3*mGlobalScope->mStateCount + LSCRIPTDataSize[LST_INTEGER]);
9925 }
9926 else
9927 {
9928 code->mStates->addBytes(LSCRIPTDataSize[LST_INTEGER]*2*mGlobalScope->mStateCount + LSCRIPTDataSize[LST_INTEGER]);
9929 }
9930 integer2bytestream(code->mStates->mCodeChunk, nooffset, mGlobalScope->mStateCount);
9931 mStates->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, code->mStates, NULL, stacksize, entry, entrycount, NULL);
9932
9933 // now, put it all together and spit it out
9934 // we need
9935 FILE *bcfp = LLFile::fopen(mBytecodeDest, "wb");
9936
9937 code->build(fp, bcfp);
9938 fclose(bcfp);
9939 }
9940 break;
9941 case LSCP_EMIT_CIL_ASSEMBLY:
9942
9943 // Output dependencies.
9944 fprintf(fp, ".assembly extern mscorlib {.ver 1:0:5000:0}\n");
9945 fprintf(fp, ".assembly extern LScriptLibrary {.ver 0:0:0:0}\n");
9946
9947 // Output assembly name.
9948 fprintf(fp, ".assembly 'lsl' {.ver 0:0:0:0}\n");
9949
9950 // Output class header.
9951 fprintf(fp, ".class public auto ansi beforefieldinit LSL extends [mscorlib]System.Object\n");
9952 fprintf(fp, "{\n");
9953
9954 // Output globals as members.
9955 if(NULL != mGlobals)
9956 {
9957 print_cil_globals(fp, mGlobals);
9958 }
9959
9960 // Output "runtime". Only needed to allow stand alone execution. Not needed when compiling to DLL and using embedded runtime.
9961 fprintf(fp, ".method public static hidebysig default void Main () cil managed\n");
9962 fprintf(fp, "{\n");
9963 fprintf(fp, ".entrypoint\n");
9964 fprintf(fp, ".maxstack 2\n");
9965 fprintf(fp, ".locals init (class LSL V_0)\n");
9966 fprintf(fp, "newobj instance void class LSL::.ctor()\n");
9967 fprintf(fp, "stloc.0\n");
9968 fprintf(fp, "ldloc.0\n");
9969 fprintf(fp, "callvirt instance void class LSL::defaultstate_entry()\n");
9970 fprintf(fp, "ret\n");
9971 fprintf(fp, "}\n");
9972
9973 // Output ctor header.
9974 fprintf(fp, ".method public hidebysig specialname rtspecialname instance default void .ctor () cil managed\n");
9975 fprintf(fp, "{\n");
9976 fprintf(fp, ".maxstack 500\n");
9977
9978 // Initialise globals as members in ctor.
9979 if (mGlobals)
9980 {
9981 fdotabs(fp, tabs, tabsize);
9982 mGlobals->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9983 fprintf(fp, "\n");
9984 }
9985
9986 // Output ctor footer.
9987 fprintf(fp, "ldarg.0\n");
9988 fprintf(fp, "call instance void valuetype [mscorlib]System.Object::.ctor()\n");
9989 fprintf(fp, "ret\n");
9990 fprintf(fp, "}\n");
9991
9992 // Output functions as methods.
9993 if (mGlobalFunctions)
9994 {
9995 fdotabs(fp, tabs, tabsize);
9996 mGlobalFunctions->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
9997 fprintf(fp, "\n");
9998 }
9999
10000 // Output states as name mangled methods.
10001 fdotabs(fp, tabs, tabsize);
10002 mStates->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
10003 fprintf(fp, "\n");
10004
10005 // Output class footer.
10006 fprintf(fp, "}\n");
10007
10008 break;
10009 default:
10010 if (mGlobals)
10011 mGlobals->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
10012 if (mGlobalFunctions)
10013 mGlobalFunctions->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
10014 mStates->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
10015 break;
10016 }
10017}
diff --git a/linden/indra/lscript/lscript_compile/lscript_tree.h b/linden/indra/lscript/lscript_compile/lscript_tree.h
new file mode 100644
index 0000000..a535e76
--- /dev/null
+++ b/linden/indra/lscript/lscript_compile/lscript_tree.h
@@ -0,0 +1,2298 @@
1/**
2 * @file lscript_tree.h
3 * @brief provides the classes required to build lscript's abstract syntax tree and symbol table
4 *
5 * Copyright (c) 2002-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28#ifndef LL_LSCRIPT_TREE_H
29#define LL_LSCRIPT_TREE_H
30
31#include <stdio.h>
32#include "stdtypes.h"
33#include "v3math.h"
34#include "llquaternion.h"
35#include "linked_lists.h"
36#include "lscript_error.h"
37#include "lscript_typecheck.h"
38#include "lscript_byteformat.h"
39
40
41// Nota Bene: Class destructors don't delete pointed to classes because it isn't guaranteed that lex/yacc will build
42// complete data structures. Instead various chunks that are allocated are stored and deleted by allocation lists
43
44class LLScriptType : public LLScriptFilePosition
45{
46public:
47 LLScriptType(S32 line, S32 col, LSCRIPTType type)
48 : LLScriptFilePosition(line, col), mType(type)
49 {
50 }
51
52 ~LLScriptType() {}
53
54 void recurse(FILE *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);
55 S32 getSize();
56
57 LSCRIPTType mType;
58};
59
60// contains a literal or constant value
61class LLScriptConstant : public LLScriptFilePosition
62{
63public:
64 LLScriptConstant(S32 line, S32 col, LSCRIPTType type)
65 : LLScriptFilePosition(line, col), mType(type)
66 {
67 }
68
69 virtual ~LLScriptConstant() {}
70
71 void recurse(FILE *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);
72 S32 getSize();
73
74 LSCRIPTType mType;
75};
76
77class LLScriptConstantInteger : public LLScriptConstant
78{
79public:
80 LLScriptConstantInteger(S32 line, S32 col, S32 value)
81 : LLScriptConstant(line, col, LST_INTEGER), mValue(value)
82 {
83 }
84
85 ~LLScriptConstantInteger() {}
86
87 void recurse(FILE *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);
88 S32 getSize();
89
90 S32 mValue;
91};
92
93class LLScriptConstantFloat : public LLScriptConstant
94{
95public:
96 LLScriptConstantFloat(S32 line, S32 col, F32 value)
97 : LLScriptConstant(line, col, LST_FLOATINGPOINT), mValue(value)
98 {
99 }
100
101 ~LLScriptConstantFloat() {}
102
103 void recurse(FILE *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);
104 S32 getSize();
105
106 F32 mValue;
107};
108
109class LLScriptConstantString : public LLScriptConstant
110{
111public:
112 LLScriptConstantString(S32 line, S32 col, char *value)
113 : LLScriptConstant(line, col, LST_STRING), mValue(value)
114 {
115 }
116
117 ~LLScriptConstantString()
118 {
119 delete [] mValue;
120 mValue = NULL;
121 }
122
123 void recurse(FILE *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);
124 S32 getSize();
125
126 char *mValue;
127};
128
129// container for individual identifiers
130class LLScriptIdentifier : public LLScriptFilePosition
131{
132public:
133 LLScriptIdentifier(S32 line, S32 col, char *name, LLScriptType *type = NULL)
134 : LLScriptFilePosition(line, col), mName(name), mScopeEntry(NULL), mType(type)
135 {
136 }
137
138 ~LLScriptIdentifier()
139 {
140 delete [] mName;
141 mName = NULL;
142 }
143
144 void recurse(FILE *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);
145 S32 getSize();
146
147 char *mName;
148 LLScriptScopeEntry *mScopeEntry;
149 LLScriptType *mType;
150};
151
152typedef enum e_lscript_simple_assignable_type
153{
154 LSSAT_NULL,
155 LSSAT_IDENTIFIER,
156 LSSAT_CONSTANT,
157 LSSAT_VECTOR_CONSTANT,
158 LSSAT_QUATERNION_CONSTANT,
159 LSSAT_LIST_CONSTANT,
160 LSSAT_EOF
161} LSCRIPTSimpleAssignableType;
162
163class LLScriptSimpleAssignable : public LLScriptFilePosition
164{
165public:
166 LLScriptSimpleAssignable(S32 line, S32 col, LSCRIPTSimpleAssignableType type)
167 : LLScriptFilePosition(line, col), mType(type), mNextp(NULL)
168 {
169 }
170
171 void addAssignable(LLScriptSimpleAssignable *assign);
172
173 virtual ~LLScriptSimpleAssignable()
174 {
175 // don't delete next pointer because we're going to store allocation lists and delete from those
176 }
177
178 void recurse(FILE *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);
179 S32 getSize();
180
181 LSCRIPTSimpleAssignableType mType;
182 LLScriptSimpleAssignable *mNextp;
183};
184
185class LLScriptSAIdentifier : public LLScriptSimpleAssignable
186{
187public:
188 LLScriptSAIdentifier(S32 line, S32 col, LLScriptIdentifier *identifier)
189 : LLScriptSimpleAssignable(line, col, LSSAT_IDENTIFIER), mIdentifier(identifier)
190 {
191 }
192
193 ~LLScriptSAIdentifier()
194 {
195 }
196
197 void recurse(FILE *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);
198 S32 getSize();
199
200 LLScriptIdentifier *mIdentifier;
201};
202
203class LLScriptSAConstant : public LLScriptSimpleAssignable
204{
205public:
206 LLScriptSAConstant(S32 line, S32 col, LLScriptConstant *constant)
207 : LLScriptSimpleAssignable(line, col, LSSAT_CONSTANT), mConstant(constant)
208 {
209 }
210
211 ~LLScriptSAConstant()
212 {
213 }
214
215 void recurse(FILE *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);
216 S32 getSize();
217
218 LLScriptConstant *mConstant;
219};
220
221class LLScriptSAVector : public LLScriptSimpleAssignable
222{
223public:
224 LLScriptSAVector(S32 line, S32 col, LLScriptSimpleAssignable *e1,
225 LLScriptSimpleAssignable *e2,
226 LLScriptSimpleAssignable *e3)
227 : LLScriptSimpleAssignable(line, col, LSSAT_VECTOR_CONSTANT),
228 mEntry1(e1), mEntry2(e2), mEntry3(e3)
229 {
230 }
231
232 ~LLScriptSAVector()
233 {
234 }
235
236 void recurse(FILE *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);
237 S32 getSize();
238
239 LLScriptSimpleAssignable *mEntry1;
240 LLScriptSimpleAssignable *mEntry2;
241 LLScriptSimpleAssignable *mEntry3;
242};
243
244class LLScriptSAQuaternion : public LLScriptSimpleAssignable
245{
246public:
247 LLScriptSAQuaternion(S32 line, S32 col, LLScriptSimpleAssignable *e1,
248 LLScriptSimpleAssignable *e2,
249 LLScriptSimpleAssignable *e3,
250 LLScriptSimpleAssignable *e4)
251 : LLScriptSimpleAssignable(line, col, LSSAT_QUATERNION_CONSTANT),
252 mEntry1(e1), mEntry2(e2), mEntry3(e3), mEntry4(e4)
253 {
254 }
255
256 ~LLScriptSAQuaternion()
257 {
258 }
259
260 void recurse(FILE *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);
261 S32 getSize();
262
263 LLScriptSimpleAssignable *mEntry1;
264 LLScriptSimpleAssignable *mEntry2;
265 LLScriptSimpleAssignable *mEntry3;
266 LLScriptSimpleAssignable *mEntry4;
267};
268
269class LLScriptSAList : public LLScriptSimpleAssignable
270{
271public:
272 LLScriptSAList(S32 line, S32 col, LLScriptSimpleAssignable *elist)
273 : LLScriptSimpleAssignable(line, col, LSSAT_QUATERNION_CONSTANT), mEntryList(elist)
274 {
275 }
276
277 ~LLScriptSAList()
278 {
279 }
280
281 void recurse(FILE *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);
282 S32 getSize();
283
284 LLScriptSimpleAssignable *mEntryList;
285};
286
287// global variables
288class LLScriptGlobalVariable : public LLScriptFilePosition
289{
290public:
291 LLScriptGlobalVariable(S32 line, S32 col, LLScriptType *type,
292 LLScriptIdentifier *identifier,
293 LLScriptSimpleAssignable *assignable)
294 : LLScriptFilePosition(line, col), mType(type), mIdentifier(identifier), mAssignable(assignable), mNextp(NULL), mAssignableType(LST_NULL)
295 {
296 }
297
298 void addGlobal(LLScriptGlobalVariable *global);
299
300 ~LLScriptGlobalVariable()
301 {
302 }
303
304 void gonext(FILE *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);
305
306 void recurse(FILE *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);
307 S32 getSize();
308
309 LLScriptType *mType;
310 LLScriptIdentifier *mIdentifier;
311 LLScriptSimpleAssignable *mAssignable;
312 LLScriptGlobalVariable *mNextp;
313 LSCRIPTType mAssignableType;
314};
315
316// events
317
318class LLScriptEvent : public LLScriptFilePosition
319{
320public:
321 LLScriptEvent(S32 line, S32 col, LSCRIPTStateEventType type)
322 : LLScriptFilePosition(line, col), mType(type)
323 {
324 }
325
326 virtual ~LLScriptEvent()
327 {
328 // don't delete next pointer because we're going to store allocation lists and delete from those
329 }
330
331 void recurse(FILE *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);
332 S32 getSize();
333
334 LSCRIPTStateEventType mType;
335};
336
337class LLScriptStateEntryEvent : public LLScriptEvent
338{
339public:
340 LLScriptStateEntryEvent(S32 line, S32 col)
341 : LLScriptEvent(line, col, LSTT_STATE_ENTRY)
342 {
343 }
344
345 void recurse(FILE *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);
346 S32 getSize();
347
348 ~LLScriptStateEntryEvent() {}
349};
350
351class LLScriptStateExitEvent : public LLScriptEvent
352{
353public:
354 LLScriptStateExitEvent(S32 line, S32 col)
355 : LLScriptEvent(line, col, LSTT_STATE_EXIT)
356 {
357 }
358
359 ~LLScriptStateExitEvent() {}
360
361 void recurse(FILE *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);
362 S32 getSize();
363};
364
365class LLScriptTouchStartEvent : public LLScriptEvent
366{
367public:
368 LLScriptTouchStartEvent(S32 line, S32 col, LLScriptIdentifier *count)
369 : LLScriptEvent(line, col, LSTT_TOUCH_START), mCount(count)
370 {
371 }
372
373 ~LLScriptTouchStartEvent()
374 {
375 }
376
377 void recurse(FILE *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);
378 S32 getSize();
379
380 LLScriptIdentifier *mCount;
381};
382
383class LLScriptTouchEvent : public LLScriptEvent
384{
385public:
386 LLScriptTouchEvent(S32 line, S32 col, LLScriptIdentifier *count)
387 : LLScriptEvent(line, col, LSTT_TOUCH), mCount(count)
388 {
389 }
390
391 ~LLScriptTouchEvent()
392 {
393 }
394
395 void recurse(FILE *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);
396 S32 getSize();
397
398 LLScriptIdentifier *mCount;
399};
400
401class LLScriptTouchEndEvent : public LLScriptEvent
402{
403public:
404 LLScriptTouchEndEvent(S32 line, S32 col, LLScriptIdentifier *count)
405 : LLScriptEvent(line, col, LSTT_TOUCH_END), mCount(count)
406 {
407 }
408
409 ~LLScriptTouchEndEvent()
410 {
411 }
412
413 void recurse(FILE *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 S32 getSize();
415
416 LLScriptIdentifier *mCount;
417};
418
419class LLScriptCollisionStartEvent : public LLScriptEvent
420{
421public:
422 LLScriptCollisionStartEvent(S32 line, S32 col, LLScriptIdentifier *count)
423 : LLScriptEvent(line, col, LSTT_COLLISION_START), mCount(count)
424 {
425 }
426
427 ~LLScriptCollisionStartEvent()
428 {
429 }
430
431 void recurse(FILE *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 S32 getSize();
433
434 LLScriptIdentifier *mCount;
435};
436
437class LLScriptCollisionEvent : public LLScriptEvent
438{
439public:
440 LLScriptCollisionEvent(S32 line, S32 col, LLScriptIdentifier *count)
441 : LLScriptEvent(line, col, LSTT_COLLISION), mCount(count)
442 {
443 }
444
445 ~LLScriptCollisionEvent()
446 {
447 }
448
449 void recurse(FILE *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);
450 S32 getSize();
451
452 LLScriptIdentifier *mCount;
453};
454
455class LLScriptCollisionEndEvent : public LLScriptEvent
456{
457public:
458 LLScriptCollisionEndEvent(S32 line, S32 col, LLScriptIdentifier *count)
459 : LLScriptEvent(line, col, LSTT_COLLISION_END), mCount(count)
460 {
461 }
462
463 ~LLScriptCollisionEndEvent()
464 {
465 }
466
467 void recurse(FILE *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);
468 S32 getSize();
469
470 LLScriptIdentifier *mCount;
471};
472
473class LLScriptLandCollisionStartEvent : public LLScriptEvent
474{
475public:
476 LLScriptLandCollisionStartEvent(S32 line, S32 col, LLScriptIdentifier *pos)
477 : LLScriptEvent(line, col, LSTT_LAND_COLLISION_START), mPosition(pos)
478 {
479 }
480
481 ~LLScriptLandCollisionStartEvent()
482 {
483 }
484
485 void recurse(FILE *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);
486 S32 getSize();
487
488 LLScriptIdentifier *mPosition;
489};
490
491class LLScriptLandCollisionEvent : public LLScriptEvent
492{
493public:
494 LLScriptLandCollisionEvent(S32 line, S32 col, LLScriptIdentifier *pos)
495 : LLScriptEvent(line, col, LSTT_LAND_COLLISION), mPosition(pos)
496 {
497 }
498
499 ~LLScriptLandCollisionEvent()
500 {
501 }
502
503 void recurse(FILE *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);
504 S32 getSize();
505
506 LLScriptIdentifier *mPosition;
507};
508
509class LLScriptLandCollisionEndEvent : public LLScriptEvent
510{
511public:
512 LLScriptLandCollisionEndEvent(S32 line, S32 col, LLScriptIdentifier *pos)
513 : LLScriptEvent(line, col, LSTT_LAND_COLLISION_END), mPosition(pos)
514 {
515 }
516
517 ~LLScriptLandCollisionEndEvent()
518 {
519 }
520
521 void recurse(FILE *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);
522 S32 getSize();
523
524 LLScriptIdentifier *mPosition;
525};
526
527class LLScriptInventoryEvent : public LLScriptEvent
528{
529public:
530 LLScriptInventoryEvent(S32 line, S32 col, LLScriptIdentifier *change)
531 : LLScriptEvent(line, col, LSTT_INVENTORY), mChange(change)
532 {
533 }
534
535 ~LLScriptInventoryEvent() {}
536
537 void recurse(FILE *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);
538 S32 getSize();
539
540 LLScriptIdentifier *mChange;
541};
542
543class LLScriptAttachEvent : public LLScriptEvent
544{
545public:
546 LLScriptAttachEvent(S32 line, S32 col, LLScriptIdentifier *attach)
547 : LLScriptEvent(line, col, LSTT_ATTACH), mAttach(attach)
548 {
549 }
550
551 ~LLScriptAttachEvent() {}
552
553 void recurse(FILE *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);
554 S32 getSize();
555
556 LLScriptIdentifier *mAttach;
557};
558
559class LLScriptDataserverEvent : public LLScriptEvent
560{
561public:
562 LLScriptDataserverEvent(S32 line, S32 col, LLScriptIdentifier *id, LLScriptIdentifier *data)
563 : LLScriptEvent(line, col, LSTT_DATASERVER), mID(id), mData(data)
564 {
565 }
566
567 ~LLScriptDataserverEvent() {}
568
569 void recurse(FILE *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);
570 S32 getSize();
571
572 LLScriptIdentifier *mID;
573 LLScriptIdentifier *mData;
574};
575
576class LLScriptTimerEvent : public LLScriptEvent
577{
578public:
579 LLScriptTimerEvent(S32 line, S32 col)
580 : LLScriptEvent(line, col, LSTT_TIMER)
581 {
582 }
583
584 ~LLScriptTimerEvent() {}
585
586 void recurse(FILE *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);
587 S32 getSize();
588};
589
590class LLScriptMovingStartEvent : public LLScriptEvent
591{
592public:
593 LLScriptMovingStartEvent(S32 line, S32 col)
594 : LLScriptEvent(line, col, LSTT_MOVING_START)
595 {
596 }
597
598 ~LLScriptMovingStartEvent() {}
599
600 void recurse(FILE *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);
601 S32 getSize();
602};
603
604class LLScriptMovingEndEvent : public LLScriptEvent
605{
606public:
607 LLScriptMovingEndEvent(S32 line, S32 col)
608 : LLScriptEvent(line, col, LSTT_MOVING_END)
609 {
610 }
611
612 ~LLScriptMovingEndEvent() {}
613
614 void recurse(FILE *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);
615 S32 getSize();
616};
617
618class LLScriptRTPEvent : public LLScriptEvent
619{
620public:
621 LLScriptRTPEvent(S32 line, S32 col, LLScriptIdentifier *rtperm)
622 : LLScriptEvent(line, col, LSTT_RTPERMISSIONS), mRTPermissions(rtperm)
623 {
624 }
625
626 ~LLScriptRTPEvent() {}
627
628 void recurse(FILE *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);
629 S32 getSize();
630
631 LLScriptIdentifier *mRTPermissions;
632};
633
634class LLScriptChatEvent : public LLScriptEvent
635{
636public:
637 LLScriptChatEvent(S32 line, S32 col, LLScriptIdentifier *channel, LLScriptIdentifier *name, LLScriptIdentifier *id, LLScriptIdentifier *message)
638 : LLScriptEvent(line, col, LSTT_CHAT), mChannel(channel), mName(name), mID(id), mMessage(message)
639 {
640 }
641
642 ~LLScriptChatEvent()
643 {
644 }
645
646 void recurse(FILE *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);
647 S32 getSize();
648
649 LLScriptIdentifier *mChannel;
650 LLScriptIdentifier *mName;
651 LLScriptIdentifier *mID;
652 LLScriptIdentifier *mMessage;
653};
654
655class LLScriptObjectRezEvent : public LLScriptEvent
656{
657public:
658 LLScriptObjectRezEvent(S32 line, S32 col, LLScriptIdentifier *id)
659 : LLScriptEvent(line, col, LSTT_OBJECT_REZ), mID(id)
660 {
661 }
662
663 ~LLScriptObjectRezEvent()
664 {
665 }
666
667 void recurse(FILE *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);
668 S32 getSize();
669
670 LLScriptIdentifier *mID;
671};
672
673class LLScriptSensorEvent : public LLScriptEvent
674{
675public:
676 LLScriptSensorEvent(S32 line, S32 col, LLScriptIdentifier *number)
677 : LLScriptEvent(line, col, LSTT_SENSOR), mNumber(number)
678 {
679 }
680
681 ~LLScriptSensorEvent()
682 {
683 }
684
685 void recurse(FILE *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);
686 S32 getSize();
687
688 LLScriptIdentifier *mNumber;
689};
690
691class LLScriptControlEvent : public LLScriptEvent
692{
693public:
694 LLScriptControlEvent(S32 line, S32 col, LLScriptIdentifier *name, LLScriptIdentifier *levels, LLScriptIdentifier *edges)
695 : LLScriptEvent(line, col, LSTT_CONTROL), mName(name), mLevels(levels), mEdges(edges)
696 {
697 }
698
699 ~LLScriptControlEvent()
700 {
701 }
702
703 void recurse(FILE *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);
704 S32 getSize();
705
706 LLScriptIdentifier *mName;
707 LLScriptIdentifier *mLevels;
708 LLScriptIdentifier *mEdges;
709};
710
711class LLScriptLinkMessageEvent : public LLScriptEvent
712{
713public:
714 LLScriptLinkMessageEvent(S32 line, S32 col, LLScriptIdentifier *sender, LLScriptIdentifier *num, LLScriptIdentifier *str, LLScriptIdentifier *id)
715 : LLScriptEvent(line, col, LSTT_LINK_MESSAGE), mSender(sender), mNum(num), mStr(str), mID(id)
716 {
717 }
718
719 ~LLScriptLinkMessageEvent()
720 {
721 }
722
723 void recurse(FILE *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);
724 S32 getSize();
725
726 LLScriptIdentifier *mSender;
727 LLScriptIdentifier *mNum;
728 LLScriptIdentifier *mStr;
729 LLScriptIdentifier *mID;
730};
731
732class LLScriptRemoteEvent : public LLScriptEvent
733{
734public:
735 LLScriptRemoteEvent(S32 line, S32 col, LLScriptIdentifier *type, LLScriptIdentifier *channel, LLScriptIdentifier *message_id, LLScriptIdentifier *sender, LLScriptIdentifier *int_val, LLScriptIdentifier *str_val)
736 : LLScriptEvent(line, col, LSTT_REMOTE_DATA), mType(type), mChannel(channel), mMessageID(message_id), mSender(sender), mIntVal(int_val), mStrVal(str_val)
737 {
738 }
739
740 ~LLScriptRemoteEvent()
741 {
742 }
743
744 void recurse(FILE *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);
745 S32 getSize();
746
747 LLScriptIdentifier *mType;
748 LLScriptIdentifier *mChannel;
749 LLScriptIdentifier *mMessageID;
750 LLScriptIdentifier *mSender;
751 LLScriptIdentifier *mIntVal;
752 LLScriptIdentifier *mStrVal;
753};
754
755class LLScriptHTTPResponseEvent : public LLScriptEvent
756{
757public:
758 LLScriptHTTPResponseEvent(S32 line, S32 col,
759 LLScriptIdentifier *reqeust_id,
760 LLScriptIdentifier *status,
761 LLScriptIdentifier *metadata,
762 LLScriptIdentifier *body)
763 : LLScriptEvent(line, col, LSTT_HTTP_RESPONSE),
764 mRequestId(reqeust_id), mStatus(status), mMetadata(metadata), mBody(body)
765 {
766 }
767
768 void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass,
769 LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope,
770 LSCRIPTType &type, LSCRIPTType basetype, U64 &count,
771 LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap,
772 S32 stacksize, LLScriptScopeEntry *entry,
773 S32 entrycount, LLScriptLibData **ldata);
774
775 S32 getSize();
776
777 LLScriptIdentifier *mRequestId;
778 LLScriptIdentifier *mStatus;
779 LLScriptIdentifier *mMetadata;
780 LLScriptIdentifier *mBody;
781};
782
783class LLScriptRezEvent : public LLScriptEvent
784{
785public:
786 LLScriptRezEvent(S32 line, S32 col, LLScriptIdentifier *start_param)
787 : LLScriptEvent(line, col, LSTT_REZ), mStartParam(start_param)
788 {
789 }
790 ~LLScriptRezEvent() {}
791
792 void recurse(FILE *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);
793 S32 getSize();
794
795 LLScriptIdentifier *mStartParam;
796};
797
798class LLScriptNoSensorEvent : public LLScriptEvent
799{
800public:
801 LLScriptNoSensorEvent(S32 line, S32 col)
802 : LLScriptEvent(line, col, LSTT_NO_SENSOR)
803 {
804 }
805
806 void recurse(FILE *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);
807 S32 getSize();
808
809 ~LLScriptNoSensorEvent() {}
810};
811
812class LLScriptAtTarget : public LLScriptEvent
813{
814public:
815 LLScriptAtTarget(S32 line, S32 col, LLScriptIdentifier *tnumber, LLScriptIdentifier *tpos, LLScriptIdentifier *ourpos)
816 : LLScriptEvent(line, col, LSTT_AT_TARGET), mTargetNumber(tnumber), mTargetPosition(tpos), mOurPosition(ourpos)
817 {
818 }
819
820 void recurse(FILE *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);
821 S32 getSize();
822
823 ~LLScriptAtTarget() {}
824
825 LLScriptIdentifier *mTargetNumber;
826 LLScriptIdentifier *mTargetPosition;
827 LLScriptIdentifier *mOurPosition;
828};
829
830class LLScriptNotAtTarget : public LLScriptEvent
831{
832public:
833 LLScriptNotAtTarget(S32 line, S32 col)
834 : LLScriptEvent(line, col, LSTT_NOT_AT_TARGET)
835 {
836 }
837
838 void recurse(FILE *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);
839 S32 getSize();
840
841 ~LLScriptNotAtTarget() {}
842};
843
844class LLScriptAtRotTarget : public LLScriptEvent
845{
846public:
847 LLScriptAtRotTarget(S32 line, S32 col, LLScriptIdentifier *tnumber, LLScriptIdentifier *trot, LLScriptIdentifier *ourrot)
848 : LLScriptEvent(line, col, LSTT_AT_ROT_TARGET), mTargetNumber(tnumber), mTargetRotation(trot), mOurRotation(ourrot)
849 {
850 }
851
852 void recurse(FILE *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);
853 S32 getSize();
854
855 ~LLScriptAtRotTarget() {}
856
857 LLScriptIdentifier *mTargetNumber;
858 LLScriptIdentifier *mTargetRotation;
859 LLScriptIdentifier *mOurRotation;
860};
861
862class LLScriptNotAtRotTarget : public LLScriptEvent
863{
864public:
865 LLScriptNotAtRotTarget(S32 line, S32 col)
866 : LLScriptEvent(line, col, LSTT_NOT_AT_ROT_TARGET)
867 {
868 }
869
870 void recurse(FILE *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);
871 S32 getSize();
872
873 ~LLScriptNotAtRotTarget() {}
874};
875
876class LLScriptMoneyEvent : public LLScriptEvent
877{
878public:
879 LLScriptMoneyEvent(S32 line, S32 col, LLScriptIdentifier *name, LLScriptIdentifier *amount)
880 : LLScriptEvent(line, col, LSTT_MONEY), mName(name), mAmount(amount)
881 {
882 }
883
884 ~LLScriptMoneyEvent()
885 {
886 }
887
888 void recurse(FILE *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);
889 S32 getSize();
890
891 LLScriptIdentifier *mName;
892 LLScriptIdentifier *mAmount;
893};
894
895class LLScriptEmailEvent : public LLScriptEvent
896{
897public:
898 LLScriptEmailEvent(S32 line, S32 col, LLScriptIdentifier *time, LLScriptIdentifier *address, LLScriptIdentifier *subject, LLScriptIdentifier *body, LLScriptIdentifier *number)
899 : LLScriptEvent(line, col, LSTT_EMAIL), mTime(time), mAddress(address), mSubject(subject), mBody(body), mNumber(number)
900 {
901 }
902
903 ~LLScriptEmailEvent()
904 {
905 }
906
907 void recurse(FILE *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);
908 S32 getSize();
909
910 LLScriptIdentifier *mTime;
911 LLScriptIdentifier *mAddress;
912 LLScriptIdentifier *mSubject;
913 LLScriptIdentifier *mBody;
914 LLScriptIdentifier *mNumber;
915};
916
917
918class LLScriptExpression : public LLScriptFilePosition
919{
920public:
921 LLScriptExpression(S32 line, S32 col, LSCRIPTExpressionType type)
922 : LLScriptFilePosition(line, col), mType(type), mNextp(NULL), mLeftType(LST_NULL), mRightType(LST_NULL), mReturnType(LST_NULL)
923 {
924 }
925
926 void addExpression(LLScriptExpression *expression);
927
928 virtual ~LLScriptExpression()
929 {
930 // don't delete next pointer because we're going to store allocation lists and delete from those
931 }
932
933 void recurse(FILE *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);
934
935 void gonext(FILE *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);
936 S32 getSize();
937
938 LSCRIPTExpressionType mType;
939 LLScriptExpression *mNextp;
940 LSCRIPTType mLeftType, mRightType, mReturnType;
941
942};
943
944class LLScriptForExpressionList : public LLScriptExpression
945{
946public:
947 LLScriptForExpressionList(S32 line, S32 col, LLScriptExpression *first, LLScriptExpression *second)
948 : LLScriptExpression(line, col, LET_FOR_EXPRESSION_LIST), mFirstp(first), mSecondp(second)
949 {
950 }
951
952 ~LLScriptForExpressionList()
953 {
954 }
955
956 void recurse(FILE *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);
957 S32 getSize();
958
959 LLScriptExpression *mFirstp;
960 LLScriptExpression *mSecondp;
961};
962
963class LLScriptFuncExpressionList : public LLScriptExpression
964{
965public:
966 LLScriptFuncExpressionList(S32 line, S32 col, LLScriptExpression *first, LLScriptExpression *second)
967 : LLScriptExpression(line, col, LET_FUNC_EXPRESSION_LIST), mFirstp(first), mSecondp(second)
968 {
969 }
970
971 ~LLScriptFuncExpressionList()
972 {
973 }
974
975 void recurse(FILE *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);
976 S32 getSize();
977
978 LLScriptExpression *mFirstp;
979 LLScriptExpression *mSecondp;
980};
981
982class LLScriptListExpressionList : public LLScriptExpression
983{
984public:
985 LLScriptListExpressionList(S32 line, S32 col, LLScriptExpression *first, LLScriptExpression *second)
986 : LLScriptExpression(line, col, LET_LIST_EXPRESSION_LIST), mFirstp(first), mSecondp(second)
987 {
988 }
989
990 ~LLScriptListExpressionList()
991 {
992 }
993
994 void recurse(FILE *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);
995 S32 getSize();
996
997 LLScriptExpression *mFirstp;
998 LLScriptExpression *mSecondp;
999};
1000
1001class LLScriptLValue : public LLScriptExpression
1002{
1003public:
1004 LLScriptLValue(S32 line, S32 col, LLScriptIdentifier *identifier, LLScriptIdentifier *accessor)
1005 : LLScriptExpression(line, col, LET_LVALUE), mOffset(0), mIdentifier(identifier), mAccessor(accessor)
1006 {
1007 }
1008
1009 ~LLScriptLValue()
1010 {
1011 }
1012
1013 void recurse(FILE *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);
1014 S32 getSize();
1015
1016 S32 mOffset;
1017 LLScriptIdentifier *mIdentifier;
1018 LLScriptIdentifier *mAccessor;
1019};
1020
1021class LLScriptAssignment : public LLScriptExpression
1022{
1023public:
1024 LLScriptAssignment(S32 line, S32 col, LLScriptExpression *lvalue, LLScriptExpression *rightside)
1025 : LLScriptExpression(line, col, LET_ASSIGNMENT), mLValue(lvalue), mRightSide(rightside)
1026 {
1027 }
1028
1029 ~LLScriptAssignment()
1030 {
1031 }
1032
1033 void recurse(FILE *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);
1034 S32 getSize();
1035
1036 LLScriptExpression *mLValue;
1037 LLScriptExpression *mRightSide;
1038};
1039
1040class LLScriptAddAssignment : public LLScriptExpression
1041{
1042public:
1043 LLScriptAddAssignment(S32 line, S32 col, LLScriptExpression *lvalue, LLScriptExpression *rightside)
1044 : LLScriptExpression(line, col, LET_ADD_ASSIGN), mLValue(lvalue), mRightSide(rightside)
1045 {
1046 }
1047
1048 ~LLScriptAddAssignment()
1049 {
1050 }
1051
1052 void recurse(FILE *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);
1053 S32 getSize();
1054
1055 LLScriptExpression *mLValue;
1056 LLScriptExpression *mRightSide;
1057};
1058
1059class LLScriptSubAssignment : public LLScriptExpression
1060{
1061public:
1062 LLScriptSubAssignment(S32 line, S32 col, LLScriptExpression *lvalue, LLScriptExpression *rightside)
1063 : LLScriptExpression(line, col, LET_SUB_ASSIGN), mLValue(lvalue), mRightSide(rightside)
1064 {
1065 }
1066
1067 ~LLScriptSubAssignment()
1068 {
1069 }
1070
1071 void recurse(FILE *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);
1072 S32 getSize();
1073
1074 LLScriptExpression *mLValue;
1075 LLScriptExpression *mRightSide;
1076};
1077
1078class LLScriptMulAssignment : public LLScriptExpression
1079{
1080public:
1081 LLScriptMulAssignment(S32 line, S32 col, LLScriptExpression *lvalue, LLScriptExpression *rightside)
1082 : LLScriptExpression(line, col, LET_MUL_ASSIGN), mLValue(lvalue), mRightSide(rightside)
1083 {
1084 }
1085
1086 ~LLScriptMulAssignment()
1087 {
1088 }
1089
1090 void recurse(FILE *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);
1091 S32 getSize();
1092
1093 LLScriptExpression *mLValue;
1094 LLScriptExpression *mRightSide;
1095};
1096
1097class LLScriptDivAssignment : public LLScriptExpression
1098{
1099public:
1100 LLScriptDivAssignment(S32 line, S32 col, LLScriptExpression *lvalue, LLScriptExpression *rightside)
1101 : LLScriptExpression(line, col, LET_DIV_ASSIGN), mLValue(lvalue), mRightSide(rightside)
1102 {
1103 }
1104
1105 ~LLScriptDivAssignment()
1106 {
1107 }
1108
1109 void recurse(FILE *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);
1110 S32 getSize();
1111
1112 LLScriptExpression *mLValue;
1113 LLScriptExpression *mRightSide;
1114};
1115
1116class LLScriptModAssignment : public LLScriptExpression
1117{
1118public:
1119 LLScriptModAssignment(S32 line, S32 col, LLScriptExpression *lvalue, LLScriptExpression *rightside)
1120 : LLScriptExpression(line, col, LET_MOD_ASSIGN), mLValue(lvalue), mRightSide(rightside)
1121 {
1122 }
1123
1124 ~LLScriptModAssignment()
1125 {
1126 }
1127
1128 void recurse(FILE *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);
1129 S32 getSize();
1130
1131 LLScriptExpression *mLValue;
1132 LLScriptExpression *mRightSide;
1133};
1134
1135class LLScriptEquality : public LLScriptExpression
1136{
1137public:
1138 LLScriptEquality(S32 line, S32 col, LLScriptExpression *leftside, LLScriptExpression *rightside)
1139 : LLScriptExpression(line, col, LET_EQUALITY), mLeftSide(leftside), mRightSide(rightside)
1140 {
1141 }
1142
1143 ~LLScriptEquality()
1144 {
1145 }
1146
1147 void recurse(FILE *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 S32 getSize();
1149
1150 LLScriptExpression *mLeftSide;
1151 LLScriptExpression *mRightSide;
1152};
1153
1154class LLScriptNotEquals : public LLScriptExpression
1155{
1156public:
1157 LLScriptNotEquals(S32 line, S32 col, LLScriptExpression *leftside, LLScriptExpression *rightside)
1158 : LLScriptExpression(line, col, LET_NOT_EQUALS), mLeftSide(leftside), mRightSide(rightside)
1159 {
1160 }
1161
1162 ~LLScriptNotEquals()
1163 {
1164 }
1165
1166 void recurse(FILE *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);
1167 S32 getSize();
1168
1169 LLScriptExpression *mLeftSide;
1170 LLScriptExpression *mRightSide;
1171};
1172
1173class LLScriptLessEquals : public LLScriptExpression
1174{
1175public:
1176 LLScriptLessEquals(S32 line, S32 col, LLScriptExpression *leftside, LLScriptExpression *rightside)
1177 : LLScriptExpression(line, col, LET_LESS_EQUALS), mLeftSide(leftside), mRightSide(rightside)
1178 {
1179 }
1180
1181 ~LLScriptLessEquals()
1182 {
1183 }
1184
1185 void recurse(FILE *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);
1186 S32 getSize();
1187
1188 LLScriptExpression *mLeftSide;
1189 LLScriptExpression *mRightSide;
1190};
1191
1192class LLScriptGreaterEquals : public LLScriptExpression
1193{
1194public:
1195 LLScriptGreaterEquals(S32 line, S32 col, LLScriptExpression *leftside, LLScriptExpression *rightside)
1196 : LLScriptExpression(line, col, LET_GREATER_EQUALS), mLeftSide(leftside), mRightSide(rightside)
1197 {
1198 }
1199
1200 ~LLScriptGreaterEquals()
1201 {
1202 }
1203
1204 void recurse(FILE *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);
1205 S32 getSize();
1206
1207 LLScriptExpression *mLeftSide;
1208 LLScriptExpression *mRightSide;
1209};
1210
1211class LLScriptLessThan : public LLScriptExpression
1212{
1213public:
1214 LLScriptLessThan(S32 line, S32 col, LLScriptExpression *leftside, LLScriptExpression *rightside)
1215 : LLScriptExpression(line, col, LET_LESS_THAN), mLeftSide(leftside), mRightSide(rightside)
1216 {
1217 }
1218
1219 ~LLScriptLessThan()
1220 {
1221 }
1222
1223 void recurse(FILE *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);
1224 S32 getSize();
1225
1226 LLScriptExpression *mLeftSide;
1227 LLScriptExpression *mRightSide;
1228};
1229
1230class LLScriptGreaterThan : public LLScriptExpression
1231{
1232public:
1233 LLScriptGreaterThan(S32 line, S32 col, LLScriptExpression *leftside, LLScriptExpression *rightside)
1234 : LLScriptExpression(line, col, LET_GREATER_THAN), mLeftSide(leftside), mRightSide(rightside)
1235 {
1236 }
1237
1238 ~LLScriptGreaterThan()
1239 {
1240 }
1241
1242 void recurse(FILE *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);
1243 S32 getSize();
1244
1245 LLScriptExpression *mLeftSide;
1246 LLScriptExpression *mRightSide;
1247};
1248
1249class LLScriptPlus : public LLScriptExpression
1250{
1251public:
1252 LLScriptPlus(S32 line, S32 col, LLScriptExpression *leftside, LLScriptExpression *rightside)
1253 : LLScriptExpression(line, col, LET_PLUS), mLeftSide(leftside), mRightSide(rightside)
1254 {
1255 }
1256
1257 ~LLScriptPlus()
1258 {
1259 }
1260
1261 void recurse(FILE *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);
1262 S32 getSize();
1263
1264 LLScriptExpression *mLeftSide;
1265 LLScriptExpression *mRightSide;
1266};
1267
1268class LLScriptMinus : public LLScriptExpression
1269{
1270public:
1271 LLScriptMinus(S32 line, S32 col, LLScriptExpression *leftside, LLScriptExpression *rightside)
1272 : LLScriptExpression(line, col, LET_MINUS), mLeftSide(leftside), mRightSide(rightside)
1273 {
1274 }
1275
1276 ~LLScriptMinus()
1277 {
1278 }
1279
1280 void recurse(FILE *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);
1281 S32 getSize();
1282
1283 LLScriptExpression *mLeftSide;
1284 LLScriptExpression *mRightSide;
1285};
1286
1287class LLScriptTimes : public LLScriptExpression
1288{
1289public:
1290 LLScriptTimes(S32 line, S32 col, LLScriptExpression *leftside, LLScriptExpression *rightside)
1291 : LLScriptExpression(line, col, LET_TIMES), mLeftSide(leftside), mRightSide(rightside)
1292 {
1293 }
1294
1295 ~LLScriptTimes()
1296 {
1297 }
1298
1299 void recurse(FILE *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);
1300 S32 getSize();
1301
1302 LLScriptExpression *mLeftSide;
1303 LLScriptExpression *mRightSide;
1304};
1305
1306class LLScriptDivide : public LLScriptExpression
1307{
1308public:
1309 LLScriptDivide(S32 line, S32 col, LLScriptExpression *leftside, LLScriptExpression *rightside)
1310 : LLScriptExpression(line, col, LET_DIVIDE), mLeftSide(leftside), mRightSide(rightside)
1311 {
1312 }
1313
1314 ~LLScriptDivide()
1315 {
1316 }
1317
1318 void recurse(FILE *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);
1319 S32 getSize();
1320
1321 LLScriptExpression *mLeftSide;
1322 LLScriptExpression *mRightSide;
1323};
1324
1325class LLScriptMod : public LLScriptExpression
1326{
1327public:
1328 LLScriptMod(S32 line, S32 col, LLScriptExpression *leftside, LLScriptExpression *rightside)
1329 : LLScriptExpression(line, col, LET_MOD), mLeftSide(leftside), mRightSide(rightside)
1330 {
1331 }
1332
1333 ~LLScriptMod()
1334 {
1335 }
1336
1337 void recurse(FILE *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);
1338 S32 getSize();
1339
1340 LLScriptExpression *mLeftSide;
1341 LLScriptExpression *mRightSide;
1342};
1343
1344class LLScriptBitAnd : public LLScriptExpression
1345{
1346public:
1347 LLScriptBitAnd(S32 line, S32 col, LLScriptExpression *leftside, LLScriptExpression *rightside)
1348 : LLScriptExpression(line, col, LET_BIT_AND), mLeftSide(leftside), mRightSide(rightside)
1349 {
1350 }
1351
1352 ~LLScriptBitAnd()
1353 {
1354 }
1355
1356 void recurse(FILE *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);
1357 S32 getSize();
1358
1359 LLScriptExpression *mLeftSide;
1360 LLScriptExpression *mRightSide;
1361};
1362
1363class LLScriptBitOr : public LLScriptExpression
1364{
1365public:
1366 LLScriptBitOr(S32 line, S32 col, LLScriptExpression *leftside, LLScriptExpression *rightside)
1367 : LLScriptExpression(line, col, LET_BIT_OR), mLeftSide(leftside), mRightSide(rightside)
1368 {
1369 }
1370
1371 ~LLScriptBitOr()
1372 {
1373 }
1374
1375 void recurse(FILE *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);
1376 S32 getSize();
1377
1378 LLScriptExpression *mLeftSide;
1379 LLScriptExpression *mRightSide;
1380};
1381
1382class LLScriptBitXor : public LLScriptExpression
1383{
1384public:
1385 LLScriptBitXor(S32 line, S32 col, LLScriptExpression *leftside, LLScriptExpression *rightside)
1386 : LLScriptExpression(line, col, LET_BIT_XOR), mLeftSide(leftside), mRightSide(rightside)
1387 {
1388 }
1389
1390 ~LLScriptBitXor()
1391 {
1392 }
1393
1394 void recurse(FILE *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);
1395 S32 getSize();
1396
1397 LLScriptExpression *mLeftSide;
1398 LLScriptExpression *mRightSide;
1399};
1400
1401class LLScriptBooleanAnd : public LLScriptExpression
1402{
1403public:
1404 LLScriptBooleanAnd(S32 line, S32 col, LLScriptExpression *leftside, LLScriptExpression *rightside)
1405 : LLScriptExpression(line, col, LET_BOOLEAN_AND), mLeftSide(leftside), mRightSide(rightside)
1406 {
1407 }
1408
1409 ~LLScriptBooleanAnd()
1410 {
1411 }
1412
1413 void recurse(FILE *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);
1414 S32 getSize();
1415
1416 LLScriptExpression *mLeftSide;
1417 LLScriptExpression *mRightSide;
1418};
1419
1420class LLScriptBooleanOr : public LLScriptExpression
1421{
1422public:
1423 LLScriptBooleanOr(S32 line, S32 col, LLScriptExpression *leftside, LLScriptExpression *rightside)
1424 : LLScriptExpression(line, col, LET_BOOLEAN_OR), mLeftSide(leftside), mRightSide(rightside)
1425 {
1426 }
1427
1428 ~LLScriptBooleanOr()
1429 {
1430 }
1431
1432 void recurse(FILE *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);
1433 S32 getSize();
1434
1435 LLScriptExpression *mLeftSide;
1436 LLScriptExpression *mRightSide;
1437};
1438
1439class LLScriptShiftLeft : public LLScriptExpression
1440{
1441public:
1442 LLScriptShiftLeft(S32 line, S32 col, LLScriptExpression *leftside, LLScriptExpression *rightside)
1443 : LLScriptExpression(line, col, LET_SHIFT_LEFT), mLeftSide(leftside), mRightSide(rightside)
1444 {
1445 }
1446
1447 ~LLScriptShiftLeft()
1448 {
1449 }
1450
1451 void recurse(FILE *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);
1452 S32 getSize();
1453
1454 LLScriptExpression *mLeftSide;
1455 LLScriptExpression *mRightSide;
1456};
1457
1458class LLScriptShiftRight : public LLScriptExpression
1459{
1460public:
1461 LLScriptShiftRight(S32 line, S32 col, LLScriptExpression *leftside, LLScriptExpression *rightside)
1462 : LLScriptExpression(line, col, LET_SHIFT_RIGHT), mLeftSide(leftside), mRightSide(rightside)
1463 {
1464 }
1465
1466 ~LLScriptShiftRight()
1467 {
1468 }
1469
1470 void recurse(FILE *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);
1471 S32 getSize();
1472
1473 LLScriptExpression *mLeftSide;
1474 LLScriptExpression *mRightSide;
1475};
1476
1477class LLScriptParenthesis : public LLScriptExpression
1478{
1479public:
1480 LLScriptParenthesis(S32 line, S32 col, LLScriptExpression *expression)
1481 : LLScriptExpression(line, col, LET_PARENTHESIS), mExpression(expression)
1482 {
1483 }
1484
1485 ~LLScriptParenthesis()
1486 {
1487 }
1488
1489 void recurse(FILE *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);
1490 S32 getSize();
1491
1492 LLScriptExpression *mExpression;
1493};
1494
1495class LLScriptUnaryMinus : public LLScriptExpression
1496{
1497public:
1498 LLScriptUnaryMinus(S32 line, S32 col, LLScriptExpression *expression)
1499 : LLScriptExpression(line, col, LET_UNARY_MINUS), mExpression(expression)
1500 {
1501 }
1502
1503 ~LLScriptUnaryMinus()
1504 {
1505 }
1506
1507 void recurse(FILE *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);
1508 S32 getSize();
1509
1510 LLScriptExpression *mExpression;
1511};
1512
1513class LLScriptBooleanNot : public LLScriptExpression
1514{
1515public:
1516 LLScriptBooleanNot(S32 line, S32 col, LLScriptExpression *expression)
1517 : LLScriptExpression(line, col, LET_BOOLEAN_NOT), mExpression(expression)
1518 {
1519 }
1520
1521 ~LLScriptBooleanNot()
1522 {
1523 }
1524
1525 void recurse(FILE *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);
1526 S32 getSize();
1527
1528 LLScriptExpression *mExpression;
1529};
1530
1531class LLScriptBitNot : public LLScriptExpression
1532{
1533public:
1534 LLScriptBitNot(S32 line, S32 col, LLScriptExpression *expression)
1535 : LLScriptExpression(line, col, LET_BIT_NOT), mExpression(expression)
1536 {
1537 }
1538
1539 ~LLScriptBitNot()
1540 {
1541 }
1542
1543 void recurse(FILE *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);
1544 S32 getSize();
1545
1546 LLScriptExpression *mExpression;
1547};
1548
1549class LLScriptPreIncrement : public LLScriptExpression
1550{
1551public:
1552 LLScriptPreIncrement(S32 line, S32 col, LLScriptExpression *expression)
1553 : LLScriptExpression(line, col, LET_PRE_INCREMENT), mExpression(expression)
1554 {
1555 }
1556
1557 ~LLScriptPreIncrement()
1558 {
1559 }
1560
1561 void recurse(FILE *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);
1562 S32 getSize();
1563
1564 LLScriptExpression *mExpression;
1565};
1566
1567class LLScriptPreDecrement : public LLScriptExpression
1568{
1569public:
1570 LLScriptPreDecrement(S32 line, S32 col, LLScriptExpression *expression)
1571 : LLScriptExpression(line, col, LET_PRE_DECREMENT), mExpression(expression)
1572 {
1573 }
1574
1575 ~LLScriptPreDecrement()
1576 {
1577 }
1578
1579 void recurse(FILE *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);
1580 S32 getSize();
1581
1582 LLScriptExpression *mExpression;
1583};
1584
1585class LLScriptTypeCast : public LLScriptExpression
1586{
1587public:
1588 LLScriptTypeCast(S32 line, S32 col, LLScriptType *type, LLScriptExpression *expression)
1589 : LLScriptExpression(line, col, LET_CAST), mType(type), mExpression(expression)
1590 {
1591 }
1592
1593 ~LLScriptTypeCast()
1594 {
1595 }
1596
1597 void recurse(FILE *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);
1598 S32 getSize();
1599
1600 LLScriptType *mType;
1601 LLScriptExpression *mExpression;
1602};
1603
1604class LLScriptVectorInitializer : public LLScriptExpression
1605{
1606public:
1607 LLScriptVectorInitializer(S32 line, S32 col, LLScriptExpression *expression1,
1608 LLScriptExpression *expression2,
1609 LLScriptExpression *expression3)
1610 : LLScriptExpression(line, col, LET_VECTOR_INITIALIZER),
1611 mExpression1(expression1),
1612 mExpression2(expression2),
1613 mExpression3(expression3)
1614 {
1615 }
1616
1617 ~LLScriptVectorInitializer()
1618 {
1619 }
1620
1621 void recurse(FILE *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);
1622 S32 getSize();
1623
1624 LLScriptExpression *mExpression1;
1625 LLScriptExpression *mExpression2;
1626 LLScriptExpression *mExpression3;
1627};
1628
1629class LLScriptQuaternionInitializer : public LLScriptExpression
1630{
1631public:
1632 LLScriptQuaternionInitializer(S32 line, S32 col, LLScriptExpression *expression1,
1633 LLScriptExpression *expression2,
1634 LLScriptExpression *expression3,
1635 LLScriptExpression *expression4)
1636 : LLScriptExpression(line, col, LET_VECTOR_INITIALIZER),
1637 mExpression1(expression1),
1638 mExpression2(expression2),
1639 mExpression3(expression3),
1640 mExpression4(expression4)
1641 {
1642 }
1643
1644 ~LLScriptQuaternionInitializer()
1645 {
1646 }
1647
1648 void recurse(FILE *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);
1649 S32 getSize();
1650
1651 LLScriptExpression *mExpression1;
1652 LLScriptExpression *mExpression2;
1653 LLScriptExpression *mExpression3;
1654 LLScriptExpression *mExpression4;
1655};
1656
1657class LLScriptListInitializer : public LLScriptExpression
1658{
1659public:
1660 LLScriptListInitializer(S32 line, S32 col, LLScriptExpression *expressionlist)
1661 : LLScriptExpression(line, col, LET_LIST_INITIALIZER), mExpressionList(expressionlist)
1662 {
1663 }
1664
1665 ~LLScriptListInitializer()
1666 {
1667 }
1668
1669 void recurse(FILE *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);
1670 S32 getSize();
1671
1672 LLScriptExpression *mExpressionList;
1673};
1674
1675class LLScriptPostIncrement : public LLScriptExpression
1676{
1677public:
1678 LLScriptPostIncrement(S32 line, S32 col, LLScriptExpression *expression)
1679 : LLScriptExpression(line, col, LET_POST_INCREMENT), mExpression(expression)
1680 {
1681 }
1682
1683 ~LLScriptPostIncrement()
1684 {
1685 }
1686
1687 void recurse(FILE *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);
1688 S32 getSize();
1689
1690 LLScriptExpression *mExpression;
1691};
1692
1693class LLScriptPostDecrement : public LLScriptExpression
1694{
1695public:
1696 LLScriptPostDecrement(S32 line, S32 col, LLScriptExpression *expression)
1697 : LLScriptExpression(line, col, LET_POST_DECREMENT), mExpression(expression)
1698 {
1699 }
1700
1701 ~LLScriptPostDecrement()
1702 {
1703 }
1704
1705 void recurse(FILE *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);
1706 S32 getSize();
1707
1708 LLScriptExpression *mExpression;
1709};
1710
1711class LLScriptFunctionCall : public LLScriptExpression
1712{
1713public:
1714 LLScriptFunctionCall(S32 line, S32 col, LLScriptIdentifier *identifier, LLScriptExpression *expressionlist)
1715 : LLScriptExpression(line, col, LET_FUNCTION_CALL), mIdentifier(identifier), mExpressionList(expressionlist)
1716 {
1717 }
1718
1719 ~LLScriptFunctionCall()
1720 {
1721 }
1722
1723 void recurse(FILE *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);
1724 S32 getSize();
1725
1726 LLScriptIdentifier *mIdentifier;
1727 LLScriptExpression *mExpressionList;
1728};
1729
1730class LLScriptPrint : public LLScriptExpression
1731{
1732public:
1733 LLScriptPrint(S32 line, S32 col, LLScriptExpression *expression)
1734 : LLScriptExpression(line, col, LET_PRINT), mExpression(expression)
1735 {
1736 }
1737
1738 ~LLScriptPrint()
1739 {
1740 }
1741
1742 void recurse(FILE *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);
1743 S32 getSize();
1744
1745 LLScriptExpression *mExpression;
1746};
1747
1748class LLScriptConstantExpression : public LLScriptExpression
1749{
1750public:
1751 LLScriptConstantExpression(S32 line, S32 col, LLScriptConstant *constant)
1752 : LLScriptExpression(line, col, LET_CONSTANT), mConstant(constant)
1753 {
1754 }
1755
1756 ~LLScriptConstantExpression()
1757 {
1758 }
1759
1760 void recurse(FILE *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);
1761 S32 getSize();
1762
1763 LLScriptConstant *mConstant;
1764};
1765
1766// statement
1767typedef enum e_lscript_statement_types
1768{
1769 LSSMT_NULL,
1770 LSSMT_SEQUENCE,
1771 LSSMT_NOOP,
1772 LSSMT_STATE_CHANGE,
1773 LSSMT_JUMP,
1774 LSSMT_LABEL,
1775 LSSMT_RETURN,
1776 LSSMT_EXPRESSION,
1777 LSSMT_IF,
1778 LSSMT_IF_ELSE,
1779 LSSMT_FOR,
1780 LSSMT_DO_WHILE,
1781 LSSMT_WHILE,
1782 LSSMT_DECLARATION,
1783 LSSMT_COMPOUND_STATEMENT,
1784 LSSMT_EOF
1785} LSCRIPTStatementType;
1786
1787class LLScriptStatement : public LLScriptFilePosition
1788{
1789public:
1790 LLScriptStatement(S32 line, S32 col, LSCRIPTStatementType type)
1791 : LLScriptFilePosition(line, col), mType(type), mNextp(NULL), mStatementScope(NULL), mAllowDeclarations(TRUE)
1792 {
1793 }
1794
1795 virtual ~LLScriptStatement()
1796 {
1797 delete mStatementScope;
1798 }
1799
1800 void addStatement(LLScriptStatement *event);
1801
1802 void recurse(FILE *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);
1803
1804 void gonext(FILE *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);
1805 S32 getSize();
1806
1807 LSCRIPTStatementType mType;
1808 LLScriptStatement *mNextp;
1809 LLScriptScope *mStatementScope;
1810 BOOL mAllowDeclarations;
1811};
1812
1813class LLScriptStatementSequence : public LLScriptStatement
1814{
1815public:
1816 LLScriptStatementSequence(S32 line, S32 col, LLScriptStatement *first, LLScriptStatement *second)
1817 : LLScriptStatement(line, col, LSSMT_SEQUENCE), mFirstp(first), mSecondp(second)
1818 {
1819 }
1820
1821 ~LLScriptStatementSequence()
1822 {
1823 }
1824
1825 void recurse(FILE *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);
1826 S32 getSize();
1827
1828 LLScriptStatement *mFirstp;
1829 LLScriptStatement *mSecondp;
1830};
1831
1832class LLScriptNOOP : public LLScriptStatement
1833{
1834public:
1835 LLScriptNOOP(S32 line, S32 col)
1836 : LLScriptStatement(line, col, LSSMT_NOOP)
1837 {
1838 }
1839
1840 ~LLScriptNOOP() {}
1841
1842 void recurse(FILE *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);
1843 S32 getSize();
1844};
1845
1846class LLScriptStateChange : public LLScriptStatement
1847{
1848public:
1849 LLScriptStateChange(S32 line, S32 col, LLScriptIdentifier *identifier)
1850 : LLScriptStatement(line, col, LSSMT_STATE_CHANGE), mIdentifier(identifier)
1851 {
1852 }
1853
1854 ~LLScriptStateChange()
1855 {
1856 }
1857
1858 void recurse(FILE *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);
1859 S32 getSize();
1860
1861 LLScriptIdentifier *mIdentifier;
1862};
1863
1864class LLScriptJump : public LLScriptStatement
1865{
1866public:
1867 LLScriptJump(S32 line, S32 col, LLScriptIdentifier *identifier)
1868 : LLScriptStatement(line, col, LSSMT_JUMP), mIdentifier(identifier)
1869 {
1870 }
1871
1872 ~LLScriptJump()
1873 {
1874 }
1875
1876 void recurse(FILE *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);
1877 S32 getSize();
1878
1879 LLScriptIdentifier *mIdentifier;
1880};
1881
1882class LLScriptLabel : public LLScriptStatement
1883{
1884public:
1885 LLScriptLabel(S32 line, S32 col, LLScriptIdentifier *identifier)
1886 : LLScriptStatement(line, col, LSSMT_LABEL), mIdentifier(identifier)
1887 {
1888 }
1889
1890 ~LLScriptLabel()
1891 {
1892 }
1893
1894 void recurse(FILE *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);
1895 S32 getSize();
1896
1897 LLScriptIdentifier *mIdentifier;
1898};
1899
1900class LLScriptReturn : public LLScriptStatement
1901{
1902public:
1903 LLScriptReturn(S32 line, S32 col, LLScriptExpression *expression)
1904 : LLScriptStatement(line, col, LSSMT_RETURN), mExpression(expression), mType(LST_NULL)
1905 {
1906 }
1907
1908 ~LLScriptReturn()
1909 {
1910 }
1911
1912 void recurse(FILE *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);
1913 S32 getSize();
1914
1915 LLScriptExpression *mExpression;
1916 LSCRIPTType mType;
1917};
1918
1919class LLScriptExpressionStatement : public LLScriptStatement
1920{
1921public:
1922 LLScriptExpressionStatement(S32 line, S32 col, LLScriptExpression *expression)
1923 : LLScriptStatement(line, col, LSSMT_EXPRESSION), mExpression(expression)
1924 {
1925 }
1926
1927 ~LLScriptExpressionStatement()
1928 {
1929 }
1930
1931 void recurse(FILE *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);
1932 S32 getSize();
1933
1934 LLScriptExpression *mExpression;
1935};
1936
1937class LLScriptIf : public LLScriptStatement
1938{
1939public:
1940 LLScriptIf(S32 line, S32 col, LLScriptExpression *expression, LLScriptStatement *statement)
1941 : LLScriptStatement(line, col, LSSMT_IF), mType(LST_NULL), mExpression(expression), mStatement(statement)
1942 {
1943 }
1944
1945 ~LLScriptIf()
1946 {
1947 }
1948
1949 void recurse(FILE *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);
1950 S32 getSize();
1951
1952 LSCRIPTType mType;
1953 LLScriptExpression *mExpression;
1954 LLScriptStatement *mStatement;
1955};
1956
1957class LLScriptIfElse : public LLScriptStatement
1958{
1959public:
1960 LLScriptIfElse(S32 line, S32 col, LLScriptExpression *expression, LLScriptStatement *statement1, LLScriptStatement *statement2)
1961 : LLScriptStatement(line, col, LSSMT_IF_ELSE), mExpression(expression), mStatement1(statement1), mStatement2(statement2), mType(LST_NULL)
1962 {
1963 }
1964
1965 ~LLScriptIfElse()
1966 {
1967 }
1968
1969 void recurse(FILE *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);
1970 S32 getSize();
1971
1972 LLScriptExpression *mExpression;
1973 LLScriptStatement *mStatement1;
1974 LLScriptStatement *mStatement2;
1975 LSCRIPTType mType;
1976};
1977
1978class LLScriptFor : public LLScriptStatement
1979{
1980public:
1981 LLScriptFor(S32 line, S32 col, LLScriptExpression *sequence, LLScriptExpression *expression, LLScriptExpression *expressionlist, LLScriptStatement *statement)
1982 : LLScriptStatement(line, col, LSSMT_FOR), mSequence(sequence), mExpression(expression), mExpressionList(expressionlist), mStatement(statement), mType(LST_NULL)
1983 {
1984 }
1985
1986 ~LLScriptFor()
1987 {
1988 }
1989
1990 void recurse(FILE *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);
1991 S32 getSize();
1992
1993 LLScriptExpression *mSequence;
1994 LLScriptExpression *mExpression;
1995 LLScriptExpression *mExpressionList;
1996 LLScriptStatement *mStatement;
1997 LSCRIPTType mType;
1998};
1999
2000class LLScriptDoWhile : public LLScriptStatement
2001{
2002public:
2003 LLScriptDoWhile(S32 line, S32 col, LLScriptStatement *statement, LLScriptExpression *expression)
2004 : LLScriptStatement(line, col, LSSMT_DO_WHILE), mStatement(statement), mExpression(expression), mType(LST_NULL)
2005 {
2006 }
2007
2008 ~LLScriptDoWhile()
2009 {
2010 }
2011
2012 void recurse(FILE *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);
2013 S32 getSize();
2014
2015 LLScriptStatement *mStatement;
2016 LLScriptExpression *mExpression;
2017 LSCRIPTType mType;
2018};
2019
2020class LLScriptWhile : public LLScriptStatement
2021{
2022public:
2023 LLScriptWhile(S32 line, S32 col, LLScriptExpression *expression, LLScriptStatement *statement)
2024 : LLScriptStatement(line, col, LSSMT_WHILE), mExpression(expression), mStatement(statement), mType(LST_NULL)
2025 {
2026 }
2027
2028 ~LLScriptWhile()
2029 {
2030 }
2031
2032 void recurse(FILE *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);
2033 S32 getSize();
2034
2035 LLScriptExpression *mExpression;
2036 LLScriptStatement *mStatement;
2037 LSCRIPTType mType;
2038};
2039
2040// local variables
2041class LLScriptDeclaration : public LLScriptStatement
2042{
2043public:
2044 LLScriptDeclaration(S32 line, S32 col, LLScriptType *type, LLScriptIdentifier *identifier, LLScriptExpression *expression)
2045 : LLScriptStatement(line, col, LSSMT_DECLARATION), mType(type), mIdentifier(identifier), mExpression(expression)
2046 {
2047 }
2048
2049 ~LLScriptDeclaration()
2050 {
2051 }
2052
2053 void recurse(FILE *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);
2054 S32 getSize();
2055
2056 LLScriptType *mType;
2057 LLScriptIdentifier *mIdentifier;
2058 LLScriptExpression *mExpression;
2059};
2060
2061class LLScriptCompoundStatement : public LLScriptStatement
2062{
2063public:
2064 LLScriptCompoundStatement(S32 line, S32 col, LLScriptStatement *statement)
2065 : LLScriptStatement(line, col, LSSMT_COMPOUND_STATEMENT), mStatement(statement)
2066 {
2067 }
2068
2069 ~LLScriptCompoundStatement()
2070 {
2071 }
2072
2073 void recurse(FILE *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);
2074 S32 getSize();
2075
2076 LLScriptStatement *mStatement;
2077};
2078
2079class LLScriptEventHandler : public LLScriptFilePosition
2080{
2081public:
2082 LLScriptEventHandler(S32 line, S32 col, LLScriptEvent *event, LLScriptStatement *statement)
2083 : LLScriptFilePosition(line, col), mEventp(event), mStatement(statement), mNextp(NULL), mEventScope(NULL), mbNeedTrailingReturn(FALSE), mScopeEntry(NULL), mStackSpace(0)
2084 {
2085 }
2086
2087 ~LLScriptEventHandler()
2088 {
2089 delete mEventScope;
2090 delete mScopeEntry;
2091 }
2092
2093 void addEvent(LLScriptEventHandler *event);
2094
2095 void gonext(FILE *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);
2096
2097 void recurse(FILE *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);
2098 S32 getSize();
2099
2100 LLScriptEvent *mEventp;
2101 LLScriptStatement *mStatement;
2102 LLScriptEventHandler *mNextp;
2103 LLScriptScope *mEventScope;
2104 BOOL mbNeedTrailingReturn;
2105 LLScriptScopeEntry *mScopeEntry;
2106
2107 S32 mStackSpace;
2108
2109};
2110
2111
2112// global functions
2113class LLScriptFunctionDec : public LLScriptFilePosition
2114{
2115public:
2116 LLScriptFunctionDec(S32 line, S32 col, LLScriptType *type, LLScriptIdentifier *identifier)
2117 : LLScriptFilePosition(line, col), mType(type), mIdentifier(identifier), mNextp(NULL)
2118 {
2119 }
2120
2121 ~LLScriptFunctionDec()
2122 {
2123 }
2124
2125 void addFunctionParameter(LLScriptFunctionDec *dec);
2126
2127 void gonext(FILE *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);
2128
2129 void recurse(FILE *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);
2130 S32 getSize();
2131
2132 LLScriptType *mType;
2133 LLScriptIdentifier *mIdentifier;
2134 LLScriptFunctionDec *mNextp;
2135};
2136
2137class LLScriptGlobalFunctions : public LLScriptFilePosition
2138{
2139public:
2140 LLScriptGlobalFunctions(S32 line, S32 col, LLScriptType *type,
2141 LLScriptIdentifier *identifier,
2142 LLScriptFunctionDec *parameters,
2143 LLScriptStatement *statements)
2144 : LLScriptFilePosition(line, col), mType(type), mIdentifier(identifier), mParameters(parameters), mStatements(statements), mNextp(NULL), mFunctionScope(NULL), mbNeedTrailingReturn(FALSE)
2145 {
2146 }
2147
2148 void addGlobalFunction(LLScriptGlobalFunctions *global);
2149
2150 ~LLScriptGlobalFunctions()
2151 {
2152 delete mFunctionScope;
2153 }
2154
2155 void gonext(FILE *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);
2156
2157 void recurse(FILE *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);
2158 S32 getSize();
2159
2160 LLScriptType *mType;
2161 LLScriptIdentifier *mIdentifier;
2162 LLScriptFunctionDec *mParameters;
2163 LLScriptStatement *mStatements;
2164 LLScriptGlobalFunctions *mNextp;
2165 LLScriptScope *mFunctionScope;
2166 BOOL mbNeedTrailingReturn;
2167
2168};
2169
2170typedef enum e_lscript_state_type
2171{
2172 LSSTYPE_NULL,
2173 LSSTYPE_DEFAULT,
2174 LSSTYPE_USER,
2175 LSSTYPE_EOF
2176} LSCRIPTStateType;
2177
2178// info on state
2179class LLScriptState : public LLScriptFilePosition
2180{
2181public:
2182 LLScriptState(S32 line, S32 col, LSCRIPTStateType type, LLScriptIdentifier *identifier, LLScriptEventHandler *event)
2183 : LLScriptFilePosition(line, col), mType(type), mIdentifier(identifier), mEvent(event), mNextp(NULL)
2184 {
2185 }
2186
2187 void addState(LLScriptState *state);
2188
2189 ~LLScriptState()
2190 {
2191 }
2192
2193 void gonext(FILE *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);
2194
2195 void recurse(FILE *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);
2196 S32 getSize();
2197
2198 LSCRIPTStateType mType;
2199 LLScriptIdentifier *mIdentifier;
2200 LLScriptEventHandler *mEvent;
2201 LLScriptState *mNextp;
2202
2203};
2204
2205class LLScritpGlobalStorage : public LLScriptFilePosition
2206{
2207public:
2208
2209 LLScritpGlobalStorage(LLScriptGlobalVariable *var)
2210 : LLScriptFilePosition(0, 0), mGlobal(var), mbGlobalFunction(FALSE), mNextp(NULL)
2211 {
2212 }
2213
2214 LLScritpGlobalStorage(LLScriptGlobalFunctions *func)
2215 : LLScriptFilePosition(0, 0), mGlobal(func), mbGlobalFunction(TRUE), mNextp(NULL)
2216 {
2217 }
2218
2219 ~LLScritpGlobalStorage()
2220 {
2221 }
2222
2223 void recurse(FILE *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)
2224 {
2225 }
2226
2227 S32 getSize()
2228 {
2229 return 0;
2230 }
2231
2232 void addGlobal(LLScritpGlobalStorage *global)
2233 {
2234 if (mNextp)
2235 {
2236 global->mNextp = mNextp;
2237 }
2238 mNextp = global;
2239 }
2240
2241 LLScriptFilePosition *mGlobal;
2242 BOOL mbGlobalFunction;
2243 LLScritpGlobalStorage *mNextp;
2244};
2245
2246// top level container for entire script
2247class LLScriptScript : public LLScriptFilePosition
2248{
2249public:
2250 LLScriptScript(LLScritpGlobalStorage *globals,
2251 LLScriptState *states);
2252
2253 ~LLScriptScript()
2254 {
2255 delete mGlobalScope;
2256 }
2257
2258 void recurse(FILE *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);
2259 S32 getSize();
2260
2261 void setBytecodeDest(const char* dst_filename);
2262
2263 LLScriptState *mStates;
2264 LLScriptScope *mGlobalScope;
2265 LLScriptGlobalVariable *mGlobals;
2266 LLScriptGlobalFunctions *mGlobalFunctions;
2267 BOOL mGodLike;
2268
2269private:
2270 char mBytecodeDest[MAX_STRING];
2271};
2272
2273class LLScriptAllocationManager
2274{
2275public:
2276 LLScriptAllocationManager() {}
2277 ~LLScriptAllocationManager()
2278 {
2279 mAllocationList.deleteAllData();
2280 }
2281
2282 void addAllocation(LLScriptFilePosition *ptr)
2283 {
2284 mAllocationList.addData(ptr);
2285 }
2286
2287 void deleteAllocations()
2288 {
2289 mAllocationList.deleteAllData();
2290 }
2291
2292 LLLinkedList<LLScriptFilePosition> mAllocationList;
2293};
2294
2295extern LLScriptAllocationManager *gAllocationManager;
2296extern LLScriptScript *gScriptp;
2297
2298#endif
diff --git a/linden/indra/lscript/lscript_compile/lscript_typecheck.cpp b/linden/indra/lscript/lscript_compile/lscript_typecheck.cpp
new file mode 100644
index 0000000..fbef711
--- /dev/null
+++ b/linden/indra/lscript/lscript_compile/lscript_typecheck.cpp
@@ -0,0 +1,581 @@
1/**
2 * @file lscript_typecheck.cpp
3 * @brief typechecks script
4 *
5 * Copyright (c) 2002-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28#include "linden_common.h"
29
30#include "lscript_tree.h"
31
32/*
33 LScript automatic type casting
34
35 LST_INTEGER -> LST_INTEGER
36
37 LST_FLOATINGPOINT -> LST_FLOATINGPOINT
38 LST_INTEGER -> LST_FLOATINGPOINT
39
40 LST_FLOATINGPOINT -> LST_STRING
41 LST_INTEGER -> LST_STRING
42 LST_STRING -> LST_STRING
43 LST_VECTOR -> LST_STRING
44 LST_QUATERNION -> LST_STRING
45 LST_LIST -> LST_STRING
46
47 LST_VECTOR -> LST_VECTOR
48
49 LST_QUATERNION -> LST_QUATERNION
50
51 LST_FLOATINGPOINT -> LST_LIST
52 LST_INTEGER -> LST_LIST
53 LST_STRING -> LST_LIST
54 LST_VECTOR -> LST_LIST
55 LST_QUATERNION -> LST_LIST
56 LST_LIST -> LST_LIST
57*/
58
59LSCRIPTType implicit_casts(LSCRIPTType left_side, LSCRIPTType right_side)
60{
61 switch(left_side)
62 {
63 // shouldn't be doing an operation on void types
64 case LST_NULL:
65 return LST_NULL;
66 // shouldn't be doing an operation on undefined types
67 case LST_UNDEFINED:
68 return LST_UNDEFINED;
69 // only integers can become integers
70 case LST_INTEGER:
71 switch(right_side)
72 {
73 case LST_INTEGER:
74 return LST_INTEGER;
75 default:
76 return LST_UNDEFINED;
77 }
78 // only integers and floats can become floats
79 case LST_FLOATINGPOINT:
80 switch(right_side)
81 {
82 case LST_INTEGER:
83 case LST_FLOATINGPOINT:
84 return LST_FLOATINGPOINT;
85 default:
86 return LST_UNDEFINED;
87 }
88 // only strings and keys can become strings
89 case LST_STRING:
90 switch(right_side)
91 {
92 case LST_STRING:
93 case LST_KEY:
94 return LST_STRING;
95 default:
96 return LST_UNDEFINED;
97 }
98 // only strings and keys can become keys
99 case LST_KEY:
100 switch(right_side)
101 {
102 case LST_STRING:
103 case LST_KEY:
104 return LST_KEY;
105 default:
106 return LST_UNDEFINED;
107 }
108 // only vectors can become vectors
109 case LST_VECTOR:
110 switch(right_side)
111 {
112 case LST_VECTOR:
113 return LST_VECTOR;
114 default:
115 return LST_UNDEFINED;
116 }
117 // only quaternions can become quaternions
118 case LST_QUATERNION:
119 switch(right_side)
120 {
121 case LST_QUATERNION:
122 return LST_QUATERNION;
123 default:
124 return LST_UNDEFINED;
125 }
126 // only lists can become lists
127 case LST_LIST:
128 switch(right_side)
129 {
130 case LST_LIST:
131 return LST_LIST;
132 default:
133 return LST_UNDEFINED;
134 }
135 default:
136 return LST_UNDEFINED;
137 }
138}
139
140LSCRIPTType promote(LSCRIPTType left_side, LSCRIPTType right_side)
141{
142 LSCRIPTType type;
143 type = implicit_casts(left_side, right_side);
144 if (type != LST_UNDEFINED)
145 {
146 return type;
147 }
148 type = implicit_casts(right_side, left_side);
149 if (type != LST_UNDEFINED)
150 {
151 return type;
152 }
153 return LST_UNDEFINED;
154}
155
156BOOL legal_assignment(LSCRIPTType left_side, LSCRIPTType right_side)
157{
158 // this is to prevent cascading errors
159 if ( (left_side == LST_UNDEFINED)
160 ||(right_side == LST_UNDEFINED))
161 {
162 return TRUE;
163 }
164
165 if (implicit_casts(left_side, right_side) != LST_UNDEFINED)
166 {
167 return TRUE;
168 }
169 else
170 {
171 return FALSE;
172 }
173}
174
175BOOL legal_casts(LSCRIPTType cast, LSCRIPTType base)
176{
177 switch(base)
178 {
179 // shouldn't be doing an operation on void types
180 case LST_NULL:
181 return FALSE;
182 // shouldn't be doing an operation on undefined types
183 case LST_UNDEFINED:
184 return FALSE;
185 case LST_INTEGER:
186 switch(cast)
187 {
188 case LST_INTEGER:
189 case LST_FLOATINGPOINT:
190 case LST_STRING:
191 case LST_LIST:
192 return TRUE;
193 break;
194 default:
195 return FALSE;
196 break;
197 }
198 break;
199 case LST_FLOATINGPOINT:
200 switch(cast)
201 {
202 case LST_INTEGER:
203 case LST_FLOATINGPOINT:
204 case LST_STRING:
205 case LST_LIST:
206 return TRUE;
207 break;
208 default:
209 return FALSE;
210 break;
211 }
212 break;
213 case LST_STRING:
214 switch(cast)
215 {
216 case LST_INTEGER:
217 case LST_FLOATINGPOINT:
218 case LST_STRING:
219 case LST_KEY:
220 case LST_VECTOR:
221 case LST_QUATERNION:
222 case LST_LIST:
223 return TRUE;
224 break;
225 default:
226 return FALSE;
227 break;
228 }
229 break;
230 case LST_KEY:
231 switch(cast)
232 {
233 case LST_STRING:
234 case LST_KEY:
235 case LST_LIST:
236 return TRUE;
237 break;
238 default:
239 return FALSE;
240 break;
241 }
242 break;
243 case LST_VECTOR:
244 switch(cast)
245 {
246 case LST_VECTOR:
247 case LST_STRING:
248 case LST_LIST:
249 return TRUE;
250 break;
251 default:
252 return FALSE;
253 break;
254 }
255 break;
256 case LST_QUATERNION:
257 switch(cast)
258 {
259 case LST_QUATERNION:
260 case LST_STRING:
261 case LST_LIST:
262 return TRUE;
263 break;
264 default:
265 return FALSE;
266 break;
267 }
268 break;
269 // lists can only be cast to lists and strings
270 case LST_LIST:
271 switch(cast)
272 {
273 case LST_LIST:
274 case LST_STRING:
275 return TRUE;
276 break;
277 default:
278 return FALSE;
279 break;
280 }
281 break;
282 default:
283 return FALSE;
284 break;
285 }
286}
287
288LSCRIPTType gSupportedExpressionArray[LET_EOF][LST_EOF][LST_EOF];
289
290void init_supported_expressions(void)
291{
292 S32 i, j, k;
293 // zero out, then set the ones that matter
294 for (i = 0; i < LET_EOF; i++)
295 {
296 for (j = 0; j < LST_EOF; j++)
297 {
298 for (k = 0; k < LST_EOF; k++)
299 {
300 gSupportedExpressionArray[i][j][k] = LST_NULL;
301 }
302 }
303 }
304
305 // LET_ASSIGNMENT
306 gSupportedExpressionArray[LET_ASSIGNMENT][LST_INTEGER][LST_INTEGER] = LST_INTEGER;
307 gSupportedExpressionArray[LET_ASSIGNMENT][LST_FLOATINGPOINT][LST_INTEGER] = LST_FLOATINGPOINT;
308 gSupportedExpressionArray[LET_ASSIGNMENT][LST_INTEGER][LST_FLOATINGPOINT] = LST_FLOATINGPOINT;
309 gSupportedExpressionArray[LET_ASSIGNMENT][LST_FLOATINGPOINT][LST_FLOATINGPOINT] = LST_FLOATINGPOINT;
310 gSupportedExpressionArray[LET_ASSIGNMENT][LST_STRING][LST_STRING] = LST_STRING;
311 gSupportedExpressionArray[LET_ASSIGNMENT][LST_KEY][LST_KEY] = LST_KEY;
312 gSupportedExpressionArray[LET_ASSIGNMENT][LST_VECTOR][LST_VECTOR] = LST_VECTOR;
313 gSupportedExpressionArray[LET_ASSIGNMENT][LST_QUATERNION][LST_QUATERNION] = LST_QUATERNION;
314 gSupportedExpressionArray[LET_ASSIGNMENT][LST_LIST][LST_INTEGER] = LST_LIST;
315 gSupportedExpressionArray[LET_ASSIGNMENT][LST_LIST][LST_FLOATINGPOINT] = LST_LIST;
316 gSupportedExpressionArray[LET_ASSIGNMENT][LST_LIST][LST_STRING] = LST_LIST;
317 gSupportedExpressionArray[LET_ASSIGNMENT][LST_LIST][LST_KEY] = LST_LIST;
318 gSupportedExpressionArray[LET_ASSIGNMENT][LST_LIST][LST_VECTOR] = LST_LIST;
319 gSupportedExpressionArray[LET_ASSIGNMENT][LST_LIST][LST_QUATERNION] = LST_LIST;
320 gSupportedExpressionArray[LET_ASSIGNMENT][LST_LIST][LST_LIST] = LST_LIST;
321
322 // LET_ADD_ASSIGN
323 gSupportedExpressionArray[LET_ADD_ASSIGN][LST_INTEGER][LST_INTEGER] = LST_INTEGER;
324 gSupportedExpressionArray[LET_ADD_ASSIGN][LST_FLOATINGPOINT][LST_INTEGER] = LST_FLOATINGPOINT;
325 gSupportedExpressionArray[LET_ADD_ASSIGN][LST_FLOATINGPOINT][LST_FLOATINGPOINT] = LST_FLOATINGPOINT;
326 gSupportedExpressionArray[LET_ADD_ASSIGN][LST_STRING][LST_STRING] = LST_STRING;
327 gSupportedExpressionArray[LET_ADD_ASSIGN][LST_VECTOR][LST_VECTOR] = LST_VECTOR;
328 gSupportedExpressionArray[LET_ADD_ASSIGN][LST_QUATERNION][LST_QUATERNION] = LST_QUATERNION;
329 gSupportedExpressionArray[LET_ADD_ASSIGN][LST_LIST][LST_INTEGER] = LST_LIST;
330 gSupportedExpressionArray[LET_ADD_ASSIGN][LST_LIST][LST_FLOATINGPOINT] = LST_LIST;
331 gSupportedExpressionArray[LET_ADD_ASSIGN][LST_LIST][LST_STRING] = LST_LIST;
332 gSupportedExpressionArray[LET_ADD_ASSIGN][LST_LIST][LST_KEY] = LST_LIST;
333 gSupportedExpressionArray[LET_ADD_ASSIGN][LST_LIST][LST_VECTOR] = LST_LIST;
334 gSupportedExpressionArray[LET_ADD_ASSIGN][LST_LIST][LST_QUATERNION] = LST_LIST;
335 gSupportedExpressionArray[LET_ADD_ASSIGN][LST_LIST][LST_LIST] = LST_LIST;
336
337 // LET_SUB_ASSIGN
338 gSupportedExpressionArray[LET_SUB_ASSIGN][LST_INTEGER][LST_INTEGER] = LST_INTEGER;
339 gSupportedExpressionArray[LET_SUB_ASSIGN][LST_FLOATINGPOINT][LST_INTEGER] = LST_FLOATINGPOINT;
340 gSupportedExpressionArray[LET_SUB_ASSIGN][LST_FLOATINGPOINT][LST_FLOATINGPOINT] = LST_FLOATINGPOINT;
341 gSupportedExpressionArray[LET_SUB_ASSIGN][LST_VECTOR][LST_VECTOR] = LST_VECTOR;
342 gSupportedExpressionArray[LET_SUB_ASSIGN][LST_QUATERNION][LST_QUATERNION] = LST_QUATERNION;
343
344 // LET_MUL_ASSIGN
345 gSupportedExpressionArray[LET_MUL_ASSIGN][LST_INTEGER][LST_INTEGER] = LST_INTEGER;
346 gSupportedExpressionArray[LET_MUL_ASSIGN][LST_FLOATINGPOINT][LST_INTEGER] = LST_FLOATINGPOINT;
347 gSupportedExpressionArray[LET_MUL_ASSIGN][LST_INTEGER][LST_FLOATINGPOINT] = LST_FLOATINGPOINT;
348 gSupportedExpressionArray[LET_MUL_ASSIGN][LST_FLOATINGPOINT][LST_FLOATINGPOINT] = LST_FLOATINGPOINT;
349 gSupportedExpressionArray[LET_MUL_ASSIGN][LST_VECTOR][LST_INTEGER] = LST_VECTOR;
350 gSupportedExpressionArray[LET_MUL_ASSIGN][LST_INTEGER][LST_VECTOR] = LST_VECTOR;
351 gSupportedExpressionArray[LET_MUL_ASSIGN][LST_VECTOR][LST_FLOATINGPOINT] = LST_VECTOR;
352 gSupportedExpressionArray[LET_MUL_ASSIGN][LST_FLOATINGPOINT][LST_VECTOR] = LST_VECTOR;
353 gSupportedExpressionArray[LET_MUL_ASSIGN][LST_VECTOR][LST_VECTOR] = LST_FLOATINGPOINT;
354 gSupportedExpressionArray[LET_MUL_ASSIGN][LST_VECTOR][LST_QUATERNION] = LST_VECTOR;
355 gSupportedExpressionArray[LET_MUL_ASSIGN][LST_QUATERNION][LST_QUATERNION] = LST_QUATERNION;
356
357 // LET_DIV_ASSIGN
358 gSupportedExpressionArray[LET_DIV_ASSIGN][LST_INTEGER][LST_INTEGER] = LST_INTEGER;
359 gSupportedExpressionArray[LET_DIV_ASSIGN][LST_FLOATINGPOINT][LST_INTEGER] = LST_FLOATINGPOINT;
360 gSupportedExpressionArray[LET_DIV_ASSIGN][LST_FLOATINGPOINT][LST_FLOATINGPOINT] = LST_FLOATINGPOINT;
361 gSupportedExpressionArray[LET_DIV_ASSIGN][LST_VECTOR][LST_INTEGER] = LST_VECTOR;
362 gSupportedExpressionArray[LET_DIV_ASSIGN][LST_VECTOR][LST_FLOATINGPOINT] = LST_VECTOR;
363 gSupportedExpressionArray[LET_DIV_ASSIGN][LST_VECTOR][LST_QUATERNION] = LST_VECTOR;
364 gSupportedExpressionArray[LET_DIV_ASSIGN][LST_QUATERNION][LST_QUATERNION] = LST_QUATERNION;
365
366 // LET_MOD_ASSIGN
367 gSupportedExpressionArray[LET_MOD_ASSIGN][LST_INTEGER][LST_INTEGER] = LST_INTEGER;
368 gSupportedExpressionArray[LET_MOD_ASSIGN][LST_VECTOR][LST_VECTOR] = LST_VECTOR;
369
370 // LET_EQUALITY
371 gSupportedExpressionArray[LET_EQUALITY][LST_INTEGER][LST_INTEGER] = LST_INTEGER;
372 gSupportedExpressionArray[LET_EQUALITY][LST_INTEGER][LST_FLOATINGPOINT] = LST_INTEGER;
373 gSupportedExpressionArray[LET_EQUALITY][LST_FLOATINGPOINT][LST_INTEGER] = LST_INTEGER;
374 gSupportedExpressionArray[LET_EQUALITY][LST_FLOATINGPOINT][LST_FLOATINGPOINT] = LST_INTEGER;
375 gSupportedExpressionArray[LET_EQUALITY][LST_STRING][LST_STRING] = LST_INTEGER;
376 gSupportedExpressionArray[LET_EQUALITY][LST_STRING][LST_KEY] = LST_INTEGER;
377 gSupportedExpressionArray[LET_EQUALITY][LST_KEY][LST_STRING] = LST_INTEGER;
378 gSupportedExpressionArray[LET_EQUALITY][LST_KEY][LST_KEY] = LST_INTEGER;
379 gSupportedExpressionArray[LET_EQUALITY][LST_VECTOR][LST_VECTOR] = LST_INTEGER;
380 gSupportedExpressionArray[LET_EQUALITY][LST_QUATERNION][LST_QUATERNION] = LST_INTEGER;
381 gSupportedExpressionArray[LET_EQUALITY][LST_LIST][LST_LIST] = LST_INTEGER;
382
383 // LET_NOT_EQUALS
384 gSupportedExpressionArray[LET_NOT_EQUALS][LST_INTEGER][LST_INTEGER] = LST_INTEGER;
385 gSupportedExpressionArray[LET_NOT_EQUALS][LST_INTEGER][LST_FLOATINGPOINT] = LST_INTEGER;
386 gSupportedExpressionArray[LET_NOT_EQUALS][LST_FLOATINGPOINT][LST_INTEGER] = LST_INTEGER;
387 gSupportedExpressionArray[LET_NOT_EQUALS][LST_FLOATINGPOINT][LST_FLOATINGPOINT] = LST_INTEGER;
388 gSupportedExpressionArray[LET_NOT_EQUALS][LST_STRING][LST_STRING] = LST_INTEGER;
389 gSupportedExpressionArray[LET_NOT_EQUALS][LST_STRING][LST_KEY] = LST_INTEGER;
390 gSupportedExpressionArray[LET_NOT_EQUALS][LST_KEY][LST_STRING] = LST_INTEGER;
391 gSupportedExpressionArray[LET_NOT_EQUALS][LST_KEY][LST_KEY] = LST_INTEGER;
392 gSupportedExpressionArray[LET_NOT_EQUALS][LST_VECTOR][LST_VECTOR] = LST_INTEGER;
393 gSupportedExpressionArray[LET_NOT_EQUALS][LST_QUATERNION][LST_QUATERNION] = LST_INTEGER;
394 gSupportedExpressionArray[LET_NOT_EQUALS][LST_LIST][LST_LIST] = LST_INTEGER;
395
396 // LET_LESS_EQUALS
397 gSupportedExpressionArray[LET_LESS_EQUALS][LST_INTEGER][LST_INTEGER] = LST_INTEGER;
398 gSupportedExpressionArray[LET_LESS_EQUALS][LST_INTEGER][LST_FLOATINGPOINT] = LST_INTEGER;
399 gSupportedExpressionArray[LET_LESS_EQUALS][LST_FLOATINGPOINT][LST_INTEGER] = LST_INTEGER;
400 gSupportedExpressionArray[LET_LESS_EQUALS][LST_FLOATINGPOINT][LST_FLOATINGPOINT] = LST_INTEGER;
401
402 // LET_GREATER_EQUALS
403 gSupportedExpressionArray[LET_GREATER_EQUALS][LST_INTEGER][LST_INTEGER] = LST_INTEGER;
404 gSupportedExpressionArray[LET_GREATER_EQUALS][LST_INTEGER][LST_FLOATINGPOINT] = LST_INTEGER;
405 gSupportedExpressionArray[LET_GREATER_EQUALS][LST_FLOATINGPOINT][LST_INTEGER] = LST_INTEGER;
406 gSupportedExpressionArray[LET_GREATER_EQUALS][LST_FLOATINGPOINT][LST_FLOATINGPOINT] = LST_INTEGER;
407
408 // LET_LESS_THAN
409 gSupportedExpressionArray[LET_LESS_THAN][LST_INTEGER][LST_INTEGER] = LST_INTEGER;
410 gSupportedExpressionArray[LET_LESS_THAN][LST_INTEGER][LST_FLOATINGPOINT] = LST_INTEGER;
411 gSupportedExpressionArray[LET_LESS_THAN][LST_FLOATINGPOINT][LST_INTEGER] = LST_INTEGER;
412 gSupportedExpressionArray[LET_LESS_THAN][LST_FLOATINGPOINT][LST_FLOATINGPOINT] = LST_INTEGER;
413
414 // LET_GREATER_THAN
415 gSupportedExpressionArray[LET_GREATER_THAN][LST_INTEGER][LST_INTEGER] = LST_INTEGER;
416 gSupportedExpressionArray[LET_GREATER_THAN][LST_INTEGER][LST_FLOATINGPOINT] = LST_INTEGER;
417 gSupportedExpressionArray[LET_GREATER_THAN][LST_FLOATINGPOINT][LST_INTEGER] = LST_INTEGER;
418 gSupportedExpressionArray[LET_GREATER_THAN][LST_FLOATINGPOINT][LST_FLOATINGPOINT] = LST_INTEGER;
419
420 // LET_PLUS
421 gSupportedExpressionArray[LET_PLUS][LST_INTEGER][LST_INTEGER] = LST_INTEGER;
422 gSupportedExpressionArray[LET_PLUS][LST_FLOATINGPOINT][LST_INTEGER] = LST_FLOATINGPOINT;
423 gSupportedExpressionArray[LET_PLUS][LST_INTEGER][LST_FLOATINGPOINT] = LST_FLOATINGPOINT;
424 gSupportedExpressionArray[LET_PLUS][LST_FLOATINGPOINT][LST_FLOATINGPOINT] = LST_FLOATINGPOINT;
425 gSupportedExpressionArray[LET_PLUS][LST_STRING][LST_STRING] = LST_STRING;
426 gSupportedExpressionArray[LET_PLUS][LST_VECTOR][LST_VECTOR] = LST_VECTOR;
427 gSupportedExpressionArray[LET_PLUS][LST_QUATERNION][LST_QUATERNION] = LST_QUATERNION;
428 gSupportedExpressionArray[LET_PLUS][LST_LIST][LST_INTEGER] = LST_LIST;
429 gSupportedExpressionArray[LET_PLUS][LST_LIST][LST_FLOATINGPOINT] = LST_LIST;
430 gSupportedExpressionArray[LET_PLUS][LST_LIST][LST_STRING] = LST_LIST;
431 gSupportedExpressionArray[LET_PLUS][LST_LIST][LST_KEY] = LST_LIST;
432 gSupportedExpressionArray[LET_PLUS][LST_LIST][LST_VECTOR] = LST_LIST;
433 gSupportedExpressionArray[LET_PLUS][LST_LIST][LST_QUATERNION] = LST_LIST;
434 gSupportedExpressionArray[LET_PLUS][LST_INTEGER][LST_LIST] = LST_LIST;
435 gSupportedExpressionArray[LET_PLUS][LST_FLOATINGPOINT][LST_LIST] = LST_LIST;
436 gSupportedExpressionArray[LET_PLUS][LST_STRING][LST_LIST] = LST_LIST;
437 gSupportedExpressionArray[LET_PLUS][LST_KEY][LST_LIST] = LST_LIST;
438 gSupportedExpressionArray[LET_PLUS][LST_VECTOR][LST_LIST] = LST_LIST;
439 gSupportedExpressionArray[LET_PLUS][LST_QUATERNION][LST_LIST] = LST_LIST;
440 gSupportedExpressionArray[LET_PLUS][LST_LIST][LST_LIST] = LST_LIST;
441
442 // LET_MINUS
443 gSupportedExpressionArray[LET_MINUS][LST_INTEGER][LST_INTEGER] = LST_INTEGER;
444 gSupportedExpressionArray[LET_MINUS][LST_FLOATINGPOINT][LST_INTEGER] = LST_FLOATINGPOINT;
445 gSupportedExpressionArray[LET_MINUS][LST_INTEGER][LST_FLOATINGPOINT] = LST_FLOATINGPOINT;
446 gSupportedExpressionArray[LET_MINUS][LST_FLOATINGPOINT][LST_FLOATINGPOINT] = LST_FLOATINGPOINT;
447 gSupportedExpressionArray[LET_MINUS][LST_VECTOR][LST_VECTOR] = LST_VECTOR;
448 gSupportedExpressionArray[LET_MINUS][LST_QUATERNION][LST_QUATERNION] = LST_QUATERNION;
449
450 // LET_TIMES
451 gSupportedExpressionArray[LET_TIMES][LST_INTEGER][LST_INTEGER] = LST_INTEGER;
452 gSupportedExpressionArray[LET_TIMES][LST_FLOATINGPOINT][LST_INTEGER] = LST_FLOATINGPOINT;
453 gSupportedExpressionArray[LET_TIMES][LST_INTEGER][LST_FLOATINGPOINT] = LST_FLOATINGPOINT;
454 gSupportedExpressionArray[LET_TIMES][LST_FLOATINGPOINT][LST_FLOATINGPOINT] = LST_FLOATINGPOINT;
455 gSupportedExpressionArray[LET_TIMES][LST_VECTOR][LST_INTEGER] = LST_VECTOR;
456 gSupportedExpressionArray[LET_TIMES][LST_INTEGER][LST_VECTOR] = LST_VECTOR;
457 gSupportedExpressionArray[LET_TIMES][LST_VECTOR][LST_FLOATINGPOINT] = LST_VECTOR;
458 gSupportedExpressionArray[LET_TIMES][LST_FLOATINGPOINT][LST_VECTOR] = LST_VECTOR;
459 gSupportedExpressionArray[LET_TIMES][LST_VECTOR][LST_VECTOR] = LST_FLOATINGPOINT;
460 gSupportedExpressionArray[LET_TIMES][LST_VECTOR][LST_QUATERNION] = LST_VECTOR;
461 gSupportedExpressionArray[LET_TIMES][LST_QUATERNION][LST_QUATERNION] = LST_QUATERNION;
462
463 // LET_DIVIDE
464 gSupportedExpressionArray[LET_DIVIDE][LST_INTEGER][LST_INTEGER] = LST_INTEGER;
465 gSupportedExpressionArray[LET_DIVIDE][LST_INTEGER][LST_FLOATINGPOINT] = LST_FLOATINGPOINT;
466 gSupportedExpressionArray[LET_DIVIDE][LST_FLOATINGPOINT][LST_INTEGER] = LST_FLOATINGPOINT;
467 gSupportedExpressionArray[LET_DIVIDE][LST_FLOATINGPOINT][LST_FLOATINGPOINT] = LST_FLOATINGPOINT;
468 gSupportedExpressionArray[LET_DIVIDE][LST_VECTOR][LST_INTEGER] = LST_VECTOR;
469 gSupportedExpressionArray[LET_DIVIDE][LST_VECTOR][LST_FLOATINGPOINT] = LST_VECTOR;
470 gSupportedExpressionArray[LET_DIVIDE][LST_VECTOR][LST_QUATERNION] = LST_VECTOR;
471 gSupportedExpressionArray[LET_DIVIDE][LST_QUATERNION][LST_QUATERNION] = LST_QUATERNION;
472
473 // LET_MOD
474 gSupportedExpressionArray[LET_MOD][LST_INTEGER][LST_INTEGER] = LST_INTEGER;
475 gSupportedExpressionArray[LET_MOD][LST_VECTOR][LST_VECTOR] = LST_VECTOR;
476
477 // LET_BIT_AND
478 gSupportedExpressionArray[LET_BIT_AND][LST_INTEGER][LST_INTEGER] = LST_INTEGER;
479
480 // LET_BIT_OR
481 gSupportedExpressionArray[LET_BIT_OR][LST_INTEGER][LST_INTEGER] = LST_INTEGER;
482
483 // LET_BIT_XOR
484 gSupportedExpressionArray[LET_BIT_XOR][LST_INTEGER][LST_INTEGER] = LST_INTEGER;
485
486 // LET_BOOLEAN_AND
487 gSupportedExpressionArray[LET_BOOLEAN_AND][LST_INTEGER][LST_INTEGER] = LST_INTEGER;
488
489 // LET_BOOLEAN_OR
490 gSupportedExpressionArray[LET_BOOLEAN_OR][LST_INTEGER][LST_INTEGER] = LST_INTEGER;
491
492 // LET_SHIFT_LEFT
493 gSupportedExpressionArray[LET_SHIFT_LEFT][LST_INTEGER][LST_INTEGER] = LST_INTEGER;
494
495 // LET_SHIFT_RIGHT
496 gSupportedExpressionArray[LET_SHIFT_RIGHT][LST_INTEGER][LST_INTEGER] = LST_INTEGER;
497
498 // LET_PARENTHESIS
499 gSupportedExpressionArray[LET_PARENTHESIS][LST_INTEGER][LST_NULL] = LST_INTEGER;
500 gSupportedExpressionArray[LET_PARENTHESIS][LST_FLOATINGPOINT][LST_NULL] = LST_INTEGER;
501 gSupportedExpressionArray[LET_PARENTHESIS][LST_STRING][LST_NULL] = LST_INTEGER;
502 gSupportedExpressionArray[LET_PARENTHESIS][LST_LIST][LST_NULL] = LST_INTEGER;
503
504 // LET_UNARY_MINUS
505 gSupportedExpressionArray[LET_UNARY_MINUS][LST_INTEGER][LST_NULL] = LST_INTEGER;
506 gSupportedExpressionArray[LET_UNARY_MINUS][LST_FLOATINGPOINT][LST_NULL] = LST_FLOATINGPOINT;
507 gSupportedExpressionArray[LET_UNARY_MINUS][LST_VECTOR][LST_NULL] = LST_VECTOR;
508 gSupportedExpressionArray[LET_UNARY_MINUS][LST_QUATERNION][LST_NULL] = LST_QUATERNION;
509
510 // LET_BOOLEAN_NOT
511 gSupportedExpressionArray[LET_BOOLEAN_NOT][LST_INTEGER][LST_NULL] = LST_INTEGER;
512
513 // LET_BIT_NOT
514 gSupportedExpressionArray[LET_BIT_NOT][LST_INTEGER][LST_NULL] = LST_INTEGER;
515
516 // LET_PRE_INCREMENT
517 gSupportedExpressionArray[LET_PRE_INCREMENT][LST_INTEGER][LST_NULL] = LST_INTEGER;
518 gSupportedExpressionArray[LET_PRE_INCREMENT][LST_FLOATINGPOINT][LST_NULL] = LST_FLOATINGPOINT;
519
520 // LET_PRE_DECREMENT
521 gSupportedExpressionArray[LET_PRE_DECREMENT][LST_INTEGER][LST_NULL] = LST_INTEGER;
522 gSupportedExpressionArray[LET_PRE_DECREMENT][LST_FLOATINGPOINT][LST_NULL] = LST_FLOATINGPOINT;
523
524 // LET_POST_INCREMENT
525 gSupportedExpressionArray[LET_POST_INCREMENT][LST_INTEGER][LST_NULL] = LST_INTEGER;
526 gSupportedExpressionArray[LET_POST_INCREMENT][LST_FLOATINGPOINT][LST_NULL] = LST_FLOATINGPOINT;
527
528 // LET_POST_DECREMENT
529 gSupportedExpressionArray[LET_POST_DECREMENT][LST_INTEGER][LST_NULL] = LST_INTEGER;
530 gSupportedExpressionArray[LET_POST_DECREMENT][LST_FLOATINGPOINT][LST_NULL] = LST_FLOATINGPOINT;
531}
532
533BOOL legal_binary_expression(LSCRIPTType &result, LSCRIPTType left_side, LSCRIPTType right_side, LSCRIPTExpressionType expression)
534{
535 if ( (left_side == LST_UNDEFINED)
536 ||(right_side == LST_UNDEFINED))
537 {
538 result = LST_UNDEFINED;
539 return TRUE;
540 }
541
542 if ( (left_side == LST_NULL)
543 ||(right_side == LST_NULL))
544 {
545 result = LST_UNDEFINED;
546 return FALSE;
547 }
548
549 result = gSupportedExpressionArray[expression][left_side][right_side];
550 if (result)
551 return TRUE;
552 else
553 {
554 result = LST_UNDEFINED;
555 return FALSE;
556 }
557}
558
559BOOL legal_unary_expression(LSCRIPTType &result, LSCRIPTType left_side, LSCRIPTExpressionType expression)
560{
561 if (left_side == LST_UNDEFINED)
562 {
563 result = LST_UNDEFINED;
564 return TRUE;
565 }
566
567 if (left_side == LST_NULL)
568 {
569 result = LST_UNDEFINED;
570 return FALSE;
571 }
572
573 result = gSupportedExpressionArray[expression][left_side][LST_NULL];
574 if (result)
575 return TRUE;
576 else
577 {
578 result = LST_UNDEFINED;
579 return FALSE;
580 }
581}
diff --git a/linden/indra/lscript/lscript_compile/lscript_typecheck.h b/linden/indra/lscript/lscript_compile/lscript_typecheck.h
new file mode 100644
index 0000000..4867a25
--- /dev/null
+++ b/linden/indra/lscript/lscript_compile/lscript_typecheck.h
@@ -0,0 +1,119 @@
1/**
2 * @file lscript_typecheck.h
3 * @brief typechecks script
4 *
5 * Copyright (c) 2002-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28#ifndef LL_LSCRIPT_TYPECHECK_H
29#define LL_LSCRIPT_TYPECHECK_H
30
31#include "lscript_error.h"
32
33LSCRIPTType implicit_casts(LSCRIPTType left_side, LSCRIPTType right_side);
34BOOL legal_casts(LSCRIPTType cast, LSCRIPTType base);
35LSCRIPTType promote(LSCRIPTType left_side, LSCRIPTType right_side);
36BOOL legal_assignment(LSCRIPTType left_side, LSCRIPTType right_side);
37
38typedef enum e_lscript_expression_types
39{
40 LET_NULL,
41 LET_ASSIGNMENT,
42 LET_ADD_ASSIGN,
43 LET_SUB_ASSIGN,
44 LET_MUL_ASSIGN,
45 LET_DIV_ASSIGN,
46 LET_MOD_ASSIGN,
47 LET_EQUALITY,
48 LET_NOT_EQUALS,
49 LET_LESS_EQUALS,
50 LET_GREATER_EQUALS,
51 LET_LESS_THAN,
52 LET_GREATER_THAN,
53 LET_PLUS,
54 LET_MINUS,
55 LET_TIMES,
56 LET_DIVIDE,
57 LET_MOD,
58 LET_BIT_AND,
59 LET_BIT_OR,
60 LET_BIT_XOR,
61 LET_BOOLEAN_AND,
62 LET_BOOLEAN_OR,
63 LET_PARENTHESIS,
64 LET_UNARY_MINUS,
65 LET_BOOLEAN_NOT,
66 LET_BIT_NOT,
67 LET_PRE_INCREMENT,
68 LET_PRE_DECREMENT,
69 LET_CAST,
70 LET_VECTOR_INITIALIZER,
71 LET_QUATERNION_INITIALIZER,
72 LET_LIST_INITIALIZER,
73 LET_LVALUE,
74 LET_POST_INCREMENT,
75 LET_POST_DECREMENT,
76 LET_FUNCTION_CALL,
77 LET_CONSTANT,
78 LET_FOR_EXPRESSION_LIST,
79 LET_FUNC_EXPRESSION_LIST,
80 LET_LIST_EXPRESSION_LIST,
81 LET_PRINT,
82 LET_SHIFT_LEFT,
83 LET_SHIFT_RIGHT,
84 LET_EOF
85} LSCRIPTExpressionType;
86
87BOOL legal_binary_expression(LSCRIPTType &result, LSCRIPTType left_side, LSCRIPTType right_side, LSCRIPTExpressionType expression);
88BOOL legal_unary_expression(LSCRIPTType &result, LSCRIPTType left_side, LSCRIPTExpressionType expression);
89
90void init_supported_expressions(void);
91
92/*
93 LScript automatic type casting
94
95 LST_INTEGER -> LST_INTEGER
96
97 LST_FLOATINGPOINT -> LST_FLOATINGPOINT
98 LST_INTEGER -> LST_FLOATINGPOINT
99
100 LST_FLOATINGPOINT -> LST_STRING
101 LST_INTEGER -> LST_STRING
102 LST_STRING -> LST_STRING
103 LST_VECTOR -> LST_STRING
104 LST_QUATERNION -> LST_STRING
105 LST_LIST -> LST_STRING
106
107 LST_VECTOR -> LST_VECTOR
108
109 LST_QUATERNION -> LST_QUATERNION
110
111 LST_FLOATINGPOINT -> LST_LIST
112 LST_INTEGER -> LST_LIST
113 LST_STRING -> LST_LIST
114 LST_VECTOR -> LST_LIST
115 LST_QUATERNION -> LST_LIST
116 LST_LIST -> LST_LIST
117*/
118
119#endif
diff --git a/linden/indra/lscript/lscript_execute.h b/linden/indra/lscript/lscript_execute.h
new file mode 100644
index 0000000..736095a
--- /dev/null
+++ b/linden/indra/lscript/lscript_execute.h
@@ -0,0 +1,383 @@
1/**
2 * @file lscript_execute.h
3 * @brief Classes to execute bytecode
4 *
5 * Copyright (c) 2002-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28#ifndef LL_LSCRIPT_EXECUTE_H
29#define LL_LSCRIPT_EXECUTE_H
30
31#include <stdio.h>
32#include "lscript_byteconvert.h"
33#include "linked_lists.h"
34#include "lscript_library.h"
35
36// Return values for run() methods
37const U32 NO_DELETE_FLAG = 0x0000;
38const U32 DELETE_FLAG = 0x0001;
39const U32 CREDIT_MONEY_FLAG = 0x0002;
40
41// list of op code execute functions
42BOOL run_noop(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
43BOOL run_pop(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
44BOOL run_pops(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
45BOOL run_popl(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
46BOOL run_popv(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
47BOOL run_popq(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
48BOOL run_poparg(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
49BOOL run_popip(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
50BOOL run_popbp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
51BOOL run_popsp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
52BOOL run_popslr(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
53
54BOOL run_dup(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
55BOOL run_dups(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
56BOOL run_dupl(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
57BOOL run_dupv(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
58BOOL run_dupq(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
59
60BOOL run_store(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
61BOOL run_stores(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
62BOOL run_storel(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
63BOOL run_storev(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
64BOOL run_storeq(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
65BOOL run_storeg(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
66BOOL run_storegs(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
67BOOL run_storegl(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
68BOOL run_storegv(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
69BOOL run_storegq(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
70BOOL run_loadp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
71BOOL run_loadsp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
72BOOL run_loadlp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
73BOOL run_loadvp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
74BOOL run_loadqp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
75BOOL run_loadgp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
76BOOL run_loadgsp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
77BOOL run_loadglp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
78BOOL run_loadgvp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
79BOOL run_loadgqp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
80
81BOOL run_push(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
82BOOL run_pushs(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
83BOOL run_pushl(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
84BOOL run_pushv(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
85BOOL run_pushq(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
86BOOL run_pushg(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
87BOOL run_pushgs(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
88BOOL run_pushgl(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
89BOOL run_pushgv(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
90BOOL run_pushgq(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
91BOOL run_puship(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
92BOOL run_pushbp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
93BOOL run_pushsp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
94BOOL run_pushargb(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
95BOOL run_pushargi(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
96BOOL run_pushargf(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
97BOOL run_pushargs(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
98BOOL run_pushargv(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
99BOOL run_pushargq(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
100BOOL run_pushe(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
101BOOL run_pushev(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
102BOOL run_pusheq(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
103BOOL run_pusharge(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
104
105BOOL run_add(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
106BOOL run_sub(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
107BOOL run_mul(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
108BOOL run_div(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
109BOOL run_mod(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
110
111BOOL run_eq(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
112BOOL run_neq(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
113BOOL run_leq(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
114BOOL run_geq(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
115BOOL run_less(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
116BOOL run_greater(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
117
118BOOL run_bitand(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
119BOOL run_bitor(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
120BOOL run_bitxor(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
121BOOL run_booland(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
122BOOL run_boolor(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
123
124BOOL run_shl(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
125BOOL run_shr(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
126
127BOOL run_neg(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
128BOOL run_bitnot(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
129BOOL run_boolnot(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
130
131BOOL run_jump(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
132BOOL run_jumpif(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
133BOOL run_jumpnif(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
134
135BOOL run_state(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
136BOOL run_call(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
137BOOL run_return(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
138BOOL run_cast(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
139BOOL run_stacktos(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
140BOOL run_stacktol(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
141
142BOOL run_print(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
143
144BOOL run_calllib(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
145BOOL run_calllib_two_byte(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
146
147void unknown_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode);
148void integer_integer_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode);
149void integer_float_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode);
150void integer_vector_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode);
151void float_integer_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode);
152void float_float_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode);
153void float_vector_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode);
154void string_string_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode);
155void string_key_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode);
156void key_string_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode);
157void key_key_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode);
158void vector_integer_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode);
159void vector_float_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode);
160void vector_vector_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode);
161void vector_quaternion_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode);
162void quaternion_quaternion_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode);
163
164
165void integer_list_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode);
166void float_list_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode);
167void string_list_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode);
168void key_list_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode);
169void vector_list_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode);
170void quaternion_list_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode);
171void list_integer_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode);
172void list_float_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode);
173void list_string_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode);
174void list_key_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode);
175void list_vector_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode);
176void list_quaternion_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode);
177void list_list_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode);
178
179void integer_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode);
180void float_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode);
181void vector_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode);
182void quaternion_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode);
183
184class LLScriptDataCollection
185{
186public:
187 LLScriptDataCollection(LSCRIPTStateEventType type, LLScriptLibData *data)
188 : mType(type), mData(data)
189 {
190 }
191 LLScriptDataCollection(U8 *src, S32 &offset)
192 {
193 S32 i, number;
194 mType = (LSCRIPTStateEventType)bytestream2integer(src, offset);
195 number = bytestream2integer(src, offset);
196
197 mData = new LLScriptLibData[number];
198
199 for (i = 0; i < number; i++)
200 {
201 mData[i].set(src, offset);
202 }
203
204 }
205
206 ~LLScriptDataCollection()
207 {
208 delete [] mData;
209 mData = NULL;
210 }
211
212 S32 getSavedSize()
213 {
214 S32 size = 0;
215 // mTyoe
216 size += 4;
217 // number of entries
218 size += 4;
219
220 S32 i = 0;
221 do
222 {
223 size += mData[i].getSavedSize();;
224 }
225 while (mData[i++].mType != LST_NULL);
226 return size;
227 }
228
229 S32 write2bytestream(U8 *dest)
230 {
231 S32 offset = 0;
232 // mTyoe
233 integer2bytestream(dest, offset, mType);
234 // count number of entries
235 S32 number = 0;
236 while (mData[number++].mType != LST_NULL)
237 ;
238 integer2bytestream(dest, offset, number);
239
240 // now the entries themselves
241 number = 0;
242 do
243 {
244 offset += mData[number].write2bytestream(dest + offset);
245 }
246 while (mData[number++].mType != LST_NULL);
247 return offset;
248 }
249
250
251 LSCRIPTStateEventType mType;
252 LLScriptLibData *mData;
253};
254const S32 MAX_EVENTS_IN_QUEUE = 64;
255
256class LLScriptEventData
257{
258public:
259 LLScriptEventData() {}
260 LLScriptEventData(U8 *src, S32 &offset)
261 {
262 S32 i, number = bytestream2integer(src, offset);
263 for (i = 0; i < number; i++)
264 {
265 mEventDataList.addData(new LLScriptDataCollection(src, offset));
266 }
267 }
268
269 void set(U8 *src, S32 &offset)
270 {
271 S32 i, number = bytestream2integer(src, offset);
272 for (i = 0; i < number; i++)
273 {
274 mEventDataList.addData(new LLScriptDataCollection(src, offset));
275 }
276 }
277
278 ~LLScriptEventData()
279 {
280 mEventDataList.deleteAllData();
281 }
282
283 void addEventData(LLScriptDataCollection *data)
284 {
285 if (mEventDataList.getLength() < MAX_EVENTS_IN_QUEUE)
286 mEventDataList.addDataAtEnd(data);
287 else
288 delete data;
289 }
290 LLScriptDataCollection *getNextEvent(LSCRIPTStateEventType type)
291 {
292 LLScriptDataCollection *temp;
293 for (temp = mEventDataList.getFirstData();
294 temp;
295 temp = mEventDataList.getNextData())
296 {
297 if (temp->mType == type)
298 {
299 mEventDataList.removeCurrentData();
300 return temp;
301 }
302 }
303 return NULL;
304 }
305 LLScriptDataCollection *getNextEvent()
306 {
307 LLScriptDataCollection *temp;
308 temp = mEventDataList.getFirstData();
309 if (temp)
310 {
311 mEventDataList.removeCurrentData();
312 return temp;
313 }
314 return NULL;
315 }
316 void removeEventType(LSCRIPTStateEventType type)
317 {
318 LLScriptDataCollection *temp;
319 for (temp = mEventDataList.getFirstData();
320 temp;
321 temp = mEventDataList.getNextData())
322 {
323 if (temp->mType == type)
324 {
325 mEventDataList.deleteCurrentData();
326 }
327 }
328 }
329
330 S32 getSavedSize()
331 {
332 S32 size = 0;
333 // number in linked list
334 size += 4;
335 LLScriptDataCollection *temp;
336 for (temp = mEventDataList.getFirstData();
337 temp;
338 temp = mEventDataList.getNextData())
339 {
340 size += temp->getSavedSize();
341 }
342 return size;
343 }
344
345 S32 write2bytestream(U8 *dest)
346 {
347 S32 offset = 0;
348 // number in linked list
349 S32 number = mEventDataList.getLength();
350 integer2bytestream(dest, offset, number);
351 LLScriptDataCollection *temp;
352 for (temp = mEventDataList.getFirstData();
353 temp;
354 temp = mEventDataList.getNextData())
355 {
356 offset += temp->write2bytestream(dest + offset);
357 }
358 return offset;
359 }
360
361 LLLinkedList<LLScriptDataCollection> mEventDataList;
362};
363
364class LLScriptExecute
365{
366public:
367 LLScriptExecute(FILE *fp);
368 LLScriptExecute(U8 *buffer);
369 ~LLScriptExecute();
370
371 void init();
372 U32 run(BOOL b_print, const LLUUID &id, char **errorstr, BOOL &state_transition);
373
374 BOOL (*mExecuteFuncs[0x100])(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id);
375
376 U32 mInstructionCount;
377 U8 *mBuffer;
378 LLScriptEventData mEventData;
379
380 static S64 sGlobalInstructionCount;
381};
382
383#endif
diff --git a/linden/indra/lscript/lscript_execute/lscript_execute.cpp b/linden/indra/lscript/lscript_execute/lscript_execute.cpp
new file mode 100644
index 0000000..a81d706
--- /dev/null
+++ b/linden/indra/lscript/lscript_execute/lscript_execute.cpp
@@ -0,0 +1,3929 @@
1/**
2 * @file lscript_execute.cpp
3 * @brief classes to execute bytecode
4 *
5 * Copyright (c) 2002-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28#include "linden_common.h"
29
30#include <sstream>
31
32#include "lscript_execute.h"
33#include "lltimer.h"
34#include "lscript_readlso.h"
35#include "lscript_library.h"
36#include "lscript_heapruntime.h"
37#include "lscript_alloc.h"
38
39void (*binary_operations[LST_EOF][LST_EOF])(U8 *buffer, LSCRIPTOpCodesEnum opcode);
40void (*unary_operations[LST_EOF])(U8 *buffer, LSCRIPTOpCodesEnum opcode);
41
42char *LSCRIPTRunTimeFaultStrings[LSRF_EOF] =
43{
44 "invalid", // LSRF_INVALID,
45 "Math Error", // LSRF_MATH,
46 "Stack-Heap Collision", // LSRF_STACK_HEAP_COLLISION,
47 "Bounds Check Error", // LSRF_BOUND_CHECK_ERROR,
48 "Heap Error", // LSRF_HEAP_ERROR,
49 "Version Mismatch", // LSRF_VERSION_MISMATCH,
50 "Missing Inventory", // LSRF_MISSING_INVENTORY,
51 "Hit Sandbox Limit", // LSRF_SANDBOX,
52 "Chat Overrun", // LSRF_CHAT_OVERRUN,
53 "Too Many Listens", // LSRF_TOO_MANY_LISTENS,
54 "Lists may not contain lists" // LSRF_NESTING_LISTS,
55};
56
57//static
58S64 LLScriptExecute::sGlobalInstructionCount = 0;
59
60LLScriptExecute::LLScriptExecute(FILE *fp)
61{
62 U8 sizearray[4];
63 S32 filesize;
64 S32 pos = 0;
65 fread(&sizearray, 1, 4, fp);
66 filesize = bytestream2integer(sizearray, pos);
67 mBuffer = new U8[filesize];
68 fseek(fp, 0, SEEK_SET);
69 fread(mBuffer, 1, filesize, fp);
70 fclose(fp);
71
72 init();
73}
74
75LLScriptExecute::LLScriptExecute(U8 *buffer)
76{
77 mBuffer = buffer;
78
79 init();
80}
81
82LLScriptExecute::~LLScriptExecute()
83{
84 delete [] mBuffer;
85}
86
87void LLScriptExecute::init()
88{
89 S32 i, j;
90
91 mInstructionCount = 0;
92
93 for (i = 0; i < 256; i++)
94 {
95 mExecuteFuncs[i] = run_noop;
96 }
97 mExecuteFuncs[LSCRIPTOpCodes[LOPC_NOOP]] = run_noop;
98
99 mExecuteFuncs[LSCRIPTOpCodes[LOPC_POP]] = run_pop;
100 mExecuteFuncs[LSCRIPTOpCodes[LOPC_POPS]] = run_pops;
101 mExecuteFuncs[LSCRIPTOpCodes[LOPC_POPL]] = run_popl;
102 mExecuteFuncs[LSCRIPTOpCodes[LOPC_POPV]] = run_popv;
103 mExecuteFuncs[LSCRIPTOpCodes[LOPC_POPQ]] = run_popq;
104 mExecuteFuncs[LSCRIPTOpCodes[LOPC_POPARG]] = run_poparg;
105 mExecuteFuncs[LSCRIPTOpCodes[LOPC_POPIP]] = run_popip;
106 mExecuteFuncs[LSCRIPTOpCodes[LOPC_POPBP]] = run_popbp;
107 mExecuteFuncs[LSCRIPTOpCodes[LOPC_POPSP]] = run_popsp;
108 mExecuteFuncs[LSCRIPTOpCodes[LOPC_POPSLR]] = run_popslr;
109
110 mExecuteFuncs[LSCRIPTOpCodes[LOPC_DUP]] = run_dup;
111 mExecuteFuncs[LSCRIPTOpCodes[LOPC_DUPS]] = run_dups;
112 mExecuteFuncs[LSCRIPTOpCodes[LOPC_DUPL]] = run_dupl;
113 mExecuteFuncs[LSCRIPTOpCodes[LOPC_DUPV]] = run_dupv;
114 mExecuteFuncs[LSCRIPTOpCodes[LOPC_DUPQ]] = run_dupq;
115
116 mExecuteFuncs[LSCRIPTOpCodes[LOPC_STORE]] = run_store;
117 mExecuteFuncs[LSCRIPTOpCodes[LOPC_STORES]] = run_stores;
118 mExecuteFuncs[LSCRIPTOpCodes[LOPC_STOREL]] = run_storel;
119 mExecuteFuncs[LSCRIPTOpCodes[LOPC_STOREV]] = run_storev;
120 mExecuteFuncs[LSCRIPTOpCodes[LOPC_STOREQ]] = run_storeq;
121 mExecuteFuncs[LSCRIPTOpCodes[LOPC_STOREG]] = run_storeg;
122 mExecuteFuncs[LSCRIPTOpCodes[LOPC_STOREGL]] = run_storegl;
123 mExecuteFuncs[LSCRIPTOpCodes[LOPC_STOREGS]] = run_storegs;
124 mExecuteFuncs[LSCRIPTOpCodes[LOPC_STOREGV]] = run_storegv;
125 mExecuteFuncs[LSCRIPTOpCodes[LOPC_STOREGQ]] = run_storegq;
126 mExecuteFuncs[LSCRIPTOpCodes[LOPC_LOADP]] = run_loadp;
127 mExecuteFuncs[LSCRIPTOpCodes[LOPC_LOADSP]] = run_loadsp;
128 mExecuteFuncs[LSCRIPTOpCodes[LOPC_LOADLP]] = run_loadlp;
129 mExecuteFuncs[LSCRIPTOpCodes[LOPC_LOADVP]] = run_loadvp;
130 mExecuteFuncs[LSCRIPTOpCodes[LOPC_LOADQP]] = run_loadqp;
131 mExecuteFuncs[LSCRIPTOpCodes[LOPC_LOADGP]] = run_loadgp;
132 mExecuteFuncs[LSCRIPTOpCodes[LOPC_LOADGSP]] = run_loadgsp;
133 mExecuteFuncs[LSCRIPTOpCodes[LOPC_LOADGLP]] = run_loadglp;
134 mExecuteFuncs[LSCRIPTOpCodes[LOPC_LOADGVP]] = run_loadgvp;
135 mExecuteFuncs[LSCRIPTOpCodes[LOPC_LOADGQP]] = run_loadgqp;
136
137 mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSH]] = run_push;
138 mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHS]] = run_pushs;
139 mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHL]] = run_pushl;
140 mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHV]] = run_pushv;
141 mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHQ]] = run_pushq;
142 mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHG]] = run_pushg;
143 mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHGS]] = run_pushgs;
144 mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHGL]] = run_pushgl;
145 mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHGV]] = run_pushgv;
146 mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHGQ]] = run_pushgq;
147 mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHIP]] = run_puship;
148 mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHSP]] = run_pushsp;
149 mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHBP]] = run_pushbp;
150 mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHARGB]] = run_pushargb;
151 mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHARGI]] = run_pushargi;
152 mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHARGF]] = run_pushargf;
153 mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHARGS]] = run_pushargs;
154 mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHARGV]] = run_pushargv;
155 mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHARGQ]] = run_pushargq;
156 mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHE]] = run_pushe;
157 mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHEV]] = run_pushev;
158 mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHEQ]] = run_pusheq;
159 mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHARGE]] = run_pusharge;
160
161 mExecuteFuncs[LSCRIPTOpCodes[LOPC_ADD]] = run_add;
162 mExecuteFuncs[LSCRIPTOpCodes[LOPC_SUB]] = run_sub;
163 mExecuteFuncs[LSCRIPTOpCodes[LOPC_MUL]] = run_mul;
164 mExecuteFuncs[LSCRIPTOpCodes[LOPC_DIV]] = run_div;
165 mExecuteFuncs[LSCRIPTOpCodes[LOPC_MOD]] = run_mod;
166
167 mExecuteFuncs[LSCRIPTOpCodes[LOPC_EQ]] = run_eq;
168 mExecuteFuncs[LSCRIPTOpCodes[LOPC_NEQ]] = run_neq;
169 mExecuteFuncs[LSCRIPTOpCodes[LOPC_LEQ]] = run_leq;
170 mExecuteFuncs[LSCRIPTOpCodes[LOPC_GEQ]] = run_geq;
171 mExecuteFuncs[LSCRIPTOpCodes[LOPC_LESS]] = run_less;
172 mExecuteFuncs[LSCRIPTOpCodes[LOPC_GREATER]] = run_greater;
173
174 mExecuteFuncs[LSCRIPTOpCodes[LOPC_BITAND]] = run_bitand;
175 mExecuteFuncs[LSCRIPTOpCodes[LOPC_BITOR]] = run_bitor;
176 mExecuteFuncs[LSCRIPTOpCodes[LOPC_BITXOR]] = run_bitxor;
177
178 mExecuteFuncs[LSCRIPTOpCodes[LOPC_BOOLAND]] = run_booland;
179 mExecuteFuncs[LSCRIPTOpCodes[LOPC_BOOLOR]] = run_boolor;
180
181 mExecuteFuncs[LSCRIPTOpCodes[LOPC_SHL]] = run_shl;
182 mExecuteFuncs[LSCRIPTOpCodes[LOPC_SHR]] = run_shr;
183
184 mExecuteFuncs[LSCRIPTOpCodes[LOPC_NEG]] = run_neg;
185 mExecuteFuncs[LSCRIPTOpCodes[LOPC_BITNOT]] = run_bitnot;
186 mExecuteFuncs[LSCRIPTOpCodes[LOPC_BOOLNOT]] = run_boolnot;
187
188 mExecuteFuncs[LSCRIPTOpCodes[LOPC_JUMP]] = run_jump;
189 mExecuteFuncs[LSCRIPTOpCodes[LOPC_JUMPIF]] = run_jumpif;
190 mExecuteFuncs[LSCRIPTOpCodes[LOPC_JUMPNIF]] = run_jumpnif;
191
192 mExecuteFuncs[LSCRIPTOpCodes[LOPC_STATE]] = run_state;
193 mExecuteFuncs[LSCRIPTOpCodes[LOPC_CALL]] = run_call;
194 mExecuteFuncs[LSCRIPTOpCodes[LOPC_RETURN]] = run_return;
195 mExecuteFuncs[LSCRIPTOpCodes[LOPC_CAST]] = run_cast;
196 mExecuteFuncs[LSCRIPTOpCodes[LOPC_STACKTOS]] = run_stacktos;
197 mExecuteFuncs[LSCRIPTOpCodes[LOPC_STACKTOL]] = run_stacktol;
198
199 mExecuteFuncs[LSCRIPTOpCodes[LOPC_PRINT]] = run_print;
200
201 mExecuteFuncs[LSCRIPTOpCodes[LOPC_CALLLIB]] = run_calllib;
202 mExecuteFuncs[LSCRIPTOpCodes[LOPC_CALLLIB_TWO_BYTE]] = run_calllib_two_byte;
203
204 for (i = 0; i < LST_EOF; i++)
205 {
206 for (j = 0; j < LST_EOF; j++)
207 {
208 binary_operations[i][j] = unknown_operation;
209 }
210 }
211
212 binary_operations[LST_INTEGER][LST_INTEGER] = integer_integer_operation;
213 binary_operations[LST_INTEGER][LST_FLOATINGPOINT] = integer_float_operation;
214 binary_operations[LST_INTEGER][LST_VECTOR] = integer_vector_operation;
215
216 binary_operations[LST_FLOATINGPOINT][LST_INTEGER] = float_integer_operation;
217 binary_operations[LST_FLOATINGPOINT][LST_FLOATINGPOINT] = float_float_operation;
218 binary_operations[LST_FLOATINGPOINT][LST_VECTOR] = float_vector_operation;
219
220 binary_operations[LST_STRING][LST_STRING] = string_string_operation;
221 binary_operations[LST_STRING][LST_KEY] = string_key_operation;
222
223 binary_operations[LST_KEY][LST_STRING] = key_string_operation;
224 binary_operations[LST_KEY][LST_KEY] = key_key_operation;
225
226 binary_operations[LST_VECTOR][LST_INTEGER] = vector_integer_operation;
227 binary_operations[LST_VECTOR][LST_FLOATINGPOINT] = vector_float_operation;
228 binary_operations[LST_VECTOR][LST_VECTOR] = vector_vector_operation;
229 binary_operations[LST_VECTOR][LST_QUATERNION] = vector_quaternion_operation;
230
231 binary_operations[LST_QUATERNION][LST_QUATERNION] = quaternion_quaternion_operation;
232
233 binary_operations[LST_INTEGER][LST_LIST] = integer_list_operation;
234 binary_operations[LST_FLOATINGPOINT][LST_LIST] = float_list_operation;
235 binary_operations[LST_STRING][LST_LIST] = string_list_operation;
236 binary_operations[LST_KEY][LST_LIST] = key_list_operation;
237 binary_operations[LST_VECTOR][LST_LIST] = vector_list_operation;
238 binary_operations[LST_QUATERNION][LST_LIST] = quaternion_list_operation;
239 binary_operations[LST_LIST][LST_INTEGER] = list_integer_operation;
240 binary_operations[LST_LIST][LST_FLOATINGPOINT] = list_float_operation;
241 binary_operations[LST_LIST][LST_STRING] = list_string_operation;
242 binary_operations[LST_LIST][LST_KEY] = list_key_operation;
243 binary_operations[LST_LIST][LST_VECTOR] = list_vector_operation;
244 binary_operations[LST_LIST][LST_QUATERNION] = list_quaternion_operation;
245 binary_operations[LST_LIST][LST_LIST] = list_list_operation;
246
247 for (i = 0; i < LST_EOF; i++)
248 {
249 unary_operations[i] = unknown_operation;
250 }
251
252 unary_operations[LST_INTEGER] = integer_operation;
253 unary_operations[LST_FLOATINGPOINT] = float_operation;
254 unary_operations[LST_VECTOR] = vector_operation;
255 unary_operations[LST_QUATERNION] = quaternion_operation;
256
257}
258
259S32 lscript_push_variable(LLScriptLibData *data, U8 *buffer);
260
261U32 LLScriptExecute::run(BOOL b_print, const LLUUID &id, char **errorstr, BOOL &state_transition)
262{
263 // is there a fault?
264 // if yes, print out message and exit
265 state_transition = FALSE;
266 S32 value = get_register(mBuffer, LREG_VN);
267 S32 major_version = 0;
268 if (value == LSL2_VERSION1_END_NUMBER)
269 {
270 major_version = 1;
271 }
272 else if (value == LSL2_VERSION_NUMBER)
273 {
274 major_version = 2;
275 }
276 else
277 {
278 set_fault(mBuffer, LSRF_VERSION_MISMATCH);
279 }
280 value = get_register(mBuffer, LREG_FR);
281 if (value)
282 {
283 if (b_print)
284 {
285 printf("Error!\n");
286 }
287 *errorstr = LSCRIPTRunTimeFaultStrings[value];
288 return NO_DELETE_FLAG;
289 }
290 else
291 {
292 *errorstr = NULL;
293 }
294
295 // Get IP
296 // is IP nonzero?
297 value = get_register(mBuffer, LREG_IP);
298
299 if (value)
300 {
301 // if yes, we're in opcodes, execute the next opcode by:
302 // call opcode run function pointer with buffer and IP
303 mInstructionCount++;
304 sGlobalInstructionCount++;
305 S32 tvalue = value;
306 S32 opcode = safe_instruction_bytestream2byte(mBuffer, tvalue);
307 S32 b_ret_val = mExecuteFuncs[opcode](mBuffer, value, b_print, id);
308 set_ip(mBuffer, value);
309 add_register_fp(mBuffer, LREG_ESR, -0.1f);
310 // lsa_print_heap(mBuffer);
311
312 if (b_print)
313 {
314 lsa_print_heap(mBuffer);
315 printf("ip: 0x%X\n", get_register(mBuffer, LREG_IP));
316 printf("sp: 0x%X\n", get_register(mBuffer, LREG_SP));
317 printf("bp: 0x%X\n", get_register(mBuffer, LREG_BP));
318 printf("hr: 0x%X\n", get_register(mBuffer, LREG_HR));
319 printf("hp: 0x%X\n", get_register(mBuffer, LREG_HP));
320 }
321 // update IP
322 if (b_ret_val)
323 {
324 return DELETE_FLAG | CREDIT_MONEY_FLAG;
325 }
326 else
327 {
328 return NO_DELETE_FLAG;
329 }
330 }
331 else
332 {
333 // make sure that IE is zero
334 set_event_register(mBuffer, LREG_IE, 0, major_version);
335
336 // if no, we're in a state and waiting for an event
337 S32 next_state = get_register(mBuffer, LREG_NS);
338 S32 current_state = get_register(mBuffer, LREG_CS);
339 U64 current_events = get_event_register(mBuffer, LREG_CE, major_version);
340 U64 event_register = get_event_register(mBuffer, LREG_ER, major_version);
341 // check NS to see if need to switch states (NS != CS)
342 if (next_state != current_state)
343 {
344 state_transition = TRUE;
345 // ok, blow away any pending events
346 mEventData.mEventDataList.deleteAllData();
347
348 // if yes, check state exit flag is set
349 if (current_events & LSCRIPTStateBitField[LSTT_STATE_EXIT])
350 {
351 // if yes, clear state exit flag
352 set_event_register(mBuffer, LREG_IE, LSCRIPTStateBitField[LSTT_STATE_EXIT], major_version);
353 current_events &= ~LSCRIPTStateBitField[LSTT_STATE_EXIT];
354 set_event_register(mBuffer, LREG_CE, current_events, major_version);
355 // check state exit event handler
356 // if there is a handler, call it
357 if (event_register & LSCRIPTStateBitField[LSTT_STATE_EXIT])
358 {
359 // push a zero to be popped
360 lscript_push(mBuffer, 0);
361 // push sp as current bp
362 S32 sp = get_register(mBuffer, LREG_SP);
363 lscript_push(mBuffer, sp);
364
365 // now, push any additional stack space
366 S32 additional_size = get_event_stack_size(mBuffer, current_state, LSTT_STATE_EXIT);
367 lscript_pusharge(mBuffer, additional_size);
368
369 sp = get_register(mBuffer, LREG_SP);
370 sp += additional_size;
371 set_bp(mBuffer, sp);
372 // set IP to the event handler
373 S32 opcode_start = get_state_event_opcoode_start(mBuffer, current_state, LSTT_STATE_EXIT);
374 set_ip(mBuffer, opcode_start);
375 return NO_DELETE_FLAG;
376 }
377 }
378 // if no handler or no state exit flag switch to new state
379 // set state entry flag and clear other CE flags
380 current_events = LSCRIPTStateBitField[LSTT_STATE_ENTRY];
381 set_event_register(mBuffer, LREG_CE, current_events, major_version);
382 // copy NS to CS
383 set_register(mBuffer, LREG_CS, next_state);
384 // copy new state's handled events into ER (SR + CS*4 + 4)
385 U64 handled_events = get_handled_events(mBuffer, next_state);
386 set_event_register(mBuffer, LREG_ER, handled_events, major_version);
387 }
388// check to see if any current events are covered by events handled by this state (CE & ER != 0)
389// now, we want to look like we were called like a function
390// 0x0000: 00 00 00 00 (return ip)
391// 0x0004: bp (current sp)
392// 0x0008: parameters
393// push sp
394// add parameter size
395// pop bp
396// set ip
397
398 S32 size = 0;
399// try to get next event from stack
400 BOOL b_done = FALSE;
401 LSCRIPTStateEventType event = LSTT_NULL;
402 LLScriptDataCollection *eventdata;
403
404 next_state = get_register(mBuffer, LREG_NS);
405 current_state = get_register(mBuffer, LREG_CS);
406 current_events = get_event_register(mBuffer, LREG_CE, major_version);
407 event_register = get_event_register(mBuffer, LREG_ER, major_version);
408
409 // first, check to see if state_entry or onrez are raised and handled
410 if ( (current_events & LSCRIPTStateBitField[LSTT_STATE_ENTRY])
411 &&(current_events & event_register))
412 {
413 // ok, this is easy since there isn't any data waiting, just set it
414 // push a zero to be popped
415 lscript_push(mBuffer, 0);
416// push sp as current bp
417 S32 sp = get_register(mBuffer, LREG_SP);
418 lscript_push(mBuffer, sp);
419
420 event = return_first_event((S32)LSCRIPTStateBitField[LSTT_STATE_ENTRY]);
421 set_event_register(mBuffer, LREG_IE, LSCRIPTStateBitField[event], major_version);
422 current_events &= ~LSCRIPTStateBitField[event];
423 set_event_register(mBuffer, LREG_CE, current_events, major_version);
424// now, push any additional stack space
425 S32 additional_size = get_event_stack_size(mBuffer, current_state, event) - size;
426 lscript_pusharge(mBuffer, additional_size);
427
428// now set the bp correctly
429 sp = get_register(mBuffer, LREG_SP);
430 sp += additional_size + size;
431 set_bp(mBuffer, sp);
432// set IP to the function
433 S32 opcode_start = get_state_event_opcoode_start(mBuffer, current_state, event);
434 set_ip(mBuffer, opcode_start);
435 b_done = TRUE;
436 }
437 else if ( (current_events & LSCRIPTStateBitField[LSTT_REZ])
438 &&(current_events & event_register))
439 {
440 for (eventdata = mEventData.mEventDataList.getFirstData(); eventdata; eventdata = mEventData.mEventDataList.getNextData())
441 {
442 if (eventdata->mType & LSCRIPTStateBitField[LSTT_REZ])
443 {
444 // push a zero to be popped
445 lscript_push(mBuffer, 0);
446 // push sp as current bp
447 S32 sp = get_register(mBuffer, LREG_SP);
448 lscript_push(mBuffer, sp);
449
450 set_event_register(mBuffer, LREG_IE, LSCRIPTStateBitField[event], major_version);
451 current_events &= ~LSCRIPTStateBitField[event];
452 set_event_register(mBuffer, LREG_CE, current_events, major_version);
453
454 // push any arguments that need to be pushed onto the stack
455 // last piece of data will be type LST_NULL
456 LLScriptLibData *data = eventdata->mData;
457 while (data->mType)
458 {
459 size += lscript_push_variable(data, mBuffer);
460 data++;
461 }
462 // now, push any additional stack space
463 S32 additional_size = get_event_stack_size(mBuffer, current_state, event) - size;
464 lscript_pusharge(mBuffer, additional_size);
465
466 // now set the bp correctly
467 sp = get_register(mBuffer, LREG_SP);
468 sp += additional_size + size;
469 set_bp(mBuffer, sp);
470 // set IP to the function
471 S32 opcode_start = get_state_event_opcoode_start(mBuffer, current_state, event);
472 set_ip(mBuffer, opcode_start);
473 mEventData.mEventDataList.deleteCurrentData();
474 b_done = TRUE;
475 break;
476 }
477 }
478 }
479
480 while (!b_done)
481 {
482 eventdata = mEventData.getNextEvent();
483 if (eventdata)
484 {
485 event = eventdata->mType;
486
487 // make sure that we can actually handle this one
488 if (LSCRIPTStateBitField[event] & event_register)
489 {
490 // push a zero to be popped
491 lscript_push(mBuffer, 0);
492 // push sp as current bp
493 S32 sp = get_register(mBuffer, LREG_SP);
494 lscript_push(mBuffer, sp);
495
496 set_event_register(mBuffer, LREG_IE, LSCRIPTStateBitField[event], major_version);
497 current_events &= ~LSCRIPTStateBitField[event];
498 set_event_register(mBuffer, LREG_CE, current_events, major_version);
499
500 // push any arguments that need to be pushed onto the stack
501 // last piece of data will be type LST_NULL
502 LLScriptLibData *data = eventdata->mData;
503 while (data->mType)
504 {
505 size += lscript_push_variable(data, mBuffer);
506 data++;
507 }
508 b_done = TRUE;
509 // now, push any additional stack space
510 S32 additional_size = get_event_stack_size(mBuffer, current_state, event) - size;
511 lscript_pusharge(mBuffer, additional_size);
512
513 // now set the bp correctly
514 sp = get_register(mBuffer, LREG_SP);
515 sp += additional_size + size;
516 set_bp(mBuffer, sp);
517 // set IP to the function
518 S32 opcode_start = get_state_event_opcoode_start(mBuffer, current_state, event);
519 set_ip(mBuffer, opcode_start);
520 }
521 else
522 {
523 llwarns << "Shit, somehow got an event that we're not registered for!" << llendl;
524 }
525 delete eventdata;
526 }
527 else
528 {
529// if no data waiting, do it the old way:
530 U64 handled_current = current_events & event_register;
531 if (handled_current)
532 {
533 // push a zero to be popped
534 lscript_push(mBuffer, 0);
535 // push sp as current bp
536 S32 sp = get_register(mBuffer, LREG_SP);
537 lscript_push(mBuffer, sp);
538
539 event = return_first_event((S32)handled_current);
540 set_event_register(mBuffer, LREG_IE, LSCRIPTStateBitField[event], major_version);
541 current_events &= ~LSCRIPTStateBitField[event];
542 set_event_register(mBuffer, LREG_CE, current_events, major_version);
543 // now, push any additional stack space
544 S32 additional_size = get_event_stack_size(mBuffer, current_state, event) - size;
545 lscript_pusharge(mBuffer, additional_size);
546
547 // now set the bp correctly
548 sp = get_register(mBuffer, LREG_SP);
549 sp += additional_size + size;
550 set_bp(mBuffer, sp);
551 // set IP to the function
552 S32 opcode_start = get_state_event_opcoode_start(mBuffer, current_state, event);
553 set_ip(mBuffer, opcode_start);
554 }
555 b_done = TRUE;
556 }
557 }
558
559 return NO_DELETE_FLAG;
560 }
561}
562
563BOOL run_noop(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
564{
565 if (b_print)
566 printf("[0x%X]\tNOOP\n", offset);
567 offset++;
568 return FALSE;
569}
570
571BOOL run_pop(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
572{
573 if (b_print)
574 printf("[0x%X]\tPOP\n", offset);
575 offset++;
576 lscript_poparg(buffer, LSCRIPTDataSize[LST_INTEGER]);
577 return FALSE;
578}
579
580BOOL run_pops(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
581{
582 if (b_print)
583 printf("[0x%X]\tPOPS\n", offset);
584 offset++;
585 S32 address = lscript_pop_int(buffer);
586 if (address)
587 lsa_decrease_ref_count(buffer, address);
588 return FALSE;
589}
590
591BOOL run_popl(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
592{
593 if (b_print)
594 printf("[0x%X]\tPOPL\n", offset);
595 offset++;
596 S32 address = lscript_pop_int(buffer);
597 if (address)
598 lsa_decrease_ref_count(buffer, address);
599 return FALSE;
600}
601
602BOOL run_popv(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
603{
604 if (b_print)
605 printf("[0x%X]\tPOPV\n", offset);
606 offset++;
607 lscript_poparg(buffer, LSCRIPTDataSize[LST_VECTOR]);
608 return FALSE;
609}
610
611BOOL run_popq(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
612{
613 if (b_print)
614 printf("[0x%X]\tPOPQ\n", offset);
615 offset++;
616 lscript_poparg(buffer, LSCRIPTDataSize[LST_QUATERNION]);
617 return FALSE;
618}
619
620BOOL run_poparg(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
621{
622 if (b_print)
623 printf("[0x%X]\tPOPARG ", offset);
624 offset++;
625 S32 arg = safe_instruction_bytestream2integer(buffer, offset);
626 if (b_print)
627 printf("%d\n", arg);
628 lscript_poparg(buffer, arg);
629 return FALSE;
630}
631
632BOOL run_popip(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
633{
634 if (b_print)
635 printf("[0x%X]\tPOPIP\n", offset);
636 offset++;
637 offset = lscript_pop_int(buffer);
638 return FALSE;
639}
640
641BOOL run_popbp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
642{
643 if (b_print)
644 printf("[0x%X]\tPOPBP\n", offset);
645 offset++;
646 S32 bp = lscript_pop_int(buffer);
647 set_bp(buffer, bp);
648 return FALSE;
649}
650
651BOOL run_popsp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
652{
653 if (b_print)
654 printf("[0x%X]\tPOPSP\n", offset);
655 offset++;
656 S32 sp = lscript_pop_int(buffer);
657 set_sp(buffer, sp);
658 return FALSE;
659}
660
661BOOL run_popslr(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
662{
663 if (b_print)
664 printf("[0x%X]\tPOPSLR\n", offset);
665 offset++;
666 S32 slr = lscript_pop_int(buffer);
667 set_register(buffer, LREG_SLR, slr);
668 return FALSE;
669}
670
671BOOL run_dup(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
672{
673 if (b_print)
674 printf("[0x%X]\tDUP\n", offset);
675 offset++;
676 S32 sp = get_register(buffer, LREG_SP);
677 S32 value = bytestream2integer(buffer, sp);
678 lscript_push(buffer, value);
679 return FALSE;
680}
681
682BOOL run_dups(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
683{
684 if (b_print)
685 printf("[0x%X]\tDUPS\n", offset);
686 offset++;
687 S32 sp = get_register(buffer, LREG_SP);
688 S32 value = bytestream2integer(buffer, sp);
689 lscript_push(buffer, value);
690 lsa_increase_ref_count(buffer, value);
691 return FALSE;
692}
693
694BOOL run_dupl(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
695{
696 if (b_print)
697 printf("[0x%X]\tDUPL\n", offset);
698 offset++;
699 S32 sp = get_register(buffer, LREG_SP);
700 S32 value = bytestream2integer(buffer, sp);
701 lscript_push(buffer, value);
702 lsa_increase_ref_count(buffer, value);
703 return FALSE;
704}
705
706BOOL run_dupv(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
707{
708 if (b_print)
709 printf("[0x%X]\tDUPV\n", offset);
710 offset++;
711 S32 sp = get_register(buffer, LREG_SP);
712 LLVector3 value;
713 bytestream2vector(value, buffer, sp);
714 lscript_push(buffer, value);
715 return FALSE;
716}
717
718BOOL run_dupq(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
719{
720 if (b_print)
721 printf("[0x%X]\tDUPV\n", offset);
722 offset++;
723 S32 sp = get_register(buffer, LREG_SP);
724 LLQuaternion value;
725 bytestream2quaternion(value, buffer, sp);
726 lscript_push(buffer, value);
727 return FALSE;
728}
729
730BOOL run_store(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
731{
732 if (b_print)
733 printf("[0x%X]\tSTORE ", offset);
734 offset++;
735 S32 arg = safe_instruction_bytestream2integer(buffer, offset);
736 if (b_print)
737 printf("0x%X\n", arg);
738 S32 sp = get_register(buffer, LREG_SP);
739 S32 value = bytestream2integer(buffer, sp);
740 lscript_local_store(buffer, arg, value);
741 return FALSE;
742}
743
744BOOL run_stores(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
745{
746 if (b_print)
747 printf("[0x%X]\tSTORES ", offset);
748 offset++;
749 S32 arg = safe_instruction_bytestream2integer(buffer, offset);
750 if (b_print)
751 printf("0x%X\n", arg);
752 S32 sp = get_register(buffer, LREG_SP);
753 S32 value = bytestream2integer(buffer, sp);
754
755 S32 address = lscript_local_get(buffer, arg);
756
757 lscript_local_store(buffer, arg, value);
758 lsa_increase_ref_count(buffer, value);
759 if (address)
760 lsa_decrease_ref_count(buffer, address);
761 return FALSE;
762}
763
764BOOL run_storel(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
765{
766 if (b_print)
767 printf("[0x%X]\tSTOREL ", offset);
768 offset++;
769 S32 arg = safe_instruction_bytestream2integer(buffer, offset);
770 if (b_print)
771 printf("0x%X\n", arg);
772 S32 sp = get_register(buffer, LREG_SP);
773 S32 value = bytestream2integer(buffer, sp);
774
775 S32 address = lscript_local_get(buffer, arg);
776
777 lscript_local_store(buffer, arg, value);
778 lsa_increase_ref_count(buffer, value);
779 if (address)
780 lsa_decrease_ref_count(buffer, address);
781 return FALSE;
782}
783
784BOOL run_storev(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
785{
786 if (b_print)
787 printf("[0x%X]\tSTOREV ", offset);
788 offset++;
789 S32 arg = safe_instruction_bytestream2integer(buffer, offset);
790 if (b_print)
791 printf("0x%X\n", arg);
792 LLVector3 value;
793 S32 sp = get_register(buffer, LREG_SP);
794 bytestream2vector(value, buffer, sp);
795 lscript_local_store(buffer, arg, value);
796 return FALSE;
797}
798
799BOOL run_storeq(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
800{
801 if (b_print)
802 printf("[0x%X]\tSTOREQ ", offset);
803 offset++;
804 S32 arg = safe_instruction_bytestream2integer(buffer, offset);
805 if (b_print)
806 printf("0x%X\n", arg);
807 LLQuaternion value;
808 S32 sp = get_register(buffer, LREG_SP);
809 bytestream2quaternion(value, buffer, sp);
810 lscript_local_store(buffer, arg, value);
811 return FALSE;
812}
813
814BOOL run_storeg(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
815{
816 if (b_print)
817 printf("[0x%X]\tSTOREG ", offset);
818 offset++;
819 S32 arg = safe_instruction_bytestream2integer(buffer, offset);
820 if (b_print)
821 printf("0x%X\n", arg);
822 S32 sp = get_register(buffer, LREG_SP);
823 S32 value = bytestream2integer(buffer, sp);
824 lscript_global_store(buffer, arg, value);
825 return FALSE;
826}
827
828BOOL run_storegs(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
829{
830 if (b_print)
831 printf("[0x%X]\tSTOREGS ", offset);
832 offset++;
833 S32 arg = safe_instruction_bytestream2integer(buffer, offset);
834 if (b_print)
835 printf("0x%X\n", arg);
836 S32 sp = get_register(buffer, LREG_SP);
837 S32 value = bytestream2integer(buffer, sp);
838
839 S32 address = lscript_global_get(buffer, arg);
840
841 lscript_global_store(buffer, arg, value);
842
843 lsa_increase_ref_count(buffer, value);
844 if (address)
845 lsa_decrease_ref_count(buffer, address);
846 return FALSE;
847}
848
849BOOL run_storegl(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
850{
851 if (b_print)
852 printf("[0x%X]\tSTOREGL ", offset);
853 offset++;
854 S32 arg = safe_instruction_bytestream2integer(buffer, offset);
855 if (b_print)
856 printf("0x%X\n", arg);
857 S32 sp = get_register(buffer, LREG_SP);
858 S32 value = bytestream2integer(buffer, sp);
859
860 S32 address = lscript_global_get(buffer, arg);
861
862 lscript_global_store(buffer, arg, value);
863
864 lsa_increase_ref_count(buffer, value);
865 if (address)
866 lsa_decrease_ref_count(buffer, address);
867 return FALSE;
868}
869
870BOOL run_storegv(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
871{
872 if (b_print)
873 printf("[0x%X]\tSTOREGV ", offset);
874 offset++;
875 S32 arg = safe_instruction_bytestream2integer(buffer, offset);
876 if (b_print)
877 printf("0x%X\n", arg);
878 LLVector3 value;
879 S32 sp = get_register(buffer, LREG_SP);
880 bytestream2vector(value, buffer, sp);
881 lscript_global_store(buffer, arg, value);
882 return FALSE;
883}
884
885BOOL run_storegq(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
886{
887 if (b_print)
888 printf("[0x%X]\tSTOREGQ ", offset);
889 offset++;
890 S32 arg = safe_instruction_bytestream2integer(buffer, offset);
891 if (b_print)
892 printf("0x%X\n", arg);
893 LLQuaternion value;
894 S32 sp = get_register(buffer, LREG_SP);
895 bytestream2quaternion(value, buffer, sp);
896 lscript_global_store(buffer, arg, value);
897 return FALSE;
898}
899
900BOOL run_loadp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
901{
902 if (b_print)
903 printf("[0x%X]\tSTOREP ", offset);
904 offset++;
905 S32 arg = safe_instruction_bytestream2integer(buffer, offset);
906 if (b_print)
907 printf("0x%X\n", arg);
908 S32 value = lscript_pop_int(buffer);
909 lscript_local_store(buffer, arg, value);
910 return FALSE;
911}
912
913BOOL run_loadsp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
914{
915 if (b_print)
916 printf("[0x%X]\tSTORESP ", offset);
917 offset++;
918 S32 arg = safe_instruction_bytestream2integer(buffer, offset);
919 if (b_print)
920 printf("0x%X\n", arg);
921 S32 value = lscript_pop_int(buffer);
922
923 S32 address = lscript_local_get(buffer, arg);
924 if (address)
925 lsa_decrease_ref_count(buffer, address);
926
927 lscript_local_store(buffer, arg, value);
928 return FALSE;
929}
930
931BOOL run_loadlp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
932{
933 if (b_print)
934 printf("[0x%X]\tSTORELP ", offset);
935 offset++;
936 S32 arg = safe_instruction_bytestream2integer(buffer, offset);
937 if (b_print)
938 printf("0x%X\n", arg);
939 S32 value = lscript_pop_int(buffer);
940
941 S32 address = lscript_local_get(buffer, arg);
942 if (address)
943 lsa_decrease_ref_count(buffer, address);
944
945 lscript_local_store(buffer, arg, value);
946 return FALSE;
947}
948
949BOOL run_loadvp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
950{
951 if (b_print)
952 printf("[0x%X]\tSTOREVP ", offset);
953 offset++;
954 S32 arg = safe_instruction_bytestream2integer(buffer, offset);
955 if (b_print)
956 printf("0x%X\n", arg);
957 LLVector3 value;
958 lscript_pop_vector(buffer, value);
959 lscript_local_store(buffer, arg, value);
960 return FALSE;
961}
962
963BOOL run_loadqp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
964{
965 if (b_print)
966 printf("[0x%X]\tSTOREQP ", offset);
967 offset++;
968 S32 arg = safe_instruction_bytestream2integer(buffer, offset);
969 if (b_print)
970 printf("0x%X\n", arg);
971 LLQuaternion value;
972 lscript_pop_quaternion(buffer, value);
973 lscript_local_store(buffer, arg, value);
974 return FALSE;
975}
976
977BOOL run_loadgp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
978{
979 if (b_print)
980 printf("[0x%X]\tSTOREGP ", offset);
981 offset++;
982 S32 arg = safe_instruction_bytestream2integer(buffer, offset);
983 if (b_print)
984 printf("0x%X\n", arg);
985 S32 value = lscript_pop_int(buffer);
986 lscript_global_store(buffer, arg, value);
987 return FALSE;
988}
989
990BOOL run_loadgsp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
991{
992 if (b_print)
993 printf("[0x%X]\tSTOREGSP ", offset);
994 offset++;
995 S32 arg = safe_instruction_bytestream2integer(buffer, offset);
996 if (b_print)
997 printf("%d\n", arg);
998 S32 value = lscript_pop_int(buffer);
999
1000 S32 address = lscript_global_get(buffer, arg);
1001 if (address)
1002 lsa_decrease_ref_count(buffer, address);
1003
1004 lscript_global_store(buffer, arg, value);
1005 return FALSE;
1006}
1007
1008BOOL run_loadglp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1009{
1010 if (b_print)
1011 printf("[0x%X]\tSTOREGLP ", offset);
1012 offset++;
1013 S32 arg = safe_instruction_bytestream2integer(buffer, offset);
1014 if (b_print)
1015 printf("0x%X\n", arg);
1016 S32 value = lscript_pop_int(buffer);
1017
1018 S32 address = lscript_global_get(buffer, arg);
1019 if (address)
1020 lsa_decrease_ref_count(buffer, address);
1021
1022 lscript_global_store(buffer, arg, value);
1023 return FALSE;
1024}
1025
1026BOOL run_loadgvp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1027{
1028 if (b_print)
1029 printf("[0x%X]\tSTOREGVP ", offset);
1030 offset++;
1031 S32 arg = safe_instruction_bytestream2integer(buffer, offset);
1032 if (b_print)
1033 printf("0x%X\n", arg);
1034 LLVector3 value;
1035 lscript_pop_vector(buffer, value);
1036 lscript_global_store(buffer, arg, value);
1037 return FALSE;
1038}
1039
1040BOOL run_loadgqp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1041{
1042 if (b_print)
1043 printf("[0x%X]\tSTOREGQP ", offset);
1044 offset++;
1045 S32 arg = safe_instruction_bytestream2integer(buffer, offset);
1046 if (b_print)
1047 printf("0x%X\n", arg);
1048 LLQuaternion value;
1049 lscript_pop_quaternion(buffer, value);
1050 lscript_global_store(buffer, arg, value);
1051 return FALSE;
1052}
1053
1054BOOL run_push(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1055{
1056 if (b_print)
1057 printf("[0x%X]\tPUSH ", offset);
1058 offset++;
1059 S32 arg = safe_instruction_bytestream2integer(buffer, offset);
1060 if (b_print)
1061 printf("0x%X\n", arg);
1062 S32 value = lscript_local_get(buffer, arg);
1063 lscript_push(buffer, value);
1064 return FALSE;
1065}
1066
1067BOOL run_pushs(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1068{
1069 if (b_print)
1070 printf("[0x%X]\tPUSHS ", offset);
1071 offset++;
1072 S32 arg = safe_instruction_bytestream2integer(buffer, offset);
1073 if (b_print)
1074 printf("0x%X\n", arg);
1075 S32 value = lscript_local_get(buffer, arg);
1076 lscript_push(buffer, value);
1077 lsa_increase_ref_count(buffer, value);
1078 return FALSE;
1079}
1080
1081BOOL run_pushl(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1082{
1083 if (b_print)
1084 printf("[0x%X]\tPUSHL ", offset);
1085 offset++;
1086 S32 arg = safe_instruction_bytestream2integer(buffer, offset);
1087 if (b_print)
1088 printf("0x%X\n", arg);
1089 S32 value = lscript_local_get(buffer, arg);
1090 lscript_push(buffer, value);
1091 lsa_increase_ref_count(buffer, value);
1092 return FALSE;
1093}
1094
1095BOOL run_pushv(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1096{
1097 if (b_print)
1098 printf("[0x%X]\tPUSHV ", offset);
1099 offset++;
1100 S32 arg = safe_instruction_bytestream2integer(buffer, offset);
1101 if (b_print)
1102 printf("0x%X\n", arg);
1103 LLVector3 value;
1104 lscript_local_get(buffer, arg, value);
1105 lscript_push(buffer, value);
1106 return FALSE;
1107}
1108
1109BOOL run_pushq(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1110{
1111 if (b_print)
1112 printf("[0x%X]\tPUSHQ ", offset);
1113 offset++;
1114 S32 arg = safe_instruction_bytestream2integer(buffer, offset);
1115 if (b_print)
1116 printf("0x%X\n", arg);
1117 LLQuaternion value;
1118 lscript_local_get(buffer, arg, value);
1119 lscript_push(buffer, value);
1120 return FALSE;
1121}
1122
1123BOOL run_pushg(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1124{
1125 if (b_print)
1126 printf("[0x%X]\tPUSHG ", offset);
1127 offset++;
1128 S32 arg = safe_instruction_bytestream2integer(buffer, offset);
1129 if (b_print)
1130 printf("0x%X\n", arg);
1131 S32 value = lscript_global_get(buffer, arg);
1132 lscript_push(buffer, value);
1133 return FALSE;
1134}
1135
1136BOOL run_pushgs(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1137{
1138 if (b_print)
1139 printf("[0x%X]\tPUSHGS ", offset);
1140 offset++;
1141 S32 arg = safe_instruction_bytestream2integer(buffer, offset);
1142 if (b_print)
1143 printf("0x%X\n", arg);
1144 S32 value = lscript_global_get(buffer, arg);
1145 lscript_push(buffer, value);
1146 lsa_increase_ref_count(buffer, value);
1147 return FALSE;
1148}
1149
1150BOOL run_pushgl(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1151{
1152 if (b_print)
1153 printf("[0x%X]\tPUSHGL ", offset);
1154 offset++;
1155 S32 arg = safe_instruction_bytestream2integer(buffer, offset);
1156 if (b_print)
1157 printf("0x%X\n", arg);
1158 S32 value = lscript_global_get(buffer, arg);
1159 lscript_push(buffer, value);
1160 lsa_increase_ref_count(buffer, value);
1161 return FALSE;
1162}
1163
1164BOOL run_pushgv(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1165{
1166 if (b_print)
1167 printf("[0x%X]\tPUSHGV ", offset);
1168 offset++;
1169 S32 arg = safe_instruction_bytestream2integer(buffer, offset);
1170 if (b_print)
1171 printf("0x%X\n", arg);
1172 LLVector3 value;
1173 lscript_global_get(buffer, arg, value);
1174 lscript_push(buffer, value);
1175 return FALSE;
1176}
1177
1178BOOL run_pushgq(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1179{
1180 if (b_print)
1181 printf("[0x%X]\tPUSHGQ ", offset);
1182 offset++;
1183 S32 arg = safe_instruction_bytestream2integer(buffer, offset);
1184 if (b_print)
1185 printf("0x%X\n", arg);
1186 LLQuaternion value;
1187 lscript_global_get(buffer, arg, value);
1188 lscript_push(buffer, value);
1189 return FALSE;
1190}
1191
1192BOOL run_puship(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1193{
1194 if (b_print)
1195 printf("[0x%X]\tPUSHIP\n", offset);
1196 offset++;
1197 lscript_push(buffer, offset);
1198 return FALSE;
1199}
1200
1201BOOL run_pushbp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1202{
1203 if (b_print)
1204 printf("[0x%X]\tPUSHBP\n", offset);
1205 offset++;
1206 lscript_push(buffer, get_register(buffer, LREG_BP));
1207 return FALSE;
1208}
1209
1210BOOL run_pushsp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1211{
1212 if (b_print)
1213 printf("[0x%X]\tPUSHSP\n", offset);
1214 offset++;
1215 lscript_push(buffer, get_register(buffer, LREG_SP));
1216 return FALSE;
1217}
1218
1219BOOL run_pushargb(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1220{
1221 if (b_print)
1222 printf("[0x%X]\tPUSHGARGB ", offset);
1223 offset++;
1224 U8 arg = safe_instruction_bytestream2byte(buffer, offset);
1225 if (b_print)
1226 printf("%d\n", (U32)arg);
1227 lscript_push(buffer, arg);
1228 return FALSE;
1229}
1230
1231BOOL run_pushargi(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1232{
1233 if (b_print)
1234 printf("[0x%X]\tPUSHARGI ", offset);
1235 offset++;
1236 S32 arg = safe_instruction_bytestream2integer(buffer, offset);
1237 if (b_print)
1238 printf("%d\n", arg);
1239 lscript_push(buffer, arg);
1240 return FALSE;
1241}
1242
1243BOOL run_pushargf(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1244{
1245 if (b_print)
1246 printf("[0x%X]\tPUSHARGF ", offset);
1247 offset++;
1248 F32 arg = safe_instruction_bytestream2float(buffer, offset);
1249 if (b_print)
1250 printf("%f\n", arg);
1251 lscript_push(buffer, arg);
1252 return FALSE;
1253}
1254
1255BOOL run_pushargs(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1256{
1257 if (b_print)
1258 printf("[0x%X]\tPUSHARGS ", offset);
1259 S32 toffset = offset;
1260 safe_instruction_bytestream_count_char(buffer, toffset);
1261 S32 size = toffset - offset;
1262 char *arg = new char[size];
1263 offset++;
1264 safe_instruction_bytestream2char(arg, buffer, offset);
1265 if (b_print)
1266 printf("%s\n", arg);
1267 S32 address = lsa_heap_add_data(buffer, new LLScriptLibData(arg), get_max_heap_size(buffer), TRUE);
1268 lscript_push(buffer, address);
1269 delete [] arg;
1270 return FALSE;
1271}
1272
1273BOOL run_pushargv(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1274{
1275 if (b_print)
1276 printf("[0x%X]\tPUSHARGV ", offset);
1277 offset++;
1278 LLVector3 arg;
1279 safe_instruction_bytestream2vector(arg, buffer, offset);
1280 if (b_print)
1281 printf("< %f, %f, %f >\n", arg.mV[VX], arg.mV[VY], arg.mV[VZ]);
1282 lscript_push(buffer, arg);
1283 return FALSE;
1284}
1285BOOL run_pushargq(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1286{
1287 if (b_print)
1288 printf("[0x%X]\tPUSHARGQ ", offset);
1289 offset++;
1290 LLQuaternion arg;
1291 safe_instruction_bytestream2quaternion(arg, buffer, offset);
1292 if (b_print)
1293 printf("< %f, %f, %f, %f >\n", arg.mQ[VX], arg.mQ[VY], arg.mQ[VZ], arg.mQ[VS]);
1294 lscript_push(buffer, arg);
1295 return FALSE;
1296}
1297BOOL run_pushe(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1298{
1299 if (b_print)
1300 printf("[0x%X]\tPUSHE\n", offset);
1301 offset++;
1302 lscript_pusharge(buffer, LSCRIPTDataSize[LST_INTEGER]);
1303 return FALSE;
1304}
1305BOOL run_pushev(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1306{
1307 if (b_print)
1308 printf("[0x%X]\tPUSHEV\n", offset);
1309 offset++;
1310 lscript_pusharge(buffer, LSCRIPTDataSize[LST_VECTOR]);
1311 return FALSE;
1312}
1313BOOL run_pusheq(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1314{
1315 if (b_print)
1316 printf("[0x%X]\tPUSHEQ\n", offset);
1317 offset++;
1318 lscript_pusharge(buffer, LSCRIPTDataSize[LST_QUATERNION]);
1319 return FALSE;
1320}
1321BOOL run_pusharge(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1322{
1323 if (b_print)
1324 printf("[0x%X]\tPUSHARGE ", offset);
1325 offset++;
1326 S32 arg = safe_instruction_bytestream2integer(buffer, offset);
1327 if (b_print)
1328 printf("%d\n", arg);
1329 lscript_pusharge(buffer, arg);
1330 return FALSE;
1331}
1332
1333void print_type(U8 type)
1334{
1335 if (type == LSCRIPTTypeByte[LST_INTEGER])
1336 {
1337 printf("integer");
1338 }
1339 else if (type == LSCRIPTTypeByte[LST_FLOATINGPOINT])
1340 {
1341 printf("float");
1342 }
1343 else if (type == LSCRIPTTypeByte[LST_STRING])
1344 {
1345 printf("string");
1346 }
1347 else if (type == LSCRIPTTypeByte[LST_KEY])
1348 {
1349 printf("key");
1350 }
1351 else if (type == LSCRIPTTypeByte[LST_VECTOR])
1352 {
1353 printf("vector");
1354 }
1355 else if (type == LSCRIPTTypeByte[LST_QUATERNION])
1356 {
1357 printf("quaternion");
1358 }
1359 else if (type == LSCRIPTTypeByte[LST_LIST])
1360 {
1361 printf("list");
1362 }
1363}
1364
1365void unknown_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
1366{
1367 printf("Unknown arithmetic operation!\n");
1368}
1369
1370void integer_integer_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
1371{
1372 S32 lside = lscript_pop_int(buffer);
1373 S32 rside = lscript_pop_int(buffer);
1374 S32 result = 0;
1375
1376 switch(opcode)
1377 {
1378 case LOPC_ADD:
1379 result = lside + rside;
1380 break;
1381 case LOPC_SUB:
1382 result = lside - rside;
1383 break;
1384 case LOPC_MUL:
1385 result = lside * rside;
1386 break;
1387 case LOPC_DIV:
1388 if (rside)
1389 result = lside / rside;
1390 else
1391 set_fault(buffer, LSRF_MATH);
1392 break;
1393 case LOPC_MOD:
1394 if (rside)
1395 result = lside % rside;
1396 else
1397 set_fault(buffer, LSRF_MATH);
1398 break;
1399 case LOPC_EQ:
1400 result = (lside == rside);
1401 break;
1402 case LOPC_NEQ:
1403 result = (lside != rside);
1404 break;
1405 case LOPC_LEQ:
1406 result = (lside <= rside);
1407 break;
1408 case LOPC_GEQ:
1409 result = (lside >= rside);
1410 break;
1411 case LOPC_LESS:
1412 result = (lside < rside);
1413 break;
1414 case LOPC_GREATER:
1415 result = (lside > rside);
1416 break;
1417 case LOPC_BITAND:
1418 result = (lside & rside);
1419 break;
1420 case LOPC_BITOR:
1421 result = (lside | rside);
1422 break;
1423 case LOPC_BITXOR:
1424 result = (lside ^ rside);
1425 break;
1426 case LOPC_BOOLAND:
1427 result = (lside && rside);
1428 break;
1429 case LOPC_BOOLOR:
1430 result = (lside || rside);
1431 break;
1432 case LOPC_SHL:
1433 result = (lside << rside);
1434 break;
1435 case LOPC_SHR:
1436 result = (lside >> rside);
1437 break;
1438 default:
1439 break;
1440 }
1441 lscript_push(buffer, result);
1442}
1443
1444void integer_float_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
1445{
1446 S32 lside = lscript_pop_int(buffer);
1447 F32 rside = lscript_pop_float(buffer);
1448 S32 resulti = 0;
1449 F32 resultf = 0;
1450
1451 switch(opcode)
1452 {
1453 case LOPC_ADD:
1454 resultf = lside + rside;
1455 lscript_push(buffer, resultf);
1456 break;
1457 case LOPC_SUB:
1458 resultf = lside - rside;
1459 lscript_push(buffer, resultf);
1460 break;
1461 case LOPC_MUL:
1462 resultf = lside * rside;
1463 lscript_push(buffer, resultf);
1464 break;
1465 case LOPC_DIV:
1466 if (rside)
1467 resultf = lside / rside;
1468 else
1469 set_fault(buffer, LSRF_MATH);
1470 lscript_push(buffer, resultf);
1471 break;
1472 case LOPC_EQ:
1473 resulti = (lside == rside);
1474 lscript_push(buffer, resulti);
1475 break;
1476 case LOPC_NEQ:
1477 resulti = (lside != rside);
1478 lscript_push(buffer, resulti);
1479 break;
1480 case LOPC_LEQ:
1481 resulti = (lside <= rside);
1482 lscript_push(buffer, resulti);
1483 break;
1484 case LOPC_GEQ:
1485 resulti = (lside >= rside);
1486 lscript_push(buffer, resulti);
1487 break;
1488 case LOPC_LESS:
1489 resulti = (lside < rside);
1490 lscript_push(buffer, resulti);
1491 break;
1492 case LOPC_GREATER:
1493 resulti = (lside > rside);
1494 lscript_push(buffer, resulti);
1495 break;
1496 default:
1497 break;
1498 }
1499}
1500
1501void integer_vector_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
1502{
1503 S32 lside = lscript_pop_int(buffer);
1504 LLVector3 rside;
1505 lscript_pop_vector(buffer, rside);
1506
1507 switch(opcode)
1508 {
1509 case LOPC_MUL:
1510 rside *= (F32)lside;
1511 lscript_push(buffer, rside);
1512 break;
1513 default:
1514 break;
1515 }
1516}
1517
1518void float_integer_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
1519{
1520 F32 lside = lscript_pop_float(buffer);
1521 S32 rside = lscript_pop_int(buffer);
1522 S32 resulti = 0;
1523 F32 resultf = 0;
1524
1525 switch(opcode)
1526 {
1527 case LOPC_ADD:
1528 resultf = lside + rside;
1529 lscript_push(buffer, resultf);
1530 break;
1531 case LOPC_SUB:
1532 resultf = lside - rside;
1533 lscript_push(buffer, resultf);
1534 break;
1535 case LOPC_MUL:
1536 resultf = lside * rside;
1537 lscript_push(buffer, resultf);
1538 break;
1539 case LOPC_DIV:
1540 if (rside)
1541 resultf = lside / rside;
1542 else
1543 set_fault(buffer, LSRF_MATH);
1544 lscript_push(buffer, resultf);
1545 break;
1546 case LOPC_EQ:
1547 resulti = (lside == rside);
1548 lscript_push(buffer, resulti);
1549 break;
1550 case LOPC_NEQ:
1551 resulti = (lside != rside);
1552 lscript_push(buffer, resulti);
1553 break;
1554 case LOPC_LEQ:
1555 resulti = (lside <= rside);
1556 lscript_push(buffer, resulti);
1557 break;
1558 case LOPC_GEQ:
1559 resulti = (lside >= rside);
1560 lscript_push(buffer, resulti);
1561 break;
1562 case LOPC_LESS:
1563 resulti = (lside < rside);
1564 lscript_push(buffer, resulti);
1565 break;
1566 case LOPC_GREATER:
1567 resulti = (lside > rside);
1568 lscript_push(buffer, resulti);
1569 break;
1570 default:
1571 break;
1572 }
1573}
1574
1575void float_float_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
1576{
1577 F32 lside = lscript_pop_float(buffer);
1578 F32 rside = lscript_pop_float(buffer);
1579 F32 resultf = 0;
1580 S32 resulti = 0;
1581
1582 switch(opcode)
1583 {
1584 case LOPC_ADD:
1585 resultf = lside + rside;
1586 lscript_push(buffer, resultf);
1587 break;
1588 case LOPC_SUB:
1589 resultf = lside - rside;
1590 lscript_push(buffer, resultf);
1591 break;
1592 case LOPC_MUL:
1593 resultf = lside * rside;
1594 lscript_push(buffer, resultf);
1595 break;
1596 case LOPC_DIV:
1597 if (rside)
1598 resultf = lside / rside;
1599 else
1600 set_fault(buffer, LSRF_MATH);
1601 lscript_push(buffer, resultf);
1602 break;
1603 case LOPC_EQ:
1604 resulti = (lside == rside);
1605 lscript_push(buffer, resulti);
1606 break;
1607 case LOPC_NEQ:
1608 resulti = (lside != rside);
1609 lscript_push(buffer, resulti);
1610 break;
1611 case LOPC_LEQ:
1612 resulti = (lside <= rside);
1613 lscript_push(buffer, resulti);
1614 break;
1615 case LOPC_GEQ:
1616 resulti = (lside >= rside);
1617 lscript_push(buffer, resulti);
1618 break;
1619 case LOPC_LESS:
1620 resulti = (lside < rside);
1621 lscript_push(buffer, resulti);
1622 break;
1623 case LOPC_GREATER:
1624 resulti = (lside > rside);
1625 lscript_push(buffer, resulti);
1626 break;
1627 default:
1628 break;
1629 }
1630}
1631
1632void float_vector_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
1633{
1634 F32 lside = lscript_pop_float(buffer);
1635 LLVector3 rside;
1636 lscript_pop_vector(buffer, rside);
1637
1638 switch(opcode)
1639 {
1640 case LOPC_MUL:
1641 rside *= lside;
1642 lscript_push(buffer, rside);
1643 break;
1644 default:
1645 break;
1646 }
1647}
1648
1649void string_string_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
1650{
1651 S32 lside = lscript_pop_int(buffer);
1652 S32 rside = lscript_pop_int(buffer);
1653 S32 resulti;
1654 S32 address;
1655
1656 switch(opcode)
1657 {
1658 case LOPC_ADD:
1659 address = lsa_cat_strings(buffer, lside, rside, get_max_heap_size(buffer));
1660 lscript_push(buffer, address);
1661 break;
1662 case LOPC_EQ:
1663 resulti = !lsa_cmp_strings(buffer, lside, rside);
1664 lscript_push(buffer, resulti);
1665 break;
1666 case LOPC_NEQ:
1667 resulti = lsa_cmp_strings(buffer, lside, rside);
1668 lscript_push(buffer, resulti);
1669 break;
1670 default:
1671 break;
1672 }
1673}
1674
1675void string_key_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
1676{
1677 S32 lside = lscript_pop_int(buffer);
1678 S32 rside = lscript_pop_int(buffer);
1679 S32 resulti;
1680
1681 switch(opcode)
1682 {
1683 case LOPC_NEQ:
1684 resulti = lsa_cmp_strings(buffer, lside, rside);
1685 lscript_push(buffer, resulti);
1686 break;
1687 case LOPC_EQ:
1688 resulti = !lsa_cmp_strings(buffer, lside, rside);
1689 lscript_push(buffer, resulti);
1690 break;
1691 default:
1692 break;
1693 }
1694}
1695
1696void key_string_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
1697{
1698 S32 lside = lscript_pop_int(buffer);
1699 S32 rside = lscript_pop_int(buffer);
1700 S32 resulti;
1701
1702 switch(opcode)
1703 {
1704 case LOPC_NEQ:
1705 resulti = lsa_cmp_strings(buffer, lside, rside);
1706 lscript_push(buffer, resulti);
1707 break;
1708 case LOPC_EQ:
1709 resulti = !lsa_cmp_strings(buffer, lside, rside);
1710 lscript_push(buffer, resulti);
1711 break;
1712 default:
1713 break;
1714 }
1715}
1716
1717void key_key_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
1718{
1719 S32 lside = lscript_pop_int(buffer);
1720 S32 rside = lscript_pop_int(buffer);
1721 S32 resulti;
1722
1723 switch(opcode)
1724 {
1725 case LOPC_EQ:
1726 resulti = !lsa_cmp_strings(buffer, lside, rside);
1727 lscript_push(buffer, resulti);
1728 break;
1729 case LOPC_NEQ:
1730 resulti = lsa_cmp_strings(buffer, lside, rside);
1731 lscript_push(buffer, resulti);
1732 break;
1733 default:
1734 break;
1735 }
1736}
1737
1738void vector_integer_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
1739{
1740 LLVector3 lside;
1741 lscript_pop_vector(buffer, lside);
1742 S32 rside = lscript_pop_int(buffer);
1743
1744 switch(opcode)
1745 {
1746 case LOPC_MUL:
1747 lside *= (F32)rside;
1748 lscript_push(buffer, lside);
1749 break;
1750 case LOPC_DIV:
1751 if (rside)
1752 lside *= (1.f/rside);
1753 else
1754 set_fault(buffer, LSRF_MATH);
1755 lscript_push(buffer, lside);
1756 break;
1757 default:
1758 break;
1759 }
1760}
1761
1762void vector_float_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
1763{
1764 LLVector3 lside;
1765 lscript_pop_vector(buffer, lside);
1766 F32 rside = lscript_pop_float(buffer);
1767
1768 switch(opcode)
1769 {
1770 case LOPC_MUL:
1771 lside *= rside;
1772 lscript_push(buffer, lside);
1773 break;
1774 case LOPC_DIV:
1775 if (rside)
1776 lside *= (1.f/rside);
1777 else
1778 set_fault(buffer, LSRF_MATH);
1779 lscript_push(buffer, lside);
1780 break;
1781 default:
1782 break;
1783 }
1784}
1785
1786void vector_vector_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
1787{
1788 LLVector3 lside;
1789 lscript_pop_vector(buffer, lside);
1790 LLVector3 rside;
1791 lscript_pop_vector(buffer, rside);
1792 S32 resulti = 0;
1793 F32 resultf = 0.f;
1794
1795 switch(opcode)
1796 {
1797 case LOPC_ADD:
1798 lside += rside;
1799 lscript_push(buffer, lside);
1800 break;
1801 case LOPC_SUB:
1802 lside -= rside;
1803 lscript_push(buffer, lside);
1804 break;
1805 case LOPC_MUL:
1806 resultf = lside * rside;
1807 lscript_push(buffer, resultf);
1808 break;
1809 case LOPC_MOD:
1810 lside = lside % rside;
1811 lscript_push(buffer, lside);
1812 break;
1813 case LOPC_EQ:
1814 resulti = (lside == rside);
1815 lscript_push(buffer, resulti);
1816 break;
1817 case LOPC_NEQ:
1818 resulti = (lside != rside);
1819 lscript_push(buffer, resulti);
1820 break;
1821 default:
1822 break;
1823 }
1824}
1825
1826void vector_quaternion_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
1827{
1828 LLVector3 lside;
1829 lscript_pop_vector(buffer, lside);
1830 LLQuaternion rside;
1831 lscript_pop_quaternion(buffer, rside);
1832
1833 switch(opcode)
1834 {
1835 case LOPC_MUL:
1836 lside = lside * rside;
1837 lscript_push(buffer, lside);
1838 break;
1839 case LOPC_DIV:
1840 lside = lside * rside.conjQuat();
1841 lscript_push(buffer, lside);
1842 break;
1843 default:
1844 break;
1845 }
1846}
1847
1848void quaternion_quaternion_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
1849{
1850 LLQuaternion lside;
1851 lscript_pop_quaternion(buffer, lside);
1852 LLQuaternion rside;
1853 lscript_pop_quaternion(buffer, rside);
1854 S32 resulti = 0;
1855
1856 switch(opcode)
1857 {
1858 case LOPC_ADD:
1859 lside = lside + rside;
1860 lscript_push(buffer, lside);
1861 break;
1862 case LOPC_SUB:
1863 lside = lside - rside;
1864 lscript_push(buffer, lside);
1865 break;
1866 case LOPC_MUL:
1867 lside *= rside;
1868 lscript_push(buffer, lside);
1869 break;
1870 case LOPC_DIV:
1871 lside = lside * rside.conjQuat();
1872 lscript_push(buffer, lside);
1873 break;
1874 case LOPC_EQ:
1875 resulti = (lside == rside);
1876 lscript_push(buffer, resulti);
1877 break;
1878 case LOPC_NEQ:
1879 resulti = (lside != rside);
1880 lscript_push(buffer, resulti);
1881 break;
1882 default:
1883 break;
1884 }
1885}
1886
1887void integer_list_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
1888{
1889 S32 lside = lscript_pop_int(buffer);
1890 S32 rside = lscript_pop_int(buffer);
1891 S32 address;
1892
1893 switch(opcode)
1894 {
1895 case LOPC_ADD:
1896 {
1897 LLScriptLibData *list = new LLScriptLibData;
1898 list->mType = LST_LIST;
1899 list->mListp = new LLScriptLibData(lside);
1900 address = lsa_preadd_lists(buffer, list, rside, get_max_heap_size(buffer));
1901 lscript_push(buffer, address);
1902 list->mListp = NULL;
1903 delete list;
1904 }
1905 break;
1906 default:
1907 break;
1908 }
1909}
1910
1911void float_list_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
1912{
1913 F32 lside = lscript_pop_float(buffer);
1914 S32 rside = lscript_pop_int(buffer);
1915 S32 address;
1916
1917 switch(opcode)
1918 {
1919 case LOPC_ADD:
1920 {
1921 LLScriptLibData *list = new LLScriptLibData;
1922 list->mType = LST_LIST;
1923 list->mListp = new LLScriptLibData(lside);
1924 address = lsa_preadd_lists(buffer, list, rside, get_max_heap_size(buffer));
1925 lscript_push(buffer, address);
1926 list->mListp = NULL;
1927 delete list;
1928 }
1929 break;
1930 default:
1931 break;
1932 }
1933}
1934
1935void string_list_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
1936{
1937 S32 lside = lscript_pop_int(buffer);
1938 S32 rside = lscript_pop_int(buffer);
1939 S32 address;
1940
1941 switch(opcode)
1942 {
1943 case LOPC_ADD:
1944 {
1945 LLScriptLibData *string = lsa_get_data(buffer, lside, TRUE);
1946 LLScriptLibData *list = new LLScriptLibData;
1947 list->mType = LST_LIST;
1948 list->mListp = string;
1949 address = lsa_preadd_lists(buffer, list, rside, get_max_heap_size(buffer));
1950 lscript_push(buffer, address);
1951 list->mListp = NULL;
1952 delete list;
1953 }
1954 break;
1955 default:
1956 break;
1957 }
1958}
1959
1960void key_list_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
1961{
1962 S32 lside = lscript_pop_int(buffer);
1963 S32 rside = lscript_pop_int(buffer);
1964 S32 address;
1965
1966 switch(opcode)
1967 {
1968 case LOPC_ADD:
1969 {
1970 LLScriptLibData *key = lsa_get_data(buffer, lside, TRUE);
1971 // need to convert key to key, since it comes out like a string
1972 if (key->mType == LST_STRING)
1973 {
1974 key->mKey = key->mString;
1975 key->mString = NULL;
1976 key->mType = LST_KEY;
1977 }
1978 LLScriptLibData *list = new LLScriptLibData;
1979 list->mType = LST_LIST;
1980 list->mListp = key;
1981 address = lsa_preadd_lists(buffer, list, rside, get_max_heap_size(buffer));
1982 lscript_push(buffer, address);
1983 list->mListp = NULL;
1984 delete list;
1985 }
1986 break;
1987 default:
1988 break;
1989 }
1990}
1991
1992void vector_list_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
1993{
1994 LLVector3 lside;
1995 lscript_pop_vector(buffer, lside);
1996 S32 rside = lscript_pop_int(buffer);
1997 S32 address;
1998
1999 switch(opcode)
2000 {
2001 case LOPC_ADD:
2002 {
2003 LLScriptLibData *list = new LLScriptLibData;
2004 list->mType = LST_LIST;
2005 list->mListp = new LLScriptLibData(lside);
2006 address = lsa_preadd_lists(buffer, list, rside, get_max_heap_size(buffer));
2007 lscript_push(buffer, address);
2008 list->mListp = NULL;
2009 delete list;
2010 }
2011 break;
2012 default:
2013 break;
2014 }
2015}
2016
2017void quaternion_list_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
2018{
2019 LLQuaternion lside;
2020 lscript_pop_quaternion(buffer, lside);
2021 S32 rside = lscript_pop_int(buffer);
2022 S32 address;
2023
2024 switch(opcode)
2025 {
2026 case LOPC_ADD:
2027 {
2028 LLScriptLibData *list = new LLScriptLibData;
2029 list->mType = LST_LIST;
2030 list->mListp = new LLScriptLibData(lside);
2031 address = lsa_preadd_lists(buffer, list, rside, get_max_heap_size(buffer));
2032 lscript_push(buffer, address);
2033 list->mListp = NULL;
2034 delete list;
2035 }
2036 break;
2037 default:
2038 break;
2039 }
2040}
2041
2042void list_integer_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
2043{
2044 S32 lside = lscript_pop_int(buffer);
2045 S32 rside = lscript_pop_int(buffer);
2046 S32 address;
2047
2048 switch(opcode)
2049 {
2050 case LOPC_ADD:
2051 {
2052 LLScriptLibData *list = new LLScriptLibData;
2053 list->mType = LST_LIST;
2054 list->mListp = new LLScriptLibData(rside);
2055 address = lsa_postadd_lists(buffer, lside, list, get_max_heap_size(buffer));
2056 list->mListp = NULL;
2057 delete list;
2058 lscript_push(buffer, address);
2059 }
2060 break;
2061 default:
2062 break;
2063 }
2064}
2065
2066void list_float_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
2067{
2068 S32 lside = lscript_pop_int(buffer);
2069 F32 rside = lscript_pop_float(buffer);
2070 S32 address;
2071
2072 switch(opcode)
2073 {
2074 case LOPC_ADD:
2075 {
2076 LLScriptLibData *list = new LLScriptLibData;
2077 list->mType = LST_LIST;
2078 list->mListp = new LLScriptLibData(rside);
2079 address = lsa_postadd_lists(buffer, lside, list, get_max_heap_size(buffer));
2080 list->mListp = NULL;
2081 delete list;
2082 lscript_push(buffer, address);
2083 }
2084 break;
2085 default:
2086 break;
2087 }
2088}
2089
2090void list_string_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
2091{
2092 S32 lside = lscript_pop_int(buffer);
2093 S32 rside = lscript_pop_int(buffer);
2094 S32 address;
2095
2096 switch(opcode)
2097 {
2098 case LOPC_ADD:
2099 {
2100 LLScriptLibData *string = lsa_get_data(buffer, rside, TRUE);
2101 LLScriptLibData *list = new LLScriptLibData;
2102 list->mType = LST_LIST;
2103 list->mListp = string;
2104 address = lsa_postadd_lists(buffer, lside, list, get_max_heap_size(buffer));
2105 list->mListp = NULL;
2106 delete list;
2107 lscript_push(buffer, address);
2108 }
2109 break;
2110 default:
2111 break;
2112 }
2113}
2114
2115void list_key_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
2116{
2117 S32 lside = lscript_pop_int(buffer);
2118 S32 rside = lscript_pop_int(buffer);
2119 S32 address;
2120
2121 switch(opcode)
2122 {
2123 case LOPC_ADD:
2124 {
2125 LLScriptLibData *key = lsa_get_data(buffer, rside, TRUE);
2126 // need to convert key to key, since it comes out like a string
2127 if (key->mType == LST_STRING)
2128 {
2129 key->mKey = key->mString;
2130 key->mString = NULL;
2131 key->mType = LST_KEY;
2132 }
2133 LLScriptLibData *list = new LLScriptLibData;
2134 list->mType = LST_LIST;
2135 list->mListp = key;
2136 address = lsa_postadd_lists(buffer, lside, list, get_max_heap_size(buffer));
2137 list->mListp = NULL;
2138 delete list;
2139 lscript_push(buffer, address);
2140 }
2141 break;
2142 default:
2143 break;
2144 }
2145}
2146
2147void list_vector_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
2148{
2149 S32 lside = lscript_pop_int(buffer);
2150 LLVector3 rside;
2151 lscript_pop_vector(buffer, rside);
2152 S32 address;
2153
2154 switch(opcode)
2155 {
2156 case LOPC_ADD:
2157 {
2158 LLScriptLibData *list = new LLScriptLibData;
2159 list->mType = LST_LIST;
2160 list->mListp = new LLScriptLibData(rside);
2161 address = lsa_postadd_lists(buffer, lside, list, get_max_heap_size(buffer));
2162 list->mListp = NULL;
2163 delete list;
2164 lscript_push(buffer, address);
2165 }
2166 break;
2167 default:
2168 break;
2169 }
2170}
2171
2172void list_quaternion_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
2173{
2174 S32 lside = lscript_pop_int(buffer);
2175 LLQuaternion rside;
2176 lscript_pop_quaternion(buffer, rside);
2177 S32 address;
2178
2179 switch(opcode)
2180 {
2181 case LOPC_ADD:
2182 {
2183 LLScriptLibData *list = new LLScriptLibData;
2184 list->mType = LST_LIST;
2185 list->mListp = new LLScriptLibData(rside);
2186 address = lsa_postadd_lists(buffer, lside, list, get_max_heap_size(buffer));
2187 list->mListp = NULL;
2188 delete list;
2189 lscript_push(buffer, address);
2190 }
2191 break;
2192 default:
2193 break;
2194 }
2195}
2196
2197void list_list_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
2198{
2199 S32 lside = lscript_pop_int(buffer);
2200 S32 rside = lscript_pop_int(buffer);
2201 S32 resulti;
2202 S32 address;
2203
2204 switch(opcode)
2205 {
2206 case LOPC_ADD:
2207 address = lsa_cat_lists(buffer, lside, rside, get_max_heap_size(buffer));
2208 lscript_push(buffer, address);
2209 break;
2210 case LOPC_EQ:
2211 resulti = !lsa_cmp_lists(buffer, lside, rside);
2212 lscript_push(buffer, resulti);
2213 break;
2214 case LOPC_NEQ:
2215 resulti = lsa_cmp_lists(buffer, lside, rside);
2216 lscript_push(buffer, resulti);
2217 break;
2218 default:
2219 break;
2220 }
2221}
2222
2223BOOL run_add(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
2224{
2225 if (b_print)
2226 printf("[0x%X]\tADD ", offset);
2227 offset++;
2228 U8 arg = safe_instruction_bytestream2byte(buffer, offset);
2229 U8 arg1 = arg >> 4;
2230 U8 arg2 = arg & 0xf;
2231 if (b_print)
2232 {
2233 print_type(arg1);
2234 printf(", ");
2235 print_type(arg2);
2236 printf("\n");
2237 }
2238 binary_operations[arg1][arg2](buffer, LOPC_ADD);
2239 return FALSE;
2240}
2241
2242BOOL run_sub(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
2243{
2244 if (b_print)
2245 printf("[0x%X]\tSUB ", offset);
2246 offset++;
2247 U8 arg = safe_instruction_bytestream2byte(buffer, offset);
2248 U8 arg1 = arg >> 4;
2249 U8 arg2 = arg & 0xf;
2250 if (b_print)
2251 {
2252 print_type(arg1);
2253 printf(", ");
2254 print_type(arg2);
2255 printf("\n");
2256 }
2257 binary_operations[arg1][arg2](buffer, LOPC_SUB);
2258 return FALSE;
2259}
2260BOOL run_mul(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
2261{
2262 if (b_print)
2263 printf("[0x%X]\tMUL ", offset);
2264 offset++;
2265 U8 arg = safe_instruction_bytestream2byte(buffer, offset);
2266 U8 arg1 = arg >> 4;
2267 U8 arg2 = arg & 0xf;
2268 if (b_print)
2269 {
2270 print_type(arg1);
2271 printf(", ");
2272 print_type(arg2);
2273 printf("\n");
2274 }
2275 binary_operations[arg1][arg2](buffer, LOPC_MUL);
2276 return FALSE;
2277}
2278BOOL run_div(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
2279{
2280 if (b_print)
2281 printf("[0x%X]\tDIV ", offset);
2282 offset++;
2283 U8 arg = safe_instruction_bytestream2byte(buffer, offset);
2284 U8 arg1 = arg >> 4;
2285 U8 arg2 = arg & 0xf;
2286 if (b_print)
2287 {
2288 print_type(arg1);
2289 printf(", ");
2290 print_type(arg2);
2291 printf("\n");
2292 }
2293 binary_operations[arg1][arg2](buffer, LOPC_DIV);
2294 return FALSE;
2295}
2296BOOL run_mod(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
2297{
2298 if (b_print)
2299 printf("[0x%X]\tMOD ", offset);
2300 offset++;
2301 U8 arg = safe_instruction_bytestream2byte(buffer, offset);
2302 U8 arg1 = arg >> 4;
2303 U8 arg2 = arg & 0xf;
2304 if (b_print)
2305 {
2306 print_type(arg1);
2307 printf(", ");
2308 print_type(arg2);
2309 printf("\n");
2310 }
2311 binary_operations[arg1][arg2](buffer, LOPC_MOD);
2312 return FALSE;
2313}
2314
2315BOOL run_eq(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
2316{
2317 if (b_print)
2318 printf("[0x%X]\tEQ ", offset);
2319 offset++;
2320 U8 arg = safe_instruction_bytestream2byte(buffer, offset);
2321 U8 arg1 = arg >> 4;
2322 U8 arg2 = arg & 0xf;
2323 if (b_print)
2324 {
2325 print_type(arg1);
2326 printf(", ");
2327 print_type(arg2);
2328 printf("\n");
2329 }
2330 binary_operations[arg1][arg2](buffer, LOPC_EQ);
2331 return FALSE;
2332}
2333BOOL run_neq(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
2334{
2335 if (b_print)
2336 printf("[0x%X]\tNEQ ", offset);
2337 offset++;
2338 U8 arg = safe_instruction_bytestream2byte(buffer, offset);
2339 U8 arg1 = arg >> 4;
2340 U8 arg2 = arg & 0xf;
2341 if (b_print)
2342 {
2343 print_type(arg1);
2344 printf(", ");
2345 print_type(arg2);
2346 printf("\n");
2347 }
2348 binary_operations[arg1][arg2](buffer, LOPC_NEQ);
2349 return FALSE;
2350}
2351BOOL run_leq(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
2352{
2353 if (b_print)
2354 printf("[0x%X]\tLEQ ", offset);
2355 offset++;
2356 U8 arg = safe_instruction_bytestream2byte(buffer, offset);
2357 U8 arg1 = arg >> 4;
2358 U8 arg2 = arg & 0xf;
2359 if (b_print)
2360 {
2361 print_type(arg1);
2362 printf(", ");
2363 print_type(arg2);
2364 printf("\n");
2365 }
2366 binary_operations[arg1][arg2](buffer, LOPC_LEQ);
2367 return FALSE;
2368}
2369BOOL run_geq(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
2370{
2371 if (b_print)
2372 printf("[0x%X]\tGEQ ", offset);
2373 offset++;
2374 U8 arg = safe_instruction_bytestream2byte(buffer, offset);
2375 U8 arg1 = arg >> 4;
2376 U8 arg2 = arg & 0xf;
2377 if (b_print)
2378 {
2379 print_type(arg1);
2380 printf(", ");
2381 print_type(arg2);
2382 printf("\n");
2383 }
2384 binary_operations[arg1][arg2](buffer, LOPC_GEQ);
2385 return FALSE;
2386}
2387BOOL run_less(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
2388{
2389 if (b_print)
2390 printf("[0x%X]\tLESS ", offset);
2391 offset++;
2392 U8 arg = safe_instruction_bytestream2byte(buffer, offset);
2393 U8 arg1 = arg >> 4;
2394 U8 arg2 = arg & 0xf;
2395 if (b_print)
2396 {
2397 print_type(arg1);
2398 printf(", ");
2399 print_type(arg2);
2400 printf("\n");
2401 }
2402 binary_operations[arg1][arg2](buffer, LOPC_LESS);
2403 return FALSE;
2404}
2405BOOL run_greater(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
2406{
2407 if (b_print)
2408 printf("[0x%X]\tGREATER ", offset);
2409 offset++;
2410 U8 arg = safe_instruction_bytestream2byte(buffer, offset);
2411 U8 arg1 = arg >> 4;
2412 U8 arg2 = arg & 0xf;
2413 if (b_print)
2414 {
2415 print_type(arg1);
2416 printf(", ");
2417 print_type(arg2);
2418 printf("\n");
2419 }
2420 binary_operations[arg1][arg2](buffer, LOPC_GREATER);
2421 return FALSE;
2422}
2423
2424BOOL run_bitand(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
2425{
2426 if (b_print)
2427 printf("[0x%X]\tBITAND\n", offset);
2428 offset++;
2429 binary_operations[LST_INTEGER][LST_INTEGER](buffer, LOPC_BITAND);
2430 return FALSE;
2431}
2432BOOL run_bitor(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
2433{
2434 if (b_print)
2435 printf("[0x%X]\tBITOR\n", offset);
2436 offset++;
2437 binary_operations[LST_INTEGER][LST_INTEGER](buffer, LOPC_BITOR);
2438 return FALSE;
2439}
2440BOOL run_bitxor(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
2441{
2442 if (b_print)
2443 printf("[0x%X]\tBITXOR\n", offset);
2444 offset++;
2445 binary_operations[LST_INTEGER][LST_INTEGER](buffer, LOPC_BITXOR);
2446 return FALSE;
2447}
2448BOOL run_booland(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
2449{
2450 if (b_print)
2451 printf("[0x%X]\tBOOLAND\n", offset);
2452 offset++;
2453 binary_operations[LST_INTEGER][LST_INTEGER](buffer, LOPC_BOOLAND);
2454 return FALSE;
2455}
2456BOOL run_boolor(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
2457{
2458 if (b_print)
2459 printf("[0x%X]\tBOOLOR\n", offset);
2460 offset++;
2461 binary_operations[LST_INTEGER][LST_INTEGER](buffer, LOPC_BOOLOR);
2462 return FALSE;
2463}
2464
2465BOOL run_shl(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
2466{
2467 if (b_print)
2468 printf("[0x%X]\tSHL\n", offset);
2469 offset++;
2470 binary_operations[LST_INTEGER][LST_INTEGER](buffer, LOPC_SHL);
2471 return FALSE;
2472}
2473BOOL run_shr(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
2474{
2475 if (b_print)
2476 printf("[0x%X]\tSHR\n", offset);
2477 offset++;
2478 binary_operations[LST_INTEGER][LST_INTEGER](buffer, LOPC_SHR);
2479 return FALSE;
2480}
2481
2482void integer_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
2483{
2484 S32 lside = lscript_pop_int(buffer);
2485 S32 result = 0;
2486
2487 switch(opcode)
2488 {
2489 case LOPC_NEG:
2490 result = -lside;
2491 break;
2492 case LOPC_BITNOT:
2493 result = ~lside;
2494 break;
2495 case LOPC_BOOLNOT:
2496 result = !lside;
2497 break;
2498 default:
2499 break;
2500 }
2501 lscript_push(buffer, result);
2502}
2503
2504void float_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
2505{
2506 F32 lside = lscript_pop_float(buffer);
2507 F32 result = 0;
2508
2509 switch(opcode)
2510 {
2511 case LOPC_NEG:
2512 result = -lside;
2513 lscript_push(buffer, result);
2514 break;
2515 default:
2516 break;
2517 }
2518}
2519
2520void vector_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
2521{
2522 LLVector3 lside;
2523 lscript_pop_vector(buffer, lside);
2524 LLVector3 result;
2525
2526 switch(opcode)
2527 {
2528 case LOPC_NEG:
2529 result = -lside;
2530 lscript_push(buffer, result);
2531 break;
2532 default:
2533 break;
2534 }
2535}
2536
2537void quaternion_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
2538{
2539 LLQuaternion lside;
2540 lscript_pop_quaternion(buffer, lside);
2541 LLQuaternion result;
2542
2543 switch(opcode)
2544 {
2545 case LOPC_NEG:
2546 result = -lside;
2547 lscript_push(buffer, result);
2548 break;
2549 default:
2550 break;
2551 }
2552}
2553
2554
2555BOOL run_neg(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
2556{
2557 if (b_print)
2558 printf("[0x%X]\tNEG ", offset);
2559 offset++;
2560 U8 arg = safe_instruction_bytestream2byte(buffer, offset);
2561 if (b_print)
2562 {
2563 print_type(arg);
2564 printf("\n");
2565 }
2566 unary_operations[arg](buffer, LOPC_NEG);
2567 return FALSE;
2568}
2569
2570BOOL run_bitnot(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
2571{
2572 if (b_print)
2573 printf("[0x%X]\tBITNOT\n", offset);
2574 offset++;
2575 unary_operations[LST_INTEGER](buffer, LOPC_BITNOT);
2576 return FALSE;
2577}
2578
2579BOOL run_boolnot(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
2580{
2581 if (b_print)
2582 printf("[0x%X]\tBOOLNOT\n", offset);
2583 offset++;
2584 unary_operations[LST_INTEGER](buffer, LOPC_BOOLNOT);
2585 return FALSE;
2586}
2587
2588BOOL run_jump(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
2589{
2590 if (b_print)
2591 printf("[0x%X]\tJUMP ", offset);
2592 offset++;
2593 S32 arg = safe_instruction_bytestream2integer(buffer, offset);
2594 if (b_print)
2595 printf("%d\n", arg);
2596 offset += arg;
2597 return FALSE;
2598}
2599BOOL run_jumpif(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
2600{
2601 if (b_print)
2602 printf("[0x%X]\tJUMPIF ", offset);
2603 offset++;
2604 U8 type = safe_instruction_bytestream2byte(buffer, offset);
2605 if (b_print)
2606 {
2607 print_type(type);
2608 printf(", ");
2609 }
2610 S32 arg = safe_instruction_bytestream2integer(buffer, offset);
2611 if (b_print)
2612 printf("%d\n", arg);
2613
2614 if (type == LST_INTEGER)
2615 {
2616 S32 test = lscript_pop_int(buffer);
2617 if (test)
2618 {
2619 offset += arg;
2620 }
2621 }
2622 else if (type == LST_FLOATINGPOINT)
2623 {
2624 F32 test = lscript_pop_float(buffer);
2625 if (test)
2626 {
2627 offset += arg;
2628 }
2629 }
2630 else if (type == LST_VECTOR)
2631 {
2632 LLVector3 test;
2633 lscript_pop_vector(buffer, test);
2634 if (!test.isExactlyZero())
2635 {
2636 offset += arg;
2637 }
2638 }
2639 else if (type == LST_QUATERNION)
2640 {
2641 LLQuaternion test;
2642 lscript_pop_quaternion(buffer, test);
2643 if (!test.isIdentity())
2644 {
2645 offset += arg;
2646 }
2647 }
2648 else if (type == LST_STRING)
2649 {
2650 S32 base_address = lscript_pop_int(buffer);
2651 // this bit of nastiness is to get around that code paths to local variables can result in lack of initialization
2652 // and function clean up of ref counts isn't based on scope (a mistake, I know)
2653 S32 address = base_address + get_register(buffer, LREG_HR) - 1;
2654 if (address)
2655 {
2656 S32 string = address;
2657 string += SIZEOF_SCRIPT_ALLOC_ENTRY;
2658 if (safe_heap_check_address(buffer, string, 1))
2659 {
2660 S32 toffset = string;
2661 safe_heap_bytestream_count_char(buffer, toffset);
2662 S32 size = toffset - string;
2663 char *sdata = new char[size];
2664 bytestream2char(sdata, buffer, string);
2665 if (strlen(sdata))
2666 {
2667 offset += arg;
2668 }
2669 delete [] sdata;
2670 }
2671 lsa_decrease_ref_count(buffer, base_address);
2672 }
2673 }
2674 else if (type == LST_KEY)
2675 {
2676 S32 base_address = lscript_pop_int(buffer);
2677 // this bit of nastiness is to get around that code paths to local variables can result in lack of initialization
2678 // and function clean up of ref counts isn't based on scope (a mistake, I know)
2679 S32 address = base_address + get_register(buffer, LREG_HR) - 1;
2680 if (address)
2681 {
2682 S32 string = address;
2683 string += SIZEOF_SCRIPT_ALLOC_ENTRY;
2684 if (safe_heap_check_address(buffer, string, 1))
2685 {
2686 S32 toffset = string;
2687 safe_heap_bytestream_count_char(buffer, toffset);
2688 S32 size = toffset - string;
2689 char *sdata = new char[size];
2690 bytestream2char(sdata, buffer, string);
2691 if (strlen(sdata))
2692 {
2693 LLUUID id;
2694 id.set(sdata);
2695 if (id != LLUUID::null)
2696 offset += arg;
2697 }
2698 delete [] sdata;
2699 }
2700 lsa_decrease_ref_count(buffer, base_address);
2701 }
2702 else if (type == LST_LIST)
2703 {
2704 S32 address = lscript_pop_int(buffer);
2705 LLScriptLibData *list = lsa_get_data(buffer, address, TRUE);
2706 if (list->getListLength())
2707 {
2708 offset += arg;
2709 }
2710 }
2711 }
2712 return FALSE;
2713}
2714BOOL run_jumpnif(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
2715{
2716 if (b_print)
2717 printf("[0x%X]\tJUMPNIF ", offset);
2718 offset++;
2719 U8 type = safe_instruction_bytestream2byte(buffer, offset);
2720 if (b_print)
2721 {
2722 print_type(type);
2723 printf(", ");
2724 }
2725 S32 arg = safe_instruction_bytestream2integer(buffer, offset);
2726 if (b_print)
2727 printf("%d\n", arg);
2728
2729 if (type == LST_INTEGER)
2730 {
2731 S32 test = lscript_pop_int(buffer);
2732 if (!test)
2733 {
2734 offset += arg;
2735 }
2736 }
2737 else if (type == LST_FLOATINGPOINT)
2738 {
2739 F32 test = lscript_pop_float(buffer);
2740 if (!test)
2741 {
2742 offset += arg;
2743 }
2744 }
2745 else if (type == LST_VECTOR)
2746 {
2747 LLVector3 test;
2748 lscript_pop_vector(buffer, test);
2749 if (test.isExactlyZero())
2750 {
2751 offset += arg;
2752 }
2753 }
2754 else if (type == LST_QUATERNION)
2755 {
2756 LLQuaternion test;
2757 lscript_pop_quaternion(buffer, test);
2758 if (test.isIdentity())
2759 {
2760 offset += arg;
2761 }
2762 }
2763 else if (type == LST_STRING)
2764 {
2765 S32 base_address = lscript_pop_int(buffer);
2766 // this bit of nastiness is to get around that code paths to local variables can result in lack of initialization
2767 // and function clean up of ref counts isn't based on scope (a mistake, I know)
2768 S32 address = base_address + get_register(buffer, LREG_HR) - 1;
2769 if (address)
2770 {
2771 S32 string = address;
2772 string += SIZEOF_SCRIPT_ALLOC_ENTRY;
2773 if (safe_heap_check_address(buffer, string, 1))
2774 {
2775 S32 toffset = string;
2776 safe_heap_bytestream_count_char(buffer, toffset);
2777 S32 size = toffset - string;
2778 char *sdata = new char[size];
2779 bytestream2char(sdata, buffer, string);
2780 if (!strlen(sdata))
2781 {
2782 offset += arg;
2783 }
2784 delete [] sdata;
2785 }
2786 lsa_decrease_ref_count(buffer, base_address);
2787 }
2788 }
2789 else if (type == LST_KEY)
2790 {
2791 S32 base_address = lscript_pop_int(buffer);
2792 // this bit of nastiness is to get around that code paths to local variables can result in lack of initialization
2793 // and function clean up of ref counts isn't based on scope (a mistake, I know)
2794 S32 address = base_address + get_register(buffer, LREG_HR) - 1;
2795 if (address)
2796 {
2797 S32 string = address;
2798 string += SIZEOF_SCRIPT_ALLOC_ENTRY;
2799 if (safe_heap_check_address(buffer, string, 1))
2800 {
2801 S32 toffset = string;
2802 safe_heap_bytestream_count_char(buffer, toffset);
2803 S32 size = toffset - string;
2804 char *sdata = new char[size];
2805 bytestream2char(sdata, buffer, string);
2806 if (strlen(sdata))
2807 {
2808 LLUUID id;
2809 id.set(sdata);
2810 if (id == LLUUID::null)
2811 offset += arg;
2812 }
2813 else
2814 {
2815 offset += arg;
2816 }
2817 delete [] sdata;
2818 }
2819 lsa_decrease_ref_count(buffer, base_address);
2820 }
2821 else if (type == LST_LIST)
2822 {
2823 S32 address = lscript_pop_int(buffer);
2824 LLScriptLibData *list = lsa_get_data(buffer, address, TRUE);
2825 if (!list->getListLength())
2826 {
2827 offset += arg;
2828 }
2829 }
2830 }
2831 return FALSE;
2832}
2833
2834BOOL run_state(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
2835{
2836 if (b_print)
2837 printf("[0x%X]\tSTATE ", offset);
2838 offset++;
2839 S32 state = safe_instruction_bytestream2integer(buffer, offset);
2840 if (b_print)
2841 printf("%d\n", state);
2842
2843 S32 bp = lscript_pop_int(buffer);
2844 set_bp(buffer, bp);
2845
2846 offset = lscript_pop_int(buffer);
2847
2848 S32 major_version = 0;
2849 S32 value = get_register(buffer, LREG_VN);
2850 if (value == LSL2_VERSION1_END_NUMBER)
2851 {
2852 major_version = 1;
2853 }
2854 else if (value == LSL2_VERSION_NUMBER)
2855 {
2856 major_version = 2;
2857 }
2858
2859 S32 current_state = get_register(buffer, LREG_CS);
2860 if (state != current_state)
2861 {
2862 U64 ce = get_event_register(buffer, LREG_CE, major_version);
2863 ce |= LSCRIPTStateBitField[LSTT_STATE_EXIT];
2864 set_event_register(buffer, LREG_CE, ce, major_version);
2865 }
2866 set_register(buffer, LREG_NS, state);
2867 return FALSE;
2868}
2869
2870BOOL run_call(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
2871{
2872 if (b_print)
2873 printf("[0x%X]\tCALL ", offset);
2874 offset++;
2875 S32 func = safe_instruction_bytestream2integer(buffer, offset);
2876 if (b_print)
2877 printf("%d\n", func);
2878
2879 lscript_local_store(buffer, -8, offset);
2880
2881 S32 minimum = get_register(buffer, LREG_GFR);
2882 S32 maximum = get_register(buffer, LREG_SR);
2883 S32 lookup = minimum + func*4 + 4;
2884 S32 function;
2885
2886 if ( (lookup >= minimum)
2887 &&(lookup < maximum))
2888 {
2889 function = bytestream2integer(buffer, lookup) + minimum;
2890 if ( (lookup >= minimum)
2891 &&(lookup < maximum))
2892 {
2893 offset = function;
2894 offset += bytestream2integer(buffer, function);
2895 }
2896 else
2897 {
2898 set_fault(buffer, LSRF_BOUND_CHECK_ERROR);
2899 }
2900 }
2901 else
2902 {
2903 set_fault(buffer, LSRF_BOUND_CHECK_ERROR);
2904 }
2905 return FALSE;
2906}
2907
2908BOOL run_return(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
2909{
2910 if (b_print)
2911 printf("[0x%X]\tRETURN\n", offset);
2912 offset++;
2913 S32 bp = lscript_pop_int(buffer);
2914 set_bp(buffer, bp);
2915 offset = lscript_pop_int(buffer);
2916 return FALSE;
2917}
2918
2919S32 axtoi(char *hexStg)
2920{
2921 S32 n = 0; // position in string
2922 S32 m = 0; // position in digit[] to shift
2923 S32 count; // loop index
2924 S32 intValue = 0; // integer value of hex string
2925 S32 digit[9]; // hold values to convert
2926 while (n < 8)
2927 {
2928 if (hexStg[n]=='\0')
2929 break;
2930 if (hexStg[n] > 0x29 && hexStg[n] < 0x40 ) //if 0 to 9
2931 digit[n] = hexStg[n] & 0x0f; //convert to int
2932 else if (hexStg[n] >='a' && hexStg[n] <= 'f') //if a to f
2933 digit[n] = (hexStg[n] & 0x0f) + 9; //convert to int
2934 else if (hexStg[n] >='A' && hexStg[n] <= 'F') //if A to F
2935 digit[n] = (hexStg[n] & 0x0f) + 9; //convert to int
2936 else break;
2937 n++;
2938 }
2939 count = n;
2940 m = n - 1;
2941 n = 0;
2942 while(n < count)
2943 {
2944 // digit[n] is value of hex digit at position n
2945 // (m << 2) is the number of positions to shift
2946 // OR the bits into return value
2947 intValue = intValue | (digit[n] << (m << 2));
2948 m--; // adjust the position to set
2949 n++; // next digit to process
2950 }
2951 return (intValue);
2952}
2953
2954
2955BOOL run_cast(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
2956{
2957 char caststr[1024];
2958 if (b_print)
2959 printf("[0x%X]\tCAST ", offset);
2960 offset++;
2961 U8 arg = safe_instruction_bytestream2byte(buffer, offset);
2962 U8 from = arg >> 4;
2963 U8 to = arg & 0xf;
2964 if (b_print)
2965 {
2966 print_type(from);
2967 printf(", ");
2968 print_type(to);
2969 printf("\n");
2970 }
2971
2972 switch(from)
2973 {
2974 case LST_INTEGER:
2975 {
2976 switch(to)
2977 {
2978 case LST_INTEGER:
2979 break;
2980 case LST_FLOATINGPOINT:
2981 {
2982 S32 source = lscript_pop_int(buffer);
2983 F32 dest = (F32)source;
2984 lscript_push(buffer, dest);
2985 }
2986 break;
2987 case LST_STRING:
2988 {
2989 S32 address, source = lscript_pop_int(buffer);
2990 sprintf(caststr, "%d", source);
2991 address = lsa_heap_add_data(buffer, new LLScriptLibData(caststr), get_max_heap_size(buffer), TRUE);
2992 lscript_push(buffer, address);
2993 }
2994 break;
2995 case LST_LIST:
2996 {
2997 S32 address, source = lscript_pop_int(buffer);
2998 LLScriptLibData *list = new LLScriptLibData;
2999 list->mType = LST_LIST;
3000 list->mListp = new LLScriptLibData(source);
3001 address = lsa_heap_add_data(buffer, list, get_max_heap_size(buffer), TRUE);
3002 lscript_push(buffer, address);
3003 }
3004 break;
3005 default:
3006 break;
3007 }
3008 }
3009 break;
3010 case LST_FLOATINGPOINT:
3011 {
3012 switch(to)
3013 {
3014 case LST_INTEGER:
3015 {
3016 F32 source = lscript_pop_float(buffer);
3017 S32 dest = (S32)source;
3018 lscript_push(buffer, dest);
3019 }
3020 break;
3021 case LST_FLOATINGPOINT:
3022 break;
3023 case LST_STRING:
3024 {
3025 S32 address;
3026 F32 source = lscript_pop_float(buffer);
3027 sprintf(caststr, "%f", source);
3028 address = lsa_heap_add_data(buffer, new LLScriptLibData(caststr), get_max_heap_size(buffer), TRUE);
3029 lscript_push(buffer, address);
3030 }
3031 break;
3032 case LST_LIST:
3033 {
3034 S32 address;
3035 F32 source = lscript_pop_float(buffer);
3036 LLScriptLibData *list = new LLScriptLibData;
3037 list->mType = LST_LIST;
3038 list->mListp = new LLScriptLibData(source);
3039 address = lsa_heap_add_data(buffer, list, get_max_heap_size(buffer), TRUE);
3040 lscript_push(buffer, address);
3041 }
3042 break;
3043 default:
3044 break;
3045 }
3046 }
3047 break;
3048 case LST_STRING:
3049 {
3050 switch(to)
3051 {
3052 case LST_INTEGER:
3053 {
3054 S32 base_address = lscript_pop_int(buffer);
3055 // this bit of nastiness is to get around that code paths to local variables can result in lack of initialization
3056 // and function clean up of ref counts isn't based on scope (a mistake, I know)
3057 S32 address = base_address + get_register(buffer, LREG_HR) - 1;
3058 if (address)
3059 {
3060 S32 string = address;
3061 string += SIZEOF_SCRIPT_ALLOC_ENTRY;
3062 if (safe_heap_check_address(buffer, string, 1))
3063 {
3064 S32 toffset = string;
3065 safe_heap_bytestream_count_char(buffer, toffset);
3066 S32 size = toffset - string;
3067 char *arg = new char[size];
3068 bytestream2char(arg, buffer, string);
3069 // S32 length = strlen(arg);
3070 S32 dest;
3071 S32 base;
3072
3073 // Check to see if this is a hexidecimal number.
3074 if ( (arg[0] == '0') &&
3075 (arg[1] == 'x' || arg[1] == 'X') )
3076 {
3077 // Let strtoul do a hex conversion.
3078 base = 16;
3079 }
3080 else
3081 {
3082 // Force base-10, so octal is never used.
3083 base = 10;
3084 }
3085
3086 dest = strtoul(arg, NULL, base);
3087
3088 lscript_push(buffer, dest);
3089 delete [] arg;
3090 }
3091 lsa_decrease_ref_count(buffer, base_address);
3092 }
3093 }
3094 break;
3095 case LST_FLOATINGPOINT:
3096 {
3097 S32 base_address = lscript_pop_int(buffer);
3098 // this bit of nastiness is to get around that code paths to local variables can result in lack of initialization
3099 // and function clean up of ref counts isn't based on scope (a mistake, I know)
3100 S32 address = base_address + get_register(buffer, LREG_HR) - 1;
3101 if (address)
3102 {
3103 S32 string = address;
3104 string += SIZEOF_SCRIPT_ALLOC_ENTRY;
3105 if (safe_heap_check_address(buffer, string, 1))
3106 {
3107 S32 toffset = string;
3108 safe_heap_bytestream_count_char(buffer, toffset);
3109 S32 size = toffset - string;
3110 char *arg = new char[size];
3111 bytestream2char(arg, buffer, string);
3112 F32 dest = (F32)atof(arg);
3113
3114
3115 lscript_push(buffer, dest);
3116 delete [] arg;
3117 }
3118 lsa_decrease_ref_count(buffer, base_address);
3119 }
3120 }
3121 break;
3122 case LST_STRING:
3123 break;
3124 case LST_LIST:
3125 {
3126 S32 saddress = lscript_pop_int(buffer);
3127 LLScriptLibData *string = lsa_get_data(buffer, saddress, TRUE);
3128 LLScriptLibData *list = new LLScriptLibData;
3129 list->mType = LST_LIST;
3130 list->mListp = string;
3131 S32 address = lsa_heap_add_data(buffer, list, get_max_heap_size(buffer), TRUE);
3132 lscript_push(buffer, address);
3133 }
3134 break;
3135 case LST_VECTOR:
3136 {
3137 S32 base_address = lscript_pop_int(buffer);
3138 // this bit of nastiness is to get around that code paths to local variables can result in lack of initialization
3139 // and function clean up of ref counts isn't based on scope (a mistake, I know)
3140 S32 address = base_address + get_register(buffer, LREG_HR) - 1;
3141 if (address)
3142 {
3143 S32 string = address;
3144 string += SIZEOF_SCRIPT_ALLOC_ENTRY;
3145 if (safe_heap_check_address(buffer, string, 1))
3146 {
3147 S32 toffset = string;
3148 safe_heap_bytestream_count_char(buffer, toffset);
3149 S32 size = toffset - string;
3150 char *arg = new char[size];
3151 bytestream2char(arg, buffer, string);
3152 LLVector3 vec;
3153 S32 num = sscanf(arg, "<%f, %f, %f>", &vec.mV[VX], &vec.mV[VY], &vec.mV[VZ]);
3154 if (num != 3)
3155 {
3156 vec = LLVector3::zero;
3157 }
3158 lscript_push(buffer, vec);
3159 delete [] arg;
3160 }
3161 lsa_decrease_ref_count(buffer, base_address);
3162 }
3163 }
3164 break;
3165 case LST_QUATERNION:
3166 {
3167 S32 base_address = lscript_pop_int(buffer);
3168 // this bit of nastiness is to get around that code paths to local variables can result in lack of initialization
3169 // and function clean up of ref counts isn't based on scope (a mistake, I know)
3170 S32 address = base_address + get_register(buffer, LREG_HR) - 1;
3171 if (address)
3172 {
3173 S32 string = address;
3174 string += SIZEOF_SCRIPT_ALLOC_ENTRY;
3175 if (safe_heap_check_address(buffer, string, 1))
3176 {
3177 S32 toffset = string;
3178 safe_heap_bytestream_count_char(buffer, toffset);
3179 S32 size = toffset - string;
3180 char *arg = new char[size];
3181 bytestream2char(arg, buffer, string);
3182 LLQuaternion quat;
3183 S32 num = sscanf(arg, "<%f, %f, %f, %f>", &quat.mQ[VX], &quat.mQ[VY], &quat.mQ[VZ], &quat.mQ[VW]);
3184 if (num != 4)
3185 {
3186 quat = LLQuaternion::DEFAULT;
3187
3188 }
3189 lscript_push(buffer, quat);
3190 delete [] arg;
3191 }
3192 lsa_decrease_ref_count(buffer, base_address);
3193 }
3194 }
3195 break;
3196 default:
3197 break;
3198 }
3199 }
3200 break;
3201 case LST_KEY:
3202 {
3203 switch(to)
3204 {
3205 case LST_KEY:
3206 break;
3207 case LST_STRING:
3208 break;
3209 case LST_LIST:
3210 {
3211 S32 saddress = lscript_pop_int(buffer);
3212 LLScriptLibData *string = lsa_get_data(buffer, saddress, TRUE);
3213 LLScriptLibData *list = new LLScriptLibData;
3214 list->mType = LST_LIST;
3215 list->mListp = string;
3216 S32 address = lsa_heap_add_data(buffer, list, get_max_heap_size(buffer), TRUE);
3217 lscript_push(buffer, address);
3218 }
3219 break;
3220 default:
3221 break;
3222 }
3223 }
3224 break;
3225 case LST_VECTOR:
3226 {
3227 switch(to)
3228 {
3229 case LST_VECTOR:
3230 break;
3231 case LST_STRING:
3232 {
3233 S32 address;
3234 LLVector3 source;
3235 lscript_pop_vector(buffer, source);
3236 sprintf(caststr, "<%5.5f, %5.5f, %5.5f>", source.mV[VX], source.mV[VY], source.mV[VZ]);
3237 address = lsa_heap_add_data(buffer, new LLScriptLibData(caststr), get_max_heap_size(buffer), TRUE);
3238 lscript_push(buffer, address);
3239 }
3240 break;
3241 case LST_LIST:
3242 {
3243 S32 address;
3244 LLVector3 source;
3245 lscript_pop_vector(buffer, source);
3246 LLScriptLibData *list = new LLScriptLibData;
3247 list->mType = LST_LIST;
3248 list->mListp = new LLScriptLibData(source);
3249 address = lsa_heap_add_data(buffer, list, get_max_heap_size(buffer), TRUE);
3250 lscript_push(buffer, address);
3251 }
3252 break;
3253 default:
3254 break;
3255 }
3256 }
3257 break;
3258 case LST_QUATERNION:
3259 {
3260 switch(to)
3261 {
3262 case LST_QUATERNION:
3263 break;
3264 case LST_STRING:
3265 {
3266 S32 address;
3267 LLQuaternion source;
3268 lscript_pop_quaternion(buffer, source);
3269 sprintf(caststr, "<%5.5f, %5.5f, %5.5f, %5.5f>", source.mQ[VX], source.mQ[VY], source.mQ[VZ], source.mQ[VS]);
3270 address = lsa_heap_add_data(buffer, new LLScriptLibData(caststr), get_max_heap_size(buffer), TRUE);
3271 lscript_push(buffer, address);
3272 }
3273 break;
3274 case LST_LIST:
3275 {
3276 S32 address;
3277 LLQuaternion source;
3278 lscript_pop_quaternion(buffer, source);
3279 LLScriptLibData *list = new LLScriptLibData;
3280 list->mType = LST_LIST;
3281 list->mListp = new LLScriptLibData(source);
3282 address = lsa_heap_add_data(buffer, list, get_max_heap_size(buffer), TRUE);
3283 lscript_push(buffer, address);
3284 }
3285 break;
3286 default:
3287 break;
3288 }
3289 }
3290 break;
3291 case LST_LIST:
3292 {
3293 switch(to)
3294 {
3295 case LST_LIST:
3296 break;
3297 case LST_STRING:
3298 {
3299 S32 address = lscript_pop_int(buffer);
3300 LLScriptLibData *list = lsa_get_data(buffer, address, TRUE);
3301 LLScriptLibData *list_root = list;
3302
3303 std::ostringstream dest;
3304 while (list)
3305 {
3306 list->print(dest, FALSE);
3307 list = list->mListp;
3308 }
3309 delete list_root;
3310 char *tmp = strdup(dest.str().c_str());
3311 LLScriptLibData *string = new LLScriptLibData(tmp);
3312 free(tmp);
3313 tmp = NULL;
3314 S32 destaddress = lsa_heap_add_data(buffer, string, get_max_heap_size(buffer), TRUE);
3315 lscript_push(buffer, destaddress);
3316 }
3317 break;
3318 default:
3319 break;
3320 }
3321 }
3322 break;
3323 default:
3324 break;
3325 }
3326 return FALSE;
3327}
3328
3329BOOL run_stacktos(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
3330{
3331 S32 length = lscript_pop_int(buffer);
3332 S32 i;
3333 char *arg = new char[length];
3334 S32 fault;
3335 for (i = 0; i < length; i++)
3336 {
3337 fault = get_register(buffer, LREG_FR);
3338 if (fault)
3339 break;
3340
3341 arg[length - i - 1] = lscript_pop_char(buffer);
3342 }
3343 S32 address = lsa_heap_add_data(buffer, new LLScriptLibData(arg), get_max_heap_size(buffer), TRUE);
3344 lscript_push(buffer, address);
3345 delete [] arg;
3346 return FALSE;
3347}
3348
3349void lscript_stacktol_pop_variable(LLScriptLibData *data, U8 *buffer, char type)
3350{
3351 S32 address, string;
3352 S32 base_address;
3353
3354 switch(type)
3355 {
3356 case LST_INTEGER:
3357 data->mType = LST_INTEGER;
3358 data->mInteger = lscript_pop_int(buffer);
3359 break;
3360 case LST_FLOATINGPOINT:
3361 data->mType = LST_FLOATINGPOINT;
3362 data->mFP = lscript_pop_float(buffer);
3363 break;
3364 case LST_KEY:
3365 data->mType = LST_KEY;
3366
3367 base_address = lscript_pop_int(buffer);
3368 // this bit of nastiness is to get around that code paths to local variables can result in lack of initialization
3369 // and function clean up of ref counts isn't based on scope (a mistake, I know)
3370 address = base_address + get_register(buffer, LREG_HR) - 1;
3371
3372 if (address)
3373 {
3374 string = address + SIZEOF_SCRIPT_ALLOC_ENTRY;
3375 if (safe_heap_check_address(buffer, string, 1))
3376 {
3377 S32 toffset = string;
3378 safe_heap_bytestream_count_char(buffer, toffset);
3379 S32 size = toffset - string;
3380 data->mKey = new char[size];
3381 bytestream2char(data->mKey, buffer, string);
3382 }
3383 lsa_decrease_ref_count(buffer, base_address);
3384 }
3385 else
3386 {
3387 data->mKey = new char[1];
3388 data->mKey[0] = 0;
3389 }
3390 break;
3391 case LST_STRING:
3392 data->mType = LST_STRING;
3393
3394 base_address = lscript_pop_int(buffer);
3395 // this bit of nastiness is to get around that code paths to local variables can result in lack of initialization
3396 // and function clean up of ref counts isn't based on scope (a mistake, I know)
3397 address = base_address + get_register(buffer, LREG_HR) - 1;
3398
3399 if (address)
3400 {
3401 string = address + SIZEOF_SCRIPT_ALLOC_ENTRY;
3402 if (safe_heap_check_address(buffer, string, 1))
3403 {
3404 S32 toffset = string;
3405 safe_heap_bytestream_count_char(buffer, toffset);
3406 S32 size = toffset - string;
3407 data->mString = new char[size];
3408 bytestream2char(data->mString, buffer, string);
3409 }
3410 lsa_decrease_ref_count(buffer, base_address);
3411 }
3412 else
3413 {
3414 data->mString = new char[1];
3415 data->mString[0] = 0;
3416 }
3417 break;
3418 case LST_VECTOR:
3419 data->mType = LST_VECTOR;
3420 lscript_pop_vector(buffer, data->mVec);
3421 break;
3422 case LST_QUATERNION:
3423 data->mType = LST_QUATERNION;
3424 lscript_pop_quaternion(buffer, data->mQuat);
3425 break;
3426 case LST_LIST:
3427 data->mType = LST_LIST;
3428 address = lscript_pop_int(buffer);
3429 data->mListp = lsa_get_data(buffer, address, TRUE);
3430 break;
3431 }
3432}
3433
3434BOOL run_stacktol(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
3435{
3436 offset++;
3437 S32 length = safe_instruction_bytestream2integer(buffer, offset);
3438 S32 i;
3439 S32 fault;
3440
3441 S8 type;
3442
3443 LLScriptLibData *data = new LLScriptLibData, *tail;
3444 data->mType = LST_LIST;
3445
3446 for (i = 0; i < length; i++)
3447 {
3448 fault = get_register(buffer, LREG_FR);
3449 if (fault)
3450 break;
3451
3452 type = lscript_pop_char(buffer);
3453
3454 tail = new LLScriptLibData;
3455
3456 lscript_stacktol_pop_variable(tail, buffer, type);
3457
3458 tail->mListp = data->mListp;
3459 data->mListp = tail;
3460 }
3461 S32 address = lsa_heap_add_data(buffer,data, get_max_heap_size(buffer), TRUE);
3462 lscript_push(buffer, address);
3463 return FALSE;
3464}
3465
3466BOOL run_print(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
3467{
3468 if (b_print)
3469 printf("[0x%X]\tPRINT ", offset);
3470 offset++;
3471 U8 type = safe_instruction_bytestream2byte(buffer, offset);
3472 if (b_print)
3473 {
3474 print_type(type);
3475 printf("\n");
3476 }
3477 switch(type)
3478 {
3479 case LST_INTEGER:
3480 {
3481 S32 source = lscript_pop_int(buffer);
3482 printf("%d\n", source);
3483 }
3484 break;
3485 case LST_FLOATINGPOINT:
3486 {
3487 F32 source = lscript_pop_float(buffer);
3488 printf("%f\n", source);
3489 }
3490 break;
3491 case LST_STRING:
3492 {
3493 S32 base_address = lscript_pop_int(buffer);
3494 // this bit of nastiness is to get around that code paths to local variables can result in lack of initialization
3495 // and function clean up of ref counts isn't based on scope (a mistake, I know)
3496 S32 address = base_address + get_register(buffer, LREG_HR) - 1;
3497
3498 if (address)
3499 {
3500 S32 string = address;
3501 string += SIZEOF_SCRIPT_ALLOC_ENTRY;
3502 if (safe_heap_check_address(buffer, string, 1))
3503 {
3504 S32 toffset = string;
3505 safe_heap_bytestream_count_char(buffer, toffset);
3506 S32 size = toffset - string;
3507 char *arg = new char[size];
3508 bytestream2char(arg, buffer, string);
3509 printf("%s\n", arg);
3510 delete [] arg;
3511 }
3512 lsa_decrease_ref_count(buffer, base_address);
3513 }
3514 }
3515 break;
3516 case LST_VECTOR:
3517 {
3518 LLVector3 source;
3519 lscript_pop_vector(buffer, source);
3520 printf("< %f, %f, %f >\n", source.mV[VX], source.mV[VY], source.mV[VZ]);
3521 }
3522 break;
3523 case LST_QUATERNION:
3524 {
3525 LLQuaternion source;
3526 lscript_pop_quaternion(buffer, source);
3527 printf("< %f, %f, %f, %f >\n", source.mQ[VX], source.mQ[VY], source.mQ[VZ], source.mQ[VS]);
3528 }
3529 break;
3530 case LST_LIST:
3531 {
3532 S32 base_address = lscript_pop_int(buffer);
3533 LLScriptLibData *data = lsa_get_data(buffer, base_address, TRUE);
3534 LLScriptLibData *print = data;
3535
3536 printf("list\n");
3537
3538 while (print)
3539 {
3540 switch(print->mType)
3541 {
3542 case LST_INTEGER:
3543 {
3544 printf("%d\n", print->mInteger);
3545 }
3546 break;
3547 case LST_FLOATINGPOINT:
3548 {
3549 printf("%f\n", print->mFP);
3550 }
3551 break;
3552 case LST_STRING:
3553 {
3554 printf("%s\n", print->mString);
3555 }
3556 break;
3557 case LST_KEY:
3558 {
3559 printf("%s\n", print->mKey);
3560 }
3561 break;
3562 case LST_VECTOR:
3563 {
3564 printf("< %f, %f, %f >\n", print->mVec.mV[VX], print->mVec.mV[VY], print->mVec.mV[VZ]);
3565 }
3566 break;
3567 case LST_QUATERNION:
3568 {
3569 printf("< %f, %f, %f, %f >\n", print->mQuat.mQ[VX], print->mQuat.mQ[VY], print->mQuat.mQ[VZ], print->mQuat.mQ[VS]);
3570 }
3571 break;
3572 default:
3573 break;
3574 }
3575 print = print->mListp;
3576 }
3577 delete data;
3578 }
3579 break;
3580 default:
3581 break;
3582 }
3583 return FALSE;
3584}
3585
3586
3587void lscript_run(char *filename, BOOL b_debug)
3588{
3589 LLTimer timer;
3590 char *error;
3591 BOOL b_state;
3592 LLScriptExecute *execute = NULL;
3593 FILE *file = LLFile::fopen(filename, "r");
3594 if (file)
3595 {
3596 execute = new LLScriptExecute(file);
3597 fclose(file);
3598 }
3599 file = LLFile::fopen(filename, "r");
3600 if (file)
3601 {
3602 FILE *fp = LLFile::fopen("lscript.parse", "w");
3603 LLScriptLSOParse *parse = new LLScriptLSOParse(file);
3604 parse->printData(fp);
3605 fclose(file);
3606 fclose(fp);
3607 }
3608 file = LLFile::fopen(filename, "r");
3609 if (file && execute)
3610 {
3611 timer.reset();
3612 while (!execute->run(b_debug, LLUUID::null, &error, b_state))
3613 ;
3614 F32 time = timer.getElapsedTimeF32();
3615 F32 ips = execute->mInstructionCount / time;
3616 llinfos << execute->mInstructionCount << " instructions in " << time << " seconds" << llendl;
3617 llinfos << ips/1000 << "K instructions per second" << llendl;
3618 printf("ip: 0x%X\n", get_register(execute->mBuffer, LREG_IP));
3619 printf("sp: 0x%X\n", get_register(execute->mBuffer, LREG_SP));
3620 printf("bp: 0x%X\n", get_register(execute->mBuffer, LREG_BP));
3621 printf("hr: 0x%X\n", get_register(execute->mBuffer, LREG_HR));
3622 printf("hp: 0x%X\n", get_register(execute->mBuffer, LREG_HP));
3623 delete execute;
3624 fclose(file);
3625 }
3626}
3627
3628void lscript_pop_variable(LLScriptLibData *data, U8 *buffer, char type)
3629{
3630 S32 address, string;
3631 S32 base_address;
3632
3633 switch(type)
3634 {
3635 case 'i':
3636 data->mType = LST_INTEGER;
3637 data->mInteger = lscript_pop_int(buffer);
3638 break;
3639 case 'f':
3640 data->mType = LST_FLOATINGPOINT;
3641 data->mFP = lscript_pop_float(buffer);
3642 break;
3643 case 'k':
3644 data->mType = LST_KEY;
3645
3646 base_address = lscript_pop_int(buffer);
3647 // this bit of nastiness is to get around that code paths to local variables can result in lack of initialization
3648 // and function clean up of ref counts isn't based on scope (a mistake, I know)
3649 address = base_address + get_register(buffer, LREG_HR) - 1;
3650
3651 if (address)
3652 {
3653 string = address + SIZEOF_SCRIPT_ALLOC_ENTRY;
3654 if (safe_heap_check_address(buffer, string, 1))
3655 {
3656 S32 toffset = string;
3657 safe_heap_bytestream_count_char(buffer, toffset);
3658 S32 size = toffset - string;
3659 data->mKey = new char[size];
3660 bytestream2char(data->mKey, buffer, string);
3661 }
3662 lsa_decrease_ref_count(buffer, base_address);
3663 }
3664 else
3665 {
3666 data->mKey = new char[1];
3667 data->mKey[0] = 0;
3668 }
3669 break;
3670 case 's':
3671 data->mType = LST_STRING;
3672
3673 base_address = lscript_pop_int(buffer);
3674 // this bit of nastiness is to get around that code paths to local variables can result in lack of initialization
3675 // and function clean up of ref counts isn't based on scope (a mistake, I know)
3676 address = base_address + get_register(buffer, LREG_HR) - 1;
3677
3678 if (address)
3679 {
3680 string = address + SIZEOF_SCRIPT_ALLOC_ENTRY;
3681 if (safe_heap_check_address(buffer, string, 1))
3682 {
3683 S32 toffset = string;
3684 safe_heap_bytestream_count_char(buffer, toffset);
3685 S32 size = toffset - string;
3686 data->mString = new char[size];
3687 bytestream2char(data->mString, buffer, string);
3688 }
3689 lsa_decrease_ref_count(buffer, base_address);
3690 }
3691 else
3692 {
3693 data->mString = new char[1];
3694 data->mString[0] = 0;
3695 }
3696 break;
3697 case 'l':
3698 {
3699 S32 base_address = lscript_pop_int(buffer);
3700 data->mType = LST_LIST;
3701 data->mListp = lsa_get_list_ptr(buffer, base_address, TRUE);
3702 }
3703 break;
3704 case 'v':
3705 data->mType = LST_VECTOR;
3706 lscript_pop_vector(buffer, data->mVec);
3707 break;
3708 case 'q':
3709 data->mType = LST_QUATERNION;
3710 lscript_pop_quaternion(buffer, data->mQuat);
3711 break;
3712 }
3713}
3714
3715void lscript_push_return_variable(LLScriptLibData *data, U8 *buffer)
3716{
3717 S32 address;
3718 switch(data->mType)
3719 {
3720 case LST_INTEGER:
3721 lscript_local_store(buffer, -12, data->mInteger);
3722 break;
3723 case LST_FLOATINGPOINT:
3724 lscript_local_store(buffer, -12, data->mFP);
3725 break;
3726 case LST_KEY:
3727 address = lsa_heap_add_data(buffer, data, get_max_heap_size(buffer), FALSE);
3728 lscript_local_store(buffer, -12, address);
3729 break;
3730 case LST_STRING:
3731 address = lsa_heap_add_data(buffer, data, get_max_heap_size(buffer), FALSE);
3732 lscript_local_store(buffer, -12, address);
3733 break;
3734 case LST_LIST:
3735 address = lsa_heap_add_data(buffer, data, get_max_heap_size(buffer), FALSE);
3736 lscript_local_store(buffer, -12, address);
3737 break;
3738 case LST_VECTOR:
3739 lscript_local_store(buffer, -20, data->mVec);
3740 break;
3741 case LST_QUATERNION:
3742 lscript_local_store(buffer, -24, data->mQuat);
3743 break;
3744 default:
3745 break;
3746 }
3747}
3748
3749S32 lscript_push_variable(LLScriptLibData *data, U8 *buffer)
3750{
3751 S32 address;
3752 switch(data->mType)
3753 {
3754 case LST_INTEGER:
3755 lscript_push(buffer, data->mInteger);
3756 break;
3757 case LST_FLOATINGPOINT:
3758 lscript_push(buffer, data->mFP);
3759 return 4;
3760 break;
3761 case LST_KEY:
3762 address = lsa_heap_add_data(buffer, data, get_max_heap_size(buffer), FALSE);
3763 lscript_push(buffer, address);
3764 return 4;
3765 break;
3766 case LST_STRING:
3767 address = lsa_heap_add_data(buffer, data, get_max_heap_size(buffer), FALSE);
3768 lscript_push(buffer, address);
3769 return 4;
3770 break;
3771 case LST_LIST:
3772 address = lsa_heap_add_data(buffer, data, get_max_heap_size(buffer), FALSE);
3773 lscript_push(buffer, address);
3774 return 4;
3775 break;
3776 case LST_VECTOR:
3777 lscript_push(buffer, data->mVec);
3778 return 12;
3779 break;
3780 case LST_QUATERNION:
3781 lscript_push(buffer, data->mQuat);
3782 return 16;
3783 break;
3784 default:
3785 break;
3786 }
3787 return 4;
3788}
3789
3790BOOL run_calllib(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
3791{
3792 if (b_print)
3793 printf("[0x%X]\tCALLLIB ", offset);
3794 offset++;
3795 U8 arg = safe_instruction_bytestream2byte(buffer, offset);
3796 if (arg >= gScriptLibrary.mNextNumber)
3797 {
3798 set_fault(buffer, LSRF_BOUND_CHECK_ERROR);
3799 return FALSE;
3800 }
3801 if (b_print)
3802 printf("%d (%s)\n", (U32)arg, gScriptLibrary.mFunctions[arg]->mName);
3803
3804 // pull out the arguments and the return values
3805 LLScriptLibData *arguments = NULL;
3806 LLScriptLibData *returnvalue = NULL;
3807
3808 S32 i, number;
3809
3810 if (gScriptLibrary.mFunctions[arg]->mReturnType)
3811 {
3812 returnvalue = new LLScriptLibData;
3813 }
3814
3815 if (gScriptLibrary.mFunctions[arg]->mArgs)
3816 {
3817 number = (S32)strlen(gScriptLibrary.mFunctions[arg]->mArgs);
3818 arguments = new LLScriptLibData[number];
3819 }
3820 else
3821 {
3822 number = 0;
3823 }
3824
3825 for (i = number - 1; i >= 0; i--)
3826 {
3827 lscript_pop_variable(&arguments[i], buffer, gScriptLibrary.mFunctions[arg]->mArgs[i]);
3828 }
3829
3830 if (b_print)
3831 {
3832 printf("%s\n", gScriptLibrary.mFunctions[arg]->mDesc);
3833 }
3834
3835 {
3836 // LLFastTimer time_in_libraries1(LLFastTimer::FTM_TEMP7);
3837 gScriptLibrary.mFunctions[arg]->mExecFunc(returnvalue, arguments, id);
3838 }
3839 add_register_fp(buffer, LREG_ESR, -gScriptLibrary.mFunctions[arg]->mEnergyUse);
3840 add_register_fp(buffer, LREG_SLR, gScriptLibrary.mFunctions[arg]->mSleepTime);
3841
3842 if (returnvalue)
3843 {
3844 returnvalue->mType = char2type(*gScriptLibrary.mFunctions[arg]->mReturnType);
3845 lscript_push_return_variable(returnvalue, buffer);
3846 }
3847
3848 delete [] arguments;
3849 delete returnvalue;
3850
3851 // reset the BP after calling the library files
3852 S32 bp = lscript_pop_int(buffer);
3853 set_bp(buffer, bp);
3854
3855 // pop off the spot for the instruction pointer
3856 lscript_poparg(buffer, 4);
3857 return FALSE;
3858}
3859
3860
3861BOOL run_calllib_two_byte(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
3862{
3863 if (b_print)
3864 printf("[0x%X]\tCALLLIB ", offset);
3865 offset++;
3866 U16 arg = safe_instruction_bytestream2u16(buffer, offset);
3867 if (arg >= gScriptLibrary.mNextNumber)
3868 {
3869 set_fault(buffer, LSRF_BOUND_CHECK_ERROR);
3870 return FALSE;
3871 }
3872 if (b_print)
3873 printf("%d (%s)\n", (U32)arg, gScriptLibrary.mFunctions[arg]->mName);
3874
3875 // pull out the arguments and the return values
3876 LLScriptLibData *arguments = NULL;
3877 LLScriptLibData *returnvalue = NULL;
3878
3879 S32 i, number;
3880
3881 if (gScriptLibrary.mFunctions[arg]->mReturnType)
3882 {
3883 returnvalue = new LLScriptLibData;
3884 }
3885
3886 if (gScriptLibrary.mFunctions[arg]->mArgs)
3887 {
3888 number = (S32)strlen(gScriptLibrary.mFunctions[arg]->mArgs);
3889 arguments = new LLScriptLibData[number];
3890 }
3891 else
3892 {
3893 number = 0;
3894 }
3895
3896 for (i = number - 1; i >= 0; i--)
3897 {
3898 lscript_pop_variable(&arguments[i], buffer, gScriptLibrary.mFunctions[arg]->mArgs[i]);
3899 }
3900
3901 if (b_print)
3902 {
3903 printf("%s\n", gScriptLibrary.mFunctions[arg]->mDesc);
3904 }
3905
3906 {
3907 // LLFastTimer time_in_libraries2(LLFastTimer::FTM_TEMP8);
3908 gScriptLibrary.mFunctions[arg]->mExecFunc(returnvalue, arguments, id);
3909 }
3910 add_register_fp(buffer, LREG_ESR, -gScriptLibrary.mFunctions[arg]->mEnergyUse);
3911 add_register_fp(buffer, LREG_SLR, gScriptLibrary.mFunctions[arg]->mSleepTime);
3912
3913 if (returnvalue)
3914 {
3915 returnvalue->mType = char2type(*gScriptLibrary.mFunctions[arg]->mReturnType);
3916 lscript_push_return_variable(returnvalue, buffer);
3917 }
3918
3919 delete [] arguments;
3920 delete returnvalue;
3921
3922 // reset the BP after calling the library files
3923 S32 bp = lscript_pop_int(buffer);
3924 set_bp(buffer, bp);
3925
3926 // pop off the spot for the instruction pointer
3927 lscript_poparg(buffer, 4);
3928 return FALSE;
3929}
diff --git a/linden/indra/lscript/lscript_execute/lscript_execute.vcproj b/linden/indra/lscript/lscript_execute/lscript_execute.vcproj
new file mode 100644
index 0000000..1ae15ea
--- /dev/null
+++ b/linden/indra/lscript/lscript_execute/lscript_execute.vcproj
@@ -0,0 +1,189 @@
1<?xml version="1.0" encoding="Windows-1252"?>
2<VisualStudioProject
3 ProjectType="Visual C++"
4 Version="7.10"
5 Name="lscript_execute"
6 ProjectGUID="{F882263E-4F2A-43D9-A45A-FA4C8EC66552}"
7 Keyword="Win32Proj">
8 <Platforms>
9 <Platform
10 Name="Win32"/>
11 </Platforms>
12 <Configurations>
13 <Configuration
14 Name="Debug|Win32"
15 OutputDirectory="../../lib_$(ConfigurationName)/i686-win32"
16 IntermediateDirectory="Debug"
17 ConfigurationType="4"
18 CharacterSet="1">
19 <Tool
20 Name="VCCLCompilerTool"
21 Optimization="0"
22 AdditionalIncludeDirectories="..;..\..\llcommon;..\..\llmath"
23 PreprocessorDefinitions="WIN32;_DEBUG;_LIB;LL_WINDOWS;LL_DEBUG"
24 MinimalRebuild="TRUE"
25 BasicRuntimeChecks="3"
26 RuntimeLibrary="1"
27 StructMemberAlignment="4"
28 ForceConformanceInForLoopScope="TRUE"
29 UsePrecompiledHeader="0"
30 WarningLevel="3"
31 WarnAsError="TRUE"
32 Detect64BitPortabilityProblems="FALSE"
33 DebugInformationFormat="4"/>
34 <Tool
35 Name="VCCustomBuildTool"/>
36 <Tool
37 Name="VCLibrarianTool"
38 OutputFile="$(OutDir)/lscript_execute.lib"/>
39 <Tool
40 Name="VCMIDLTool"/>
41 <Tool
42 Name="VCPostBuildEventTool"/>
43 <Tool
44 Name="VCPreBuildEventTool"/>
45 <Tool
46 Name="VCPreLinkEventTool"/>
47 <Tool
48 Name="VCResourceCompilerTool"/>
49 <Tool
50 Name="VCWebServiceProxyGeneratorTool"/>
51 <Tool
52 Name="VCXMLDataGeneratorTool"/>
53 <Tool
54 Name="VCManagedWrapperGeneratorTool"/>
55 <Tool
56 Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
57 </Configuration>
58 <Configuration
59 Name="Release|Win32"
60 OutputDirectory="../../lib_$(ConfigurationName)/i686-win32"
61 IntermediateDirectory="Release"
62 ConfigurationType="4"
63 CharacterSet="1">
64 <Tool
65 Name="VCCLCompilerTool"
66 AdditionalIncludeDirectories="..;..\..\llcommon;..\..\llmath"
67 PreprocessorDefinitions="WIN32;NDEBUG;_LIB;LL_WINDOWS;LL_RELEASE"
68 RuntimeLibrary="0"
69 StructMemberAlignment="0"
70 ForceConformanceInForLoopScope="TRUE"
71 UsePrecompiledHeader="0"
72 WarningLevel="3"
73 WarnAsError="TRUE"
74 Detect64BitPortabilityProblems="FALSE"
75 DebugInformationFormat="3"/>
76 <Tool
77 Name="VCCustomBuildTool"/>
78 <Tool
79 Name="VCLibrarianTool"
80 OutputFile="$(OutDir)/lscript_execute.lib"/>
81 <Tool
82 Name="VCMIDLTool"/>
83 <Tool
84 Name="VCPostBuildEventTool"/>
85 <Tool
86 Name="VCPreBuildEventTool"/>
87 <Tool
88 Name="VCPreLinkEventTool"/>
89 <Tool
90 Name="VCResourceCompilerTool"/>
91 <Tool
92 Name="VCWebServiceProxyGeneratorTool"/>
93 <Tool
94 Name="VCXMLDataGeneratorTool"/>
95 <Tool
96 Name="VCManagedWrapperGeneratorTool"/>
97 <Tool
98 Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
99 </Configuration>
100 <Configuration
101 Name="ReleaseNoOpt|Win32"
102 OutputDirectory="../../lib_$(ConfigurationName)/i686-win32"
103 IntermediateDirectory="$(ConfigurationName)"
104 ConfigurationType="4"
105 CharacterSet="1">
106 <Tool
107 Name="VCCLCompilerTool"
108 Optimization="0"
109 AdditionalIncludeDirectories="..;..\..\llcommon;..\..\llmath"
110 PreprocessorDefinitions="WIN32;NDEBUG;_LIB;LL_WINDOWS;LL_RELEASE"
111 RuntimeLibrary="0"
112 StructMemberAlignment="0"
113 ForceConformanceInForLoopScope="TRUE"
114 UsePrecompiledHeader="0"
115 WarningLevel="3"
116 WarnAsError="TRUE"
117 Detect64BitPortabilityProblems="FALSE"
118 DebugInformationFormat="3"/>
119 <Tool
120 Name="VCCustomBuildTool"/>
121 <Tool
122 Name="VCLibrarianTool"
123 OutputFile="$(OutDir)/lscript_execute.lib"/>
124 <Tool
125 Name="VCMIDLTool"/>
126 <Tool
127 Name="VCPostBuildEventTool"/>
128 <Tool
129 Name="VCPreBuildEventTool"/>
130 <Tool
131 Name="VCPreLinkEventTool"/>
132 <Tool
133 Name="VCResourceCompilerTool"/>
134 <Tool
135 Name="VCWebServiceProxyGeneratorTool"/>
136 <Tool
137 Name="VCXMLDataGeneratorTool"/>
138 <Tool
139 Name="VCManagedWrapperGeneratorTool"/>
140 <Tool
141 Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
142 </Configuration>
143 </Configurations>
144 <References>
145 </References>
146 <Files>
147 <Filter
148 Name="Source Files"
149 Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
150 UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
151 <File
152 RelativePath=".\lscript_execute.cpp">
153 </File>
154 <File
155 RelativePath=".\lscript_heapruntime.cpp">
156 </File>
157 <File
158 RelativePath=".\lscript_readlso.cpp">
159 </File>
160 </Filter>
161 <Filter
162 Name="Header Files"
163 Filter="h;hpp;hxx;hm;inl;inc;xsd"
164 UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
165 <File
166 RelativePath="..\lscript_byteconvert.h">
167 </File>
168 <File
169 RelativePath="..\lscript_byteformat.h">
170 </File>
171 <File
172 RelativePath="..\lscript_execute.h">
173 </File>
174 <File
175 RelativePath=".\lscript_heapruntime.h">
176 </File>
177 <File
178 RelativePath=".\lscript_readlso.h">
179 </File>
180 </Filter>
181 <Filter
182 Name="Resource Files"
183 Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
184 UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
185 </Filter>
186 </Files>
187 <Globals>
188 </Globals>
189</VisualStudioProject>
diff --git a/linden/indra/lscript/lscript_execute/lscript_heapruntime.cpp b/linden/indra/lscript/lscript_execute/lscript_heapruntime.cpp
new file mode 100644
index 0000000..791fa1b
--- /dev/null
+++ b/linden/indra/lscript/lscript_execute/lscript_heapruntime.cpp
@@ -0,0 +1,520 @@
1/**
2 * @file lscript_heapruntime.cpp
3 * @brief classes to manage script heap at runtime
4 *
5 * Copyright (c) 2002-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28#if 0
29
30#include "linden_common.h"
31
32#include "lscript_heapruntime.h"
33#include "lscript_execute.h"
34
35
36/*
37 String Heap Format
38 Byte Description
39 0x0 - 0xnn Single byte string including null terminator
40
41 List Heap Format
42 Byte Description
43 0x0 Next Entry Type
44 0: End of list
45 1: Integer
46 2: Floating point
47 3: String
48 4: Vector
49 5: Quaternion
50 6: List
51 0x1 - 0x4 Integer, Floating Point, String Address, List Address
52 or
53 0x1 - 0xd Vector
54 or
55 0x1 - 0x11 Quaternion
56 . . .
57
58 Heap Block Format
59 Byte Description
60 0x0 - 0x3 Offset to Next Block
61 0x4 - 0x7 Object Reference Count
62 0x8 Block Type
63 0: Empty
64 3: String
65 6: List
66 0x9 - 0xM Object Data
67
68 Heap Management
69
70 Adding Data
71
72 1) Set last empty spot to zero.
73 2) Go to start of the heap (HR).
74 3) Get next 4 bytes of offset.
75 4) If zero, we've reached the end of used memory. If empty spot is zero go to step 9. Otherwise set base offset to 0 and go to step 9.
76 5) Skip 4 bytes.
77 6) Get next 1 byte of entry type.
78 7) If zero, this spot is empty. If empty spot is zero, set empty spot to this address and go to step 9. Otherwise, coalesce with last empty spot and then go to step 9.
79 8) Skip forward by offset and go to step 3.
80 9) If the spot is empty, check to see if the size needed == offset - 9.
81 10) If it does, let's drop our data into this spot. Set reference count to 1. Set entry type appropriately and copy the data in.
82 11) If size needed < offset - 9 then we can stick in data and add in an empty block.
83 12) Otherwise, we need to keep looking. Go to step 3.
84
85 Increasing reference counts
86
87 Decreasing reference counts
88 1) Set entry type to 0.
89 2) If offset is non-zero and the next entry is empty, coalesce. Go to step 2.
90
91 What increases reference count:
92 Initial creation sets reference count to 1.
93 Storing the reference increases reference count by 1.
94 Pushing the reference increases reference count by 1.
95 Duplicating the reference increases reference count by 1.
96
97 What decreases the reference count:
98 Popping the reference decreases reference count by 1.
99 */
100
101
102LLScriptHeapRunTime::LLScriptHeapRunTime()
103: mLastEmpty(0), mBuffer(NULL), mCurrentPosition(0), mStackPointer(0), mHeapRegister(0), mbPrint(FALSE)
104{
105}
106
107LLScriptHeapRunTime::~LLScriptHeapRunTime()
108{
109}
110
111S32 LLScriptHeapRunTime::addData(char *string)
112{
113 if (!mBuffer)
114 return 0;
115
116 S32 size = strlen(string) + 1;
117 S32 block_offset = findOpenBlock(size + HEAP_BLOCK_HEADER_SIZE);
118
119 if (mCurrentPosition)
120 {
121 S32 offset = mCurrentPosition;
122 if (offset + block_offset + HEAP_BLOCK_HEADER_SIZE + LSCRIPTDataSize[LST_INTEGER] >= mStackPointer)
123 {
124 set_fault(mBuffer, LSRF_STACK_HEAP_COLLISION);
125 return 0;
126 }
127 // cool, we've found a spot!
128 // set offset
129 integer2bytestream(mBuffer, offset, block_offset);
130 // set reference count
131 integer2bytestream(mBuffer, offset, 1);
132 // set type
133 *(mBuffer + offset++) = LSCRIPTTypeByte[LST_STRING];
134 // plug in data
135 char2bytestream(mBuffer, offset, string);
136 if (mbPrint)
137 printf("0x%X created ref count %d\n", mCurrentPosition - mHeapRegister, 1);
138
139 // now, zero out next offset to prevent "trouble"
140 // offset = mCurrentPosition + size + HEAP_BLOCK_HEADER_SIZE;
141 // integer2bytestream(mBuffer, offset, 0);
142 }
143 return mCurrentPosition;
144}
145
146S32 LLScriptHeapRunTime::addData(U8 *list)
147{
148 if (!mBuffer)
149 return 0;
150 return 0;
151}
152
153S32 LLScriptHeapRunTime::catStrings(S32 address1, S32 address2)
154{
155 if (!mBuffer)
156 return 0;
157
158 S32 dataaddress1 = address1 + 2*LSCRIPTDataSize[LST_INTEGER] + 1;
159 S32 dataaddress2 = address2 + 2*LSCRIPTDataSize[LST_INTEGER] + 1;
160
161 S32 toffset1 = dataaddress1;
162 safe_heap_bytestream_count_char(mBuffer, toffset1);
163
164 S32 toffset2 = dataaddress2;
165 safe_heap_bytestream_count_char(mBuffer, toffset2);
166
167 // calculate new string size
168 S32 size1 = toffset1 - dataaddress1;
169 S32 size2 = toffset2 - dataaddress2;
170 S32 newbuffer = size1 + size2 - 1;
171
172 char *temp = new char[newbuffer];
173
174 // get the strings
175 bytestream2char(temp, mBuffer, dataaddress1);
176 bytestream2char(temp + size1 - 1, mBuffer, dataaddress2);
177
178 decreaseRefCount(address1);
179 decreaseRefCount(address2);
180
181 S32 retaddress = addData(temp);
182
183 return retaddress;
184}
185
186S32 LLScriptHeapRunTime::cmpStrings(S32 address1, S32 address2)
187{
188 if (!mBuffer)
189 return 0;
190
191 S32 dataaddress1 = address1 + 2*LSCRIPTDataSize[LST_INTEGER] + 1;
192 S32 dataaddress2 = address2 + 2*LSCRIPTDataSize[LST_INTEGER] + 1;
193
194 S32 toffset1 = dataaddress1;
195 safe_heap_bytestream_count_char(mBuffer, toffset1);
196
197 S32 toffset2 = dataaddress2;
198 safe_heap_bytestream_count_char(mBuffer, toffset2);
199
200 // calculate new string size
201 S32 size1 = toffset1 - dataaddress1;
202 S32 size2 = toffset2 - dataaddress2;
203
204 if (size1 != size2)
205 {
206 return llmin(size1, size2);
207 }
208 else
209 {
210 return strncmp((char *)(mBuffer + dataaddress1), (char *)(mBuffer + dataaddress2), size1);
211 }
212}
213
214void LLScriptHeapRunTime::removeData(S32 address)
215{
216 if (!mBuffer)
217 return;
218
219 S32 toffset = address;
220 // read past offset (relying on function side effect
221 bytestream2integer(mBuffer, toffset);
222
223 // make sure that reference count is 0
224 integer2bytestream(mBuffer, toffset, 0);
225 // show the block as empty
226 *(mBuffer + toffset) = 0;
227
228 // now, clean up the heap
229 S32 clean = mHeapRegister;
230 S32 tclean;
231 S32 clean_offset;
232
233 S32 nclean;
234 S32 tnclean;
235 S32 next_offset;
236
237 U8 type;
238 U8 ntype;
239
240 for(;;)
241 {
242 tclean = clean;
243 clean_offset = bytestream2integer(mBuffer, tclean);
244 // is this block, empty?
245 tclean += LSCRIPTDataSize[LST_INTEGER];
246 type = *(mBuffer + tclean);
247
248 if (!clean_offset)
249 {
250 if (!type)
251 {
252 // we're done! if our block is empty, we can pull in the HP and zero out our offset
253 set_register(mBuffer, LREG_HP, clean);
254 }
255 return;
256 }
257
258
259 if (!type)
260 {
261 // if we're empty, try to coalesce with the next one
262 nclean = clean + clean_offset;
263 tnclean = nclean;
264 next_offset = bytestream2integer(mBuffer, tnclean);
265 tnclean += LSCRIPTDataSize[LST_INTEGER];
266 ntype = *(mBuffer + tnclean);
267
268 if (!next_offset)
269 {
270 // we're done! if our block is empty, we can pull in the HP and zero out our offset
271 tclean = clean;
272 integer2bytestream(mBuffer, tclean, 0);
273 set_register(mBuffer, LREG_HP, clean);
274 return;
275 }
276
277 if (!ntype)
278 {
279 // hooray! we can coalesce
280 tclean = clean;
281 integer2bytestream(mBuffer, tclean, clean_offset + next_offset);
282 // don't skip forward so that we can keep coalescing on next pass through the loop
283 }
284 else
285 {
286 clean += clean_offset;
287 }
288 }
289 else
290 {
291 // if not, move on to the next block
292 clean += clean_offset;
293 }
294 }
295}
296
297void LLScriptHeapRunTime::coalesce(S32 address1, S32 address2)
298{
299 // we need to bump the base offset by the second block's
300 S32 toffset = address1;
301 S32 offset1 = bytestream2integer(mBuffer, toffset);
302 offset1 += bytestream2integer(mBuffer, address2);
303
304 integer2bytestream(mBuffer, address1, offset1);
305}
306
307void LLScriptHeapRunTime::split(S32 address1, S32 size)
308{
309 S32 toffset = address1;
310 S32 oldoffset = bytestream2integer(mBuffer, toffset);
311
312 // add new offset and zero out reference count and block used
313 S32 newoffset = oldoffset - size;
314 S32 newblockpos = address1 + size;
315
316 // set new offset
317 integer2bytestream(mBuffer, newblockpos, newoffset);
318 // zero out reference count
319 integer2bytestream(mBuffer, newblockpos, 0);
320 // mark as empty
321 *(mBuffer + newblockpos) = 0;
322
323 // now, change the offset of the original block
324 integer2bytestream(mBuffer, address1, size + HEAP_BLOCK_HEADER_SIZE);
325}
326
327/*
328
329 For reference count changes, strings are easy. For lists, we'll need to go through the lists reducing
330 the reference counts for any included strings and lists
331
332 */
333
334void LLScriptHeapRunTime::increaseRefCount(S32 address)
335{
336 if (!mBuffer)
337 return;
338
339 if (!address)
340 {
341 // unused temp string entry
342 return;
343 }
344
345 // get current reference count
346 S32 toffset = address + 4;
347 S32 count = bytestream2integer(mBuffer, toffset);
348
349 count++;
350
351 if (mbPrint)
352 printf("0x%X inc ref count %d\n", address - mHeapRegister, count);
353
354 // see which type it is
355 U8 type = *(mBuffer + toffset);
356
357 if (type == LSCRIPTTypeByte[LST_STRING])
358 {
359 toffset = address + 4;
360 integer2bytestream(mBuffer, toffset, count);
361 }
362 // TO DO: put list stuff here!
363 else
364 {
365 set_fault(mBuffer, LSRF_HEAP_ERROR);
366 }
367}
368
369void LLScriptHeapRunTime::decreaseRefCount(S32 address)
370{
371 if (!mBuffer)
372 return;
373
374 if (!address)
375 {
376 // unused temp string entry
377 return;
378 }
379
380 // get offset
381 S32 toffset = address;
382 // read past offset (rely on function side effect)
383 bytestream2integer(mBuffer, toffset);
384
385 // get current reference count
386 S32 count = bytestream2integer(mBuffer, toffset);
387
388 // see which type it is
389 U8 type = *(mBuffer + toffset);
390
391 if (type == LSCRIPTTypeByte[LST_STRING])
392 {
393 count--;
394
395 if (mbPrint)
396 printf("0x%X dec ref count %d\n", address - mHeapRegister, count);
397
398 toffset = address + 4;
399 integer2bytestream(mBuffer, toffset, count);
400 if (!count)
401 {
402 // we can blow this one away
403 removeData(address);
404 }
405 }
406 // TO DO: put list stuff here!
407 else
408 {
409 set_fault(mBuffer, LSRF_HEAP_ERROR);
410 }
411}
412
413// if we're going to assign a variable, we need to decrement the reference count of what we were pointing at (if anything)
414void LLScriptHeapRunTime::releaseLocal(S32 address)
415{
416 S32 hr = get_register(mBuffer, LREG_HR);
417 address = lscript_local_get(mBuffer, address);
418 if ( (address >= hr)
419 &&(address < hr + get_register(mBuffer, LREG_HP)))
420 {
421 decreaseRefCount(address);
422 }
423}
424
425void LLScriptHeapRunTime::releaseGlobal(S32 address)
426{
427 // NOTA BENE: Global strings are referenced relative to the HR while local strings aren't
428 S32 hr = get_register(mBuffer, LREG_HR);
429 address = lscript_global_get(mBuffer, address) + hr;
430 if ( (address >= hr)
431 &&(address < hr + get_register(mBuffer, LREG_HP)))
432 {
433 decreaseRefCount(address);
434 }
435}
436
437
438// we know the following function has "unreachable code"
439// don't remind us every friggin' time we compile. . .
440
441#if defined(_MSC_VER)
442# pragma warning(disable: 4702) // unreachable code
443#endif
444
445S32 LLScriptHeapRunTime::findOpenBlock(S32 size)
446{
447 S32 offset;
448 S32 toffset;
449 U8 blocktype;
450
451 while(1)
452 {
453 if (mCurrentPosition + size >= mStackPointer)
454 {
455 set_fault(mBuffer, LSRF_STACK_HEAP_COLLISION);
456 mCurrentPosition = 0;
457 }
458
459 toffset = mCurrentPosition;
460 offset = bytestream2integer(mBuffer, toffset);
461 if (!offset)
462 {
463 // we've reached the end of Heap, return this location if we'll fit
464 // do we need to coalesce with last empty space?
465 if (mLastEmpty)
466 {
467 // ok, that everything from mLastEmpty to us is empty, so we don't need a block
468 // zero out the last empty's offset and return it
469 mCurrentPosition = mLastEmpty;
470 integer2bytestream(mBuffer, mLastEmpty, 0);
471 mLastEmpty = 0;
472 }
473 // now, zero out next offset to prevent "trouble"
474 offset = mCurrentPosition + size;
475 integer2bytestream(mBuffer, offset, 0);
476
477 // set HP to appropriate value
478 set_register(mBuffer, LREG_HP, mCurrentPosition + size);
479 return size;
480 }
481
482 // ok, is this slot empty?
483 toffset += LSCRIPTDataSize[LST_INTEGER];
484
485 blocktype = *(mBuffer + toffset++);
486
487 if (!blocktype)
488 {
489 // Empty block, do we need to coalesce?
490 if (mLastEmpty)
491 {
492 coalesce(mLastEmpty, mCurrentPosition);
493 mCurrentPosition = mLastEmpty;
494 toffset = mCurrentPosition;
495 offset = bytestream2integer(mBuffer, toffset);
496 }
497
498 // do we fit in this block?
499 if (offset >= size)
500 {
501 // do we need to split the block? (only split if splitting will leave > HEAP_BLOCK_SPLIT_THRESHOLD bytes of free space)
502 if (offset - HEAP_BLOCK_SPLIT_THRESHOLD >= size)
503 {
504 split(mCurrentPosition, size);
505 return size;
506 }
507 else
508 return offset;
509 }
510 }
511 // nothing found, keep looking
512 mCurrentPosition += offset;
513 }
514 // fake return to prevent warnings
515 mCurrentPosition = 0;
516 return 0;
517}
518
519LLScriptHeapRunTime gRunTime;
520#endif
diff --git a/linden/indra/lscript/lscript_execute/lscript_heapruntime.h b/linden/indra/lscript/lscript_execute/lscript_heapruntime.h
new file mode 100644
index 0000000..3e65f58
--- /dev/null
+++ b/linden/indra/lscript/lscript_execute/lscript_heapruntime.h
@@ -0,0 +1,41 @@
1/**
2 * @file lscript_heapruntime.h
3 * @brief classes to manage script heap at runtime
4 *
5 * Copyright (c) 2002-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28#if 0
29
30#ifndef LL_LSCRIPT_HEAPRUNTIME_H
31#define LL_LSCRIPT_HEAPRUNTIME_H
32
33#include "lscript_byteconvert.h"
34
35
36const S32 HEAP_BLOCK_HEADER_SIZE = 9;
37const S32 HEAP_BLOCK_SPLIT_THRESHOLD = 16;
38
39
40#endif
41#endif
diff --git a/linden/indra/lscript/lscript_execute/lscript_readlso.cpp b/linden/indra/lscript/lscript_execute/lscript_readlso.cpp
new file mode 100644
index 0000000..6734d58
--- /dev/null
+++ b/linden/indra/lscript/lscript_execute/lscript_readlso.cpp
@@ -0,0 +1,1572 @@
1/**
2 * @file lscript_readlso.cpp
3 * @brief classes to read lso file
4 *
5 * Copyright (c) 2002-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28#include "linden_common.h"
29
30#include "lscript_readlso.h"
31#include "lscript_library.h"
32#include "lscript_alloc.h"
33
34LLScriptLSOParse::LLScriptLSOParse(FILE *fp)
35{
36 U8 sizearray[4];
37 S32 filesize;
38 S32 pos = 0;
39 fread(&sizearray, 1, 4, fp);
40 filesize = bytestream2integer(sizearray, pos);
41 mRawData = new U8[filesize];
42 fseek(fp, 0, SEEK_SET);
43 fread(mRawData, 1, filesize, fp);
44 fclose(fp);
45
46 initOpCodePrinting();
47}
48
49LLScriptLSOParse::LLScriptLSOParse(U8 *buffer)
50{
51 mRawData = buffer;
52 initOpCodePrinting();
53}
54
55LLScriptLSOParse::~LLScriptLSOParse()
56{
57 delete [] mRawData;
58}
59
60void LLScriptLSOParse::printData(FILE *fp)
61{
62
63
64
65 printNameDesc(fp);
66
67 printRegisters(fp);
68
69 printGlobals(fp);
70
71 printGlobalFunctions(fp);
72
73 printStates(fp);
74
75 printHeap(fp);
76}
77
78void LLScriptLSOParse::printNameDesc(FILE *fp)
79{
80 fprintf(fp, "=============================\n\n");
81}
82
83S32 gMajorVersion = 0;
84
85void LLScriptLSOParse::printRegisters(FILE *fp)
86{
87 // print out registers first
88 S32 i;
89
90 fprintf(fp, "=============================\n");
91 fprintf(fp, "Registers\n");
92 fprintf(fp, "=============================\n");
93 S32 version = get_register(mRawData, LREG_VN);
94 if (version == LSL2_VERSION1_END_NUMBER)
95 {
96 gMajorVersion = LSL2_MAJOR_VERSION_ONE;
97 }
98 else if (version == LSL2_VERSION_NUMBER)
99 {
100 gMajorVersion = LSL2_MAJOR_VERSION_TWO;
101 }
102 for (i = LREG_IP; i < LREG_EOF; i++)
103 {
104 if (i < LREG_NCE)
105 {
106 fprintf(fp, "%s: 0x%X\n", gLSCRIPTRegisterNames[i], get_register(mRawData, (LSCRIPTRegisters)i));
107 }
108 else if (gMajorVersion == LSL2_MAJOR_VERSION_TWO)
109 {
110 U64 data = get_register_u64(mRawData, (LSCRIPTRegisters)i);
111 fprintf(fp, "%s: 0x%X%X\n", gLSCRIPTRegisterNames[i], (U32)(data>>32), (U32)(data && 0xFFFFFFFF));
112 }
113 }
114 fprintf(fp, "=============================\n\n");
115}
116
117void LLScriptLSOParse::printGlobals(FILE *fp)
118{
119 // print out registers first
120 S32 offset, varoffset;
121 S32 ivalue;
122 F32 fpvalue;
123 LLVector3 vvalue;
124 LLQuaternion qvalue;
125 char name[256];
126 U8 type;
127
128 S32 global_v_offset = get_register(mRawData, LREG_GVR);
129 S32 global_f_offset = get_register(mRawData, LREG_GFR);
130
131 fprintf(fp, "=============================\n");
132 fprintf(fp, "[0x%X] Global Variables\n", global_v_offset);
133 fprintf(fp, "=============================\n");
134
135
136 while (global_v_offset < global_f_offset)
137 {
138
139 // get offset to skip past name
140 varoffset = global_v_offset;
141 offset = bytestream2integer(mRawData, global_v_offset);
142
143 // get typeexport
144 type = *(mRawData + global_v_offset++);
145
146 // set name
147 bytestream2char(name, mRawData, global_v_offset);
148
149 switch(type)
150 {
151 case LST_INTEGER:
152 ivalue = bytestream2integer(mRawData, global_v_offset);
153 fprintf(fp, "[0x%X] integer %s = %d\n", varoffset, name, ivalue);
154 break;
155 case LST_FLOATINGPOINT:
156 fpvalue = bytestream2float(mRawData, global_v_offset);
157 fprintf(fp, "[0x%X] integer %s = %f\n", varoffset, name, fpvalue);
158 break;
159 case LST_STRING:
160 ivalue = bytestream2integer(mRawData, global_v_offset);
161 fprintf(fp, "[0x%X] string %s = 0x%X\n", varoffset, name, ivalue + get_register(mRawData, LREG_HR) - 1);
162 break;
163 case LST_KEY:
164 ivalue = bytestream2integer(mRawData, global_v_offset);
165 fprintf(fp, "[0x%X] key %s = 0x%X\n", varoffset, name, ivalue + get_register(mRawData, LREG_HR) - 1);
166 break;
167 case LST_VECTOR:
168 bytestream2vector(vvalue, mRawData, global_v_offset);
169 fprintf(fp, "[0x%X] vector %s = < %f, %f, %f >\n", varoffset, name, vvalue.mV[VX], vvalue.mV[VY], vvalue.mV[VZ]);
170 break;
171 case LST_QUATERNION:
172 bytestream2quaternion(qvalue, mRawData, global_v_offset);
173 fprintf(fp, "[0x%X] quaternion %s = < %f, %f, %f, %f >\n", varoffset, name, qvalue.mQ[VX], qvalue.mQ[VY], qvalue.mQ[VZ], qvalue.mQ[VS]);
174 break;
175 case LST_LIST:
176 ivalue = bytestream2integer(mRawData, global_v_offset);
177 fprintf(fp, "[0x%X] list %s = 0x%X\n", varoffset, name, ivalue + get_register(mRawData, LREG_HR) - 1);
178 break;
179 default:
180 break;
181 }
182 }
183
184 fprintf(fp, "=============================\n\n");
185}
186
187void LLScriptLSOParse::printGlobalFunctions(FILE *fp)
188{
189 // print out registers first
190 S32 i, offset;
191// LLVector3 vvalue; unused
192// LLQuaternion qvalue; unused
193 char name[256];
194 U8 type;
195
196 offset = get_register(mRawData, LREG_GFR);
197 S32 start_of_state = get_register(mRawData, LREG_SR);
198 if (start_of_state == offset)
199 return;
200
201 S32 global_f_offset = get_register(mRawData, LREG_GFR);
202
203 fprintf(fp, "=============================\n");
204 fprintf(fp, "[0x%X] Global Functions\n", global_f_offset);
205 fprintf(fp, "=============================\n");
206
207
208 S32 num_functions = bytestream2integer(mRawData, offset);
209 S32 orig_function_offset;
210 S32 function_offset;
211 S32 next_function_offset = 0;
212 S32 function_number = 0;
213 S32 opcode_start;
214 S32 opcode_end;
215
216 for (i = 0; i < num_functions; i++)
217 {
218 // jump to function
219 // if this is the first function
220 if (i == 0)
221 {
222 if (i < num_functions - 1)
223 {
224 function_offset = bytestream2integer(mRawData, offset);
225 next_function_offset = bytestream2integer(mRawData, offset);
226 function_offset += global_f_offset;
227 opcode_end = next_function_offset + global_f_offset;
228 }
229 else
230 {
231 function_offset = bytestream2integer(mRawData, offset);
232 function_offset += global_f_offset;
233 opcode_end = get_register(mRawData, LREG_SR);
234 }
235 }
236 else if (i < num_functions - 1)
237 {
238 function_offset = next_function_offset;
239 next_function_offset = bytestream2integer(mRawData, offset);
240 function_offset += global_f_offset;
241 opcode_end = next_function_offset + global_f_offset;
242 }
243 else
244 {
245 function_offset = next_function_offset;
246 function_offset += global_f_offset;
247 opcode_end = get_register(mRawData, LREG_SR);
248 }
249 orig_function_offset = function_offset;
250 // where do the opcodes start
251 opcode_start = bytestream2integer(mRawData, function_offset);
252 opcode_start += orig_function_offset;
253 bytestream2char(name, mRawData, function_offset);
254 // get return type
255 type = *(mRawData + function_offset++);
256 fprintf(fp, "[Function #%d] [0x%X] %s\n", function_number, orig_function_offset, name);
257 fprintf(fp, "\tReturn Type: %s\n", LSCRIPTTypeNames[type]);
258 type = *(mRawData + function_offset++);
259 S32 params;
260 params = 0;
261 S32 pcount = 0;
262 while (type)
263 {
264 bytestream2char(name, mRawData, function_offset);
265 fprintf(fp, "\tParameter #%d: %s %s\n", pcount++, LSCRIPTTypeNames[type], name);
266 type = *(mRawData + function_offset++);
267 }
268 fprintf(fp, "\t\tOpCodes: 0x%X - 0x%X\n", opcode_start, opcode_end);
269 printOpCodeRange(fp, opcode_start, opcode_end, 2);
270 function_number++;
271 }
272
273 fprintf(fp, "=============================\n\n");
274}
275
276void LLScriptLSOParse::printStates(FILE *fp)
277{
278 // print out registers first
279 S32 i, offset;
280 U32 j, k;
281// LLVector3 vvalue; unused
282// LLQuaternion qvalue; unused
283 char name[256];
284
285 S32 state_offset = get_register(mRawData, LREG_SR);
286
287 fprintf(fp, "=============================\n");
288 fprintf(fp, "[0x%X] States\n", state_offset);
289 fprintf(fp, "=============================\n");
290
291 offset = state_offset;
292 S32 num_states = bytestream2integer(mRawData, offset);
293 S32 state_info_offset;
294 S32 event_jump_table;
295 U64 event_handlers;
296 S32 event_offset;
297 S32 original_event_offset;
298 S32 opcode_start;
299 S32 worst_case_opcode_end;
300 S32 opcode_end;
301 S32 stack_size;
302 S32 read_ahead;
303 S32 first_jump = 0;
304
305 for (i = 0; i < num_states; i++)
306 {
307 state_info_offset = bytestream2integer(mRawData, offset);
308 if (gMajorVersion == LSL2_MAJOR_VERSION_TWO)
309 event_handlers = bytestream2u64(mRawData, offset);
310 else
311 event_handlers = bytestream2integer(mRawData, offset);
312 if (!first_jump)
313 {
314 first_jump = state_info_offset;
315 }
316 read_ahead = offset;
317 if (offset < first_jump + state_offset)
318 {
319 worst_case_opcode_end = bytestream2integer(mRawData, read_ahead) + state_offset;
320 }
321 else
322 {
323 worst_case_opcode_end = get_register(mRawData, LREG_HR);
324 }
325 state_info_offset += state_offset;
326 fprintf(fp, "[0x%X] ", state_info_offset);
327 state_info_offset += LSCRIPTDataSize[LST_INTEGER];
328 bytestream2char(name, mRawData, state_info_offset);
329 fprintf(fp, "%s\n", name);
330
331 event_jump_table = state_info_offset;
332
333 // run run through the handlers
334 for (j = LSTT_STATE_BEGIN; j < LSTT_STATE_END; j++)
335 {
336 if (event_handlers & LSCRIPTStateBitField[j])
337 {
338 event_offset = bytestream2integer(mRawData, state_info_offset);
339 stack_size = bytestream2integer(mRawData, state_info_offset);
340
341 read_ahead = event_jump_table;
342
343 S32 temp_end;
344 S32 dummy;
345
346 opcode_end = worst_case_opcode_end;
347
348 for (k = LSTT_STATE_BEGIN; k < LSTT_STATE_END; k++)
349 {
350 if (event_handlers & LSCRIPTStateBitField[k])
351 {
352 temp_end = bytestream2integer(mRawData, read_ahead);
353 dummy = bytestream2integer(mRawData, read_ahead);
354 if ( (temp_end < opcode_end)
355 &&(temp_end > event_offset))
356 {
357 opcode_end = temp_end;
358 }
359 }
360 }
361
362 if (event_offset)
363 {
364 event_offset += event_jump_table;
365 if (opcode_end < worst_case_opcode_end)
366 opcode_end += event_jump_table;
367 original_event_offset = event_offset;
368
369 fprintf(fp, "\t[0x%X] ", event_offset);
370
371 opcode_start = bytestream2integer(mRawData, event_offset);
372 opcode_start += original_event_offset;
373
374 switch(j)
375 {
376 case LSTT_STATE_ENTRY: // LSTT_STATE_ENTRY
377 bytestream2char(name, mRawData, event_offset);
378 fprintf(fp, "%s\n", name);
379 break;
380 case LSTT_STATE_EXIT: // LSTT_STATE_EXIT
381 bytestream2char(name, mRawData, event_offset);
382 fprintf(fp, "%s\n", name);
383 break;
384 case LSTT_TOUCH_START: // LSTT_TOUCH_START
385 bytestream2char(name, mRawData, event_offset);
386 fprintf(fp, "%s\n", name);
387 bytestream2char(name, mRawData, event_offset);
388 fprintf(fp, "\t\tkey %s\n", name);
389 bytestream2char(name, mRawData, event_offset);
390 fprintf(fp, "\t\tvector %s\n", name);
391 break;
392 case LSTT_TOUCH: // LSTT_TOUCH
393 bytestream2char(name, mRawData, event_offset);
394 fprintf(fp, "%s\n", name);
395 bytestream2char(name, mRawData, event_offset);
396 fprintf(fp, "\t\tkey %s\n", name);
397 bytestream2char(name, mRawData, event_offset);
398 fprintf(fp, "\t\tvector %s\n", name);
399 break;
400 case LSTT_TOUCH_END: // LSTT_TOUCH_END
401 bytestream2char(name, mRawData, event_offset);
402 fprintf(fp, "%s\n", name);
403 bytestream2char(name, mRawData, event_offset);
404 fprintf(fp, "\t\tkey %s\n", name);
405 bytestream2char(name, mRawData, event_offset);
406 fprintf(fp, "\t\tvector %s\n", name);
407 break;
408 case LSTT_COLLISION_START: // LSTT_COLLISION_START
409 bytestream2char(name, mRawData, event_offset);
410 fprintf(fp, "%s\n", name);
411 bytestream2char(name, mRawData, event_offset);
412 fprintf(fp, "\t\tkey %s\n", name);
413 bytestream2char(name, mRawData, event_offset);
414 fprintf(fp, "\t\tvector %s\n", name);
415 bytestream2char(name, mRawData, event_offset);
416 fprintf(fp, "\t\tvector %s\n", name);
417 break;
418 case LSTT_COLLISION: // LSTT_COLLISION
419 bytestream2char(name, mRawData, event_offset);
420 fprintf(fp, "%s\n", name);
421 bytestream2char(name, mRawData, event_offset);
422 fprintf(fp, "\t\tkey %s\n", name);
423 bytestream2char(name, mRawData, event_offset);
424 fprintf(fp, "\t\tvector %s\n", name);
425 bytestream2char(name, mRawData, event_offset);
426 fprintf(fp, "\t\tvector %s\n", name);
427 break;
428 case LSTT_COLLISION_END: // LSTT_COLLISION_END
429 bytestream2char(name, mRawData, event_offset);
430 fprintf(fp, "%s\n", name);
431 bytestream2char(name, mRawData, event_offset);
432 fprintf(fp, "\t\tkey %s\n", name);
433 bytestream2char(name, mRawData, event_offset);
434 fprintf(fp, "\t\tvector %s\n", name);
435 bytestream2char(name, mRawData, event_offset);
436 fprintf(fp, "\t\tvector %s\n", name);
437 break;
438 case LSTT_LAND_COLLISION_START: // LSTT_LAND_COLLISION_START
439 bytestream2char(name, mRawData, event_offset);
440 fprintf(fp, "%s\n", name);
441 bytestream2char(name, mRawData, event_offset);
442 fprintf(fp, "\t\tvector %s\n", name);
443 break;
444 case LSTT_LAND_COLLISION: // LSTT_LAND_COLLISION
445 bytestream2char(name, mRawData, event_offset);
446 fprintf(fp, "%s\n", name);
447 bytestream2char(name, mRawData, event_offset);
448 fprintf(fp, "\t\tvector %s\n", name);
449 break;
450 case LSTT_LAND_COLLISION_END: // LSTT_LAND_COLLISION_END
451 bytestream2char(name, mRawData, event_offset);
452 fprintf(fp, "%s\n", name);
453 bytestream2char(name, mRawData, event_offset);
454 fprintf(fp, "\t\tvector %s\n", name);
455 break;
456 case LSTT_INVENTORY: // LSTT_INVENTORY
457 bytestream2char(name, mRawData, event_offset);
458 fprintf(fp, "%s\n", name);
459 bytestream2char(name, mRawData, event_offset);
460 fprintf(fp, "\t\tinteger %s\n", name);
461 break;
462 case LSTT_ATTACH: // LSTT_ATTACH
463 bytestream2char(name, mRawData, event_offset);
464 fprintf(fp, "%s\n", name);
465 bytestream2char(name, mRawData, event_offset);
466 fprintf(fp, "\t\tkey %s\n", name);
467 break;
468 case LSTT_DATASERVER: // LSTT_DATASERVER
469 bytestream2char(name, mRawData, event_offset);
470 fprintf(fp, "%s\n", name);
471 bytestream2char(name, mRawData, event_offset);
472 fprintf(fp, "\t\tkey %s\n", name);
473 bytestream2char(name, mRawData, event_offset);
474 fprintf(fp, "\t\tstring %s\n", name);
475 break;
476 case LSTT_TIMER: // LSTT_TIMER
477 bytestream2char(name, mRawData, event_offset);
478 fprintf(fp, "%s\n", name);
479 break;
480 case LSTT_MOVING_START: // LSTT_MOVING_START
481 bytestream2char(name, mRawData, event_offset);
482 fprintf(fp, "%s\n", name);
483 break;
484 case LSTT_MOVING_END: // LSTT_MOVING_END
485 bytestream2char(name, mRawData, event_offset);
486 fprintf(fp, "%s\n", name);
487 break;
488 case LSTT_CHAT: // LSTT_CHAT
489 bytestream2char(name, mRawData, event_offset);
490 fprintf(fp, "%s\n", name);
491 bytestream2char(name, mRawData, event_offset);
492 fprintf(fp, "\t\tinteger %s\n", name);
493 bytestream2char(name, mRawData, event_offset);
494 fprintf(fp, "\t\tkey %s\n", name);
495 bytestream2char(name, mRawData, event_offset);
496 fprintf(fp, "\t\tstring %s\n", name);
497 break;
498 case LSTT_OBJECT_REZ: // LSTT_OBJECT_REZ
499 bytestream2char(name, mRawData, event_offset);
500 fprintf(fp, "%s\n", name);
501 bytestream2char(name, mRawData, event_offset);
502 fprintf(fp, "\t\tkey %s\n", name);
503 break;
504 case LSTT_REMOTE_DATA: // LSTT_REMOTE_DATA
505 bytestream2char(name, mRawData, event_offset);
506 fprintf(fp, "%s\n", name);
507 bytestream2char(name, mRawData, event_offset);
508 fprintf(fp, "\t\tinteger %s\n", name);
509 bytestream2char(name, mRawData, event_offset);
510 fprintf(fp, "\t\tkey %s\n", name);
511 bytestream2char(name, mRawData, event_offset);
512 fprintf(fp, "\t\tinteger %s\n", name);
513 bytestream2char(name, mRawData, event_offset);
514 fprintf(fp, "\t\tstring %s\n", name);
515 break;
516 case LSTT_REZ: // LSTT_REZ
517 bytestream2char(name, mRawData, event_offset);
518 fprintf(fp, "%s\n", name);
519 break;
520 case LSTT_SENSOR: // LSTT_SENSOR
521 bytestream2char(name, mRawData, event_offset);
522 fprintf(fp, "%s\n", name);
523 bytestream2char(name, mRawData, event_offset);
524 fprintf(fp, "\t\tinteger %s\n", name);
525 break;
526 case LSTT_NO_SENSOR: // LSTT_NO_SENSOR
527 bytestream2char(name, mRawData, event_offset);
528 fprintf(fp, "%s\n", name);
529 break;
530 case LSTT_CONTROL: // LSTT_CONTROL
531 bytestream2char(name, mRawData, event_offset);
532 fprintf(fp, "%s\n", name);
533 bytestream2char(name, mRawData, event_offset);
534 fprintf(fp, "\t\tkey %s\n", name);
535 bytestream2char(name, mRawData, event_offset);
536 fprintf(fp, "\t\tinteger %s\n", name);
537 bytestream2char(name, mRawData, event_offset);
538 fprintf(fp, "\t\tinteger %s\n", name);
539 break;
540 case LSTT_LINK_MESSAGE: // LSTT_LINK_MESSAGE
541 bytestream2char(name, mRawData, event_offset);
542 fprintf(fp, "%s\n", name);
543 bytestream2char(name, mRawData, event_offset);
544 fprintf(fp, "\t\tinteger %s\n", name);
545 bytestream2char(name, mRawData, event_offset);
546 fprintf(fp, "\t\tstring %s\n", name);
547 bytestream2char(name, mRawData, event_offset);
548 fprintf(fp, "\t\tkey %s\n", name);
549 break;
550 case LSTT_MONEY: // LSTT_MONEY
551 bytestream2char(name, mRawData, event_offset);
552 fprintf(fp, "%s\n", name);
553 bytestream2char(name, mRawData, event_offset);
554 fprintf(fp, "\t\tkey %s\n", name);
555 bytestream2char(name, mRawData, event_offset);
556 fprintf(fp, "\t\tinteger %s\n", name);
557 break;
558 case LSTT_EMAIL: // LSTT_EMAIL
559 bytestream2char(name, mRawData, event_offset);
560 fprintf(fp, "%s\n", name);
561 bytestream2char(name, mRawData, event_offset);
562 fprintf(fp, "\t\tstring %s\n", name);
563 bytestream2char(name, mRawData, event_offset);
564 fprintf(fp, "\t\tstring %s\n", name);
565 bytestream2char(name, mRawData, event_offset);
566 fprintf(fp, "\t\tstring %s\n", name);
567 bytestream2char(name, mRawData, event_offset);
568 fprintf(fp, "\t\tinteger %s\n", name);
569 break;
570 case LSTT_AT_TARGET: // LSTT_AT_TARGET
571 bytestream2char(name, mRawData, event_offset);
572 fprintf(fp, "%s\n", name);
573 bytestream2char(name, mRawData, event_offset);
574 fprintf(fp, "\t\tinteger %s\n", name);
575 bytestream2char(name, mRawData, event_offset);
576 fprintf(fp, "\t\tvector %s\n", name);
577 bytestream2char(name, mRawData, event_offset);
578 fprintf(fp, "\t\tvector %s\n", name);
579 break;
580 case LSTT_NOT_AT_TARGET: // LSTT_NOT_AT_TARGET
581 bytestream2char(name, mRawData, event_offset);
582 fprintf(fp, "%s\n", name);
583 break;
584 case LSTT_AT_ROT_TARGET: // LSTT_AT_ROT_TARGET
585 bytestream2char(name, mRawData, event_offset);
586 fprintf(fp, "%s\n", name);
587 bytestream2char(name, mRawData, event_offset);
588 fprintf(fp, "\t\tinteger %s\n", name);
589 bytestream2char(name, mRawData, event_offset);
590 fprintf(fp, "\t\tquaternion %s\n", name);
591 bytestream2char(name, mRawData, event_offset);
592 fprintf(fp, "\t\tquaternion %s\n", name);
593 break;
594 case LSTT_NOT_AT_ROT_TARGET: // LSTT_NOT_AT_TARGET
595 bytestream2char(name, mRawData, event_offset);
596 fprintf(fp, "%s\n", name);
597 break;
598 case LSTT_RTPERMISSIONS: // LSTT_RTPERMISSIONS
599 bytestream2char(name, mRawData, event_offset);
600 fprintf(fp, "%s\n", name);
601 fprintf(fp, "\t\tinteger %s\n", name);
602 bytestream2char(name, mRawData, event_offset);
603 break;
604 case LSTT_HTTP_RESPONSE: // LSTT_REMOTE_DATA ?!?!?!
605 bytestream2char(name, mRawData, event_offset);
606 fprintf(fp, "%s\n", name);
607 bytestream2char(name, mRawData, event_offset);
608 fprintf(fp, "\t\tkey %s\n", name);
609 bytestream2char(name, mRawData, event_offset);
610 fprintf(fp, "\t\tinteger %s\n", name);
611 bytestream2char(name, mRawData, event_offset);
612 fprintf(fp, "\t\tlist %s\n", name);
613 bytestream2char(name, mRawData, event_offset);
614 fprintf(fp, "\t\tstring %s\n", name);
615 break;
616 default:
617 break;
618 }
619 fprintf(fp, "\t\tStack Size: %d\n", stack_size);
620 fprintf(fp, "\t\t\tOpCodes: 0x%X - 0x%X\n", opcode_start, opcode_end);
621 printOpCodeRange(fp, opcode_start, opcode_end, 3);
622 }
623 }
624 }
625 }
626 fprintf(fp, "=============================\n\n");
627}
628
629void LLScriptLSOParse::printHeap(FILE *fp)
630{
631 // print out registers first
632
633 S32 heap_offset = get_register(mRawData, LREG_HR);
634 S32 heap_pointer = get_register(mRawData, LREG_HP);
635 fprintf(fp, "=============================\n");
636 fprintf(fp, "[0x%X - 0x%X] Heap\n", heap_offset, heap_pointer);
637 fprintf(fp, "=============================\n");
638
639 lsa_fprint_heap(mRawData, fp);
640
641 fprintf(fp, "=============================\n\n");
642}
643
644void lso_print_tabs(FILE *fp, S32 tabs)
645{
646 S32 i;
647 for (i = 0; i < tabs; i++)
648 {
649 fprintf(fp, "\t");
650 }
651}
652
653void LLScriptLSOParse::printOpCodes(FILE *fp, S32 &offset, S32 tabs)
654{
655 U8 opcode = *(mRawData + offset);
656 mPrintOpCodes[opcode](fp, mRawData, offset, tabs);
657}
658
659void LLScriptLSOParse::printOpCodeRange(FILE *fp, S32 start, S32 end, S32 tabs)
660{
661 while (start < end)
662 {
663 printOpCodes(fp, start, tabs);
664 }
665}
666
667void LLScriptLSOParse::initOpCodePrinting()
668{
669 S32 i;
670 for (i = 0; i < 256; i++)
671 {
672 mPrintOpCodes[i] = print_noop;
673 }
674 mPrintOpCodes[LSCRIPTOpCodes[LOPC_NOOP]] = print_noop;
675
676 mPrintOpCodes[LSCRIPTOpCodes[LOPC_POP]] = print_pop;
677 mPrintOpCodes[LSCRIPTOpCodes[LOPC_POPS]] = print_pops;
678 mPrintOpCodes[LSCRIPTOpCodes[LOPC_POPL]] = print_popl;
679 mPrintOpCodes[LSCRIPTOpCodes[LOPC_POPV]] = print_popv;
680 mPrintOpCodes[LSCRIPTOpCodes[LOPC_POPQ]] = print_popq;
681 mPrintOpCodes[LSCRIPTOpCodes[LOPC_POPARG]] = print_poparg;
682 mPrintOpCodes[LSCRIPTOpCodes[LOPC_POPIP]] = print_popip;
683 mPrintOpCodes[LSCRIPTOpCodes[LOPC_POPBP]] = print_popbp;
684 mPrintOpCodes[LSCRIPTOpCodes[LOPC_POPSP]] = print_popsp;
685 mPrintOpCodes[LSCRIPTOpCodes[LOPC_POPSLR]] = print_popslr;
686
687 mPrintOpCodes[LSCRIPTOpCodes[LOPC_DUP]] = print_dup;
688 mPrintOpCodes[LSCRIPTOpCodes[LOPC_DUPS]] = print_dups;
689 mPrintOpCodes[LSCRIPTOpCodes[LOPC_DUPL]] = print_dupl;
690 mPrintOpCodes[LSCRIPTOpCodes[LOPC_DUPV]] = print_dupv;
691 mPrintOpCodes[LSCRIPTOpCodes[LOPC_DUPQ]] = print_dupq;
692
693 mPrintOpCodes[LSCRIPTOpCodes[LOPC_STORE]] = print_store;
694 mPrintOpCodes[LSCRIPTOpCodes[LOPC_STORES]] = print_stores;
695 mPrintOpCodes[LSCRIPTOpCodes[LOPC_STOREL]] = print_storel;
696 mPrintOpCodes[LSCRIPTOpCodes[LOPC_STOREV]] = print_storev;
697 mPrintOpCodes[LSCRIPTOpCodes[LOPC_STOREQ]] = print_storeq;
698 mPrintOpCodes[LSCRIPTOpCodes[LOPC_STOREG]] = print_storeg;
699 mPrintOpCodes[LSCRIPTOpCodes[LOPC_STOREGS]] = print_storegs;
700 mPrintOpCodes[LSCRIPTOpCodes[LOPC_STOREGL]] = print_storegl;
701 mPrintOpCodes[LSCRIPTOpCodes[LOPC_STOREGV]] = print_storegv;
702 mPrintOpCodes[LSCRIPTOpCodes[LOPC_STOREGQ]] = print_storegq;
703 mPrintOpCodes[LSCRIPTOpCodes[LOPC_LOADP]] = print_loadp;
704 mPrintOpCodes[LSCRIPTOpCodes[LOPC_LOADSP]] = print_loadsp;
705 mPrintOpCodes[LSCRIPTOpCodes[LOPC_LOADLP]] = print_loadlp;
706 mPrintOpCodes[LSCRIPTOpCodes[LOPC_LOADVP]] = print_loadvp;
707 mPrintOpCodes[LSCRIPTOpCodes[LOPC_LOADQP]] = print_loadqp;
708 mPrintOpCodes[LSCRIPTOpCodes[LOPC_LOADGP]] = print_loadgp;
709 mPrintOpCodes[LSCRIPTOpCodes[LOPC_LOADGSP]] = print_loadgsp;
710 mPrintOpCodes[LSCRIPTOpCodes[LOPC_LOADGLP]] = print_loadglp;
711 mPrintOpCodes[LSCRIPTOpCodes[LOPC_LOADGVP]] = print_loadgvp;
712 mPrintOpCodes[LSCRIPTOpCodes[LOPC_LOADGQP]] = print_loadgqp;
713
714 mPrintOpCodes[LSCRIPTOpCodes[LOPC_PUSH]] = print_push;
715 mPrintOpCodes[LSCRIPTOpCodes[LOPC_PUSHS]] = print_pushs;
716 mPrintOpCodes[LSCRIPTOpCodes[LOPC_PUSHL]] = print_pushl;
717 mPrintOpCodes[LSCRIPTOpCodes[LOPC_PUSHV]] = print_pushv;
718 mPrintOpCodes[LSCRIPTOpCodes[LOPC_PUSHQ]] = print_pushq;
719 mPrintOpCodes[LSCRIPTOpCodes[LOPC_PUSHG]] = print_pushg;
720 mPrintOpCodes[LSCRIPTOpCodes[LOPC_PUSHGS]] = print_pushgs;
721 mPrintOpCodes[LSCRIPTOpCodes[LOPC_PUSHGL]] = print_pushgl;
722 mPrintOpCodes[LSCRIPTOpCodes[LOPC_PUSHGV]] = print_pushgv;
723 mPrintOpCodes[LSCRIPTOpCodes[LOPC_PUSHGQ]] = print_pushgq;
724 mPrintOpCodes[LSCRIPTOpCodes[LOPC_PUSHIP]] = print_puship;
725 mPrintOpCodes[LSCRIPTOpCodes[LOPC_PUSHSP]] = print_pushsp;
726 mPrintOpCodes[LSCRIPTOpCodes[LOPC_PUSHBP]] = print_pushbp;
727 mPrintOpCodes[LSCRIPTOpCodes[LOPC_PUSHARGB]] = print_pushargb;
728 mPrintOpCodes[LSCRIPTOpCodes[LOPC_PUSHARGI]] = print_pushargi;
729 mPrintOpCodes[LSCRIPTOpCodes[LOPC_PUSHARGF]] = print_pushargf;
730 mPrintOpCodes[LSCRIPTOpCodes[LOPC_PUSHARGS]] = print_pushargs;
731 mPrintOpCodes[LSCRIPTOpCodes[LOPC_PUSHARGV]] = print_pushargv;
732 mPrintOpCodes[LSCRIPTOpCodes[LOPC_PUSHARGQ]] = print_pushargq;
733 mPrintOpCodes[LSCRIPTOpCodes[LOPC_PUSHE]] = print_pushe;
734 mPrintOpCodes[LSCRIPTOpCodes[LOPC_PUSHEV]] = print_pushev;
735 mPrintOpCodes[LSCRIPTOpCodes[LOPC_PUSHEQ]] = print_pusheq;
736 mPrintOpCodes[LSCRIPTOpCodes[LOPC_PUSHARGE]] = print_pusharge;
737
738 mPrintOpCodes[LSCRIPTOpCodes[LOPC_ADD]] = print_add;
739 mPrintOpCodes[LSCRIPTOpCodes[LOPC_SUB]] = print_sub;
740 mPrintOpCodes[LSCRIPTOpCodes[LOPC_MUL]] = print_mul;
741 mPrintOpCodes[LSCRIPTOpCodes[LOPC_DIV]] = print_div;
742 mPrintOpCodes[LSCRIPTOpCodes[LOPC_MOD]] = print_mod;
743
744 mPrintOpCodes[LSCRIPTOpCodes[LOPC_EQ]] = print_eq;
745 mPrintOpCodes[LSCRIPTOpCodes[LOPC_NEQ]] = print_neq;
746 mPrintOpCodes[LSCRIPTOpCodes[LOPC_LEQ]] = print_leq;
747 mPrintOpCodes[LSCRIPTOpCodes[LOPC_GEQ]] = print_geq;
748 mPrintOpCodes[LSCRIPTOpCodes[LOPC_LESS]] = print_less;
749 mPrintOpCodes[LSCRIPTOpCodes[LOPC_GREATER]] = print_greater;
750
751 mPrintOpCodes[LSCRIPTOpCodes[LOPC_BITAND]] = print_bitand;
752 mPrintOpCodes[LSCRIPTOpCodes[LOPC_BITOR]] = print_bitor;
753 mPrintOpCodes[LSCRIPTOpCodes[LOPC_BITXOR]] = print_bitxor;
754
755 mPrintOpCodes[LSCRIPTOpCodes[LOPC_BOOLAND]] = print_booland;
756 mPrintOpCodes[LSCRIPTOpCodes[LOPC_BOOLOR]] = print_boolor;
757
758 mPrintOpCodes[LSCRIPTOpCodes[LOPC_SHL]] = print_shl;
759 mPrintOpCodes[LSCRIPTOpCodes[LOPC_SHR]] = print_shr;
760
761 mPrintOpCodes[LSCRIPTOpCodes[LOPC_NEG]] = print_neg;
762 mPrintOpCodes[LSCRIPTOpCodes[LOPC_BITNOT]] = print_bitnot;
763 mPrintOpCodes[LSCRIPTOpCodes[LOPC_BOOLNOT]] = print_boolnot;
764
765 mPrintOpCodes[LSCRIPTOpCodes[LOPC_JUMP]] = print_jump;
766 mPrintOpCodes[LSCRIPTOpCodes[LOPC_JUMPIF]] = print_jumpif;
767 mPrintOpCodes[LSCRIPTOpCodes[LOPC_JUMPNIF]] = print_jumpnif;
768
769 mPrintOpCodes[LSCRIPTOpCodes[LOPC_STATE]] = print_state;
770 mPrintOpCodes[LSCRIPTOpCodes[LOPC_CALL]] = print_call;
771 mPrintOpCodes[LSCRIPTOpCodes[LOPC_RETURN]] = print_return;
772 mPrintOpCodes[LSCRIPTOpCodes[LOPC_CAST]] = print_cast;
773 mPrintOpCodes[LSCRIPTOpCodes[LOPC_STACKTOS]] = print_stacktos;
774 mPrintOpCodes[LSCRIPTOpCodes[LOPC_STACKTOL]] = print_stacktol;
775
776 mPrintOpCodes[LSCRIPTOpCodes[LOPC_PRINT]] = print_print;
777
778 mPrintOpCodes[LSCRIPTOpCodes[LOPC_CALLLIB]] = print_calllib;
779
780 mPrintOpCodes[LSCRIPTOpCodes[LOPC_CALLLIB_TWO_BYTE]] = print_calllib_two_byte;
781}
782
783void print_noop(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
784{
785 lso_print_tabs(fp, tabs);
786 fprintf(fp, "[0x%X]\tNOOP\n", offset++);
787}
788
789void print_pop(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
790{
791 lso_print_tabs(fp, tabs);
792 fprintf(fp, "[0x%X]\tPOP\n", offset++);
793}
794
795void print_pops(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
796{
797 lso_print_tabs(fp, tabs);
798 fprintf(fp, "[0x%X]\tPOPS\n", offset++);
799}
800
801void print_popl(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
802{
803 lso_print_tabs(fp, tabs);
804 fprintf(fp, "[0x%X]\tPOPL\n", offset++);
805}
806
807void print_popv(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
808{
809 lso_print_tabs(fp, tabs);
810 fprintf(fp, "[0x%X]\tPOPV\n", offset++);
811}
812
813void print_popq(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
814{
815 lso_print_tabs(fp, tabs);
816 fprintf(fp, "[0x%X]\tPOPQ\n", offset++);
817}
818
819void print_poparg(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
820{
821 S32 arg;
822 lso_print_tabs(fp, tabs);
823 fprintf(fp, "[0x%X]\tPOPARG ", offset++);
824 arg = bytestream2integer(buffer, offset);
825 fprintf(fp, "%d\n", arg);
826}
827
828void print_popip(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
829{
830 lso_print_tabs(fp, tabs);
831 fprintf(fp, "[0x%X]\tPOPIP\n", offset++);
832}
833
834void print_popbp(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
835{
836 lso_print_tabs(fp, tabs);
837 fprintf(fp, "[0x%X]\tPOPBP\n", offset++);
838}
839
840void print_popsp(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
841{
842 lso_print_tabs(fp, tabs);
843 fprintf(fp, "[0x%X]\tPOPSP\n", offset++);
844}
845
846void print_popslr(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
847{
848 lso_print_tabs(fp, tabs);
849 fprintf(fp, "[0x%X]\tPOPSLR\n", offset++);
850}
851
852void print_dup(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
853{
854 lso_print_tabs(fp, tabs);
855 fprintf(fp, "[0x%X]\tDUP\n", offset++);
856}
857
858void print_dups(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
859{
860 lso_print_tabs(fp, tabs);
861 fprintf(fp, "[0x%X]\tDUPS\n", offset++);
862}
863
864void print_dupl(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
865{
866 lso_print_tabs(fp, tabs);
867 fprintf(fp, "[0x%X]\tDUPL\n", offset++);
868}
869
870void print_dupv(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
871{
872 lso_print_tabs(fp, tabs);
873 fprintf(fp, "[0x%X]\tDUPV\n", offset++);
874}
875
876void print_dupq(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
877{
878 lso_print_tabs(fp, tabs);
879 fprintf(fp, "[0x%X]\tDUPQ\n", offset++);
880}
881
882void print_store(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
883{
884 S32 arg;
885 lso_print_tabs(fp, tabs);
886 fprintf(fp, "[0x%X]\tSTORE $BP + ", offset++);
887 arg = bytestream2integer(buffer, offset);
888 fprintf(fp, "%d\n", arg);
889}
890
891void print_stores(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
892{
893 S32 arg;
894 lso_print_tabs(fp, tabs);
895 fprintf(fp, "[0x%X]\tSTORES $BP + ", offset++);
896 arg = bytestream2integer(buffer, offset);
897 fprintf(fp, "%d\n", arg);
898}
899
900void print_storel(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
901{
902 S32 arg;
903 lso_print_tabs(fp, tabs);
904 fprintf(fp, "[0x%X]\tSTOREL $BP + ", offset++);
905 arg = bytestream2integer(buffer, offset);
906 fprintf(fp, "%d\n", arg);
907}
908
909void print_storev(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
910{
911 S32 arg;
912 lso_print_tabs(fp, tabs);
913 fprintf(fp, "[0x%X]\tSTOREV $BP + ", offset++);
914 arg = bytestream2integer(buffer, offset);
915 fprintf(fp, "%d\n", arg);
916}
917
918void print_storeq(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
919{
920 S32 arg;
921 lso_print_tabs(fp, tabs);
922 fprintf(fp, "[0x%X]\tSTOREQ $BP + ", offset++);
923 arg = bytestream2integer(buffer, offset);
924 fprintf(fp, "%d\n", arg);
925}
926
927void print_storeg(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
928{
929 S32 arg;
930 lso_print_tabs(fp, tabs);
931 fprintf(fp, "[0x%X]\tSTOREG ", offset++);
932 arg = bytestream2integer(buffer, offset);
933 fprintf(fp, "%d\n", arg + get_register(buffer, LREG_GVR));
934}
935
936void print_storegs(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
937{
938 S32 arg;
939 lso_print_tabs(fp, tabs);
940 fprintf(fp, "[0x%X]\tSTOREGS ", offset++);
941 arg = bytestream2integer(buffer, offset);
942 fprintf(fp, "%d\n", arg + get_register(buffer, LREG_GVR));
943}
944
945void print_storegl(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
946{
947 S32 arg;
948 lso_print_tabs(fp, tabs);
949 fprintf(fp, "[0x%X]\tSTOREGL ", offset++);
950 arg = bytestream2integer(buffer, offset);
951 fprintf(fp, "%d\n", arg + get_register(buffer, LREG_GVR));
952}
953
954void print_storegv(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
955{
956 S32 arg;
957 lso_print_tabs(fp, tabs);
958 fprintf(fp, "[0x%X]\tSTOREGV ", offset++);
959 arg = bytestream2integer(buffer, offset);
960 fprintf(fp, "%d\n", arg + get_register(buffer, LREG_GVR));
961}
962
963void print_storegq(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
964{
965 S32 arg;
966 lso_print_tabs(fp, tabs);
967 fprintf(fp, "[0x%X]\tSTOREGQ ", offset++);
968 arg = bytestream2integer(buffer, offset);
969 fprintf(fp, "%d\n", arg + get_register(buffer, LREG_GVR));
970}
971
972void print_loadp(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
973{
974 S32 arg;
975 lso_print_tabs(fp, tabs);
976 fprintf(fp, "[0x%X]\tSTOREP $BP + ", offset++);
977 arg = bytestream2integer(buffer, offset);
978 fprintf(fp, "%d\n", arg);
979}
980
981void print_loadsp(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
982{
983 S32 arg;
984 lso_print_tabs(fp, tabs);
985 fprintf(fp, "[0x%X]\tSTOREPS $BP + ", offset++);
986 arg = bytestream2integer(buffer, offset);
987 fprintf(fp, "%d\n", arg);
988}
989
990void print_loadlp(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
991{
992 S32 arg;
993 lso_print_tabs(fp, tabs);
994 fprintf(fp, "[0x%X]\tSTOREPL $BP + ", offset++);
995 arg = bytestream2integer(buffer, offset);
996 fprintf(fp, "%d\n", arg);
997}
998
999void print_loadvp(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
1000{
1001 S32 arg;
1002 lso_print_tabs(fp, tabs);
1003 fprintf(fp, "[0x%X]\tSTOREVP $BP + ", offset++);
1004 arg = bytestream2integer(buffer, offset);
1005 fprintf(fp, "%d\n", arg);
1006}
1007
1008void print_loadqp(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
1009{
1010 S32 arg;
1011 lso_print_tabs(fp, tabs);
1012 fprintf(fp, "[0x%X]\tSTOREQP $BP + ", offset++);
1013 arg = bytestream2integer(buffer, offset);
1014 fprintf(fp, "%d\n", arg);
1015}
1016
1017void print_loadgp(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
1018{
1019 S32 arg;
1020 lso_print_tabs(fp, tabs);
1021 fprintf(fp, "[0x%X]\tSTOREGP ", offset++);
1022 arg = bytestream2integer(buffer, offset);
1023 fprintf(fp, "%d\n", arg + get_register(buffer, LREG_GVR));
1024}
1025
1026void print_loadgsp(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
1027{
1028 S32 arg;
1029 lso_print_tabs(fp, tabs);
1030 fprintf(fp, "[0x%X]\tSTOREGSP ", offset++);
1031 arg = bytestream2integer(buffer, offset);
1032 fprintf(fp, "%d\n", arg + get_register(buffer, LREG_GVR));
1033}
1034
1035void print_loadglp(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
1036{
1037 S32 arg;
1038 lso_print_tabs(fp, tabs);
1039 fprintf(fp, "[0x%X]\tSTOREGLP ", offset++);
1040 arg = bytestream2integer(buffer, offset);
1041 fprintf(fp, "%d\n", arg + get_register(buffer, LREG_GVR));
1042}
1043
1044void print_loadgvp(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
1045{
1046 S32 arg;
1047 lso_print_tabs(fp, tabs);
1048 fprintf(fp, "[0x%X]\tSTOREGVP ", offset++);
1049 arg = bytestream2integer(buffer, offset);
1050 fprintf(fp, "%d\n", arg + get_register(buffer, LREG_GVR));
1051}
1052
1053void print_loadgqp(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
1054{
1055 S32 arg;
1056 lso_print_tabs(fp, tabs);
1057 fprintf(fp, "[0x%X]\tSTOREGQP ", offset++);
1058 arg = bytestream2integer(buffer, offset);
1059 fprintf(fp, "%d\n", arg + get_register(buffer, LREG_GVR));
1060}
1061
1062void print_push(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
1063{
1064 S32 arg;
1065 lso_print_tabs(fp, tabs);
1066 fprintf(fp, "[0x%X]\tPUSH $BP + ", offset++);
1067 arg = bytestream2integer(buffer, offset);
1068 fprintf(fp, "%d\n", arg);
1069}
1070
1071void print_pushs(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
1072{
1073 S32 arg;
1074 lso_print_tabs(fp, tabs);
1075 fprintf(fp, "[0x%X]\tPUSHS $BP + ", offset++);
1076 arg = bytestream2integer(buffer, offset);
1077 fprintf(fp, "%d\n", arg);
1078}
1079
1080void print_pushl(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
1081{
1082 S32 arg;
1083 lso_print_tabs(fp, tabs);
1084 fprintf(fp, "[0x%X]\tPUSHL $BP + ", offset++);
1085 arg = bytestream2integer(buffer, offset);
1086 fprintf(fp, "%d\n", arg);
1087}
1088
1089void print_pushv(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
1090{
1091 S32 arg;
1092 lso_print_tabs(fp, tabs);
1093 fprintf(fp, "[0x%X]\tPUSHV $BP + ", offset++);
1094 arg = bytestream2integer(buffer, offset);
1095 fprintf(fp, "%d\n", arg);
1096}
1097
1098void print_pushq(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
1099{
1100 S32 arg;
1101 lso_print_tabs(fp, tabs);
1102 fprintf(fp, "[0x%X]\tPUSHQ $BP + ", offset++);
1103 arg = bytestream2integer(buffer, offset);
1104 fprintf(fp, "%d\n", arg);
1105}
1106
1107void print_pushg(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
1108{
1109 S32 arg;
1110 lso_print_tabs(fp, tabs);
1111 fprintf(fp, "[0x%X]\tPUSHG ", offset++);
1112 arg = bytestream2integer(buffer, offset);
1113 fprintf(fp, "0x%X\n", arg + get_register(buffer, LREG_GVR));
1114}
1115
1116void print_pushgs(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
1117{
1118 S32 arg;
1119 lso_print_tabs(fp, tabs);
1120 fprintf(fp, "[0x%X]\tPUSHGS ", offset++);
1121 arg = bytestream2integer(buffer, offset);
1122 fprintf(fp, "0x%X\n", arg + get_register(buffer, LREG_GVR));
1123}
1124
1125void print_pushgl(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
1126{
1127 S32 arg;
1128 lso_print_tabs(fp, tabs);
1129 fprintf(fp, "[0x%X]\tPUSHGL ", offset++);
1130 arg = bytestream2integer(buffer, offset);
1131 fprintf(fp, "0x%X\n", arg + get_register(buffer, LREG_GVR));
1132}
1133
1134void print_pushgv(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
1135{
1136 S32 arg;
1137 lso_print_tabs(fp, tabs);
1138 fprintf(fp, "[0x%X]\tPUSHGV ", offset++);
1139 arg = bytestream2integer(buffer, offset);
1140 fprintf(fp, "0x%X\n", arg + get_register(buffer, LREG_GVR));
1141}
1142
1143void print_pushgq(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
1144{
1145 S32 arg;
1146 lso_print_tabs(fp, tabs);
1147 fprintf(fp, "[0x%X]\tPUSHGQ ", offset++);
1148 arg = bytestream2integer(buffer, offset);
1149 fprintf(fp, "0x%X\n", arg + get_register(buffer, LREG_GVR));
1150}
1151
1152void print_puship(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
1153{
1154 lso_print_tabs(fp, tabs);
1155 fprintf(fp, "[0x%X]\tPUSHIP\n", offset++);
1156}
1157
1158void print_pushbp(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
1159{
1160 lso_print_tabs(fp, tabs);
1161 fprintf(fp, "[0x%X]\tPUSHBP\n", offset++);
1162}
1163
1164void print_pushsp(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
1165{
1166 lso_print_tabs(fp, tabs);
1167 fprintf(fp, "[0x%X]\tPUSHSP\n", offset++);
1168}
1169
1170void print_pushargb(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
1171{
1172 U8 arg;
1173 lso_print_tabs(fp, tabs);
1174 fprintf(fp, "[0x%X]\tPUSHARGB ", offset++);
1175 arg = *(buffer + offset++);
1176 fprintf(fp, "%d\n", (U32)arg);
1177}
1178
1179void print_pushargi(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
1180{
1181 S32 arg;
1182 lso_print_tabs(fp, tabs);
1183 fprintf(fp, "[0x%X]\tPUSHARGI ", offset++);
1184 arg = bytestream2integer(buffer, offset);
1185 fprintf(fp, "%d\n", arg);
1186}
1187
1188void print_pushargf(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
1189{
1190 F32 arg;
1191 lso_print_tabs(fp, tabs);
1192 fprintf(fp, "[0x%X]\tPUSHARGF ", offset++);
1193 arg = bytestream2float(buffer, offset);
1194 fprintf(fp, "%f\n", arg);
1195}
1196
1197void print_pushargs(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
1198{
1199 char arg[1024];
1200 lso_print_tabs(fp, tabs);
1201 fprintf(fp, "[0x%X]\tPUSHARGS ", offset++);
1202 bytestream2char(arg, buffer, offset);
1203 fprintf(fp, "%s\n", arg);
1204}
1205
1206void print_pushargv(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
1207{
1208 LLVector3 arg;
1209 lso_print_tabs(fp, tabs);
1210 fprintf(fp, "[0x%X]\tPUSHARGV ", offset++);
1211 bytestream2vector(arg, buffer, offset);
1212 fprintf(fp, "< %f, %f, %f >\n", arg.mV[VX], arg.mV[VY], arg.mV[VZ]);
1213}
1214
1215void print_pushargq(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
1216{
1217 LLQuaternion arg;
1218 lso_print_tabs(fp, tabs);
1219 fprintf(fp, "[0x%X]\tPUSHARGV ", offset++);
1220 bytestream2quaternion(arg, buffer, offset);
1221 fprintf(fp, "< %f, %f, %f, %f >\n", arg.mQ[VX], arg.mQ[VY], arg.mQ[VZ], arg.mQ[VS]);
1222}
1223
1224void print_pushe(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
1225{
1226 lso_print_tabs(fp, tabs);
1227 fprintf(fp, "[0x%X]\tPUSHE\n", offset++);
1228}
1229
1230void print_pushev(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
1231{
1232 lso_print_tabs(fp, tabs);
1233 fprintf(fp, "[0x%X]\tPUSHEV\n", offset++);
1234}
1235
1236void print_pusheq(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
1237{
1238 lso_print_tabs(fp, tabs);
1239 fprintf(fp, "[0x%X]\tPUSHEQ\n", offset++);
1240}
1241
1242void print_pusharge(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
1243{
1244 S32 arg;
1245 lso_print_tabs(fp, tabs);
1246 fprintf(fp, "[0x%X]\tPUSHARGE ", offset++);
1247 arg = bytestream2integer(buffer, offset);
1248 fprintf(fp, "%d\n", arg);
1249}
1250
1251
1252void print_add(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
1253{
1254 U8 types;
1255 U8 type1;
1256 U8 type2;
1257 lso_print_tabs(fp, tabs);
1258 fprintf(fp, "[0x%X]\tADD ", offset++);
1259 types = *(buffer + offset++);
1260 type1 = types >> 4;
1261 type2 = types & 0xf;
1262 fprintf(fp, "%s, %s\n", LSCRIPTTypeNames[type1], LSCRIPTTypeNames[type2]);
1263}
1264
1265void print_sub(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
1266{
1267 U8 types;
1268 U8 type1;
1269 U8 type2;
1270 lso_print_tabs(fp, tabs);
1271 fprintf(fp, "[0x%X]\tSUB ", offset++);
1272 types = *(buffer + offset++);
1273 type1 = types >> 4;
1274 type2 = types & 0xf;
1275 fprintf(fp, "%s, %s\n", LSCRIPTTypeNames[type1], LSCRIPTTypeNames[type2]);
1276}
1277
1278void print_mul(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
1279{
1280 U8 types;
1281 U8 type1;
1282 U8 type2;
1283 lso_print_tabs(fp, tabs);
1284 fprintf(fp, "[0x%X]\tMUL ", offset++);
1285 types = *(buffer + offset++);
1286 type1 = types >> 4;
1287 type2 = types & 0xf;
1288 fprintf(fp, "%s, %s\n", LSCRIPTTypeNames[type1], LSCRIPTTypeNames[type2]);
1289}
1290
1291void print_div(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
1292{
1293 U8 types;
1294 U8 type1;
1295 U8 type2;
1296 lso_print_tabs(fp, tabs);
1297 fprintf(fp, "[0x%X]\tDIV ", offset++);
1298 types = *(buffer + offset++);
1299 type1 = types >> 4;
1300 type2 = types & 0xf;
1301 fprintf(fp, "%s, %s\n", LSCRIPTTypeNames[type1], LSCRIPTTypeNames[type2]);
1302}
1303
1304void print_mod(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
1305{
1306 U8 types;
1307 U8 type1;
1308 U8 type2;
1309 lso_print_tabs(fp, tabs);
1310 fprintf(fp, "[0x%X]\tMOD ", offset++);
1311 types = *(buffer + offset++);
1312 type1 = types >> 4;
1313 type2 = types & 0xf;
1314 fprintf(fp, "%s, %s\n", LSCRIPTTypeNames[type1], LSCRIPTTypeNames[type2]);
1315}
1316
1317void print_eq(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
1318{
1319 U8 types;
1320 U8 type1;
1321 U8 type2;
1322 lso_print_tabs(fp, tabs);
1323 fprintf(fp, "[0x%X]\tEQ ", offset++);
1324 types = *(buffer + offset++);
1325 type1 = types >> 4;
1326 type2 = types & 0xf;
1327 fprintf(fp, "%s, %s\n", LSCRIPTTypeNames[type1], LSCRIPTTypeNames[type2]);
1328}
1329
1330void print_neq(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
1331{
1332 U8 types;
1333 U8 type1;
1334 U8 type2;
1335 lso_print_tabs(fp, tabs);
1336 fprintf(fp, "[0x%X]\tNEQ ", offset++);
1337 types = *(buffer + offset++);
1338 type1 = types >> 4;
1339 type2 = types & 0xf;
1340 fprintf(fp, "%s, %s\n", LSCRIPTTypeNames[type1], LSCRIPTTypeNames[type2]);
1341}
1342
1343void print_leq(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
1344{
1345 U8 types;
1346 U8 type1;
1347 U8 type2;
1348 lso_print_tabs(fp, tabs);
1349 fprintf(fp, "[0x%X]\tLEQ ", offset++);
1350 types = *(buffer + offset++);
1351 type1 = types >> 4;
1352 type2 = types & 0xf;
1353 fprintf(fp, "%s, %s\n", LSCRIPTTypeNames[type1], LSCRIPTTypeNames[type2]);
1354}
1355
1356void print_geq(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
1357{
1358 U8 types;
1359 U8 type1;
1360 U8 type2;
1361 lso_print_tabs(fp, tabs);
1362 fprintf(fp, "[0x%X]\tGEQ ", offset++);
1363 types = *(buffer + offset++);
1364 type1 = types >> 4;
1365 type2 = types & 0xf;
1366 fprintf(fp, "%s, %s\n", LSCRIPTTypeNames[type1], LSCRIPTTypeNames[type2]);
1367}
1368
1369void print_less(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
1370{
1371 U8 types;
1372 U8 type1;
1373 U8 type2;
1374 lso_print_tabs(fp, tabs);
1375 fprintf(fp, "[0x%X]\tLESS ", offset++);
1376 types = *(buffer + offset++);
1377 type1 = types >> 4;
1378 type2 = types & 0xf;
1379 fprintf(fp, "%s, %s\n", LSCRIPTTypeNames[type1], LSCRIPTTypeNames[type2]);
1380}
1381
1382void print_greater(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
1383{
1384 U8 types;
1385 U8 type1;
1386 U8 type2;
1387 lso_print_tabs(fp, tabs);
1388 fprintf(fp, "[0x%X]\tGREATER ", offset++);
1389 types = *(buffer + offset++);
1390 type1 = types >> 4;
1391 type2 = types & 0xf;
1392 fprintf(fp, "%s, %s\n", LSCRIPTTypeNames[type1], LSCRIPTTypeNames[type2]);
1393}
1394
1395
1396void print_bitand(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
1397{
1398 lso_print_tabs(fp, tabs);
1399 fprintf(fp, "[0x%X]\tBITAND\n", offset++);
1400}
1401
1402void print_bitor(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
1403{
1404 lso_print_tabs(fp, tabs);
1405 fprintf(fp, "[0x%X]\tBITOR\n", offset++);
1406}
1407
1408void print_bitxor(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
1409{
1410 lso_print_tabs(fp, tabs);
1411 fprintf(fp, "[0x%X]\tBITXOR\n", offset++);
1412}
1413
1414void print_booland(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
1415{
1416 lso_print_tabs(fp, tabs);
1417 fprintf(fp, "[0x%X]\tBOOLAND\n", offset++);
1418}
1419
1420void print_boolor(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
1421{
1422 lso_print_tabs(fp, tabs);
1423 fprintf(fp, "[0x%X]\tBOOLOR\n", offset++);
1424}
1425
1426void print_shl(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
1427{
1428 lso_print_tabs(fp, tabs);
1429 fprintf(fp, "[0x%X]\tSHL\n", offset++);
1430}
1431
1432void print_shr(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
1433{
1434 lso_print_tabs(fp, tabs);
1435 fprintf(fp, "[0x%X]\tSHR\n", offset++);
1436}
1437
1438
1439void print_neg(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
1440{
1441 U8 type;
1442 lso_print_tabs(fp, tabs);
1443 fprintf(fp, "[0x%X]\tNEG ", offset++);
1444 type = *(buffer + offset++);
1445 fprintf(fp, "%s\n", LSCRIPTTypeNames[type]);
1446}
1447
1448void print_bitnot(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
1449{
1450 lso_print_tabs(fp, tabs);
1451 fprintf(fp, "[0x%X]\tBITNOT\n", offset++);
1452}
1453
1454void print_boolnot(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
1455{
1456 lso_print_tabs(fp, tabs);
1457 fprintf(fp, "[0x%X]\tBOOLNOT\n", offset++);
1458}
1459
1460void print_jump(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
1461{
1462 S32 arg;
1463 lso_print_tabs(fp, tabs);
1464 fprintf(fp, "[0x%X]\tJUMP ", offset++);
1465 arg = bytestream2integer(buffer, offset);
1466 fprintf(fp, "%d\n", arg);
1467}
1468
1469void print_jumpif(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
1470{
1471 S32 arg;
1472 U8 type;
1473 lso_print_tabs(fp, tabs);
1474 fprintf(fp, "[0x%X]\tJUMPIF ", offset++);
1475 type = *(buffer + offset++);
1476 arg = bytestream2integer(buffer, offset);
1477 fprintf(fp, "%s, %d\n", LSCRIPTTypeNames[type], arg);
1478}
1479
1480void print_jumpnif(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
1481{
1482 S32 arg;
1483 U8 type;
1484 lso_print_tabs(fp, tabs);
1485 fprintf(fp, "[0x%X]\tJUMPNIF ", offset++);
1486 type = *(buffer + offset++);
1487 arg = bytestream2integer(buffer, offset);
1488 fprintf(fp, "%s, %d\n", LSCRIPTTypeNames[type], arg);
1489}
1490
1491void print_state(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
1492{
1493 S32 arg;
1494 lso_print_tabs(fp, tabs);
1495 fprintf(fp, "[0x%X]\tSTATE ", offset++);
1496 arg = bytestream2integer(buffer, offset);
1497 fprintf(fp, "%d\n", arg);
1498}
1499
1500void print_call(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
1501{
1502 S32 arg;
1503 lso_print_tabs(fp, tabs);
1504 fprintf(fp, "[0x%X]\tCALL ", offset++);
1505 arg = bytestream2integer(buffer, offset);
1506 fprintf(fp, "%d\n", arg);
1507}
1508
1509void print_return(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
1510{
1511 lso_print_tabs(fp, tabs);
1512 fprintf(fp, "[0x%X]\tRETURN\n", offset++);
1513}
1514
1515void print_cast(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
1516{
1517 U8 types;
1518 U8 type1;
1519 U8 type2;
1520 lso_print_tabs(fp, tabs);
1521 fprintf(fp, "[0x%X]\tCAST ", offset++);
1522 types = *(buffer + offset++);
1523 type1 = types >> 4;
1524 type2 = types & 0xf;
1525 fprintf(fp, "%s, %s\n", LSCRIPTTypeNames[type1], LSCRIPTTypeNames[type2]);
1526}
1527
1528void print_stacktos(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
1529{
1530 S32 arg;
1531 lso_print_tabs(fp, tabs);
1532 fprintf(fp, "[0x%X]\tSTACKTOS ", offset++);
1533 arg = bytestream2integer(buffer, offset);
1534 fprintf(fp, "%d\n", arg);
1535}
1536
1537void print_stacktol(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
1538{
1539 S32 arg;
1540 lso_print_tabs(fp, tabs);
1541 fprintf(fp, "[0x%X]\tSTACKTOL ", offset++);
1542 arg = bytestream2integer(buffer, offset);
1543 fprintf(fp, "%d\n", arg);
1544}
1545
1546void print_print(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
1547{
1548 lso_print_tabs(fp, tabs);
1549 fprintf(fp, "[0x%X]\tPRINT ", offset++);
1550 U8 type = *(buffer + offset++);
1551 fprintf(fp, "%s\n", LSCRIPTTypeNames[type]);
1552}
1553
1554void print_calllib(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
1555{
1556 U8 arg;
1557 lso_print_tabs(fp, tabs);
1558 fprintf(fp, "[0x%X]\tCALLLIB ", offset++);
1559 arg = *(buffer + offset++);
1560 fprintf(fp, "%d (%s)\n", (U32)arg, gScriptLibrary.mFunctions[arg]->mName);
1561}
1562
1563
1564void print_calllib_two_byte(FILE *fp, U8 *buffer, S32 &offset, S32 tabs)
1565{
1566 U16 arg;
1567 lso_print_tabs(fp, tabs);
1568 fprintf(fp, "[0x%X]\tCALLLIB_TWO_BYTE ", offset++);
1569 arg = bytestream2u16(buffer, offset);
1570 fprintf(fp, "%d (%s)\n", (U32)arg, gScriptLibrary.mFunctions[arg]->mName);
1571}
1572
diff --git a/linden/indra/lscript/lscript_execute/lscript_readlso.h b/linden/indra/lscript/lscript_execute/lscript_readlso.h
new file mode 100644
index 0000000..7f72dfd
--- /dev/null
+++ b/linden/indra/lscript/lscript_execute/lscript_readlso.h
@@ -0,0 +1,166 @@
1/**
2 * @file lscript_readlso.h
3 * @brief classes to read lso file
4 *
5 * Copyright (c) 2002-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28#ifndef LL_LSCRIPT_READLSO_H
29#define LL_LSCRIPT_READLSO_H
30
31#include "lscript_byteconvert.h"
32#include "linked_lists.h"
33
34// list of op code print functions
35void print_noop(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
36void print_pop(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
37void print_pops(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
38void print_popl(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
39void print_popv(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
40void print_popq(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
41void print_poparg(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
42void print_popip(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
43void print_popbp(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
44void print_popsp(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
45void print_popslr(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
46
47void print_dup(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
48void print_dups(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
49void print_dupl(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
50void print_dupv(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
51void print_dupq(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
52
53void print_store(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
54void print_stores(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
55void print_storel(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
56void print_storev(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
57void print_storeq(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
58void print_storeg(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
59void print_storegs(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
60void print_storegl(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
61void print_storegv(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
62void print_storegq(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
63void print_loadp(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
64void print_loadsp(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
65void print_loadlp(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
66void print_loadvp(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
67void print_loadqp(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
68void print_loadgp(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
69void print_loadgsp(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
70void print_loadglp(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
71void print_loadgvp(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
72void print_loadgqp(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
73
74void print_push(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
75void print_pushl(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
76void print_pushs(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
77void print_pushv(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
78void print_pushq(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
79void print_pushg(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
80void print_pushgl(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
81void print_pushgs(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
82void print_pushgv(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
83void print_pushgq(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
84void print_puship(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
85void print_pushbp(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
86void print_pushsp(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
87void print_pushargb(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
88void print_pushargi(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
89void print_pushargf(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
90void print_pushargs(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
91void print_pushargv(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
92void print_pushargq(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
93void print_pushe(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
94void print_pushev(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
95void print_pusheq(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
96void print_pusharge(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
97
98void print_add(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
99void print_sub(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
100void print_mul(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
101void print_div(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
102void print_mod(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
103
104void print_eq(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
105void print_neq(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
106void print_leq(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
107void print_geq(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
108void print_less(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
109void print_greater(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
110
111void print_bitand(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
112void print_bitor(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
113void print_bitxor(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
114void print_booland(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
115void print_boolor(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
116
117void print_shl(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
118void print_shr(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
119
120void print_neg(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
121void print_bitnot(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
122void print_boolnot(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
123
124void print_jump(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
125void print_jumpif(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
126void print_jumpnif(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
127
128void print_state(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
129void print_call(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
130void print_return(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
131void print_cast(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
132void print_stacktos(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
133void print_stacktol(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
134
135void print_print(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
136
137void print_calllib(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
138void print_calllib_two_byte(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
139
140class LLScriptLSOParse
141{
142public:
143 LLScriptLSOParse(FILE *fp);
144 LLScriptLSOParse(U8 *buffer);
145 ~LLScriptLSOParse();
146
147 void initOpCodePrinting();
148
149 void printData(FILE *fp);
150 void printNameDesc(FILE *fp);
151 void printRegisters(FILE *fp);
152 void printGlobals(FILE *fp);
153 void printGlobalFunctions(FILE *fp);
154 void printStates(FILE *fp);
155 void printHeap(FILE *fp);
156 void printOpCodes(FILE *fp, S32 &offset, S32 tabs);
157 void printOpCodeRange(FILE *fp, S32 start, S32 end, S32 tabs);
158
159 U8 *mRawData;
160 void (*mPrintOpCodes[0x100])(FILE *fp, U8 *buffer, S32 &offset, S32 tabs);
161};
162
163
164void lso_print_tabs(FILE *fp, S32 tabs);
165
166#endif
diff --git a/linden/indra/lscript/lscript_export.h b/linden/indra/lscript/lscript_export.h
new file mode 100644
index 0000000..c53948f
--- /dev/null
+++ b/linden/indra/lscript/lscript_export.h
@@ -0,0 +1,35 @@
1/**
2 * @file lscript_export.h
3 * @brief Export interface class
4 *
5 * Copyright (c) 2002-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28#ifndef LL_LSCRIPT_EXPORT_H
29#define LL_LSCRIPT_EXPORT_H
30
31#include "lscript_library.h"
32
33extern LLScriptLibrary gScriptLibrary;
34
35#endif
diff --git a/linden/indra/lscript/lscript_http.h b/linden/indra/lscript/lscript_http.h
new file mode 100644
index 0000000..e92148c
--- /dev/null
+++ b/linden/indra/lscript/lscript_http.h
@@ -0,0 +1,46 @@
1/**
2 * @file lscript_http.h
3 * @brief LSL HTTP keys
4 *
5 * Copyright (c) 2006-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28// Keys used in LSL HTTP function <key,value> pair lists.
29
30#ifndef LSCRIPT_HTTP_H
31#define LSCRIPT_HTTP_H
32
33enum LLScriptHTTPRequestParameterKey
34{
35 HTTP_METHOD,
36 HTTP_MIMETYPE,
37 HTTP_BODY_MAXLENGTH,
38 HTTP_VERIFY_CERT
39};
40
41enum LLScriptHTTPResponseMetadataKey
42{
43 HTTP_BODY_TRUNCATED
44};
45
46#endif
diff --git a/linden/indra/lscript/lscript_library.h b/linden/indra/lscript/lscript_library.h
new file mode 100644
index 0000000..300cbb6
--- /dev/null
+++ b/linden/indra/lscript/lscript_library.h
@@ -0,0 +1,401 @@
1/**
2 * @file lscript_library.h
3 * @brief External library interface
4 *
5 * Copyright (c) 2002-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28#ifndef LL_LSCRIPT_LIBRARY_H
29#define LL_LSCRIPT_LIBRARY_H
30
31#include "lscript_byteformat.h"
32#include "v3math.h"
33#include "llquaternion.h"
34#include "lluuid.h"
35#include "lscript_byteconvert.h"
36#include <stdio.h>
37
38class LLScriptLibData;
39
40class LLScriptLibraryFunction
41{
42public:
43 LLScriptLibraryFunction(F32 eu, F32 st, void (*exec_func)(LLScriptLibData *, LLScriptLibData *, const LLUUID &), char *name, char *ret_type, char *args, char *desc, BOOL god_only = FALSE);
44 ~LLScriptLibraryFunction();
45
46 F32 mEnergyUse;
47 F32 mSleepTime;
48 void (*mExecFunc)(LLScriptLibData *, LLScriptLibData *, const LLUUID &);
49 char *mName;
50 char *mReturnType;
51 char *mArgs;
52 char *mDesc;
53 BOOL mGodOnly;
54};
55
56class LLScriptLibrary
57{
58public:
59 LLScriptLibrary();
60 ~LLScriptLibrary();
61
62 void init();
63
64 void addFunction(LLScriptLibraryFunction *func);
65 void assignExec(char *name, void (*exec_func)(LLScriptLibData *, LLScriptLibData *, const LLUUID &));
66
67 S32 mNextNumber;
68 LLScriptLibraryFunction **mFunctions;
69};
70
71extern LLScriptLibrary gScriptLibrary;
72
73class LLScriptLibData
74{
75public:
76 // TODO: Change this to a union
77 LSCRIPTType mType;
78 S32 mInteger;
79 F32 mFP;
80 char *mKey;
81 char *mString;
82 LLVector3 mVec;
83 LLQuaternion mQuat;
84 LLScriptLibData *mListp;
85
86 friend const bool operator<=(const LLScriptLibData &a, const LLScriptLibData &b)
87 {
88 if (a.mType == b.mType)
89 {
90 if (a.mType == LST_INTEGER)
91 {
92 return a.mInteger <= b.mInteger;
93 }
94 if (a.mType == LST_FLOATINGPOINT)
95 {
96 return a.mFP <= b.mFP;
97 }
98 if (a.mType == LST_STRING)
99 {
100 return strcmp(a.mString, b.mString) <= 0;
101 }
102 if (a.mType == LST_KEY)
103 {
104 return strcmp(a.mKey, b.mKey) <= 0;
105 }
106 if (a.mType == LST_VECTOR)
107 {
108 return a.mVec.magVecSquared() <= b.mVec.magVecSquared();
109 }
110 }
111 return TRUE;
112 }
113
114 friend const bool operator==(const LLScriptLibData &a, const LLScriptLibData &b)
115 {
116 if (a.mType == b.mType)
117 {
118 if (a.mType == LST_INTEGER)
119 {
120 return a.mInteger == b.mInteger;
121 }
122 if (a.mType == LST_FLOATINGPOINT)
123 {
124 return a.mFP == b.mFP;
125 }
126 if (a.mType == LST_STRING)
127 {
128 return !strcmp(a.mString, b.mString);
129 }
130 if (a.mType == LST_KEY)
131 {
132 return !strcmp(a.mKey, b.mKey);
133 }
134 if (a.mType == LST_VECTOR)
135 {
136 return a.mVec == b.mVec;
137 }
138 if (a.mType == LST_QUATERNION)
139 {
140 return a.mQuat == b.mQuat;
141 }
142 }
143 return FALSE;
144 }
145
146 S32 getListLength()
147 {
148 LLScriptLibData *data = this;
149 S32 retval = 0;
150 while (data->mListp)
151 {
152 retval++;
153 data = data->mListp;
154 }
155 return retval;
156 }
157
158 BOOL checkForMultipleLists()
159 {
160 LLScriptLibData *data = this;
161 while (data->mListp)
162 {
163 data = data->mListp;
164 if (data->mType == LST_LIST)
165 return TRUE;
166 }
167 return FALSE;
168 }
169
170 S32 getSavedSize()
171 {
172 S32 size = 0;
173 // mType
174 size += 4;
175
176 switch(mType)
177 {
178 case LST_INTEGER:
179 size += 4;
180 break;
181 case LST_FLOATINGPOINT:
182 size += 4;
183 break;
184 case LST_KEY:
185 size += (S32)strlen(mKey) + 1;
186 break;
187 case LST_STRING:
188 size += (S32)strlen(mString) + 1;
189 break;
190 case LST_LIST:
191 break;
192 case LST_VECTOR:
193 size += 12;
194 break;
195 case LST_QUATERNION:
196 size += 16;
197 break;
198 default:
199 break;
200 }
201 return size;
202 }
203
204 S32 write2bytestream(U8 *dest)
205 {
206 S32 offset = 0;
207 integer2bytestream(dest, offset, mType);
208 switch(mType)
209 {
210 case LST_INTEGER:
211 integer2bytestream(dest, offset, mInteger);
212 break;
213 case LST_FLOATINGPOINT:
214 float2bytestream(dest, offset, mFP);
215 break;
216 case LST_KEY:
217 char2bytestream(dest, offset, mKey);
218 break;
219 case LST_STRING:
220 char2bytestream(dest, offset, mString);
221 break;
222 case LST_LIST:
223 break;
224 case LST_VECTOR:
225 vector2bytestream(dest, offset, mVec);
226 break;
227 case LST_QUATERNION:
228 quaternion2bytestream(dest, offset, mQuat);
229 break;
230 default:
231 break;
232 }
233 return offset;
234 }
235
236 LLScriptLibData() : mType(LST_NULL), mInteger(0), mFP(0.f), mKey(NULL), mString(NULL), mVec(), mQuat(), mListp(NULL)
237 {
238 }
239
240 LLScriptLibData(const LLScriptLibData &data) : mType(data.mType), mInteger(data.mInteger), mFP(data.mFP), mKey(NULL), mString(NULL), mVec(data.mVec), mQuat(data.mQuat), mListp(NULL)
241 {
242 if (data.mKey)
243 {
244 mKey = new char[strlen(data.mKey) + 1];
245 strcpy(mKey, data.mKey);
246 }
247 if (data.mString)
248 {
249 mString = new char[strlen(data.mString) + 1];
250 strcpy(mString, data.mString);
251 }
252 }
253
254 LLScriptLibData(U8 *src, S32 &offset) : mListp(NULL)
255 {
256 static char temp[TOP_OF_MEMORY];
257 mType = (LSCRIPTType)bytestream2integer(src, offset);
258 switch(mType)
259 {
260 case LST_INTEGER:
261 mInteger = bytestream2integer(src, offset);
262 break;
263 case LST_FLOATINGPOINT:
264 mFP = bytestream2float(src, offset);
265 break;
266 case LST_KEY:
267 {
268 bytestream2char(temp, src, offset);
269 mKey = new char[strlen(temp) + 1];
270 strcpy(mKey, temp);
271 }
272 break;
273 case LST_STRING:
274 {
275 bytestream2char(temp, src, offset);
276 mString = new char[strlen(temp) + 1];
277 strcpy(mString, temp);
278 }
279 break;
280 case LST_LIST:
281 break;
282 case LST_VECTOR:
283 bytestream2vector(mVec, src, offset);
284 break;
285 case LST_QUATERNION:
286 bytestream2quaternion(mQuat, src, offset);
287 break;
288 default:
289 break;
290 }
291 }
292
293 void set(U8 *src, S32 &offset)
294 {
295 static char temp[TOP_OF_MEMORY];
296 mType = (LSCRIPTType)bytestream2integer(src, offset);
297 switch(mType)
298 {
299 case LST_INTEGER:
300 mInteger = bytestream2integer(src, offset);
301 break;
302 case LST_FLOATINGPOINT:
303 mFP = bytestream2float(src, offset);
304 break;
305 case LST_KEY:
306 {
307 bytestream2char(temp, src, offset);
308 mKey = new char[strlen(temp) + 1];
309 strcpy(mKey, temp);
310 }
311 break;
312 case LST_STRING:
313 {
314 bytestream2char(temp, src, offset);
315 mString = new char[strlen(temp) + 1];
316 strcpy(mString, temp);
317 }
318 break;
319 case LST_LIST:
320 break;
321 case LST_VECTOR:
322 bytestream2vector(mVec, src, offset);
323 break;
324 case LST_QUATERNION:
325 bytestream2quaternion(mQuat, src, offset);
326 break;
327 default:
328 break;
329 }
330 }
331
332 void print(std::ostream &s, BOOL b_prepend_comma);
333 void print_separator(std::ostream& ostr, BOOL b_prepend_sep, char* sep);
334
335 void setFromCSV(char *src)
336 {
337 mType = LST_STRING;
338 mString = new char[strlen(src) + 1];
339 strcpy(mString, src);
340 }
341
342 LLScriptLibData(S32 integer) : mType(LST_INTEGER), mInteger(integer), mFP(0.f), mKey(NULL), mString(NULL), mVec(), mQuat(), mListp(NULL)
343 {
344 }
345
346 LLScriptLibData(F32 fp) : mType(LST_FLOATINGPOINT), mInteger(0), mFP(fp), mKey(NULL), mString(NULL), mVec(), mQuat(), mListp(NULL)
347 {
348 }
349
350 LLScriptLibData(const LLUUID &id) : mType(LST_KEY), mInteger(0), mFP(0.f), mKey(NULL), mString(NULL), mVec(), mQuat(), mListp(NULL)
351 {
352 mKey = new char[UUID_STR_LENGTH];
353 id.toString(mKey);
354 }
355
356 LLScriptLibData(char *string) : mType(LST_STRING), mInteger(0), mFP(0.f), mKey(NULL), mString(NULL), mVec(), mQuat(), mListp(NULL)
357 {
358 if (!string)
359 {
360 mString = new char[1];
361 mString[0] = 0;
362 }
363 else
364 {
365 mString = new char[strlen(string) + 1];
366 strcpy(mString, string);
367 }
368 }
369
370 LLScriptLibData(const char *string) : mType(LST_STRING), mInteger(0), mFP(0.f), mKey(NULL), mString(NULL), mVec(), mQuat(), mListp(NULL)
371 {
372 if (!string)
373 {
374 mString = new char[1];
375 mString[0] = 0;
376 }
377 else
378 {
379 mString = new char[strlen(string) + 1];
380 strcpy(mString, string);
381 }
382 }
383
384 LLScriptLibData(LLVector3 &vec) : mType(LST_VECTOR), mInteger(0), mFP(0.f), mKey(NULL), mString(NULL), mVec(vec), mQuat(), mListp(NULL)
385 {
386 }
387
388 LLScriptLibData(LLQuaternion &quat) : mType(LST_QUATERNION), mInteger(0), mFP(0.f), mKey(NULL), mString(NULL), mVec(), mQuat(quat), mListp(NULL)
389 {
390 }
391
392 ~LLScriptLibData()
393 {
394 delete mListp;
395 delete [] mKey;
396 delete [] mString;
397 }
398
399};
400
401#endif
diff --git a/linden/indra/lscript/lscript_library/lscript_alloc.cpp b/linden/indra/lscript/lscript_library/lscript_alloc.cpp
new file mode 100644
index 0000000..978d7f2
--- /dev/null
+++ b/linden/indra/lscript/lscript_library/lscript_alloc.cpp
@@ -0,0 +1,1121 @@
1/**
2 * @file lscript_alloc.cpp
3 * @brief general heap management for scripting system
4 *
5 * Copyright (c) 2002-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28// #define at top of file accelerates gcc compiles
29// Under gcc 2.9, the manual is unclear if comments can appear above #ifndef
30// Under gcc 3, the manual explicitly states comments can appear above the #ifndef
31
32#include "linden_common.h"
33
34#include "lscript_alloc.h"
35
36// supported data types
37
38// basic types
39// integer 4 bytes of integer data
40// float 4 bytes of float data
41// string data null terminated 1 byte string
42// key data null terminated 1 byte string
43// vector data 12 bytes of 3 floats
44// quaternion data 16 bytes of 4 floats
45
46// list type
47// list data 4 bytes of number of entries followed by pointer
48
49// string pointer 4 bytes of address of string data on the heap (only used in list data)
50// key pointer 4 bytes of address of key data on the heap (only used in list data)
51
52// heap format
53//
54// 4 byte offset to next block (in bytes)
55// 1 byte of type of variable or empty
56// 2 bytes of reference count
57// nn bytes of data
58
59void reset_hp_to_safe_spot(const U8 *buffer)
60{
61 set_register((U8 *)buffer, LREG_HP, TOP_OF_MEMORY);
62}
63
64// create a heap from the HR to TM
65BOOL lsa_create_heap(U8 *heap_start, S32 size)
66{
67 LLScriptAllocEntry entry(size, LST_NULL);
68
69 S32 position = 0;
70
71 alloc_entry2bytestream(heap_start, position, entry);
72
73 return TRUE;
74}
75
76S32 lsa_heap_top(U8 *heap_start, S32 maxtop)
77{
78 S32 offset = 0;
79 LLScriptAllocEntry entry;
80 bytestream2alloc_entry(entry, heap_start, offset);
81
82 while (offset + entry.mSize < maxtop)
83 {
84 offset += entry.mSize;
85 bytestream2alloc_entry(entry, heap_start, offset);
86 }
87 return offset + entry.mSize;
88}
89
90
91// adding to heap
92// if block is empty
93// if block is at least block size + 4 larger than data
94// split block
95// insert data into first part
96// return address
97// else
98// insert data into block
99// return address
100// else
101// if next block is >= SP
102// set Stack-Heap collision
103// return NULL
104// if next block is empty
105// merge next block with current block
106// go to start of algorithm
107// else
108// move to next block
109// go to start of algorithm
110
111S32 lsa_heap_add_data(U8 *buffer, LLScriptLibData *data, S32 heapsize, BOOL b_delete)
112{
113 if (get_register(buffer, LREG_FR))
114 return 1;
115 LLScriptAllocEntry entry, nextentry;
116 S32 hr = get_register(buffer, LREG_HR);
117 S32 hp = get_register(buffer, LREG_HP);
118 S32 current_offset, next_offset, offset = hr;
119 S32 size = 0;
120
121 switch(data->mType)
122 {
123 case LST_INTEGER:
124 size = 4;
125 break;
126 case LST_FLOATINGPOINT:
127 size = 4;
128 break;
129 case LST_KEY:
130 size = (S32)strlen(data->mKey) + 1;
131 break;
132 case LST_STRING:
133 size = (S32)strlen(data->mString) + 1;
134 break;
135 case LST_LIST:
136 // list data 4 bytes of number of entries followed by number of pointer
137 size = 4 + 4*data->getListLength();
138 if (data->checkForMultipleLists())
139 {
140 set_fault(buffer, LSRF_NESTING_LISTS);
141 }
142 break;
143 case LST_VECTOR:
144 size = 12;
145 break;
146 case LST_QUATERNION:
147 size = 16;
148 break;
149 default:
150 break;
151 }
152
153 current_offset = offset;
154 bytestream2alloc_entry(entry, buffer, offset);
155
156 do
157 {
158 hp = get_register(buffer, LREG_HP);
159 if (!entry.mType)
160 {
161 if (entry.mSize >= size + SIZEOF_SCRIPT_ALLOC_ENTRY + 4)
162 {
163 offset = current_offset;
164 lsa_split_block(buffer, offset, size, entry);
165 entry.mType = data->mType;
166 entry.mSize = size;
167 entry.mReferenceCount = 1;
168 offset = current_offset;
169 alloc_entry2bytestream(buffer, offset, entry);
170 lsa_insert_data(buffer, offset, data, entry, heapsize);
171 hp = get_register(buffer, LREG_HP);
172 S32 new_hp = current_offset + size + 2*SIZEOF_SCRIPT_ALLOC_ENTRY;
173 if (new_hp >= hr + heapsize)
174 {
175 break;
176 }
177 if (new_hp > hp)
178 {
179 set_register(buffer, LREG_HP, new_hp);
180 hp = get_register(buffer, LREG_HP);
181 }
182 if (b_delete)
183 delete data;
184 // this bit of nastiness is to get around that code paths to local variables can result in lack of initialization
185 // and function clean up of ref counts isn't based on scope (a mistake, I know)
186 if (current_offset <= hp)
187 return current_offset - hr + 1;
188 else
189 return hp - hr + 1;
190 }
191 else if (entry.mSize >= size)
192 {
193 entry.mType = data->mType;
194 entry.mReferenceCount = 1;
195 offset = current_offset;
196 alloc_entry2bytestream(buffer, offset, entry);
197 lsa_insert_data(buffer, offset, data, entry, heapsize);
198 hp = get_register(buffer, LREG_HP);
199 if (b_delete)
200 delete data;
201 // this bit of nastiness is to get around that code paths to local variables can result in lack of initialization
202 // and function clean up of ref counts isn't based on scope (a mistake, I know)
203 return current_offset - hr + 1;
204 }
205 }
206 offset += entry.mSize;
207 if (offset < hr + heapsize)
208 {
209 next_offset = offset;
210 bytestream2alloc_entry(nextentry, buffer, offset);
211 if (!nextentry.mType && !entry.mType)
212 {
213 entry.mSize += nextentry.mSize + SIZEOF_SCRIPT_ALLOC_ENTRY;
214 offset = current_offset;
215 alloc_entry2bytestream(buffer, offset, entry);
216 }
217 else
218 {
219 current_offset = next_offset;
220 entry = nextentry;
221 }
222
223 // this works whether we are bumping out or coming in
224 S32 new_hp = current_offset + size + 2*SIZEOF_SCRIPT_ALLOC_ENTRY;
225
226 // make sure we aren't about to be stupid
227 if (new_hp >= hr + heapsize)
228 {
229 break;
230 }
231 if (new_hp > hp)
232 {
233 set_register(buffer, LREG_HP, new_hp);
234 hp = get_register(buffer, LREG_HP);
235 }
236 }
237 else
238 {
239 break;
240 }
241 } while (1);
242 set_fault(buffer, LSRF_STACK_HEAP_COLLISION);
243 reset_hp_to_safe_spot(buffer);
244 if (b_delete)
245 delete data;
246 return 0;
247}
248
249// split block
250// set offset to point to new block
251// set offset of new block to point to original offset - block size - data size
252// set new block to empty
253// set new block reference count to 0
254void lsa_split_block(U8 *buffer, S32 &offset, S32 size, LLScriptAllocEntry &entry)
255{
256 if (get_register(buffer, LREG_FR))
257 return;
258 LLScriptAllocEntry newentry;
259
260 newentry.mSize = entry.mSize - SIZEOF_SCRIPT_ALLOC_ENTRY - size;
261 entry.mSize -= newentry.mSize + SIZEOF_SCRIPT_ALLOC_ENTRY;
262
263 alloc_entry2bytestream(buffer, offset, entry);
264 S32 orig_offset = offset + size;
265 alloc_entry2bytestream(buffer, orig_offset, newentry);
266}
267
268// insert data
269// if data is non-list type
270// set type to basic type, set reference count to 1, copy data, return address
271// else
272// set type to list data type, set reference count to 1
273// save length of list
274// for each list entry
275// insert data
276// return address
277
278void lsa_insert_data(U8 *buffer, S32 &offset, LLScriptLibData *data, LLScriptAllocEntry &entry, S32 heapsize)
279{
280 if (get_register(buffer, LREG_FR))
281 return;
282 if (data->mType != LST_LIST)
283 {
284 switch(data->mType)
285 {
286 case LST_INTEGER:
287 integer2bytestream(buffer, offset, data->mInteger);
288 break;
289 case LST_FLOATINGPOINT:
290 float2bytestream(buffer, offset, data->mFP);
291 break;
292 case LST_KEY:
293 char2bytestream(buffer, offset, data->mKey);
294 break;
295 case LST_STRING:
296 char2bytestream(buffer, offset, data->mString);
297 break;
298 case LST_VECTOR:
299 vector2bytestream(buffer, offset, data->mVec);
300 break;
301 case LST_QUATERNION:
302 quaternion2bytestream(buffer, offset, data->mQuat);
303 break;
304 default:
305 break;
306 }
307 }
308 else
309 {
310 // store length of list
311 integer2bytestream(buffer, offset, data->getListLength());
312 data = data->mListp;
313 while(data)
314 {
315 // store entry and then store address if valid
316 S32 address = lsa_heap_add_data(buffer, data, heapsize, FALSE);
317 integer2bytestream(buffer, offset, address);
318 data = data->mListp;
319 }
320 }
321}
322
323S32 lsa_create_data_block(U8 **buffer, LLScriptLibData *data, S32 base_offset)
324{
325 S32 offset = 0;
326 S32 size = 0;
327
328 LLScriptAllocEntry entry;
329
330 if (!data)
331 {
332 entry.mType = LST_NULL;
333 entry.mReferenceCount = 0;
334 entry.mSize = MAX_HEAP_SIZE;
335 size = SIZEOF_SCRIPT_ALLOC_ENTRY;
336 *buffer = new U8[size];
337 alloc_entry2bytestream(*buffer, offset, entry);
338 return size;
339 }
340
341 entry.mType = data->mType;
342 entry.mReferenceCount = 1;
343
344 if (data->mType != LST_LIST)
345 {
346 if ( (data->mType != LST_STRING)
347 &&(data->mType != LST_KEY))
348 {
349 size = LSCRIPTDataSize[data->mType];
350 }
351 else
352 {
353 if (data->mType == LST_STRING)
354 {
355 if (data->mString)
356 {
357 size = (S32)strlen(data->mString) + 1;
358 }
359 else
360 {
361 size = 1;
362 }
363 }
364 if (data->mType == LST_KEY)
365 {
366 if (data->mKey)
367 {
368 size = (S32)strlen(data->mKey) + 1;
369 }
370 else
371 {
372 size = 1;
373 }
374 }
375 }
376 entry.mSize = size;
377 size += SIZEOF_SCRIPT_ALLOC_ENTRY;
378 *buffer = new U8[size];
379 alloc_entry2bytestream(*buffer, offset, entry);
380
381 switch(data->mType)
382 {
383 case LST_INTEGER:
384 integer2bytestream(*buffer, offset, data->mInteger);
385 break;
386 case LST_FLOATINGPOINT:
387 float2bytestream(*buffer, offset, data->mFP);
388 break;
389 case LST_KEY:
390 if (data->mKey)
391 char2bytestream(*buffer, offset, data->mKey);
392 else
393 byte2bytestream(*buffer, offset, 0);
394 break;
395 case LST_STRING:
396 if (data->mString)
397 char2bytestream(*buffer, offset, data->mString);
398 else
399 byte2bytestream(*buffer, offset, 0);
400 break;
401 case LST_VECTOR:
402 vector2bytestream(*buffer, offset, data->mVec);
403 break;
404 case LST_QUATERNION:
405 quaternion2bytestream(*buffer, offset, data->mQuat);
406 break;
407 default:
408 break;
409 }
410 }
411 else
412 {
413 U8 *listbuf;
414 S32 length = data->getListLength();
415 size = 4 * length + 4;
416 entry.mSize = size;
417
418 size += SIZEOF_SCRIPT_ALLOC_ENTRY;
419 *buffer = new U8[size];
420
421 alloc_entry2bytestream(*buffer, offset, entry);
422 // store length of list
423 integer2bytestream(*buffer, offset, length);
424 data = data->mListp;
425 while(data)
426 {
427 // this bit of nastiness is to get around that code paths to local variables can result in lack of initialization
428 // and function clean up of ref counts isn't based on scope (a mistake, I know)
429 integer2bytestream(*buffer, offset, size + base_offset + 1);
430
431 S32 listsize = lsa_create_data_block(&listbuf, data, base_offset + size);
432 if (listsize)
433 {
434 U8 *tbuff = new U8[size + listsize];
435 memcpy(tbuff, *buffer, size);
436 memcpy(tbuff + size, listbuf, listsize);
437 size += listsize;
438 delete [] *buffer;
439 delete [] listbuf;
440 *buffer = tbuff;
441 }
442 data = data->mListp;
443 }
444 }
445 return size;
446}
447
448// increase reference count
449// increase reference count by 1
450
451void lsa_increase_ref_count(U8 *buffer, S32 offset)
452{
453 if (get_register(buffer, LREG_FR))
454 return;
455 // this bit of nastiness is to get around that code paths to local variables can result in lack of initialization
456 // and function clean up of ref counts isn't based on scope (a mistake, I know)
457 offset += get_register(buffer, LREG_HR) - 1;
458 if ( (offset < get_register(buffer, LREG_HR))
459 ||(offset >= get_register(buffer, LREG_HP)))
460 {
461 set_fault(buffer, LSRF_BOUND_CHECK_ERROR);
462 return;
463 }
464 S32 orig_offset = offset;
465 LLScriptAllocEntry entry;
466 bytestream2alloc_entry(entry, buffer, offset);
467
468 entry.mReferenceCount++;
469
470 alloc_entry2bytestream(buffer, orig_offset, entry);
471}
472
473// decrease reference count
474// decrease reference count by 1
475// if reference count == 0
476// set type to empty
477
478void lsa_decrease_ref_count(U8 *buffer, S32 offset)
479{
480 if (get_register(buffer, LREG_FR))
481 return;
482 // this bit of nastiness is to get around that code paths to local variables can result in lack of initialization
483 // and function clean up of ref counts isn't based on scope (a mistake, I know)
484 offset += get_register(buffer, LREG_HR) - 1;
485 if ( (offset < get_register(buffer, LREG_HR))
486 ||(offset >= get_register(buffer, LREG_HP)))
487 {
488 set_fault(buffer, LSRF_BOUND_CHECK_ERROR);
489 return;
490 }
491 S32 orig_offset = offset;
492 LLScriptAllocEntry entry;
493 bytestream2alloc_entry(entry, buffer, offset);
494
495 entry.mReferenceCount--;
496
497 if (entry.mReferenceCount < 0)
498 {
499 entry.mReferenceCount = 0;
500 set_fault(buffer, LSRF_HEAP_ERROR);
501 }
502 else if (!entry.mReferenceCount)
503 {
504 if (entry.mType == LST_LIST)
505 {
506 S32 i, num = bytestream2integer(buffer, offset);
507 for (i = 0; i < num; i++)
508 {
509 S32 list_offset = bytestream2integer(buffer, offset);
510 lsa_decrease_ref_count(buffer, list_offset);
511 }
512 }
513 entry.mType = LST_NULL;
514 }
515
516 alloc_entry2bytestream(buffer, orig_offset, entry);
517}
518
519char gLSAStringRead[16384];
520
521
522LLScriptLibData *lsa_get_data(U8 *buffer, S32 &offset, BOOL b_dec_ref)
523{
524 if (get_register(buffer, LREG_FR))
525 return (new LLScriptLibData);
526 S32 orig_offset = offset;
527 // this bit of nastiness is to get around that code paths to local variables can result in lack of initialization
528 // and function clean up of ref counts isn't based on scope (a mistake, I know)
529 offset += get_register(buffer, LREG_HR) - 1;
530 if ( (offset < get_register(buffer, LREG_HR))
531 ||(offset >= get_register(buffer, LREG_HP)))
532 {
533 set_fault(buffer, LSRF_BOUND_CHECK_ERROR);
534 return (new LLScriptLibData);
535 }
536 LLScriptAllocEntry entry;
537 bytestream2alloc_entry(entry, buffer, offset);
538
539 LLScriptLibData *retval = new LLScriptLibData;
540
541 if (!entry.mType)
542 {
543 set_fault(buffer, LSRF_HEAP_ERROR);
544 return retval;
545 }
546
547 retval->mType = (LSCRIPTType)entry.mType;
548 if (entry.mType != LST_LIST)
549 {
550 switch(entry.mType)
551 {
552 case LST_INTEGER:
553 retval->mInteger = bytestream2integer(buffer, offset);
554 break;
555 case LST_FLOATINGPOINT:
556 retval->mFP = bytestream2float(buffer, offset);
557 break;
558 case LST_KEY:
559 bytestream2char(gLSAStringRead, buffer, offset);
560 retval->mKey = new char[strlen(gLSAStringRead) + 1];
561 strcpy(retval->mKey, gLSAStringRead);
562 break;
563 case LST_STRING:
564 bytestream2char(gLSAStringRead, buffer, offset);
565 retval->mString = new char[strlen(gLSAStringRead) + 1];
566 strcpy(retval->mString, gLSAStringRead);
567 break;
568 case LST_VECTOR:
569 bytestream2vector(retval->mVec, buffer, offset);
570 break;
571 case LST_QUATERNION:
572 bytestream2quaternion(retval->mQuat, buffer, offset);
573 break;
574 default:
575 break;
576 }
577 }
578 else
579 {
580 // get length of list
581 S32 i, length = bytestream2integer(buffer, offset);
582 LLScriptLibData *tip = retval;
583
584 for (i = 0; i < length; i++)
585 {
586 S32 address = bytestream2integer(buffer, offset);
587 tip->mListp = lsa_get_data(buffer, address, FALSE);
588 tip = tip->mListp;
589 }
590 }
591 if (retval->checkForMultipleLists())
592 {
593 set_fault(buffer, LSRF_NESTING_LISTS);
594 }
595 if (b_dec_ref)
596 {
597 lsa_decrease_ref_count(buffer, orig_offset);
598 }
599 return retval;
600}
601
602LLScriptLibData *lsa_get_list_ptr(U8 *buffer, S32 &offset, BOOL b_dec_ref)
603{
604 if (get_register(buffer, LREG_FR))
605 return (new LLScriptLibData);
606 S32 orig_offset = offset;
607 // this bit of nastiness is to get around that code paths to local variables can result in lack of initialization
608 // and function clean up of ref counts isn't based on scope (a mistake, I know)
609 offset += get_register(buffer, LREG_HR) - 1;
610 if ( (offset < get_register(buffer, LREG_HR))
611 ||(offset >= get_register(buffer, LREG_HP)))
612 {
613 set_fault(buffer, LSRF_BOUND_CHECK_ERROR);
614 return (new LLScriptLibData);
615 }
616 LLScriptAllocEntry entry;
617 bytestream2alloc_entry(entry, buffer, offset);
618
619 if (!entry.mType)
620 {
621 set_fault(buffer, LSRF_HEAP_ERROR);
622 return NULL;
623 }
624
625 LLScriptLibData base, *tip = &base;
626
627 if (entry.mType != LST_LIST)
628 {
629 return NULL;
630 }
631 else
632 {
633 // get length of list
634 S32 i, length = bytestream2integer(buffer, offset);
635
636 for (i = 0; i < length; i++)
637 {
638 S32 address = bytestream2integer(buffer, offset);
639 tip->mListp = lsa_get_data(buffer, address, FALSE);
640 tip = tip->mListp;
641 }
642 }
643 if (b_dec_ref)
644 {
645 lsa_decrease_ref_count(buffer, orig_offset);
646 }
647 tip = base.mListp;
648 base.mListp = NULL;
649 return tip;
650}
651
652S32 lsa_cat_strings(U8 *buffer, S32 offset1, S32 offset2, S32 heapsize)
653{
654 if (get_register(buffer, LREG_FR))
655 return 0;
656 LLScriptLibData *string1;
657 LLScriptLibData *string2;
658 if (offset1 != offset2)
659 {
660 string1 = lsa_get_data(buffer, offset1, TRUE);
661 string2 = lsa_get_data(buffer, offset2, TRUE);
662 }
663 else
664 {
665 string1 = lsa_get_data(buffer, offset1, TRUE);
666 string2 = lsa_get_data(buffer, offset2, TRUE);
667 }
668
669 if ( (!string1)
670 ||(!string2))
671 {
672 set_fault(buffer, LSRF_HEAP_ERROR);
673 delete string1;
674 delete string2;
675 return 0;
676 }
677
678 char *test1 = NULL, *test2 = NULL;
679
680 if (string1->mType == LST_STRING)
681 {
682 test1 = string1->mString;
683 }
684 else if (string1->mType == LST_KEY)
685 {
686 test1 = string1->mKey;
687 }
688 if (string2->mType == LST_STRING)
689 {
690 test2 = string2->mString;
691 }
692 else if (string2->mType == LST_KEY)
693 {
694 test2 = string2->mKey;
695 }
696
697 if ( (!test1)
698 ||(!test2))
699 {
700 set_fault(buffer, LSRF_HEAP_ERROR);
701 delete string1;
702 delete string2;
703 return 0;
704 }
705
706 S32 size = (S32)strlen(test1) + (S32)strlen(test2) + 1;
707
708 LLScriptLibData *string3 = new LLScriptLibData;
709 string3->mType = LST_STRING;
710 string3->mString = new char[size];
711 strcpy(string3->mString, test1);
712 strcat(string3->mString, test2);
713
714 delete string1;
715 delete string2;
716
717 return lsa_heap_add_data(buffer, string3, heapsize, TRUE);
718}
719
720S32 lsa_cmp_strings(U8 *buffer, S32 offset1, S32 offset2)
721{
722 if (get_register(buffer, LREG_FR))
723 return 0;
724 LLScriptLibData *string1;
725 LLScriptLibData *string2;
726
727 string1 = lsa_get_data(buffer, offset1, TRUE);
728 string2 = lsa_get_data(buffer, offset2, TRUE);
729
730 if ( (!string1)
731 ||(!string2))
732 {
733 set_fault(buffer, LSRF_HEAP_ERROR);
734 delete string1;
735 delete string2;
736 return 0;
737 }
738
739 char *test1 = NULL, *test2 = NULL;
740
741 if (string1->mType == LST_STRING)
742 {
743 test1 = string1->mString;
744 }
745 else if (string1->mType == LST_KEY)
746 {
747 test1 = string1->mKey;
748 }
749 if (string2->mType == LST_STRING)
750 {
751 test2 = string2->mString;
752 }
753 else if (string2->mType == LST_KEY)
754 {
755 test2 = string2->mKey;
756 }
757
758 if ( (!test1)
759 ||(!test2))
760 {
761 set_fault(buffer, LSRF_HEAP_ERROR);
762 delete string1;
763 delete string2;
764 return 0;
765 }
766 S32 retval = strcmp(test1, test2);
767
768 delete string1;
769 delete string2;
770
771 return retval;
772}
773
774void lsa_print_heap(U8 *buffer)
775{
776 S32 offset = get_register(buffer, LREG_HR);
777 S32 readoffset;
778 S32 ivalue;
779 F32 fpvalue;
780 LLVector3 vvalue;
781 LLQuaternion qvalue;
782 char string[4096];
783
784 LLScriptAllocEntry entry;
785
786 bytestream2alloc_entry(entry, buffer, offset);
787
788 printf("HP: [0x%X]\n", get_register(buffer, LREG_HP));
789 printf("==========\n");
790
791 while (offset + entry.mSize < MAX_HEAP_SIZE)
792 {
793 printf("[0x%X] ", offset);
794 printf("%s ", LSCRIPTTypeNames[entry.mType]);
795 printf("Ref Count: %d ", entry.mReferenceCount);
796 printf("Size: %d = ", entry.mSize);
797
798 readoffset = offset;
799
800 switch(entry.mType)
801 {
802 case LST_INTEGER:
803 ivalue = bytestream2integer(buffer, readoffset);
804 printf("%d\n", ivalue);
805 break;
806 case LST_FLOATINGPOINT:
807 fpvalue = bytestream2float(buffer, readoffset);
808 printf("%f\n", fpvalue);
809 break;
810 case LST_STRING:
811 bytestream2char(string, buffer, readoffset);
812 printf("%s\n", string);
813 break;
814 case LST_KEY:
815 bytestream2char(string, buffer, readoffset);
816 printf("%s\n", string);
817 break;
818 case LST_VECTOR:
819 bytestream2vector(vvalue, buffer, readoffset);
820 printf("< %f, %f, %f >\n", vvalue.mV[VX], vvalue.mV[VY], vvalue.mV[VZ]);
821 break;
822 case LST_QUATERNION:
823 bytestream2quaternion(qvalue, buffer, readoffset);
824 printf("< %f, %f, %f, %f >\n", qvalue.mQ[VX], qvalue.mQ[VY], qvalue.mQ[VZ], qvalue.mQ[VS]);
825 break;
826 case LST_LIST:
827 ivalue = bytestream2integer(buffer, readoffset);
828 printf("%d\n", ivalue);
829 break;
830 default:
831 printf("\n");
832 break;
833 }
834 offset += entry.mSize;
835 bytestream2alloc_entry(entry, buffer, offset);
836 }
837 printf("[0x%X] ", offset);
838 printf("%s ", LSCRIPTTypeNames[entry.mType]);
839 printf("Ref Count: %d ", entry.mReferenceCount);
840 printf("Size: %d\n", entry.mSize);
841 printf("==========\n");
842}
843
844void lsa_fprint_heap(U8 *buffer, FILE *fp)
845{
846 S32 offset = get_register(buffer, LREG_HR);
847 S32 readoffset;
848 S32 ivalue;
849 F32 fpvalue;
850 LLVector3 vvalue;
851 LLQuaternion qvalue;
852 char string[4096];
853
854 LLScriptAllocEntry entry;
855
856 bytestream2alloc_entry(entry, buffer, offset);
857
858 while (offset + entry.mSize < MAX_HEAP_SIZE)
859 {
860 fprintf(fp, "[0x%X] ", offset);
861 fprintf(fp, "%s ", LSCRIPTTypeNames[entry.mType]);
862 fprintf(fp, "Ref Count: %d ", entry.mReferenceCount);
863 fprintf(fp, "Size: %d = ", entry.mSize);
864
865 readoffset = offset;
866
867 switch(entry.mType)
868 {
869 case LST_INTEGER:
870 ivalue = bytestream2integer(buffer, readoffset);
871 fprintf(fp, "%d\n", ivalue);
872 break;
873 case LST_FLOATINGPOINT:
874 fpvalue = bytestream2float(buffer, readoffset);
875 fprintf(fp, "%f\n", fpvalue);
876 break;
877 case LST_STRING:
878 bytestream2char(string, buffer, readoffset);
879 fprintf(fp, "%s\n", string);
880 break;
881 case LST_KEY:
882 bytestream2char(string, buffer, readoffset);
883 fprintf(fp, "%s\n", string);
884 break;
885 case LST_VECTOR:
886 bytestream2vector(vvalue, buffer, readoffset);
887 fprintf(fp, "< %f, %f, %f >\n", vvalue.mV[VX], vvalue.mV[VY], vvalue.mV[VZ]);
888 break;
889 case LST_QUATERNION:
890 bytestream2quaternion(qvalue, buffer, readoffset);
891 fprintf(fp, "< %f, %f, %f, %f >\n", qvalue.mQ[VX], qvalue.mQ[VY], qvalue.mQ[VZ], qvalue.mQ[VS]);
892 break;
893 case LST_LIST:
894 ivalue = bytestream2integer(buffer, readoffset);
895 fprintf(fp, "%d\n", ivalue);
896 break;
897 default:
898 fprintf(fp, "\n");
899 break;
900 }
901 offset += entry.mSize;
902 bytestream2alloc_entry(entry, buffer, offset);
903 }
904 fprintf(fp, "[0x%X] ", offset);
905 fprintf(fp, "%s ", LSCRIPTTypeNames[entry.mType]);
906 fprintf(fp, "Ref Count: %d ", entry.mReferenceCount);
907 fprintf(fp, "Size: %d", entry.mSize);
908 fprintf(fp, "\n");
909}
910
911S32 lsa_cat_lists(U8 *buffer, S32 offset1, S32 offset2, S32 heapsize)
912{
913 if (get_register(buffer, LREG_FR))
914 return 0;
915 LLScriptLibData *list1;
916 LLScriptLibData *list2;
917 if (offset1 != offset2)
918 {
919 list1 = lsa_get_data(buffer, offset1, TRUE);
920 list2 = lsa_get_data(buffer, offset2, TRUE);
921 }
922 else
923 {
924 list1 = lsa_get_data(buffer, offset1, TRUE);
925 list2 = lsa_get_data(buffer, offset2, TRUE);
926 }
927
928 if ( (!list1)
929 ||(!list2))
930 {
931 set_fault(buffer, LSRF_HEAP_ERROR);
932 delete list1;
933 delete list2;
934 return 0;
935 }
936
937 if ( (list1->mType != LST_LIST)
938 ||(list2->mType != LST_LIST))
939 {
940 set_fault(buffer, LSRF_HEAP_ERROR);
941 delete list1;
942 delete list2;
943 return 0;
944 }
945
946 LLScriptLibData *runner = list1;
947
948 while (runner->mListp)
949 {
950 runner = runner->mListp;
951 }
952
953 runner->mListp = list2->mListp;
954
955 list2->mListp = NULL;
956
957 delete list2;
958
959 return lsa_heap_add_data(buffer, list1, heapsize, TRUE);
960}
961
962
963S32 lsa_cmp_lists(U8 *buffer, S32 offset1, S32 offset2)
964{
965 if (get_register(buffer, LREG_FR))
966 return 0;
967 LLScriptLibData *list1;
968 LLScriptLibData *list2;
969 if (offset1 != offset2)
970 {
971 list1 = lsa_get_data(buffer, offset1, TRUE);
972 list2 = lsa_get_data(buffer, offset2, TRUE);
973 }
974 else
975 {
976 list1 = lsa_get_data(buffer, offset1, FALSE);
977 list2 = lsa_get_data(buffer, offset2, TRUE);
978 }
979
980 if ( (!list1)
981 ||(!list2))
982 {
983 set_fault(buffer, LSRF_HEAP_ERROR);
984 delete list1;
985 delete list2;
986 return 0;
987 }
988
989 if ( (list1->mType != LST_LIST)
990 ||(list2->mType != LST_LIST))
991 {
992 set_fault(buffer, LSRF_HEAP_ERROR);
993 delete list1;
994 delete list2;
995 return 0;
996 }
997
998 S32 length1 = list1->getListLength();
999 S32 length2 = list2->getListLength();
1000
1001 if (length1 != length2)
1002 {
1003 return length1 - length2;
1004 }
1005
1006 LLScriptLibData *runner1 = list1;
1007 LLScriptLibData *runner2 = list2;
1008
1009 S32 count = 0;
1010
1011 while (runner1)
1012 {
1013 if (runner1->mType != runner2->mType)
1014 return count;
1015
1016 switch(runner1->mType)
1017 {
1018 case LST_INTEGER:
1019 if (runner1->mInteger != runner2->mInteger)
1020 return count;
1021 break;
1022 case LST_FLOATINGPOINT:
1023 if (runner1->mFP != runner2->mFP)
1024 return count;
1025 break;
1026 case LST_KEY:
1027 if (strcmp(runner1->mKey, runner2->mKey))
1028 return count;
1029 break;
1030 case LST_STRING:
1031 if (strcmp(runner1->mString, runner2->mString))
1032 return count;
1033 break;
1034 case LST_VECTOR:
1035 if (runner1->mVec != runner2->mVec)
1036 return count;
1037 case LST_QUATERNION:
1038 if (runner1->mQuat != runner2->mQuat)
1039 return count;
1040 break;
1041 default:
1042 break;
1043 }
1044
1045 runner1 = runner1->mListp;
1046 runner2 = runner2->mListp;
1047 }
1048
1049 delete list1;
1050 delete list2;
1051 return 0;
1052}
1053
1054
1055S32 lsa_preadd_lists(U8 *buffer, LLScriptLibData *data, S32 offset2, S32 heapsize)
1056{
1057 if (get_register(buffer, LREG_FR))
1058 return 0;
1059 LLScriptLibData *list2 = lsa_get_data(buffer, offset2, TRUE);
1060
1061 if (!list2)
1062 {
1063 set_fault(buffer, LSRF_HEAP_ERROR);
1064 delete list2;
1065 return 0;
1066 }
1067
1068 if (list2->mType != LST_LIST)
1069 {
1070 set_fault(buffer, LSRF_HEAP_ERROR);
1071 delete list2;
1072 return 0;
1073 }
1074
1075 LLScriptLibData *runner = data->mListp;
1076
1077 while (runner->mListp)
1078 {
1079 runner = runner->mListp;
1080 }
1081
1082
1083 runner->mListp = list2->mListp;
1084 list2->mListp = data->mListp;
1085
1086 return lsa_heap_add_data(buffer, list2, heapsize, TRUE);
1087}
1088
1089
1090S32 lsa_postadd_lists(U8 *buffer, S32 offset1, LLScriptLibData *data, S32 heapsize)
1091{
1092 if (get_register(buffer, LREG_FR))
1093 return 0;
1094 LLScriptLibData *list1 = lsa_get_data(buffer, offset1, TRUE);
1095
1096 if (!list1)
1097 {
1098 set_fault(buffer, LSRF_HEAP_ERROR);
1099 delete list1;
1100 return 0;
1101 }
1102
1103 if (list1->mType != LST_LIST)
1104 {
1105 set_fault(buffer, LSRF_HEAP_ERROR);
1106 delete list1;
1107 return 0;
1108 }
1109
1110 LLScriptLibData *runner = list1;
1111
1112 while (runner->mListp)
1113 {
1114 runner = runner->mListp;
1115 }
1116
1117 runner->mListp = data->mListp;
1118
1119 return lsa_heap_add_data(buffer, list1, heapsize, TRUE);
1120}
1121
diff --git a/linden/indra/lscript/lscript_library/lscript_export.cpp b/linden/indra/lscript/lscript_library/lscript_export.cpp
new file mode 100644
index 0000000..d0a23aa
--- /dev/null
+++ b/linden/indra/lscript/lscript_library/lscript_export.cpp
@@ -0,0 +1,27 @@
1/**
2 * @file lscript_export.cpp
3 * @brief export interface class
4 *
5 * Copyright (c) 2002-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
diff --git a/linden/indra/lscript/lscript_library/lscript_library.cpp b/linden/indra/lscript/lscript_library/lscript_library.cpp
new file mode 100644
index 0000000..098c836
--- /dev/null
+++ b/linden/indra/lscript/lscript_library/lscript_library.cpp
@@ -0,0 +1,576 @@
1/**
2 * @file lscript_library.cpp
3 * @brief external library interface
4 *
5 * Copyright (c) 2002-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28// *WARNING*
29// When adding functions, they <b>MUST</b> be appended to the end of
30// the init() method. The init() associates the name with a number,
31// which is then serialized into the bytecode. Inserting a new
32// function in the middle will lead to many sim crashes. Phoenix 2006-04-10.
33
34#include "linden_common.h"
35
36#include "lscript_library.h"
37
38LLScriptLibrary::LLScriptLibrary()
39: mNextNumber(0), mFunctions(NULL)
40{
41 init();
42}
43
44LLScriptLibrary::~LLScriptLibrary()
45{
46 S32 i;
47 for (i = 0; i < mNextNumber; i++)
48 {
49 delete mFunctions[i];
50 mFunctions[i] = NULL;
51 }
52 delete [] mFunctions;
53}
54
55void dummy_func(LLScriptLibData *retval, LLScriptLibData *args, const LLUUID &id)
56{
57}
58
59void LLScriptLibrary::init()
60{
61 // IF YOU ADD NEW SCRIPT CALLS, YOU MUST PUT THEM AT THE END OF THIS LIST.
62 // Otherwise the bytecode numbers for each call will be wrong, and all
63 // existing scripts will crash.
64
65 // energy, sleep, dummy_func, name, return type, parameters, help text, gods-only
66 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSin", "f", "f", "float llSin(float theta)\ntheta in radians"));
67 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llCos", "f", "f", "float llCos(float theta)\ntheta in radians"));
68 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llTan", "f", "f", "float llTan(float theta)\ntheta radians"));
69 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llAtan2", "f", "ff", "float llAtan2(float y, float x)"));
70 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSqrt", "f", "f", "float llSqrt(float val)\nreturns 0 and triggers a Math Error for imaginary results"));
71 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llPow", "f", "ff", "float llPow(float base, float exponent)\nreturns 0 and triggers Math Error for imaginary results"));
72 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llAbs", "i", "i", "integer llAbs(integer val)"));
73 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llFabs", "f", "f", "float llFabs(float val)"));
74 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llFrand", "f", "f", "float llFrand(float mag)\nreturns random number in range [0,mag)"));
75 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llFloor", "i", "f", "integer llFloor(float val)\nreturns largest integer value <= val"));
76 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llCeil", "i", "f", "integer llCeil(float val)\nreturns smallest integer value >= val"));
77 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llRound", "i", "f", "integer llRound(float val)\nreturns val rounded to the nearest integer"));
78 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llVecMag", "f", "v", "float llVecMag(vector v)\nreturns the magnitude of v"));
79 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llVecNorm", "v", "v", "vector llVecNorm(vector v)\nreturns the v normalized"));
80 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llVecDist", "f", "vv", "float llVecDist(vector v1, vector v2)\nreturns the 3D distance between v1 and v2"));
81 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llRot2Euler", "v", "q", "vector llRot2Euler(rotation q)\nreturns the Euler representation (roll, pitch, yaw) of q"));
82 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llEuler2Rot", "q", "v", "rotation llEuler2Rot(vector v)\nreturns the rotation representation of Euler Angles v"));
83 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llAxes2Rot", "q", "vvv", "rotation llAxes2Rot(vector fwd, vector left, vector up)\nreturns the rotation defined by the coordinate axes"));
84 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llRot2Fwd", "v", "q", "vector llRot2Fwd(rotation q)\nreturns the forward vector defined by q"));
85 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llRot2Left", "v", "q", "vector llRot2Left(rotation q)\nreturns the left vector defined by q"));
86 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llRot2Up", "v", "q", "vector llRot2Up(rotation q)\nreturns the up vector defined by q"));
87 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llRotBetween", "q", "vv", "rotation llRotBetween(vector v1, vector v2)\nreturns the rotation to rotate v1 to v2"));
88 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llWhisper", NULL, "is", "llWhisper(integer channel, string msg)\nwhispers msg on channel"));
89 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSay", NULL, "is", "llSay(integer channel, string msg)\nsays msg on channel"));
90 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llShout", NULL, "is", "llShout(integer channel, string msg)\nshouts msg on channel"));
91 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llListen", "i", "isks", "integer llListen(integer channel, string name, key id, string msg)\nsets a callback for msg on channel from name and id (name, id, and/or msg can be empty) and returns an identifier that can be used to deactivate or remove the listen"));
92 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llListenControl", NULL, "ii", "llListenControl(integer number, integer active)\nmakes a listen event callback active or inactive"));
93 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llListenRemove", NULL, "i", "llListenRemove(integer number)\nremoves listen event callback number"));
94 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSensor", NULL, "skiff", "llSensor(string name, key id, integer type, float range, float arc)\nPerforms a single scan for name and id with type (AGENT, ACTIVE, PASSIVE, and/or SCRIPTED) within range meters and arc radians of forward vector (name, id, and/or keytype can be empty or 0)"));
95 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSensorRepeat", NULL, "skifff", "llSensorRepeat(string name, key id, integer type, float range, float arc, float rate)\nsets a callback for name and id with type (AGENT, ACTIVE, PASSIVE, and/or SCRIPTED) within range meters and arc radians of forward vector (name, id, and/or keytype can be empty or 0) and repeats every rate seconds"));
96 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSensorRemove", NULL, NULL, "llSensorRemove()\nremoves sensor"));
97 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llDetectedName", "s", "i", "string llDetectedName(integer number)\nreturns the name of detected object number (returns empty string if number is not valid sensed object)"));
98 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llDetectedKey", "k", "i", "key llDetectedKey(integer number)\nreturns the key of detected object number (returns empty key if number is not valid sensed object)"));
99 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llDetectedOwner", "k", "i", "key llDetectedOwner(integer number)\nreturns the key of detected object's owner (returns empty key if number is not valid sensed object)"));
100 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llDetectedType", "i", "i", "integer llDetectedType(integer number)\nreturns the type (AGENT, ACTIVE, PASSIVE, SCRIPTED) of detected object (returns 0 if number is not valid sensed object)"));
101 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llDetectedPos", "v", "i", "vector llDetectedPos(integer number)\nreturns the position of detected object number (returns <0,0,0> if number is not valid sensed object)"));
102 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llDetectedVel", "v", "i", "vector llDetectedVel(integer number)\nreturns the velocity of detected object number (returns <0,0,0> if number is not valid sensed object)"));
103 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llDetectedGrab", "v", "i", "vector llDetectedGrab(integer number)\nreturns the grab offset of the user touching object (returns <0,0,0> if number is not valid sensed object)"));
104 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llDetectedRot", "q", "i", "rotation llDetectedRot(integer number)\nreturns the rotation of detected object number (returns <0,0,0,1> if number is not valid sensed object)"));
105 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llDetectedGroup", "i", "i", "integer llDetectedGroup(integer number)\nReturns TRUE if detected object is part of same group as owner"));
106 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llDetectedLinkNumber", "i", "i", "integer llDetectedLinkNumber(integer number)\nreturns the link position of the triggered event for touches and collisions only"));
107 addFunction(new LLScriptLibraryFunction(0.f, 0.f, dummy_func, "llDie", NULL, NULL, "llDie()\ndeletes the object"));
108 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGround", "f", "v", "float llGround(vector v)\nreturns the ground height below the object position + v"));
109 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llCloud", "f", "v", "float llCloud(vector v)\nreturns the cloud density at the object position + v"));
110 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llWind", "v", "v", "vector llWind(vector v)\nreturns the wind velocity at the object position + v"));
111 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetStatus", NULL, "ii", "llSetStatus(integer status, integer value)\nsets status (STATUS_PHYSICS, STATUS_PHANTOM, STATUS_BLOCK_GRAB,\nSTATUS_ROTATE_X, STATUS_ROTATE_Y, and/or STATUS_ROTATE_Z) to value"));
112 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetStatus", "i", "i", "integer llGetStatus(integer status)\ngets value of status (STATUS_PHYSICS, STATUS_PHANTOM, STATUS_BLOCK_GRAB,\nSTATUS_ROTATE_X, STATUS_ROTATE_Y, and/or STATUS_ROTATE_Z)"));
113 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetScale", NULL, "v", "llSetScale(vector scale)\nsets the scale"));
114 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetScale", "v", NULL, "vector llGetScale()\ngets the scale"));
115 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetColor", NULL, "vi", "llSetColor(vector color, integer face)\nsets the color"));
116 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetAlpha", "f", "i", "float llGetAlpha(integer face)\ngets the alpha"));
117 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetAlpha", NULL, "fi", "llSetAlpha(float alpha, integer face)\nsets the alpha"));
118 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetColor", "v", "i", "vector llGetColor(integer face)\ngets the color"));
119 addFunction(new LLScriptLibraryFunction(10.f, 0.2f, dummy_func, "llSetTexture", NULL, "si", "llSetTexture(string texture, integer face)\nsets the texture of face"));
120 addFunction(new LLScriptLibraryFunction(10.f, 0.2f, dummy_func, "llScaleTexture", NULL, "ffi", "llScaleTexture(float scales, float scalet, integer face)\nsets the texture s, t scales for the chosen face"));
121 addFunction(new LLScriptLibraryFunction(10.f, 0.2f, dummy_func, "llOffsetTexture", NULL, "ffi", "llOffsetTexture(float offsets, float offsett, integer face)\nsets the texture s, t offsets for the chosen face"));
122 addFunction(new LLScriptLibraryFunction(10.f, 0.2f, dummy_func, "llRotateTexture", NULL, "fi", "llOffsetTexture(float rotation, integer face)\nsets the texture rotation for the chosen face"));
123 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetTexture", "s", "i", "string llGetTexture(integer face)\ngets the texture of face (if it's a texture in the object inventory, otherwise the key in a string)"));
124 addFunction(new LLScriptLibraryFunction(10.f, 0.2f, dummy_func, "llSetPos", NULL, "v", "llSetPos(vector pos)\nsets the position (if the script isn't physical)"));
125 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetPos", "v", NULL, "vector llGetPos()\ngets the position (if the script isn't physical)"));
126 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetLocalPos", "v", NULL, "vector llGetLocalPos()\ngets the position relative to the root (if the script isn't physical)"));
127 addFunction(new LLScriptLibraryFunction(10.f, 0.2f, dummy_func, "llSetRot", NULL, "q", "llSetRot(rotation rot)\nsets the rotation (if the script isn't physical)"));
128 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetRot", "q", NULL, "rotation llGetRot()\ngets the rotation (if the script isn't physical)"));
129 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetLocalRot", "q", NULL, "rotation llGetLocalRot()\ngets the rotation local to the root (if the script isn't physical)"));
130 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetForce", NULL, "vi", "llSetForce(vector force, integer local)\nsets force on object, in local coords if local == TRUE (if the script is physical)"));
131 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetForce", "v", NULL, "vector llGetForce()\ngets the force (if the script is physical)"));
132 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llTarget", "i", "vf", "integer llTarget(vector position, float range)\nset positions within range of position as a target and return an ID for the target"));
133 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llTargetRemove", NULL, "i", "llTargetRemove(integer number)\nremoves target number"));
134 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llRotTarget", "i", "qf", "integer llRotTarget(rotation rot, float error)\nset rotations with error of rot as a rotational target and return an ID for the rotational target"));
135 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llRotTargetRemove", NULL, "i", "llRotTargetRemove(integer number)\nremoves rotational target number"));
136 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llMoveToTarget", NULL, "vf", "llMoveToTarget(vector target, float tau)\ncritically damp to target in tau seconds (if the script is physical)"));
137 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llStopMoveToTarget", NULL, NULL, "llStopMoveToTarget()\nStops critically damped motion"));
138 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llApplyImpulse", NULL, "vi", "llApplyImpulse(vector force, integer local)\napplies impulse to object, in local coords if local == TRUE (if the script is physical)"));
139 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llApplyRotationalImpulse", NULL, "vi", "llApplyRotationalImpulse(vector force, integer local)\napplies rotational impulse to object, in local coords if local == TRUE (if the script is physical)"));
140 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetTorque", NULL, "vi", "llSetTorque(vector torque, integer local)\nsets the torque of object, in local coords if local == TRUE (if the script is physical)"));
141 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetTorque", "v", NULL, "vector llGetTorque()\ngets the torque (if the script is physical)"));
142 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetForceAndTorque", NULL, "vvi", "llSetForceAndTorque(vector force, vector torque, integer local)\nsets the force and torque of object, in local coords if local == TRUE (if the script is physical)"));
143 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetVel", "v", NULL, "vector llGetVel()\ngets the velocity"));
144 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetAccel", "v", NULL, "vector llGetAccel()\ngets the acceleration"));
145 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetOmega", "v", NULL, "vector llGetOmega()\ngets the omega"));
146 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetTimeOfDay", "f", "", "float llGetTimeOfDay()\ngets the time in seconds since Second Life server midnight (or since server up-time; whichever is smaller)"));
147 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetWallclock", "f", "", "float llGetWallclock()\ngets the time in seconds since midnight"));
148 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetTime", "f", NULL, "float llGetTime()\ngets the time in seconds since creation"));
149 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llResetTime", NULL, NULL, "llResetTime()\nsets the time to zero"));
150 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetAndResetTime", "f", NULL, "float llGetAndResetTime()\ngets the time in seconds since creation and sets the time to zero"));
151 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSound", NULL, "sfii", "llSound(string sound, float volume, integer queue, integer loop)\nplays sound at volume and whether it should loop or not"));
152 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llPlaySound", NULL, "sf", "llPlaySound(string sound, float volume)\nplays attached sound once at volume (0.0 - 1.0)"));
153 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llLoopSound", NULL, "sf", "llLoopSound(string sound, float volume)\nplays attached sound looping indefinitely at volume (0.0 - 1.0)"));
154 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llLoopSoundMaster", NULL, "sf", "llLoopSoundMaster(string sound, float volume)\nplays attached sound looping at volume (0.0 - 1.0), declares it a sync master"));
155 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llLoopSoundSlave", NULL, "sf", "llLoopSoundSlave(string sound, float volume)\nplays attached sound looping at volume (0.0 - 1.0), synced to most audible sync master"));
156 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llPlaySoundSlave", NULL, "sf", "llPlaySoundSlave(string sound, float volume)\nplays attached sound once at volume (0.0 - 1.0), synced to next loop of most audible sync master"));
157 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llTriggerSound", NULL, "sf", "llTriggerSound(string sound, float volume)\nplays sound at volume (0.0 - 1.0), centered at but not attached to object"));
158 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llStopSound", NULL, "", "llStopSound()\nStops currently attached sound"));
159 addFunction(new LLScriptLibraryFunction(10.f, 1.f, dummy_func, "llPreloadSound", NULL, "s", "llPreloadSound(string sound)\npreloads a sound on viewers within range"));
160 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetSubString", "s", "sii", "string llGetSubString(string src, integer start, integer end)\nreturns the indicated substring"));
161 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llDeleteSubString", "s", "sii", "string llDeleteSubString(string src, integer start, integer end)\nremoves the indicated substring and returns the result"));
162 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llInsertString", "s", "sis", "string llInsertString(string dst, integer position, string src)\ninserts src into dst at position and returns the result"));
163 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llToUpper", "s", "s", "string llToUpper(string src)\nconvert src to all upper case and returns the result"));
164 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llToLower", "s", "s", "string llToLower(string src)\nconvert src to all lower case and returns the result"));
165 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGiveMoney", "i", "ki", "llGiveMoney(key destination, integer amount)\ntransfer amount of money from script owner to destination"));
166 addFunction(new LLScriptLibraryFunction(10.f, 0.1f, dummy_func, "llMakeExplosion", NULL, "iffffsv", "llMakeExplosion(integer particles, float scale, float vel, float lifetime, float arc, string texture, vector offset)\nMake a round explosion of particles"));
167 addFunction(new LLScriptLibraryFunction(10.f, 0.1f, dummy_func, "llMakeFountain", NULL, "iffffisvf", "llMakeFountain(integer particles, float scale, float vel, float lifetime, float arc, integer bounce, string texture, vector offset, float bounce_offset)\nMake a fountain of particles"));
168 addFunction(new LLScriptLibraryFunction(10.f, 0.1f, dummy_func, "llMakeSmoke", NULL, "iffffsv", "llMakeSmoke(integer particles, float scale, float vel, float lifetime, float arc, string texture, vector offset)\nMake smoke like particles"));
169 addFunction(new LLScriptLibraryFunction(10.f, 0.1f, dummy_func, "llMakeFire", NULL, "iffffsv", "llMakeFire(integer particles, float scale, float vel, float lifetime, float arc, string texture, vector offset)\nMake fire like particles"));
170 addFunction(new LLScriptLibraryFunction(200.f, 0.1f, dummy_func, "llRezObject", NULL, "svvqi", "llRezObject(string inventory, vector pos, vector vel, rotation rot, integer param)\nInstanciate owners inventory object at pos with velocity vel and rotation rot with start parameter param"));
171 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llLookAt", NULL, "vff", "llLookAt(vector target, F32 strength, F32 damping)\nCause object name to point it's forward axis towards target"));
172 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llStopLookAt", NULL, NULL, "llStopLookAt()\nStop causing object name to point at a target"));
173 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetTimerEvent", NULL, "f", "llSetTimerEvent(float sec)\nCause the timer event to be triggered every sec seconds"));
174 addFunction(new LLScriptLibraryFunction(0.f, 0.f, dummy_func, "llSleep", NULL, "f", "llSleep(float sec)\nPut script to sleep for sec seconds"));
175 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetMass", "f", NULL, "float llGetMass()\nGet the mass of task name that script is attached to"));
176 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llCollisionFilter", NULL, "ski", "llCollisionFilter(string name, key id, integer accept)\nif accept == TRUE, only accept collisions with objects name and id (either is optional), otherwise with objects not name or id"));
177 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llTakeControls", NULL, "iii", "llTakeControls(integer controls, integer accept, integer pass_on)\nTake controls from agent task has permissions for. If (accept == (controls & input)), send input to task. If pass_on send to agent also."));
178 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llReleaseControls", NULL, NULL, "llReleaseControls()\nStop taking inputs"));
179 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llAttachToAvatar", NULL, "i", "llAttachToAvatar(integer attachment)\nAttach to avatar task has permissions for at point attachment"));
180 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llDetachFromAvatar", NULL, NULL, "llDetachFromAvatar()\nDrop off of avatar"));
181 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llTakeCamera", NULL, "k", "llTakeCamera(key avatar)\nMove avatar's viewpoint to task"));
182 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llReleaseCamera", NULL, "k", "llReleaseCamera(key avatar)\nReturn camera to agent"));
183 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetOwner", "k", NULL, "key llGetOwner()\nReturns the owner of the task"));
184 addFunction(new LLScriptLibraryFunction(10.f, 2.f, dummy_func, "llInstantMessage", NULL, "ks", "llInstantMessage(key user, string message)\nIMs message to the user"));
185 addFunction(new LLScriptLibraryFunction(10.f, 20.f, dummy_func, "llEmail", NULL, "sss", "llEmail(string address, string subject, string message)\nSends email to address with subject and message"));
186 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetNextEmail", NULL, "ss", "llGetNextEmail(string address, string subject)\nGet the next waiting email with appropriate address and/or subject (if blank they are ignored)"));
187 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetKey", "k", NULL, "key llGetKey()\nGet the key for the task the script is attached to"));
188 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetBuoyancy", NULL, "f", "llSetBuoyancy(float buoyancy)\nSet the tasks buoyancy (0 is none, < 1.0 sinks, 1.0 floats, > 1.0 rises)"));
189 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetHoverHeight", NULL, "fif", "llSetHoverHeight(float height, integer water, float tau)\nCritically damps to a height (either above ground level or above the higher of land and water if water == TRUE)"));
190 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llStopHover", NULL, NULL, "llStopHover()\nStop hovering to a height"));
191 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llMinEventDelay", NULL, "f", "llMinEventDelay(float delay)\nSet the minimum time between events being handled"));
192 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSoundPreload", NULL, "s", "llSoundPreload(string sound)\npreloads a sound on viewers within range"));
193 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llRotLookAt", NULL, "qff", "llRotLookAt(rotation target, F32 strength, F32 damping)\nCause object name to point it's forward axis towards target"));
194 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llStringLength", "i", "s", "integer llStringLength(string str)\nReturns the length of string"));
195 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llStartAnimation", NULL, "s", "llStartAnimation(string anim)\nStart animation anim for agent that owns object"));
196 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llStopAnimation", NULL, "s", "llStopAnimation(string anim)\nStop animation anim for agent that owns object"));
197 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llPointAt", NULL, "v", "llPointAt(vector pos)\nMake agent that owns object point at pos"));
198 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llStopPointAt", NULL, NULL, "llStopPointAt()\nStop agent that owns object pointing"));
199 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llTargetOmega", NULL, "vff", "llTargetOmega(vector axis, float spinrate, float gain)\nAttempt to spin at spinrate with strength gain"));
200 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetStartParameter", "i", NULL, "integer llGetStartParameter()\nGet's the start paramter passed to llRezObject"));
201 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGodLikeRezObject", NULL, "kv", "llGodLikeRezObject(key inventory, vector pos)\nrez directly off of a UUID if owner has dog-bit set", TRUE));
202 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llRequestPermissions", NULL, "ki", "llRequestPermissions(key agent, integer perm)\nask agent to allow the script to do perm (NB: Debit, ownership, link, joint, and permission requests can only go to the task's owner)"));
203 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetPermissionsKey", "k", NULL, "key llGetPermissionsKey()\nReturn agent that permissions are enabled for. NULL_KEY if not enabled"));
204 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetPermissions", "i", NULL, "integer llGetPermissions()\nreturn what permissions have been enabled"));
205 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetLinkNumber", "i", NULL, "integer llGetLinkNumber()\nReturns what number in a link set the script is attached to (0 means no link, 1 the root, 2 for first child, &c)"));
206 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetLinkColor", NULL, "ivi", "llSetLinkColor(integer linknumber, vector color, integer face)\nIf a task exists in the link chain at linknumber, set face to color"));
207 addFunction(new LLScriptLibraryFunction(10.f, 1.f, dummy_func, "llCreateLink", NULL, "ki", "llCreateLink(key target, integer parent)\nAttempt to link task script is attached to and target (requires permission PERMISSION_CHANGE_LINKS be set). If parent == TRUE, task script is attached to is the root"));
208 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llBreakLink", NULL, "i", "llBreakLink(integer linknum)\nDelinks the task with the given link number (requires permission PERMISSION_CHANGE_LINKS be set)"));
209 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llBreakAllLinks", NULL, NULL, "llBreakAllLinks()\nDelinks all tasks in the link set (requires permission PERMISSION_CHANGE_LINKS be set)"));
210 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetLinkKey", "k", "i", "key llGetLinkKey(integer linknum)\nGet the key of linknumber in link set"));
211 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetLinkName", "s", "i", "string llGetLinkName(integer linknum)\nGet the name of linknumber in link set"));
212 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetInventoryNumber", "i", "i", "integer llGetInventoryNumber(integer type)\nGet the number of items of a given type in the task's inventory.\nValid types: INVENTORY_TEXTURE, INVENTORY_SOUND, INVENTORY_OBJECT, INVENTORY_SCRIPT, INVENTORY_CLOTHING, INVENTORY_BODYPART, INVENTORY_NOTECARD, INVENTORY_LANDMARK, INVENTORY_ALL"));
213 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetInventoryName", "s", "ii", "string llGetInventoryName(integer type, integer number)\nGet the name of the inventory item number of type"));
214 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetScriptState", NULL, "si", "llSetScriptState(string name, integer run)\nControl the state of a script name."));
215 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetEnergy", "f", NULL, "float llGetEnergy()\nReturns how much energy is in the object as a percentage of maximum"));
216 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGiveInventory", NULL, "ks", "llGiveInventory(key destination, string inventory)\nGive inventory to destination"));
217 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llRemoveInventory", NULL, "s", "llRemoveInventory(string inventory)\nRemove the named inventory item"));
218 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetText", NULL, "svf", "llSetText(string text, vector color, float alpha)\nSet text floating over object"));
219 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llWater", "f", "v", "float llWater(vector v)\nreturns the water height below the object position + v"));
220 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llPassTouches", NULL, "i", "llPassTouches(integer pass)\nif pass == TRUE, touches are passed from children on to parents (default is FALSE)"));
221 addFunction(new LLScriptLibraryFunction(10.f, 0.1f, dummy_func, "llRequestAgentData", "k", "ki", "key llRequestAgentData(key id, integer data)\nRequests data about agent id. When data is available the dataserver event will be raised"));
222 addFunction(new LLScriptLibraryFunction(10.f, 1.f, dummy_func, "llRequestInventoryData", "k", "s", "key llRequestInventoryData(string name)\nRequests data from object's inventory object. When data is available the dataserver event will be raised"));
223 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetDamage", NULL, "f", "llSetDamage(float damage)\nSets the amount of damage that will be done to an object that this task hits. Task will be killed."));
224 addFunction(new LLScriptLibraryFunction(100.f, 5.f, dummy_func, "llTeleportAgentHome", NULL, "k", "llTeleportAgentHome(key id)\nTeleports agent on owner's land to agent's home location"));
225 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llModifyLand", NULL, "ii", "llModifyLand(integer action, integer size)\nModify land with action (LAND_LEVEL, LAND_RAISE, LAND_LOWER, LAND_SMOOTH, LAND_NOISE, LAND_REVERT)\non size (LAND_SMALL_BRUSH, LAND_MEDIUM_BRUSH, LAND_LARGE_BRUSH)"));
226 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llCollisionSound", NULL, "sf", "llCollisionSound(string impact_sound, float impact_volume)\nSuppress default collision sounds, replace default impact sounds with impact_sound (empty string to just suppress)"));
227 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llCollisionSprite", NULL, "s", "llCollisionSprite(string impact_sprite)\nSuppress default collision sprites, replace default impact sprite with impact_sprite (empty string to just suppress)"));
228 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetAnimation", "s", "k", "string llGetAnimation(key id)\nGet the currently playing locomotion animation for avatar id"));
229 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llResetScript", NULL, NULL, "llResetScript()\nResets the script"));
230 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llMessageLinked", NULL, "iisk", "llMessageLinked(integer linknum, integer num, string str, key id)\nSends num, str, and id to members of the link set (LINK_ROOT sends to root task in a linked set,\nLINK_SET sends to all tasks,\nLINK_ALL_OTHERS to all other tasks,\nLINK_ALL_CHILDREN to all children,\nLINK_THIS to the task the script it is in)"));
231 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llPushObject", NULL, "kvvi", "llPushObject(key id, vector impulse, vector ang_impulse, integer local)\nApplies impulse and ang_impulse to object id"));
232 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llPassCollisions", NULL, "i", "llPassCollisions(integer pass)\nif pass == TRUE, collisions are passed from children on to parents (default is FALSE)"));
233 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetScriptName", "s", NULL, "llGetScriptName()\nReturns the script name"));
234 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetNumberOfSides", "i", NULL, "integer llGetNumberOfSides()\nReturns the number of sides"));
235 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llAxisAngle2Rot", "q", "vf", "rotation llAxisAngle2Rot(vector axis, float angle)\nReturns the rotation generated angle about axis"));
236 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llRot2Axis", "v", "q", "vector llRot2Axis(rotation rot)\nReturns the rotation axis represented by rot"));
237 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llRot2Angle", "f", "q", "float llRot2Angle(rotation rot)\nReturns the rotation angle represented by rot"));
238 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llAcos", "f", "f", "float llAcos(float val)\nReturns the arccosine in radians of val"));
239 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llAsin", "f", "f", "float llAsin(float val)\nReturns the arcsine in radians of val"));
240 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llAngleBetween", "f", "qq", "float llAngleBetween(rotation a, rotation b)\nReturns angle between rotation a and b"));
241 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetInventoryKey", "k", "s", "key llGetInventoryKey(string name)\nReturns the key of the inventory name"));
242 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llAllowInventoryDrop", NULL, "i", "llAllowInventoryDrop(integer add)\nIf add == TRUE, users without permissions can still drop inventory items onto task"));
243 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetSunDirection", "v", NULL, "vector llGetSunDirection()\nReturns the sun direction on the simulator"));
244 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetTextureOffset", "v", "i", "vector llGetTextureOffset(integer side)\nReturns the texture offset of side in the x and y components of a vector"));
245 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetTextureScale", "v", "i", "vector llGetTextureScale(integer side)\nReturns the texture scale of side in the x and y components of a vector"));
246 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetTextureRot", "f", "i", "float llGetTextureRot(integer side)\nReturns the texture rotation of side"));
247 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSubStringIndex", "i", "ss", "integer llSubStringIndex(string source, string pattern)\nFinds index in source where pattern first appears (returns -1 if not found)"));
248 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetOwnerKey", "k", "k", "key llGetOwnerKey(key id)\nFind the owner of id"));
249 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetCenterOfMass", "v", NULL, "vector llGetCenterOfMass()\nGet the object's center of mass"));
250 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llListSort", "l", "lii", "list llListSort(list src, integer stride, integer ascending)\nSort the list into blocks of stride in ascending order if ascending == TRUE. Note that sort only works between same types."));
251 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetListLength", "i", "l", "integer llGetListLength(list src)\nGet the number of elements in the list"));
252 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llList2Integer", "i", "li", "integer llList2Integer(list src, integer index)\nCopy the integer at index in the list"));
253 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llList2Float", "f", "li", "float llList2Float(list src, integer index)\nCopy the float at index in the list"));
254 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llList2String", "s", "li", "string llList2String(list src, integer index)\nCopy the string at index in the list"));
255 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llList2Key", "k", "li", "key llList2Key(list src, integer index)\nCopy the key at index in the list"));
256 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llList2Vector", "v", "li", "vector llList2Vector(list src, integer index)\nCopy the vector at index in the list"));
257 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llList2Rot", "q", "li", "rotation llList2Rot(list src, integer index)\nCopy the rotation at index in the list"));
258 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llList2List", "l", "lii", "list llList2List(list src, integer start, integer end)\nCopy the slice of the list from start to end"));
259 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llDeleteSubList", "l", "lii", "list llDeleteSubList(list src, integer start, integer end)\nRemove the slice from the list and return the remainder"));
260 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetListEntryType", "i", "li", "integer llGetListEntryType(list src, integer index)\nReturns the type of the index entry in the list\n(TYPE_INTEGER, TYPE_FLOAT, TYPE_STRING, TYPE_KEY, TYPE_VECTOR, TYPE_ROTATION, or TYPE_INVALID if index is off list)"));
261 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llList2CSV", "s", "l", "string llList2CSV(list src)\nCreate a string of comma separated values from list"));
262 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llCSV2List", "l", "s", "list llCSV2List(string src)\nCreate a list from a string of comma separated values"));
263 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llListRandomize", "l", "li", "list llListRandomize(list src, integer stride)\nReturns a randomized list of blocks of size stride"));
264 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llList2ListStrided", "l", "liii", "list llList2ListStrided(list src, integer start, integer end, integer stride)\nCopy the strided slice of the list from start to end"));
265 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetRegionCorner", "v", NULL, "vector llGetRegionCorner()\nReturns a vector with the south west corner x,y position of the region the object is in"));
266 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llListInsertList", "l", "lli", "list llListInsertList(list dest, list src, integer start)\nInserts src into dest at position start"));
267 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llListFindList", "i", "ll", "integer llListFindList(list src, list test)\nReturns the start of the first instance of test in src, -1 if not found"));
268 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetObjectName", "s", NULL, "string llGetObjectName()\nReturns the name of the object script is attached to"));
269 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetObjectName", NULL, "s", "llSetObjectName(string name)\nSets the objects name"));
270 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetDate", "s", NULL, "string llGetDate()\nGets the date as YYYY-MM-DD"));
271 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llEdgeOfWorld", "i", "vv", "integer llEdgeOfWorld(vector pos, vector dir)\nChecks to see whether the border hit by dir from pos is the edge of the world (has no neighboring simulator)"));
272 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetAgentInfo", "i", "k", "integer llGetAgentInfo(key id)\nGets information about agent ID.\nReturns AGENT_FLYING, AGENT_ATTACHMENTS, AGENT_SCRIPTED, AGENT_SITTING, AGENT_ON_OBJECT, AGENT_MOUSELOOK, AGENT_AWAY, AGENT_BUSY, AGENT_TYPING, AGENT_CROUCHING, AGENT_ALWAYS_RUN, AGENT_WALKING and/or AGENT_IN_AIR."));
273 addFunction(new LLScriptLibraryFunction(10.f, 0.1f, dummy_func, "llAdjustSoundVolume", NULL, "f", "llAdjustSoundVolume(float volume)\nadjusts volume of attached sound (0.0 - 1.0)"));
274 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetSoundQueueing", NULL, "i", "llSetSoundQueueing(integer queue)\ndetermines whether attached sound calls wait for the current sound to finish (0 = no [default], nonzero = yes)"));
275 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetSoundRadius", NULL, "f", "llSetSoundRadius(float radius)\nestablishes a hard cut-off radius for audibility of scripted sounds (both attached and triggered)"));
276 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llKey2Name", "s", "k", "string llKey2Name(key id)\nReturns the name of the object key, iff the object is in the current simulator, otherwise the empty string"));
277 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetTextureAnim", NULL, "iiiifff", "llSetTextureAnim(integer mode, integer face, integer sizex, integer sizey, float start, float length, float rate)\nAnimate the texture on the specified face/faces"));
278 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llTriggerSoundLimited", NULL, "sfvv", "llTriggerSoundLimited(string sound, float volume, vector tne, vector bsw)\nplays sound at volume (0.0 - 1.0), centered at but not attached to object, limited to AABB defined by vectors top-north-east and bottom-south-west"));
279 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llEjectFromLand", NULL, "k", "llEjectFromLand(key pest)\nEjects pest from land that you own"));
280 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llParseString2List", "l", "sll", "list llParseString2List(string src, list separators, list spacers)\nBreaks src into a list, discarding separators, keeping spacers (separators and spacers must be lists of strings, maximum of 8 each)"));
281 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llOverMyLand", "i", "k", "integer llOverMyLand(key id)\nReturns TRUE if id is over land owner of object owns, FALSE otherwise"));
282 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetLandOwnerAt", "k", "v", "key llGetLandOwnerAt(vector pos)\nReturns the key of the land owner, NULL_KEY if public"));
283 addFunction(new LLScriptLibraryFunction(10.f, 0.1f, dummy_func, "llGetNotecardLine", "k", "si", "key llGetNotecardLine(string name, integer line)\nReturns line line of notecard name via the dataserver event"));
284 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetAgentSize", "v", "k", "vector llGetAgentSize(key id)\nIf the agent is in the same sim as the object, returns the size of the avatar"));
285 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSameGroup", "i", "k", "integer llSameGroup(key id)\nReturns TRUE if ID is in the same sim and has the same active group, otherwise FALSE"));
286 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llUnSit", NULL, "k", "key llUnSit(key id)\nIf agent identified by id is sitting on the object the script is attached to or is over land owned by the objects owner, the agent is forced to stand up"));
287 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGroundSlope", "v", "v", "vector llGroundSlope(vector v)\nreturns the ground slope below the object position + v"));
288 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGroundNormal", "v", "v", "vector llGroundNormal(vector v)\nreturns the ground normal below the object position + v"));
289 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGroundContour", "v", "v", "vector llGroundCountour(vector v)\nreturns the ground contour below the object position + v"));
290 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetAttached", "i", NULL, "integer llGetAttached()\nreturns the object attachment point or 0 if not attached"));
291 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetFreeMemory", "i", NULL, "integer llGetFreeMemory()\nreturns the available heap space for the current script"));
292 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetRegionName", "s", NULL, "string llGetRegionName()\nreturns the current region name"));
293 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetRegionTimeDilation", "f", NULL, "float llGetRegionTimeDilation()\nreturns the current time dilation as a float between 0 and 1"));
294 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetRegionFPS", "f", NULL, "float llGetRegionFPS()\nreturns the mean region frames per second"));
295
296 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llParticleSystem", NULL, "l", "llParticleSystem(list rules)\nCreates a particle system based on rules. Empty list removes particle system from object.\nList format is [ rule1, data1, rule2, data2 . . . rulen, datan ]"));
297 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGroundRepel", NULL, "fif", "llGroundRepel(float height, integer water, float tau)\nCritically damps to height if within height*0.5 of level (either above ground level or above the higher of land and water if water == TRUE)"));
298 addFunction(new LLScriptLibraryFunction(10.f, 3.f, dummy_func, "llGiveInventoryList", NULL, "ksl", "llGiveInventoryList(key destination, string category, list inventory)\nGive inventory to destination in a new category"));
299
300// script calls for vehicle action
301 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetVehicleType", NULL, "i", "llSetVehicleType(integer type)\nsets vehicle to one of the default types"));
302 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetVehicleFloatParam", NULL, "if", "llSetVehicleFloatParam(integer param, float value)\nsets the specified vehicle float parameter"));
303 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetVehicleVectorParam", NULL, "iv", "llSetVehicleVectorParam(integer param, vector vec)\nsets the specified vehicle vector parameter"));
304 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetVehicleRotationParam", NULL, "iq", "llSetVehicleVectorParam(integer param, rotation rot)\nsets the specified vehicle rotation parameter"));
305 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetVehicleFlags", NULL, "i", "llSetVehicleFlags(integer flags)\nsets the enabled bits in 'flags'"));
306 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llRemoveVehicleFlags", NULL, "i", "llRemoveVehicleFlags(integer flags)\nremoves the enabled bits in 'flags'"));
307 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSitTarget", NULL, "vq", "llSitTarget(vector offset, rotation rot)\nSet the sit location for this object (if offset == <0,0,0> clear it)"));
308 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llAvatarOnSitTarget", "k", NULL, "key llAvatarOnSitTarget()\nIf an avatar is sitting on the sit target, return the avatar's key, NULL_KEY otherwise"));
309 addFunction(new LLScriptLibraryFunction(10.f, 0.1f, dummy_func, "llAddToLandPassList", NULL, "kf", "llAddToLandPassList(key avatar, float hours)\nAdd avatar to the land pass list for hours"));
310 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetTouchText", NULL, "s", "llSetTouchText(string text)\nDisplays text in pie menu that acts as a touch"));
311 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetSitText", NULL, "s", "llSetSitText(string text)\nDisplays text rather than sit in pie menu"));
312 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetCameraEyeOffset", NULL, "v", "llSetCameraEyeOffset(vector offset)\nSets the camera eye offset used in this object if an avatar sits on it"));
313 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetCameraAtOffset", NULL, "v", "llSetCameraAtOffset(vector offset)\nSets the camera at offset used in this object if an avatar sits on it"));
314
315 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llDumpList2String", "s", "ls", "string llDumpList2String(list src, string separator)\nWrite the list out in a single string using separator between values"));
316 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llScriptDanger", "i", "v", "integer llScriptDanger(vector pos)\nReturns true if pos is over public land, sandbox land, land that doesn't allow everyone to edit and build, or land that doesn't allow outside scripts"));
317 addFunction(new LLScriptLibraryFunction(10.f, 1.f, dummy_func, "llDialog", NULL, "ksli", "llDialog(key avatar, string message, list buttons, integer chat_channel\nShows a dialog box on the avatar's screen with the message.\nUp to 12 strings in the list form buttons.\nIf a button is clicked, the name is chatted on chat_channel."));
318 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llVolumeDetect", NULL, "i", "llVolumeDetect(integer detect)\nIf detect = TRUE, object becomes phantom but triggers collision_start and collision_end events\nwhen other objects start and stop interpenetrating.\nMust be applied to the root object."));
319 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llResetOtherScript", NULL, "s", "llResetOtherScript(string name)\nResets script name"));
320 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetScriptState", "i", "s", "integer llGetScriptState(string name)\nResets TRUE if script name is running"));
321 addFunction(new LLScriptLibraryFunction(10.f, 3.f, dummy_func, "llRemoteLoadScript", NULL, "ksii", "Deprecated. Please use llRemoteLoadScriptPin instead."));
322
323 addFunction(new LLScriptLibraryFunction(10.f, 0.2f, dummy_func, "llSetRemoteScriptAccessPin", NULL, "i", "llSetRemoteScriptAccessPin(integer pin)\nIf pin is set to a non-zero number, the task will accept remote script\nloads via llRemoteLoadScriptPin if it passes in the correct pin.\nOthersise, llRemoteLoadScriptPin is ignored."));
324 addFunction(new LLScriptLibraryFunction(10.f, 3.f, dummy_func, "llRemoteLoadScriptPin", NULL, "ksiii", "llRemoteLoadScriptPin(key target, string name, integer pin, integer running, integer start_param)\nIf the owner of the object this script is attached can modify target,\nthey are in the same region,\nand the matching pin is used,\ncopy script name onto target,\nif running == TRUE, start the script with param."));
325
326 addFunction(new LLScriptLibraryFunction(10.f, 1.f, dummy_func, "llOpenRemoteDataChannel", NULL, NULL, "llOpenRemoteDataChannel()\nCreates a channel to listen for XML-RPC calls. Will trigger a remote_data event with channel id once it is available."));
327 addFunction(new LLScriptLibraryFunction(10.f, 3.f, dummy_func, "llSendRemoteData", "k", "ksis", "key llSendRemoteData(key channel, string dest, integer idata, string sdata)\nSend an XML-RPC request to dest through channel with payload of channel (in a string), integer idata and string sdata.\nA message identifier key is returned.\nAn XML-RPC reply will trigger a remote_data event and reference the message id.\nThe message_id is returned."));
328 addFunction(new LLScriptLibraryFunction(10.f, 3.f, dummy_func, "llRemoteDataReply", NULL, "kksi", "llRemoteDataReply(key channel, key message_id, string sdata, integer idata)\nSend an XML-RPC reply to message_id on channel with payload of string sdata and integer idata"));
329 addFunction(new LLScriptLibraryFunction(10.f, 1.f, dummy_func, "llCloseRemoteDataChannel", NULL, "k", "llCloseRemoteDataChannel(key channel)\nCloses XML-RPC channel."));
330
331 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llMD5String", "s", "si", "string llMD5String(string src, integer nonce)\nPerforms a RSA Data Security, Inc. MD5 Message-Digest Algorithm on string with nonce. Returns a 32 character hex string."));
332 addFunction(new LLScriptLibraryFunction(10.f, 0.2f, dummy_func, "llSetPrimitiveParams", NULL, "l", "llSetPrimitiveParams(list rules)\nSet primitive parameters based on rules."));
333 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llStringToBase64", "s", "s", "string llStringToBase64(string str)\nConverts a string to the Base 64 representation of the string."));
334 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llBase64ToString", "s", "s", "string llBase64ToString(string str)\nConverts a Base 64 string to a conventional string. If the conversion creates any unprintable characters, they are converted to spaces."));
335 addFunction(new LLScriptLibraryFunction(10.f, 0.3f, dummy_func, "llXorBase64Strings", "s", "ss", "string llXorBase64Strings(string s1, string s2)\nDEPRECATED! Please use llXorBase64StringsCorrect instead!! Incorrectly performs an exclusive or on two Base 64 strings and returns a Base 64 string. s2 repeats if it is shorter than s1. Retained for backwards compatability."));
336 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llRemoteDataSetRegion", NULL, NULL, "llRemoteDataSetRegion()\nIf an object using remote data channels changes regions, you must call this function to reregister the remote data channels.\nYou do not need to make this call if you don't change regions."));
337 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llLog10", "f", "f", "float llLog10(float val)\nReturns the base 10 log of val if val > 0, otherwise returns 0."));
338 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llLog", "f", "f", "float llLog(float val)\nReturns the base e log of val if val > 0, otherwise returns 0."));
339 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetAnimationList", "l", "k", "list llGetAnimationList(key id)\nGets a list of all playing animations for avatar id"));
340 addFunction(new LLScriptLibraryFunction(10.f, 2.f, dummy_func, "llSetParcelMusicURL", NULL, "s", "llSetParcelMusicURL(string url)\nSets the streaming audio URL for the parcel object is on"));
341
342 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetRootPosition", "v", NULL, "vector llGetRootPosition()\nGets the global position of the root object of the object script is attached to"));
343 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetRootRotation", "q", NULL, "rotation llGetRootRotation()\nGets the global rotation of the root object of the object script is attached to"));
344
345 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetObjectDesc", "s", NULL, "string llGetObjectDesc()\nReturns the description of the object the script is attached to"));
346 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetObjectDesc", NULL, "s", "llSetObjectDesc(string name)\nSets the object's description"));
347 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetCreator", "k", NULL, "key llGetCreator()\nReturns the creator of the object"));
348 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetTimestamp", "s", NULL, "string llGetTimestamp()\nGets the timestamp in the format: YYYY-MM-DDThh:mm:ss.ff..fZ"));
349 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetLinkAlpha", NULL, "ifi", "llSetLinkAlpha(integer linknumber, float alpha, integer face)\nIf a prim exists in the link chain at linknumber, set face to alpha"));
350 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetNumberOfPrims", "i", NULL, "integer llGetNumberOfPrims()\nReturns the number of prims in a link set the script is attached to"));
351 addFunction(new LLScriptLibraryFunction(10.f, 0.1f, dummy_func, "llGetNumberOfNotecardLines", "k", "s", "key llGetNumberOfNotecardLines(string name)\nReturns number of lines in notecard 'name' via the dataserver event (cast return value to integer)"));
352
353 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetBoundingBox", "l", "k", "list llGetBoundingBox(key object)\nReturns the bounding box around an object (including any linked prims) relative to the root prim, in a list: [ (vector) min_corner, (vector) max_corner ]"));
354 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetGeometricCenter", "v", NULL, "vector llGetGeometricCenter()\nReturns the geometric center of the linked set the script is attached to."));
355 addFunction(new LLScriptLibraryFunction(10.f, 0.2f, dummy_func, "llGetPrimitiveParams", "l", "l", "list llGetPrimitiveParams(list params)\nGets primitive parameters specified in the params list."));
356 addFunction(new LLScriptLibraryFunction(10.f, 0.0f, dummy_func, "llIntegerToBase64", "s", "i", "string llIntegerToBase64(integer number)\nBig endian encode of of integer as a Base64 string."));
357 addFunction(new LLScriptLibraryFunction(10.f, 0.0f, dummy_func, "llBase64ToInteger", "i", "s", "integer llBase64ToInteger(string str)\nBig endian decode of a Base64 string into an integer."));
358 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetGMTclock", "f", "", "float llGetGMTclock()\nGets the time in seconds since midnight in GMT"));
359 addFunction(new LLScriptLibraryFunction(10.f, 10.f, dummy_func, "llGetSimulatorHostname", "s", "", "string llGetSimulatorHostname()\nGets the hostname of the machine script is running on (same as string in viewer Help dialog)"));
360
361 addFunction(new LLScriptLibraryFunction(10.f, 0.2f, dummy_func, "llSetLocalRot", NULL, "q", "llSetLocalRot(rotation rot)\nsets the rotation of a child prim relative to the root prim"));
362
363 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llParseStringKeepNulls", "l", "sll", "list llParseStringKeepNulls(string src, list separators, list spacers)\nBreaks src into a list, discarding separators, keeping spacers (separators and spacers must be lists of strings, maximum of 8 each), keeping any null values generated."));
364 addFunction(new LLScriptLibraryFunction(200.f, 0.1f, dummy_func, "llRezAtRoot", NULL, "svvqi", "llRezAtRoot(string inventory, vector pos, vector vel, rotation rot, integer param)\nInstantiate owner's inventory object at pos with velocity vel and rotation rot with start parameter param.\nThe last selected root object's location will be set to pos"));
365
366 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetObjectPermMask", "i", "i", "integer llGetObjectPermMask(integer mask)\nReturns the requested permission mask for the root object the task is attached to.", FALSE));
367 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetObjectPermMask", NULL, "ii", "llSetObjectPermMask(integer mask, integer value)\nSets the given permission mask to the new value on the root object the task is attached to.", TRUE));
368
369 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetInventoryPermMask", "i", "si", "integer llGetInventoryPermMask(string item, integer mask)\nReturns the requested permission mask for the inventory item.", FALSE));
370 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetInventoryPermMask", NULL, "sii", "llSetInventoryPermMask(string item, integer mask, integer value)\nSets the given permission mask to the new value on the inventory item.", TRUE));
371 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetInventoryCreator", "k", "s", "key llGetInventoryCreator(string item)\nReturns the key for the creator of the inventory item.", FALSE));
372 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llOwnerSay", NULL, "s", "llOwnerSay(string msg)\nsays msg to owner only (if owner in sim)"));
373 addFunction(new LLScriptLibraryFunction(10.f, 1.f, dummy_func, "llRequestSimulatorData", "k", "si", "key llRequestSimulatorData(string simulator, integer data)\nRequests data about simulator. When data is available the dataserver event will be raised"));
374 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llForceMouselook", NULL, "i", "llForceMouselook(integer mouselook)\nIf mouselook is TRUE any avatar that sits on this object is forced into mouselook mode"));
375 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetObjectMass", "f", "k", "float llGetObjectMass(key id)\nGet the mass of the object with key id"));
376 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llListReplaceList", "l", "llii", "list llListReplaceList(list dest, list src, integer start, integer end)\nReplaces start through end of dest with src."));
377 addFunction(new LLScriptLibraryFunction(10.f, 10.f, dummy_func, "llLoadURL", NULL, "kss", "llLoadURL(key avatar_id, string message, string url)\nShows dialog to avatar avatar_id offering to load web page at URL. If user clicks yes, launches their web browser."));
378
379 addFunction(new LLScriptLibraryFunction(10.f, 2.f, dummy_func, "llParcelMediaCommandList", NULL, "l", "llParcelMediaCommandList(list command)\nSends a list of commands, some with arguments, to a parcel."));
380 addFunction(new LLScriptLibraryFunction(10.f, 2.f, dummy_func, "llParcelMediaQuery", "l", "l", "list llParcelMediaQuery(list query)\nSends a list of queries, returns a list of results."));
381
382 addFunction(new LLScriptLibraryFunction(10.f, 1.f, dummy_func, "llModPow", "i", "iii", "integer llModPow(integer a, integer b, integer c)\nReturns a raised to the b power, mod c. ( (a**b)%c ). b is capped at 0xFFFF (16 bits)."));
383
384 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetInventoryType", "i", "s", "integer llGetInventoryType(string name)\nReturns the type of the inventory name"));
385 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetPayPrice", NULL, "il", "llSetPayPrice(integer price, list quick_pay_buttons)\nSets the default amount when someone chooses to pay this object."));
386 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetCameraPos", "v", "", "vector llGetCameraPos()\nGets current camera position for agent task has permissions for."));
387 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetCameraRot", "q", "", "rotation llGetCameraRot()\nGets current camera orientation for agent task has permissions for."));
388
389 addFunction(new LLScriptLibraryFunction(10.f, 2.f, dummy_func, "llSetPrimURL", NULL, "s", "llSetPrimURL(string url)\nUpdates the URL for the web page shown on the sides of the object."));
390 addFunction(new LLScriptLibraryFunction(10.f, 20.f, dummy_func, "llRefreshPrimURL", NULL, "", "llRefreshPrimURL()\nReloads the web page shown on the sides of the object."));
391
392 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llEscapeURL", "s", "s", "string llEscapeURL(string url)\nReturns and escaped/encoded version of url, replacing spaces with %20 etc."));
393 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llUnescapeURL", "s", "s", "string llUnescapeURL(string url)\nReturns and unescaped/unencoded version of url, replacing %20 with spaces etc."));
394
395 addFunction(new LLScriptLibraryFunction(10.f, 1.f, dummy_func, "llMapDestination", NULL, "svv", "llMapDestination(string simname, vector pos, vector look_at)\nOpens world map centered on region with pos highlighted.\nOnly works for scripts attached to avatar, or during touch events.\n(NOTE: look_at currently does nothing)"));
396 addFunction(new LLScriptLibraryFunction(10.f, 0.1f, dummy_func, "llAddToLandBanList", NULL, "kf", "llAddToLandBanList(key avatar, float hours)\nAdd avatar to the land ban list for hours"));
397 addFunction(new LLScriptLibraryFunction(10.f, 0.1f, dummy_func, "llRemoveFromLandPassList", NULL, "k", "llRemoveFromLandPassList(key avatar)\nRemove avatar from the land pass list"));
398 addFunction(new LLScriptLibraryFunction(10.f, 0.1f, dummy_func, "llRemoveFromLandBanList", NULL, "k", "llRemoveFromLandBanList(key avatar)\nRemove avatar from the land ban list"));
399
400 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetCameraParams", NULL, "l", "llSetCameraParams(list rules)\nSets multiple camera parameters at once.\nList format is [ rule1, data1, rule2, data2 . . . rulen, datan ]"));
401 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llClearCameraParams", NULL, NULL, "llClearCameraParams()\nResets all camera parameters to default values and turns off scripted camera control."));
402
403 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llListStatistics", "f", "il", "integer llListStatistics(integer operation, list l)\nPerform statistical aggregate functions on list l using LIST_STAT_* operations."));
404 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetUnixTime", "i", NULL, "integer llGetUnixTime()\nGet the number of seconds elapsed since 00:00 hours, Jan 1, 1970 UTC from the system clock."));
405 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetParcelFlags", "i", "v", "integer llGetParcelFlags(vector pos)\nGet the parcel flags (PARCEL_FLAG_*) for the parcel including the point pos."));
406 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetRegionFlags", "i", NULL, "integer llGetRegionFlags()\nGet the region flags (REGION_FLAG_*) for the region the object is in."));
407 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llXorBase64StringsCorrect", "s", "ss", "string llXorBase64StringsCorrect(string s1, string s2)\nCorrectly performs an exclusive or on two Base 64 strings and returns a Base 64 string. s2 repeats if it is shorter than s1."));
408
409 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llHTTPRequest", "k", "sls", "llHTTPRequest(string url, list parameters, string body)\nSend an HTTP request."));
410
411 addFunction(new LLScriptLibraryFunction(10.f, 0.1f, dummy_func, "llResetLandBanList", NULL, NULL, "llResetLandBanList()\nRemoves all residents from the land ban list."));
412 addFunction(new LLScriptLibraryFunction(10.f, 0.1f, dummy_func, "llResetLandPassList", NULL, NULL, "llResetLandPassList()\nRemoves all residents from the land access/pass list."));
413
414 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetObjectPrimCount", "i", "k", "integer llGetObjectPrimCount(key object_id)\nReturns the total number of prims for an object."));
415 addFunction(new LLScriptLibraryFunction(10.f, 2.0f, dummy_func, "llGetParcelPrimOwners", "l", "v", "list llGetParcelPrimOwners(vector pos)\nReturns a list of all residents who own objects on the parcel and the number of objects they own.\nRequires owner-like permissions for the parcel."));
416 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetParcelPrimCount", "i", "vii","integer llGetParcelPrimCount(vector pos, integer category, integer sim_wide)\nGets the number of prims on the parcel of the given category.\nCategories: PARCEL_COUNT_TOTAL, _OWNER, _GROUP, _OTHER, _SELECTED, _TEMP."));
417 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetParcelMaxPrims", "i", "vi","integer llGetParcelMaxPrims(vector pos, integer sim_wide)\nGets the maximum number of prims allowed on the parcel at pos."));
418 addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetParcelDetails", "l", "vl","list llGetParcelDetails(vector pos, list params)\nGets the parcel details specified in params for the parcel at pos.\nParams is one or more of: PARCEL_DETAILS_NAME, _DESC, _OWNER, _GROUP, _AREA"));
419
420 // energy, sleep, dummy_func, name, return type, parameters, help text, gods-only
421
422 // IF YOU ADD NEW SCRIPT CALLS, YOU MUST PUT THEM AT THE END OF THIS LIST.
423 // Otherwise the bytecode numbers for each call will be wrong, and all
424 // existing scripts will crash.
425}
426
427 //Ventrella Follow Cam Script Stuff
428 //addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetCamPitch", NULL, "f", "llSetCamPitch(-45 to 80)\n(Adjusts the angular amount that the camera aims straight ahead vs. straight down, maintaining the same distance. Analogous to 'incidence'."));
429 //addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetCamVerticalOffset", NULL, "f", "llSetCamVerticalOffset(-2 to 2)\nAdjusts the vertical position of the camera focus position relative to the subject"));
430 //addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetCamPositionLag", NULL, "f", "llSetCamPositionLag(0 to 3) \nHow much the camera lags as it tries to move towards its 'ideal' position"));
431 //addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetCamFocusLag", NULL, "f", "llSetCamFocusLag(0 to 3)\nHow much the camera lags as it tries to aim towards the subject"));
432 //addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetCamDistance", NULL, "f", "llSetCamDistance(0.5 to 10)\nSets how far away the camera wants to be from its subject"));
433 //addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetCamBehindnessAngle", NULL, "f", "llSetCamBehindnessAngle(0 to 180)\nSets the angle in degrees within which the camera is not constrained by changes in subject rotation"));
434 //addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetCamBehindnessLag", NULL, "f", "llSetCamBehindnessLag(0 to 3)\nSets how strongly the camera is forced to stay behind the target if outside of behindness angle"));
435 //addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetCamPositionThreshold", NULL, "f", "llSetCamPositionThreshold(0 to 4)\nSets the radius of a sphere around the camera's ideal position within which it is not affected by subject motion"));
436 //addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetCamFocusThreshold", NULL, "f", "llSetCamFocusThreshold(0 to 4)\nSets the radius of a sphere around the camera's subject position within which its focus is not affected by subject motion"));
437 //addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetCamScriptControl", NULL, "i", "llSetCamScriptControl(TRUE or FALSE)\nTurns on or off scripted control of the camera"));
438 //addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetCamPosition", NULL, "v", "llSetCamPosition(vector)\nSets the position of the camera"));
439 //addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetCamFocus", NULL, "v", "llSetCamFocus(vector focus)\nSets the focus (target position) of the camera"));
440 //addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetCamPositionLocked", NULL, "i", "llSetCamPositionLocked(TRUE or FALSE)\nLocks the camera position so it will not move"));
441 //addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetCamFocusLocked", NULL, "i", "llSetCamFocusLocked(TRUE or FALSE)\nLocks the camera focus so it will not move"));
442
443// These functions are being put on hold until we think through how we want them handled (security issues). DK 02/16/05
444 //addFunction(new LLScriptLibraryFunction(10.f, 0.2f, dummy_func, "llSetLinkPrimitiveParams", NULL, "il", "llSetLinkPrimitiveParams(integer linknumber, list rules)\nSet primitive parameters for linknumber based on rules."));
445 //addFunction(new LLScriptLibraryFunction(10.f, 0.2f, dummy_func, "llSetLinkTexture", NULL, "isi", "llSetLinkTexture(integer link_pos, string texture, integer face)\nSets the texture of face for link_pos"));
446
447 //addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetForSale", "i", "ii", "integer llSetForSale(integer selltype, integer price)\nSets this object for sale in mode selltype for price. Returns TRUE if successfully set for sale."));
448
449LLScriptLibraryFunction::LLScriptLibraryFunction(F32 eu, F32 st, void (*exec_func)(LLScriptLibData *, LLScriptLibData *, const LLUUID &), char *name, char *ret_type, char *args, char *desc, BOOL god_only)
450 : mEnergyUse(eu), mSleepTime(st), mExecFunc(exec_func), mName(name), mReturnType(ret_type), mArgs(args), mGodOnly(god_only)
451{
452 mDesc = new char[512];
453 if (mSleepTime)
454 {
455 sprintf(mDesc,"%s\nSleeps script for %.1f seconds.",desc,mSleepTime);
456 }
457 else
458 {
459 strcpy(mDesc,desc);
460 }
461}
462
463LLScriptLibraryFunction::~LLScriptLibraryFunction()
464{
465 delete [] mDesc;
466}
467
468void LLScriptLibrary::addFunction(LLScriptLibraryFunction *func)
469{
470 LLScriptLibraryFunction **temp = (LLScriptLibraryFunction **)new U32[mNextNumber + 1];
471 if (mNextNumber)
472 {
473 memcpy(temp, mFunctions, sizeof(LLScriptLibraryFunction *)*mNextNumber);
474 delete [] mFunctions;
475 }
476 mFunctions = temp;
477 mFunctions[mNextNumber] = func;
478 mNextNumber++;
479}
480
481void LLScriptLibrary::assignExec(char *name, void (*exec_func)(LLScriptLibData *, LLScriptLibData *, const LLUUID &))
482{
483 S32 i;
484 for (i = 0; i < mNextNumber; i++)
485 {
486 if (!strcmp(name, mFunctions[i]->mName))
487 {
488 mFunctions[i]->mExecFunc = exec_func;
489 }
490 }
491}
492
493void LLScriptLibData::print(std::ostream &s, BOOL b_prepend_comma)
494{
495 char tmp[1024];
496 if (b_prepend_comma)
497 {
498 s << ", ";
499 }
500 switch (mType)
501 {
502 case LST_INTEGER:
503 s << mInteger;
504 break;
505 case LST_FLOATINGPOINT:
506 snprintf(tmp, 1024, "%f", mFP);
507 s << tmp;
508 break;
509 case LST_KEY:
510 s << mKey;
511 break;
512 case LST_STRING:
513 s << mString;
514 break;
515 case LST_VECTOR:
516 snprintf(tmp, 1024, "<%f, %f, %f>", mVec.mV[VX],
517 mVec.mV[VY], mVec.mV[VZ]);
518 s << tmp;
519 break;
520 case LST_QUATERNION:
521 snprintf(tmp, 1024, "<%f, %f, %f, %f>", mQuat.mQ[VX], mQuat.mQ[VY],
522 mQuat.mQ[VZ], mQuat.mQ[VS]);
523 s << tmp;
524 break;
525 default:
526 break;
527 }
528}
529
530void LLScriptLibData::print_separator(std::ostream& ostr, BOOL b_prepend_sep, char* sep)
531{
532 if (b_prepend_sep)
533 {
534 ostr << sep;
535 }
536 //print(ostr, FALSE);
537 {
538 BOOL b_prepend_comma = FALSE;
539 char tmp[1024];
540 if (b_prepend_comma)
541 {
542 ostr << ", ";
543 }
544 switch (mType)
545 {
546 case LST_INTEGER:
547 ostr << mInteger;
548 break;
549 case LST_FLOATINGPOINT:
550 snprintf(tmp, 1024, "%f", mFP);
551 ostr << tmp;
552 break;
553 case LST_KEY:
554 ostr << mKey;
555 break;
556 case LST_STRING:
557 ostr << mString;
558 break;
559 case LST_VECTOR:
560 snprintf(tmp, 1024, "<%f, %f, %f>", mVec.mV[VX],
561 mVec.mV[VY], mVec.mV[VZ]);
562 ostr << tmp;
563 break;
564 case LST_QUATERNION:
565 snprintf(tmp, 1024, "<%f, %f, %f, %f>", mQuat.mQ[VX], mQuat.mQ[VY],
566 mQuat.mQ[VZ], mQuat.mQ[VS]);
567 ostr << tmp;
568 break;
569 default:
570 break;
571 }
572 }
573}
574
575
576LLScriptLibrary gScriptLibrary;
diff --git a/linden/indra/lscript/lscript_library/lscript_library.vcproj b/linden/indra/lscript/lscript_library/lscript_library.vcproj
new file mode 100644
index 0000000..f4861c7
--- /dev/null
+++ b/linden/indra/lscript/lscript_library/lscript_library.vcproj
@@ -0,0 +1,183 @@
1<?xml version="1.0" encoding="Windows-1252"?>
2<VisualStudioProject
3 ProjectType="Visual C++"
4 Version="7.10"
5 Name="lscript_library"
6 ProjectGUID="{BFA102B0-C891-4E13-B1CF-C2F28073DA8E}"
7 Keyword="Win32Proj">
8 <Platforms>
9 <Platform
10 Name="Win32"/>
11 </Platforms>
12 <Configurations>
13 <Configuration
14 Name="Debug|Win32"
15 OutputDirectory="../../lib_$(ConfigurationName)/i686-win32"
16 IntermediateDirectory="Debug"
17 ConfigurationType="4"
18 CharacterSet="1">
19 <Tool
20 Name="VCCLCompilerTool"
21 Optimization="0"
22 AdditionalIncludeDirectories="..;..\..\llcommon;..\..\llmath"
23 PreprocessorDefinitions="WIN32;_DEBUG;_LIB;LL_WINDOWS;LL_DEBUG"
24 MinimalRebuild="TRUE"
25 BasicRuntimeChecks="3"
26 RuntimeLibrary="1"
27 StructMemberAlignment="4"
28 ForceConformanceInForLoopScope="TRUE"
29 UsePrecompiledHeader="0"
30 WarningLevel="3"
31 WarnAsError="TRUE"
32 Detect64BitPortabilityProblems="FALSE"
33 DebugInformationFormat="4"/>
34 <Tool
35 Name="VCCustomBuildTool"/>
36 <Tool
37 Name="VCLibrarianTool"
38 OutputFile="$(OutDir)/lscript_library.lib"/>
39 <Tool
40 Name="VCMIDLTool"/>
41 <Tool
42 Name="VCPostBuildEventTool"/>
43 <Tool
44 Name="VCPreBuildEventTool"/>
45 <Tool
46 Name="VCPreLinkEventTool"/>
47 <Tool
48 Name="VCResourceCompilerTool"/>
49 <Tool
50 Name="VCWebServiceProxyGeneratorTool"/>
51 <Tool
52 Name="VCXMLDataGeneratorTool"/>
53 <Tool
54 Name="VCManagedWrapperGeneratorTool"/>
55 <Tool
56 Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
57 </Configuration>
58 <Configuration
59 Name="Release|Win32"
60 OutputDirectory="../../lib_$(ConfigurationName)/i686-win32"
61 IntermediateDirectory="Release"
62 ConfigurationType="4"
63 CharacterSet="1">
64 <Tool
65 Name="VCCLCompilerTool"
66 AdditionalIncludeDirectories="..;..\..\llcommon;..\..\llmath"
67 PreprocessorDefinitions="WIN32;NDEBUG;_LIB;LL_WINDOWS;LL_RELEASE"
68 RuntimeLibrary="0"
69 StructMemberAlignment="0"
70 ForceConformanceInForLoopScope="TRUE"
71 UsePrecompiledHeader="0"
72 WarningLevel="3"
73 WarnAsError="TRUE"
74 Detect64BitPortabilityProblems="FALSE"
75 DebugInformationFormat="3"/>
76 <Tool
77 Name="VCCustomBuildTool"/>
78 <Tool
79 Name="VCLibrarianTool"
80 OutputFile="$(OutDir)/lscript_library.lib"/>
81 <Tool
82 Name="VCMIDLTool"/>
83 <Tool
84 Name="VCPostBuildEventTool"/>
85 <Tool
86 Name="VCPreBuildEventTool"/>
87 <Tool
88 Name="VCPreLinkEventTool"/>
89 <Tool
90 Name="VCResourceCompilerTool"/>
91 <Tool
92 Name="VCWebServiceProxyGeneratorTool"/>
93 <Tool
94 Name="VCXMLDataGeneratorTool"/>
95 <Tool
96 Name="VCManagedWrapperGeneratorTool"/>
97 <Tool
98 Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
99 </Configuration>
100 <Configuration
101 Name="ReleaseNoOpt|Win32"
102 OutputDirectory="../../lib_$(ConfigurationName)/i686-win32"
103 IntermediateDirectory="$(ConfigurationName)"
104 ConfigurationType="4"
105 CharacterSet="1">
106 <Tool
107 Name="VCCLCompilerTool"
108 Optimization="0"
109 AdditionalIncludeDirectories="..;..\..\llcommon;..\..\llmath"
110 PreprocessorDefinitions="WIN32;NDEBUG;_LIB;LL_WINDOWS;LL_RELEASE"
111 RuntimeLibrary="0"
112 StructMemberAlignment="0"
113 ForceConformanceInForLoopScope="TRUE"
114 UsePrecompiledHeader="0"
115 WarningLevel="3"
116 WarnAsError="TRUE"
117 Detect64BitPortabilityProblems="FALSE"
118 DebugInformationFormat="3"/>
119 <Tool
120 Name="VCCustomBuildTool"/>
121 <Tool
122 Name="VCLibrarianTool"
123 OutputFile="$(OutDir)/lscript_library.lib"/>
124 <Tool
125 Name="VCMIDLTool"/>
126 <Tool
127 Name="VCPostBuildEventTool"/>
128 <Tool
129 Name="VCPreBuildEventTool"/>
130 <Tool
131 Name="VCPreLinkEventTool"/>
132 <Tool
133 Name="VCResourceCompilerTool"/>
134 <Tool
135 Name="VCWebServiceProxyGeneratorTool"/>
136 <Tool
137 Name="VCXMLDataGeneratorTool"/>
138 <Tool
139 Name="VCManagedWrapperGeneratorTool"/>
140 <Tool
141 Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
142 </Configuration>
143 </Configurations>
144 <References>
145 </References>
146 <Files>
147 <Filter
148 Name="Source Files"
149 Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
150 UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
151 <File
152 RelativePath=".\lscript_alloc.cpp">
153 </File>
154 <File
155 RelativePath=".\lscript_export.cpp">
156 </File>
157 <File
158 RelativePath=".\lscript_library.cpp">
159 </File>
160 </Filter>
161 <Filter
162 Name="Header Files"
163 Filter="h;hpp;hxx;hm;inl;inc;xsd"
164 UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
165 <File
166 RelativePath="..\lscript_alloc.h">
167 </File>
168 <File
169 RelativePath="..\lscript_export.h">
170 </File>
171 <File
172 RelativePath="..\lscript_library.h">
173 </File>
174 </Filter>
175 <Filter
176 Name="Resource Files"
177 Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
178 UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
179 </Filter>
180 </Files>
181 <Globals>
182 </Globals>
183</VisualStudioProject>
diff --git a/linden/indra/lscript/lscript_rt_interface.h b/linden/indra/lscript/lscript_rt_interface.h
new file mode 100644
index 0000000..c8dceff
--- /dev/null
+++ b/linden/indra/lscript/lscript_rt_interface.h
@@ -0,0 +1,37 @@
1/**
2 * @file lscript_rt_interface.h
3 * @brief Interface between compiler library and applications
4 *
5 * Copyright (c) 2002-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28#ifndef LL_LSCRIPT_RT_INTERFACE_H
29#define LL_LSCRIPT_RT_INTERFACE_H
30
31BOOL lscript_compile(char *filename, BOOL is_god_like = FALSE);
32BOOL lscript_compile(const char* src_filename, const char* dst_filename,
33 const char* err_filename, BOOL is_god_like = FALSE);
34void lscript_run(char *filename, BOOL b_debug);
35
36
37#endif