aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/lscript/lscript_byteconvert.h
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:44:46 -0500
committerJacek Antonelli2008-08-15 23:44:46 -0500
commit38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch)
treeadca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/lscript/lscript_byteconvert.h
parentREADME.txt (diff)
downloadmeta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.zip
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.gz
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.bz2
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.xz
Second Life viewer sources 1.13.2.12
Diffstat (limited to 'linden/indra/lscript/lscript_byteconvert.h')
-rw-r--r--linden/indra/lscript/lscript_byteconvert.h1106
1 files changed, 1106 insertions, 0 deletions
diff --git a/linden/indra/lscript/lscript_byteconvert.h b/linden/indra/lscript/lscript_byteconvert.h
new file mode 100644
index 0000000..de81fd7
--- /dev/null
+++ b/linden/indra/lscript/lscript_byteconvert.h
@@ -0,0 +1,1106 @@
1/**
2 * @file lscript_byteconvert.h
3 * @brief Shared code for compiler and assembler for LSL
4 *
5 * Copyright (c) 2002-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28// data shared between compiler/assembler
29// used to convert data between byte stream and outside data types
30
31#ifndef LL_LSCRIPT_BYTECONVERT_H
32#define LL_LSCRIPT_BYTECONVERT_H
33
34#include "stdtypes.h"
35#include "v3math.h"
36#include "llquaternion.h"
37#include "lscript_byteformat.h"
38#include "lluuid.h"
39
40void reset_hp_to_safe_spot(const U8 *buffer);
41
42// remember that LScript byte stream is BigEndian
43void set_fault(const U8 *stream, LSCRIPTRunTimeFaults fault);
44
45inline S32 bytestream2integer(const U8 *stream, S32 &offset)
46{
47 stream += offset;
48 offset += 4;
49 return (*stream<<24) | (*(stream + 1)<<16) | (*(stream + 2)<<8) | *(stream + 3);
50}
51
52inline U32 bytestream2unsigned_integer(const U8 *stream, S32 &offset)
53{
54 stream += offset;
55 offset += 4;
56 return (*stream<<24) | (*(stream + 1)<<16) | (*(stream + 2)<<8) | *(stream + 3);
57}
58
59inline U64 bytestream2u64(const U8 *stream, S32 &offset)
60{
61 stream += offset;
62 offset += 8;
63 return ((U64)(*stream)<<56)| ((U64)(*(stream + 1))<<48) | ((U64)(*(stream + 2))<<40) | ((U64)(*(stream + 3))<<32) |
64 ((U64)(*(stream + 4))<<24) | ((U64)(*(stream + 5))<<16) | ((U64)(*(stream + 6))<<8) | (U64)(*(stream + 7));
65}
66
67inline void integer2bytestream(U8 *stream, S32 &offset, S32 integer)
68{
69 stream += offset;
70 offset += 4;
71 *(stream) = (integer >> 24);
72 *(stream + 1) = (integer >> 16) & 0xff;
73 *(stream + 2) = (integer >> 8) & 0xff;
74 *(stream + 3) = (integer) & 0xff;
75}
76
77inline void unsigned_integer2bytestream(U8 *stream, S32 &offset, U32 integer)
78{
79 stream += offset;
80 offset += 4;
81 *(stream) = (integer >> 24);
82 *(stream + 1) = (integer >> 16) & 0xff;
83 *(stream + 2) = (integer >> 8) & 0xff;
84 *(stream + 3) = (integer) & 0xff;
85}
86inline void u642bytestream(U8 *stream, S32 &offset, U64 integer)
87{
88 stream += offset;
89 offset += 8;
90 *(stream) = (U8)(integer >> 56);
91 *(stream + 1) = (U8)((integer >> 48) & 0xff);
92 *(stream + 2) = (U8)((integer >> 40) & 0xff);
93 *(stream + 3) = (U8)((integer >> 32) & 0xff);
94 *(stream + 4) = (U8)((integer >> 24) & 0xff);
95 *(stream + 5) = (U8)((integer >> 16) & 0xff);
96 *(stream + 6) = (U8)((integer >> 8) & 0xff);
97 *(stream + 7) = (U8)((integer) & 0xff);
98}
99
100inline S16 bytestream2s16(const U8 *stream, S32 &offset)
101{
102 stream += offset;
103 offset += 2;
104 return (*stream<<8) | *(stream + 1);
105}
106
107inline void s162bytestream(U8 *stream, S32 &offset, S16 integer)
108{
109 stream += offset;
110 offset += 2;
111 *(stream) = (integer >> 8);
112 *(stream + 1) = (integer) & 0xff;
113}
114
115inline U16 bytestream2u16(const U8 *stream, S32 &offset)
116{
117 stream += offset;
118 offset += 2;
119 return (*stream<<8) | *(stream + 1);
120}
121
122inline void u162bytestream(U8 *stream, S32 &offset, U16 integer)
123{
124 stream += offset;
125 offset += 2;
126 *(stream) = (integer >> 8);
127 *(stream + 1) = (integer) & 0xff;
128}
129
130inline F32 bytestream2float(const U8 *stream, S32 &offset)
131{
132 S32 value = bytestream2integer(stream, offset);
133 F32 fpvalue = *(F32 *)&value;
134 if (!llfinite(fpvalue))
135 {
136 fpvalue = 0;
137 set_fault(stream, LSRF_MATH);
138 }
139 return fpvalue;
140}
141
142inline void float2bytestream(U8 *stream, S32 &offset, F32 floatingpoint)
143{
144 S32 value = *(S32 *)&floatingpoint;
145 integer2bytestream(stream, offset, value);
146}
147
148inline void bytestream_int2float(U8 *stream, S32 &offset)
149{
150 S32 value = bytestream2integer(stream, offset);
151 offset -= 4;
152 F32 fpvalue = (F32)value;
153 if (!llfinite(fpvalue))
154 {
155 fpvalue = 0;
156 set_fault(stream, LSRF_MATH);
157 }
158 float2bytestream(stream, offset, fpvalue);
159}
160
161inline void bytestream2char(char *buffer, const U8 *stream, S32 &offset)
162{
163 while ((*buffer++ = *(stream + offset++)))
164 ;
165}
166
167inline void char2bytestream(U8 *stream, S32 &offset, char *buffer)
168{
169 while ((*(stream + offset++) = *buffer++))
170 ;
171}
172
173inline U8 bytestream2byte(const U8 *stream, S32 &offset)
174{
175 return *(stream + offset++);
176}
177
178inline void byte2bytestream(U8 *stream, S32 &offset, U8 byte)
179{
180 *(stream + offset++) = byte;
181}
182
183inline void bytestream2bytestream(U8 *dest, S32 &dest_offset, const U8 *src, S32 &src_offset, S32 count)
184{
185 while (count)
186 {
187 (*(dest + dest_offset++)) = (*(src + src_offset++));
188 count--;
189 }
190}
191
192inline void uuid2bytestream(U8 *stream, S32 &offset, const LLUUID &uuid)
193{
194 S32 i;
195 for (i = 0; i < UUID_BYTES; i++)
196 {
197 *(stream + offset++) = uuid.mData[i];
198 }
199}
200
201inline void bytestream2uuid(U8 *stream, S32 &offset, LLUUID &uuid)
202{
203 S32 i;
204 for (i = 0; i < UUID_BYTES; i++)
205 {
206 uuid.mData[i] = *(stream + offset++);
207 }
208}
209
210// vectors and quaternions and encoded in backwards order to match the way in which they are stored on the stack
211inline void bytestream2vector(LLVector3 &vector, const U8 *stream, S32 &offset)
212{
213 S32 value = bytestream2integer(stream, offset);
214 vector.mV[VZ] = *(F32 *)&value;
215 if (!llfinite(vector.mV[VZ]))
216 {
217 vector.mV[VZ] = 0;
218 set_fault(stream, LSRF_MATH);
219 }
220 value = bytestream2integer(stream, offset);
221 vector.mV[VY] = *(F32 *)&value;
222 if (!llfinite(vector.mV[VY]))
223 {
224 vector.mV[VY] = 0;
225 set_fault(stream, LSRF_MATH);
226 }
227 value = bytestream2integer(stream, offset);
228 vector.mV[VX] = *(F32 *)&value;
229 if (!llfinite(vector.mV[VX]))
230 {
231 vector.mV[VX] = 0;
232 set_fault(stream, LSRF_MATH);
233 }
234}
235
236inline void vector2bytestream(U8 *stream, S32 &offset, LLVector3 &vector)
237{
238 S32 value = *(S32 *)&vector.mV[VZ];
239 integer2bytestream(stream, offset, value);
240 value = *(S32 *)&vector.mV[VY];
241 integer2bytestream(stream, offset, value);
242 value = *(S32 *)&vector.mV[VX];
243 integer2bytestream(stream, offset, value);
244}
245
246inline void bytestream2quaternion(LLQuaternion &quat, const U8 *stream, S32 &offset)
247{
248 S32 value = bytestream2integer(stream, offset);
249 quat.mQ[VS] = *(F32 *)&value;
250 if (!llfinite(quat.mQ[VS]))
251 {
252 quat.mQ[VS] = 0;
253 set_fault(stream, LSRF_MATH);
254 }
255 value = bytestream2integer(stream, offset);
256 quat.mQ[VZ] = *(F32 *)&value;
257 if (!llfinite(quat.mQ[VZ]))
258 {
259 quat.mQ[VZ] = 0;
260 set_fault(stream, LSRF_MATH);
261 }
262 value = bytestream2integer(stream, offset);
263 quat.mQ[VY] = *(F32 *)&value;
264 if (!llfinite(quat.mQ[VY]))
265 {
266 quat.mQ[VY] = 0;
267 set_fault(stream, LSRF_MATH);
268 }
269 value = bytestream2integer(stream, offset);
270 quat.mQ[VX] = *(F32 *)&value;
271 if (!llfinite(quat.mQ[VX]))
272 {
273 quat.mQ[VX] = 0;
274 set_fault(stream, LSRF_MATH);
275 }
276}
277
278inline void quaternion2bytestream(U8 *stream, S32 &offset, LLQuaternion &quat)
279{
280 S32 value = *(S32 *)&quat.mQ[VS];
281 integer2bytestream(stream, offset, value);
282 value = *(S32 *)&quat.mQ[VZ];
283 integer2bytestream(stream, offset, value);
284 value = *(S32 *)&quat.mQ[VY];
285 integer2bytestream(stream, offset, value);
286 value = *(S32 *)&quat.mQ[VX];
287 integer2bytestream(stream, offset, value);
288}
289
290inline S32 get_register(const U8 *stream, LSCRIPTRegisters reg)
291{
292 S32 offset = gLSCRIPTRegisterAddresses[reg];
293 return bytestream2integer(stream, offset);
294}
295
296inline F32 get_register_fp(U8 *stream, LSCRIPTRegisters reg)
297{
298 S32 offset = gLSCRIPTRegisterAddresses[reg];
299 F32 value = bytestream2float(stream, offset);
300 if (!llfinite(value))
301 {
302 value = 0;
303 set_fault(stream, LSRF_MATH);
304 }
305 return value;
306}
307inline U64 get_register_u64(U8 *stream, LSCRIPTRegisters reg)
308{
309 S32 offset = gLSCRIPTRegisterAddresses[reg];
310 return bytestream2u64(stream, offset);
311}
312
313inline U64 get_event_register(U8 *stream, LSCRIPTRegisters reg, S32 major_version)
314{
315 if (major_version == 1)
316 {
317 S32 offset = gLSCRIPTRegisterAddresses[reg];
318 return (U64)bytestream2integer(stream, offset);
319 }
320 else if (major_version == 2)
321 {
322 S32 offset = gLSCRIPTRegisterAddresses[reg + (LREG_NCE - LREG_CE)];
323 return bytestream2u64(stream, offset);
324 }
325 else
326 {
327 S32 offset = gLSCRIPTRegisterAddresses[reg];
328 return (U64)bytestream2integer(stream, offset);
329 }
330}
331
332inline void set_register(U8 *stream, LSCRIPTRegisters reg, S32 value)
333{
334 S32 offset = gLSCRIPTRegisterAddresses[reg];
335 integer2bytestream(stream, offset, value);
336}
337
338inline void set_register_fp(U8 *stream, LSCRIPTRegisters reg, F32 value)
339{
340 S32 offset = gLSCRIPTRegisterAddresses[reg];
341 float2bytestream(stream, offset, value);
342}
343
344inline void set_register_u64(U8 *stream, LSCRIPTRegisters reg, U64 value)
345{
346 S32 offset = gLSCRIPTRegisterAddresses[reg];
347 u642bytestream(stream, offset, value);
348}
349
350inline void set_event_register(U8 *stream, LSCRIPTRegisters reg, U64 value, S32 major_version)
351{
352 if (major_version == 1)
353 {
354 S32 offset = gLSCRIPTRegisterAddresses[reg];
355 integer2bytestream(stream, offset, (S32)value);
356 }
357 else if (major_version == 2)
358 {
359 S32 offset = gLSCRIPTRegisterAddresses[reg + (LREG_NCE - LREG_CE)];
360 u642bytestream(stream, offset, value);
361 }
362 else
363 {
364 S32 offset = gLSCRIPTRegisterAddresses[reg];
365 integer2bytestream(stream, offset, (S32)value);
366 }
367}
368
369
370inline F32 add_register_fp(U8 *stream, LSCRIPTRegisters reg, F32 value)
371{
372 S32 offset = gLSCRIPTRegisterAddresses[reg];
373 F32 newvalue = bytestream2float(stream, offset);
374 newvalue += value;
375 if (!llfinite(newvalue))
376 {
377 newvalue = 0;
378 set_fault(stream, LSRF_MATH);
379 }
380 offset = gLSCRIPTRegisterAddresses[reg];
381 float2bytestream(stream, offset, newvalue);
382 return newvalue;
383}
384
385void lsa_print_heap(U8 *buffer);
386
387
388inline void set_fault(const U8 *stream, LSCRIPTRunTimeFaults fault)
389{
390 S32 fr = get_register(stream, LREG_FR);
391 // record the first error
392 if (!fr)
393 {
394 if ( (fault == LSRF_HEAP_ERROR)
395 ||(fault == LSRF_STACK_HEAP_COLLISION)
396 ||(fault == LSRF_BOUND_CHECK_ERROR))
397 {
398 reset_hp_to_safe_spot(stream);
399// lsa_print_heap((U8 *)stream);
400 }
401 fr = LSCRIPTRunTimeFaultBits[fault];
402 set_register((U8 *)stream, LREG_FR, fr);
403 }
404}
405
406inline BOOL set_ip(U8 *stream, S32 ip)
407{
408 // Verify that the Instruction Pointer is in a valid
409 // code area (between the Global Function Register
410 // and Heap Register).
411 S32 gfr = get_register(stream, LREG_GFR);
412 if (ip == 0)
413 {
414 set_register(stream, LREG_IP, ip);
415 return TRUE;
416 }
417 if (ip < gfr)
418 {
419 set_fault(stream, LSRF_BOUND_CHECK_ERROR);
420 return FALSE;
421 }
422 S32 hr = get_register(stream, LREG_HR);
423 if (ip >= hr)
424 {
425 set_fault(stream, LSRF_BOUND_CHECK_ERROR);
426 return FALSE;
427 }
428 set_register(stream, LREG_IP, ip);
429 return TRUE;
430}
431
432inline BOOL set_bp(U8 *stream, S32 bp)
433{
434 // Verify that the Base Pointer is in a valid
435 // data area (between the Heap Pointer and
436 // the Top of Memory, and below the
437 // Stack Pointer).
438 S32 hp = get_register(stream, LREG_HP);
439 if (bp <= hp)
440 {
441 set_fault(stream, LSRF_STACK_HEAP_COLLISION);
442 return FALSE;
443 }
444 S32 tm = get_register(stream, LREG_TM);
445 if (bp >= tm)
446 {
447 set_fault(stream, LSRF_BOUND_CHECK_ERROR);
448 return FALSE;
449 }
450 S32 sp = get_register(stream, LREG_SP);
451 if (bp < sp)
452 {
453 set_fault(stream, LSRF_BOUND_CHECK_ERROR);
454 return FALSE;
455 }
456 set_register(stream, LREG_BP, bp);
457 return TRUE;
458}
459
460inline BOOL set_sp(U8 *stream, S32 sp)
461{
462 // Verify that the Stack Pointer is in a valid
463 // data area (between the Heap Pointer and
464 // the Top of Memory).
465 S32 hp = get_register(stream, LREG_HP);
466 if (sp <= hp)
467 {
468 set_fault(stream, LSRF_STACK_HEAP_COLLISION);
469 return FALSE;
470 }
471 S32 tm = get_register(stream, LREG_TM);
472 if (sp >= tm)
473 {
474 set_fault(stream, LSRF_BOUND_CHECK_ERROR);
475 return FALSE;
476 }
477 set_register(stream, LREG_SP, sp);
478 return TRUE;
479}
480
481inline void lscript_push(U8 *stream, U8 value)
482{
483 S32 sp = get_register(stream, LREG_SP);
484 sp -= 1;
485
486 if (set_sp(stream, sp))
487 {
488 *(stream + sp) = value;
489 }
490}
491
492inline void lscript_push(U8 *stream, S32 value)
493{
494 S32 sp = get_register(stream, LREG_SP);
495 sp -= LSCRIPTDataSize[LST_INTEGER];
496
497 if (set_sp(stream, sp))
498 {
499 integer2bytestream(stream, sp, value);
500 }
501}
502
503inline void lscript_push(U8 *stream, F32 value)
504{
505 S32 sp = get_register(stream, LREG_SP);
506 sp -= LSCRIPTDataSize[LST_FLOATINGPOINT];
507
508 if (set_sp(stream, sp))
509 {
510 float2bytestream(stream, sp, value);
511 }
512}
513
514inline void lscript_push(U8 *stream, LLVector3 &value)
515{
516 S32 sp = get_register(stream, LREG_SP);
517 sp -= LSCRIPTDataSize[LST_VECTOR];
518
519 if (set_sp(stream, sp))
520 {
521 vector2bytestream(stream, sp, value);
522 }
523}
524
525inline void lscript_push(U8 *stream, LLQuaternion &value)
526{
527 S32 sp = get_register(stream, LREG_SP);
528 sp -= LSCRIPTDataSize[LST_QUATERNION];
529
530 if (set_sp(stream, sp))
531 {
532 quaternion2bytestream(stream, sp, value);
533 }
534}
535
536inline void lscript_pusharg(U8 *stream, S32 arg)
537{
538 S32 sp = get_register(stream, LREG_SP);
539 sp -= arg;
540
541 set_sp(stream, sp);
542}
543
544inline void lscript_poparg(U8 *stream, S32 arg)
545{
546 S32 sp = get_register(stream, LREG_SP);
547 sp += arg;
548
549 set_sp(stream, sp);
550}
551
552inline U8 lscript_pop_char(U8 *stream)
553{
554 S32 sp = get_register(stream, LREG_SP);
555 U8 value = *(stream + sp++);
556 set_sp(stream, sp);
557 return value;
558}
559
560inline S32 lscript_pop_int(U8 *stream)
561{
562 S32 sp = get_register(stream, LREG_SP);
563 S32 value = bytestream2integer(stream, sp);
564 set_sp(stream, sp);
565 return value;
566}
567
568inline F32 lscript_pop_float(U8 *stream)
569{
570 S32 sp = get_register(stream, LREG_SP);
571 F32 value = bytestream2float(stream, sp);
572 if (!llfinite(value))
573 {
574 value = 0;
575 set_fault(stream, LSRF_MATH);
576 }
577 set_sp(stream, sp);
578 return value;
579}
580
581inline void lscript_pop_vector(U8 *stream, LLVector3 &value)
582{
583 S32 sp = get_register(stream, LREG_SP);
584 bytestream2vector(value, stream, sp);
585 set_sp(stream, sp);
586}
587
588inline void lscript_pop_quaternion(U8 *stream, LLQuaternion &value)
589{
590 S32 sp = get_register(stream, LREG_SP);
591 bytestream2quaternion(value, stream, sp);
592 set_sp(stream, sp);
593}
594
595inline void lscript_pusharge(U8 *stream, S32 value)
596{
597 S32 sp = get_register(stream, LREG_SP);
598 sp -= value;
599 if (set_sp(stream, sp))
600 {
601 S32 i;
602 for (i = 0; i < value; i++)
603 {
604 *(stream + sp++) = 0;
605 }
606 }
607}
608
609inline BOOL lscript_check_local(U8 *stream, S32 &address, S32 size)
610{
611 S32 sp = get_register(stream, LREG_SP);
612 S32 bp = get_register(stream, LREG_BP);
613
614 address += size;
615 address = bp - address;
616
617 if (address < sp - size)
618 {
619 set_fault(stream, LSRF_BOUND_CHECK_ERROR);
620 return FALSE;
621 }
622 S32 tm = get_register(stream, LREG_TM);
623 if (address + size > tm)
624 {
625 set_fault(stream, LSRF_BOUND_CHECK_ERROR);
626 return FALSE;
627 }
628 return TRUE;
629}
630
631inline BOOL lscript_check_global(U8 *stream, S32 &address, S32 size)
632{
633 S32 gvr = get_register(stream, LREG_GVR);
634
635 // Possibility of overwriting registers? -- DK 09/07/04
636 if (address < 0)
637 {
638 set_fault(stream, LSRF_BOUND_CHECK_ERROR);
639 return FALSE;
640 }
641
642 address += gvr;
643 S32 gfr = get_register(stream, LREG_GFR);
644
645 if (address + size > gfr)
646 {
647 set_fault(stream, LSRF_BOUND_CHECK_ERROR);
648 return FALSE;
649 }
650 return TRUE;
651}
652
653inline void lscript_local_store(U8 *stream, S32 address, S32 value)
654{
655 if (lscript_check_local(stream, address, LSCRIPTDataSize[LST_INTEGER]))
656 integer2bytestream(stream, address, value);
657}
658
659inline void lscript_local_store(U8 *stream, S32 address, F32 value)
660{
661 if (lscript_check_local(stream, address, LSCRIPTDataSize[LST_FLOATINGPOINT]))
662 float2bytestream(stream, address, value);
663}
664
665inline void lscript_local_store(U8 *stream, S32 address, LLVector3 value)
666{
667 if (lscript_check_local(stream, address, LSCRIPTDataSize[LST_VECTOR]))
668 vector2bytestream(stream, address, value);
669}
670
671inline void lscript_local_store(U8 *stream, S32 address, LLQuaternion value)
672{
673 if (lscript_check_local(stream, address, LSCRIPTDataSize[LST_QUATERNION]))
674 quaternion2bytestream(stream, address, value);
675}
676
677inline void lscript_global_store(U8 *stream, S32 address, S32 value)
678{
679 if (lscript_check_global(stream, address, LSCRIPTDataSize[LST_INTEGER]))
680 integer2bytestream(stream, address, value);
681}
682
683inline void lscript_global_store(U8 *stream, S32 address, F32 value)
684{
685 if (lscript_check_global(stream, address, LSCRIPTDataSize[LST_FLOATINGPOINT]))
686 float2bytestream(stream, address, value);
687}
688
689inline void lscript_global_store(U8 *stream, S32 address, LLVector3 value)
690{
691 if (lscript_check_global(stream, address, LSCRIPTDataSize[LST_VECTOR]))
692 vector2bytestream(stream, address, value);
693}
694
695inline void lscript_global_store(U8 *stream, S32 address, LLQuaternion value)
696{
697 if (lscript_check_global(stream, address, LSCRIPTDataSize[LST_QUATERNION]))
698 quaternion2bytestream(stream, address, value);
699}
700
701inline S32 lscript_local_get(U8 *stream, S32 address)
702{
703 if (lscript_check_local(stream, address, LSCRIPTDataSize[LST_INTEGER]))
704 return bytestream2integer(stream, address);
705 return 0;
706}
707
708inline void lscript_local_get(U8 *stream, S32 address, F32 &value)
709{
710 if (lscript_check_local(stream, address, LSCRIPTDataSize[LST_FLOATINGPOINT]))
711 value = bytestream2float(stream, address);
712 if (!llfinite(value))
713 {
714 value = 0;
715 set_fault(stream, LSRF_MATH);
716 }
717}
718
719inline void lscript_local_get(U8 *stream, S32 address, LLVector3 &value)
720{
721 if (lscript_check_local(stream, address, LSCRIPTDataSize[LST_VECTOR]))
722 bytestream2vector(value, stream, address);
723}
724
725inline void lscript_local_get(U8 *stream, S32 address, LLQuaternion &value)
726{
727 if (lscript_check_local(stream, address, LSCRIPTDataSize[LST_QUATERNION]))
728 bytestream2quaternion(value, stream, address);
729}
730
731inline S32 lscript_global_get(U8 *stream, S32 address)
732{
733 if (lscript_check_global(stream, address, LSCRIPTDataSize[LST_INTEGER]))
734 return bytestream2integer(stream, address);
735 return 0;
736}
737
738inline void lscript_global_get(U8 *stream, S32 address, F32 &value)
739{
740 if (lscript_check_global(stream, address, LSCRIPTDataSize[LST_FLOATINGPOINT]))
741 value = bytestream2float(stream, address);
742 if (!llfinite(value))
743 {
744 value = 0;
745 set_fault(stream, LSRF_MATH);
746 }
747}
748
749inline void lscript_global_get(U8 *stream, S32 address, LLVector3 &value)
750{
751 if (lscript_check_global(stream, address, LSCRIPTDataSize[LST_VECTOR]))
752 bytestream2vector(value, stream, address);
753}
754
755inline void lscript_global_get(U8 *stream, S32 address, LLQuaternion &value)
756{
757 if (lscript_check_global(stream, address, LSCRIPTDataSize[LST_QUATERNION]))
758 bytestream2quaternion(value, stream, address);
759}
760
761
762
763inline S32 get_state_event_opcoode_start(U8 *stream, S32 state, LSCRIPTStateEventType event)
764{
765 // get the start of the state table
766 S32 sr = get_register(stream, LREG_SR);
767
768 // get the position of the jump to the desired state
769 S32 value = get_register(stream, LREG_VN);
770
771 S32 state_offset_offset = 0;
772 S32 major_version = 0;
773 if (value == LSL2_VERSION1_END_NUMBER)
774 {
775 major_version = LSL2_MAJOR_VERSION_ONE;
776 state_offset_offset = sr + LSCRIPTDataSize[LST_INTEGER] + LSCRIPTDataSize[LST_INTEGER]*2*state;
777 }
778 else if (value == LSL2_VERSION_NUMBER)
779 {
780 major_version = LSL2_MAJOR_VERSION_TWO;
781 state_offset_offset = sr + LSCRIPTDataSize[LST_INTEGER] + LSCRIPTDataSize[LST_INTEGER]*3*state;
782 }
783
784 // get the actual position in memory of the desired state
785 S32 state_offset = sr + bytestream2integer(stream, state_offset_offset);
786
787 // save that value
788 S32 state_offset_base = state_offset;
789
790 // jump past the state name
791 S32 event_jump_offset = state_offset_base + bytestream2integer(stream, state_offset);
792
793 // get the location of the event offset
794 S32 event_offset = event_jump_offset + LSCRIPTDataSize[LST_INTEGER]*2*get_event_handler_jump_position(get_event_register(stream, LREG_ER, major_version), event);
795
796 // now, jump to the event
797 S32 event_start = bytestream2integer(stream, event_offset);
798 event_start += event_jump_offset;
799
800 S32 event_start_original = event_start;
801
802 // now skip past the parameters
803 S32 opcode_offset = bytestream2integer(stream, event_start);
804 return opcode_offset + event_start_original;
805}
806
807inline U64 get_handled_events(U8 *stream, S32 state)
808{
809 U64 retvalue = 0;
810 // get the start of the state table
811 S32 sr = get_register(stream, LREG_SR);
812
813 // get the position of the jump to the desired state
814 S32 value = get_register(stream, LREG_VN);
815 S32 state_handled_offset = 0;
816 if (value == LSL2_VERSION1_END_NUMBER)
817 {
818 state_handled_offset = sr + LSCRIPTDataSize[LST_INTEGER]*2*state + 2*LSCRIPTDataSize[LST_INTEGER];
819 retvalue = bytestream2integer(stream, state_handled_offset);
820 }
821 else if (value == LSL2_VERSION_NUMBER)
822 {
823 state_handled_offset = sr + LSCRIPTDataSize[LST_INTEGER]*3*state + 2*LSCRIPTDataSize[LST_INTEGER];
824 retvalue = bytestream2u64(stream, state_handled_offset);
825 }
826
827 // get the handled events
828 return retvalue;
829}
830
831inline S32 get_event_stack_size(U8 *stream, S32 state, LSCRIPTStateEventType event)
832{
833 // get the start of the state table
834 S32 sr = get_register(stream, LREG_SR);
835
836 // get state offset
837 S32 value = get_register(stream, LREG_VN);
838 S32 state_offset_offset = 0;
839 S32 major_version = 0;
840 if (value == LSL2_VERSION1_END_NUMBER)
841 {
842 major_version = LSL2_MAJOR_VERSION_ONE;
843 state_offset_offset = sr + LSCRIPTDataSize[LST_INTEGER] + LSCRIPTDataSize[LST_INTEGER]*2*state;
844 }
845 else if (value == LSL2_VERSION_NUMBER)
846 {
847 major_version = LSL2_MAJOR_VERSION_TWO;
848 state_offset_offset = sr + LSCRIPTDataSize[LST_INTEGER] + LSCRIPTDataSize[LST_INTEGER]*3*state;
849 }
850
851 S32 state_offset = bytestream2integer(stream, state_offset_offset);
852 state_offset += sr;
853
854 state_offset_offset = state_offset;
855
856 // skip to jump table
857 S32 jump_table = bytestream2integer(stream, state_offset_offset);
858
859 jump_table += state_offset;
860
861 // get the position of the jump to the desired state
862 S32 stack_size_offset = jump_table + LSCRIPTDataSize[LST_INTEGER]*2*get_event_handler_jump_position(get_event_register(stream, LREG_ER, major_version), event) + LSCRIPTDataSize[LST_INTEGER];
863
864 // get the handled events
865 S32 stack_size = bytestream2integer(stream, stack_size_offset);
866 return stack_size;
867}
868
869inline LSCRIPTStateEventType return_first_event(S32 event)
870{
871 S32 count = 1;
872 while (count < LSTT_EOF)
873 {
874 if (event & 0x1)
875 {
876 return (LSCRIPTStateEventType) count;
877 }
878 else
879 {
880 event >>= 1;
881 count++;
882 }
883 }
884 return LSTT_NULL;
885}
886
887
888// the safe instruction versions of these commands will only work if offset is between
889// GFR and HR, meaning that it is an instruction (more or less) in global functions or event handlers
890
891inline BOOL safe_instruction_check_address(U8 *stream, S32 offset, S32 size)
892{
893 S32 gfr = get_register(stream, LREG_GFR);
894 if (offset < gfr)
895 {
896 set_fault(stream, LSRF_BOUND_CHECK_ERROR);
897 return FALSE;
898 }
899 else
900 {
901 S32 hr = get_register(stream, LREG_HR);
902 if (offset + size > hr)
903 {
904 set_fault(stream, LSRF_BOUND_CHECK_ERROR);
905 return FALSE;
906 }
907 else
908 {
909 return TRUE;
910 }
911 }
912}
913
914inline BOOL safe_heap_check_address(U8 *stream, S32 offset, S32 size)
915{
916 S32 hr = get_register(stream, LREG_HR);
917 if (offset < hr)
918 {
919 set_fault(stream, LSRF_BOUND_CHECK_ERROR);
920 return FALSE;
921 }
922 else
923 {
924 S32 hp = get_register(stream, LREG_HP);
925 if (offset + size > hp)
926 {
927 set_fault(stream, LSRF_BOUND_CHECK_ERROR);
928 return FALSE;
929 }
930 else
931 {
932 return TRUE;
933 }
934 }
935}
936
937inline U8 safe_instruction_bytestream2byte(U8 *stream, S32 &offset)
938{
939 if (safe_instruction_check_address(stream, offset, 1))
940 {
941 return *(stream + offset++);
942 }
943 else
944 {
945 return 0;
946 }
947}
948
949inline void safe_instruction_byte2bytestream(U8 *stream, S32 &offset, U8 byte)
950{
951 if (safe_instruction_check_address(stream, offset, 1))
952 {
953 *(stream + offset++) = byte;
954 }
955}
956
957inline S32 safe_instruction_bytestream2integer(U8 *stream, S32 &offset)
958{
959 if (safe_instruction_check_address(stream, offset, LSCRIPTDataSize[LST_INTEGER]))
960 {
961 return (bytestream2integer(stream, offset));
962 }
963 else
964 {
965 return 0;
966 }
967}
968
969inline void safe_instruction_integer2bytestream(U8 *stream, S32 &offset, S32 value)
970{
971 if (safe_instruction_check_address(stream, offset, LSCRIPTDataSize[LST_INTEGER]))
972 {
973 integer2bytestream(stream, offset, value);
974 }
975}
976
977inline U16 safe_instruction_bytestream2u16(U8 *stream, S32 &offset)
978{
979 if (safe_instruction_check_address(stream, offset, 2))
980 {
981 return (bytestream2u16(stream, offset));
982 }
983 else
984 {
985 return 0;
986 }
987}
988
989inline void safe_instruction_u162bytestream(U8 *stream, S32 &offset, U16 value)
990{
991 if (safe_instruction_check_address(stream, offset, 2))
992 {
993 u162bytestream(stream, offset, value);
994 }
995}
996
997inline F32 safe_instruction_bytestream2float(U8 *stream, S32 &offset)
998{
999 if (safe_instruction_check_address(stream, offset, LSCRIPTDataSize[LST_INTEGER]))
1000 {
1001 F32 value = bytestream2float(stream, offset);
1002 if (!llfinite(value))
1003 {
1004 value = 0;
1005 set_fault(stream, LSRF_MATH);
1006 }
1007 return value;
1008 }
1009 else
1010 {
1011 return 0;
1012 }
1013}
1014
1015inline void safe_instruction_float2bytestream(U8 *stream, S32 &offset, F32 value)
1016{
1017 if (safe_instruction_check_address(stream, offset, LSCRIPTDataSize[LST_FLOATINGPOINT]))
1018 {
1019 float2bytestream(stream, offset, value);
1020 }
1021}
1022
1023inline void safe_instruction_bytestream2char(char *buffer, U8 *stream, S32 &offset)
1024{
1025 while ( (safe_instruction_check_address(stream, offset, 1))
1026 &&(*buffer++ = *(stream + offset++)))
1027 ;
1028}
1029
1030inline void safe_instruction_bytestream_count_char(U8 *stream, S32 &offset)
1031{
1032 while ( (safe_instruction_check_address(stream, offset, 1))
1033 &&(*(stream + offset++)))
1034 ;
1035}
1036
1037inline void safe_heap_bytestream_count_char(U8 *stream, S32 &offset)
1038{
1039 while ( (safe_heap_check_address(stream, offset, 1))
1040 &&(*(stream + offset++)))
1041 ;
1042}
1043
1044inline void safe_instruction_char2bytestream(U8 *stream, S32 &offset, char *buffer)
1045{
1046 while ( (safe_instruction_check_address(stream, offset, 1))
1047 &&(*(stream + offset++) = *buffer++))
1048 ;
1049}
1050
1051inline void safe_instruction_bytestream2vector(LLVector3 &value, U8 *stream, S32 &offset)
1052{
1053 if (safe_instruction_check_address(stream, offset, LSCRIPTDataSize[LST_VECTOR]))
1054 {
1055 bytestream2vector(value, stream, offset);
1056 }
1057}
1058
1059inline void safe_instruction_vector2bytestream(U8 *stream, S32 &offset, LLVector3 &value)
1060{
1061 if (safe_instruction_check_address(stream, offset, LSCRIPTDataSize[LST_VECTOR]))
1062 {
1063 vector2bytestream(stream, offset, value);
1064 }
1065}
1066
1067inline void safe_instruction_bytestream2quaternion(LLQuaternion &value, U8 *stream, S32 &offset)
1068{
1069 if (safe_instruction_check_address(stream, offset, LSCRIPTDataSize[LST_QUATERNION]))
1070 {
1071 bytestream2quaternion(value, stream, offset);
1072 }
1073}
1074
1075inline void safe_instruction_quaternion2bytestream(U8 *stream, S32 &offset, LLQuaternion &value)
1076{
1077 if (safe_instruction_check_address(stream, offset, LSCRIPTDataSize[LST_QUATERNION]))
1078 {
1079 quaternion2bytestream(stream, offset, value);
1080 }
1081}
1082
1083static inline LSCRIPTType char2type(char type)
1084{
1085 switch(type)
1086 {
1087 case 'i':
1088 return LST_INTEGER;
1089 case 'f':
1090 return LST_FLOATINGPOINT;
1091 case 's':
1092 return LST_STRING;
1093 case 'k':
1094 return LST_KEY;
1095 case 'v':
1096 return LST_VECTOR;
1097 case 'q':
1098 return LST_QUATERNION;
1099 case 'l':
1100 return LST_LIST;
1101 default:
1102 return LST_NULL;
1103 }
1104}
1105
1106#endif