aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/lscript/lscript_execute/lscript_execute.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/lscript/lscript_execute/lscript_execute.cpp')
-rw-r--r--linden/indra/lscript/lscript_execute/lscript_execute.cpp3929
1 files changed, 3929 insertions, 0 deletions
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}