summaryrefslogtreecommitdiff
path: root/indra/lscript/lscript_byteconvert.h
diff options
context:
space:
mode:
Diffstat (limited to 'indra/lscript/lscript_byteconvert.h')
-rwxr-xr-xindra/lscript/lscript_byteconvert.h1170
1 files changed, 0 insertions, 1170 deletions
diff --git a/indra/lscript/lscript_byteconvert.h b/indra/lscript/lscript_byteconvert.h
deleted file mode 100755
index 5b08481d7d..0000000000
--- a/indra/lscript/lscript_byteconvert.h
+++ /dev/null
@@ -1,1170 +0,0 @@
-/**
- * @file lscript_byteconvert.h
- * @brief Shared code for compiler and assembler for LSL
- *
- * $LicenseInfo:firstyear=2002&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-// data shared between compiler/assembler
-// used to convert data between byte stream and outside data types
-
-#ifndef LL_LSCRIPT_BYTECONVERT_H
-#define LL_LSCRIPT_BYTECONVERT_H
-
-#include "stdtypes.h"
-#include "v3math.h"
-#include "llquaternion.h"
-#include "lscript_byteformat.h"
-#include "lluuid.h"
-
-void reset_hp_to_safe_spot(const U8 *buffer);
-
-// remember that LScript byte stream is BigEndian
-void set_fault(const U8 *stream, LSCRIPTRunTimeFaults fault);
-
-inline S32 bytestream2integer(const U8 *stream, S32 &offset)
-{
- stream += offset;
- offset += 4;
- return (*stream<<24) | (*(stream + 1)<<16) | (*(stream + 2)<<8) | *(stream + 3);
-}
-
-inline U32 bytestream2unsigned_integer(const U8 *stream, S32 &offset)
-{
- stream += offset;
- offset += 4;
- return (*stream<<24) | (*(stream + 1)<<16) | (*(stream + 2)<<8) | *(stream + 3);
-}
-
-inline U64 bytestream2u64(const U8 *stream, S32 &offset)
-{
- stream += offset;
- offset += 8;
- return ((U64)(*stream)<<56)| ((U64)(*(stream + 1))<<48) | ((U64)(*(stream + 2))<<40) | ((U64)(*(stream + 3))<<32) |
- ((U64)(*(stream + 4))<<24) | ((U64)(*(stream + 5))<<16) | ((U64)(*(stream + 6))<<8) | (U64)(*(stream + 7));
-}
-
-inline void integer2bytestream(U8 *stream, S32 &offset, S32 integer)
-{
- stream += offset;
- offset += 4;
- *(stream) = (integer >> 24);
- *(stream + 1) = (integer >> 16) & 0xff;
- *(stream + 2) = (integer >> 8) & 0xff;
- *(stream + 3) = (integer) & 0xff;
-}
-
-inline void unsigned_integer2bytestream(U8 *stream, S32 &offset, U32 integer)
-{
- stream += offset;
- offset += 4;
- *(stream) = (integer >> 24);
- *(stream + 1) = (integer >> 16) & 0xff;
- *(stream + 2) = (integer >> 8) & 0xff;
- *(stream + 3) = (integer) & 0xff;
-}
-inline void u642bytestream(U8 *stream, S32 &offset, U64 integer)
-{
- stream += offset;
- offset += 8;
- *(stream) = (U8)(integer >> 56);
- *(stream + 1) = (U8)((integer >> 48) & 0xff);
- *(stream + 2) = (U8)((integer >> 40) & 0xff);
- *(stream + 3) = (U8)((integer >> 32) & 0xff);
- *(stream + 4) = (U8)((integer >> 24) & 0xff);
- *(stream + 5) = (U8)((integer >> 16) & 0xff);
- *(stream + 6) = (U8)((integer >> 8) & 0xff);
- *(stream + 7) = (U8)((integer) & 0xff);
-}
-
-inline S16 bytestream2s16(const U8 *stream, S32 &offset)
-{
- stream += offset;
- offset += 2;
- return (*stream<<8) | *(stream + 1);
-}
-
-inline void s162bytestream(U8 *stream, S32 &offset, S16 integer)
-{
- stream += offset;
- offset += 2;
- *(stream) = (integer >> 8);
- *(stream + 1) = (integer) & 0xff;
-}
-
-inline U16 bytestream2u16(const U8 *stream, S32 &offset)
-{
- stream += offset;
- offset += 2;
- return (*stream<<8) | *(stream + 1);
-}
-
-inline void u162bytestream(U8 *stream, S32 &offset, U16 integer)
-{
- stream += offset;
- offset += 2;
- *(stream) = (integer >> 8);
- *(stream + 1) = (integer) & 0xff;
-}
-
-inline F32 bytestream2float(const U8 *stream, S32 &offset)
-{
- S32 value = bytestream2integer(stream, offset);
- F32 fpvalue = *(F32 *)&value;
- if (!llfinite(fpvalue))
- {
- fpvalue = 0;
- set_fault(stream, LSRF_MATH);
- }
- return fpvalue;
-}
-
-inline void float2bytestream(U8 *stream, S32 &offset, F32 floatingpoint)
-{
- S32 value = *(S32 *)&floatingpoint;
- integer2bytestream(stream, offset, value);
-}
-
-inline void bytestream_int2float(U8 *stream, S32 &offset)
-{
- S32 value = bytestream2integer(stream, offset);
- offset -= 4;
- F32 fpvalue = (F32)value;
- if (!llfinite(fpvalue))
- {
- fpvalue = 0;
- set_fault(stream, LSRF_MATH);
- }
- float2bytestream(stream, offset, fpvalue);
-}
-
-// Returns true on success, return false and clip copy on buffer overflow
-inline bool bytestream2char(char *buffer, const U8 *stream, S32 &offset, S32 buffsize)
-{
- S32 source_len = strlen( (const char *)stream+offset );
- S32 copy_len = buffsize - 1;
- if( copy_len > source_len )
- {
- copy_len = source_len;
- }
-
- // strncpy without \0 padding overhead
- memcpy( buffer, stream+offset, copy_len );
- buffer[copy_len] = 0;
-
- offset += source_len + 1; // advance past source string, include terminating '\0'
-
- return source_len < buffsize;
-}
-
-inline void char2bytestream(U8 *stream, S32 &offset, const char *buffer)
-{
- while ((*(stream + offset++) = *buffer++))
- ;
-}
-
-inline U8 bytestream2byte(const U8 *stream, S32 &offset)
-{
- return *(stream + offset++);
-}
-
-inline void byte2bytestream(U8 *stream, S32 &offset, U8 byte)
-{
- *(stream + offset++) = byte;
-}
-
-inline void bytestream2bytestream(U8 *dest, S32 &dest_offset, const U8 *src, S32 &src_offset, S32 count)
-{
- while (count)
- {
- (*(dest + dest_offset++)) = (*(src + src_offset++));
- count--;
- }
-}
-
-inline void uuid2bytestream(U8 *stream, S32 &offset, const LLUUID &uuid)
-{
- S32 i;
- for (i = 0; i < UUID_BYTES; i++)
- {
- *(stream + offset++) = uuid.mData[i];
- }
-}
-
-inline void bytestream2uuid(U8 *stream, S32 &offset, LLUUID &uuid)
-{
- S32 i;
- for (i = 0; i < UUID_BYTES; i++)
- {
- uuid.mData[i] = *(stream + offset++);
- }
-}
-
-// vectors and quaternions and encoded in backwards order to match the way in which they are stored on the stack
-inline void bytestream2vector(LLVector3 &vector, const U8 *stream, S32 &offset)
-{
- S32 value = bytestream2integer(stream, offset);
- vector.mV[VZ] = *(F32 *)&value;
- if (!llfinite(vector.mV[VZ]))
- {
- vector.mV[VZ] = 0;
- set_fault(stream, LSRF_MATH);
- }
- value = bytestream2integer(stream, offset);
- vector.mV[VY] = *(F32 *)&value;
- if (!llfinite(vector.mV[VY]))
- {
- vector.mV[VY] = 0;
- set_fault(stream, LSRF_MATH);
- }
- value = bytestream2integer(stream, offset);
- vector.mV[VX] = *(F32 *)&value;
- if (!llfinite(vector.mV[VX]))
- {
- vector.mV[VX] = 0;
- set_fault(stream, LSRF_MATH);
- }
-}
-
-inline void vector2bytestream(U8 *stream, S32 &offset, const LLVector3 &vector)
-{
- S32 value = *(S32 *)&vector.mV[VZ];
- integer2bytestream(stream, offset, value);
- value = *(S32 *)&vector.mV[VY];
- integer2bytestream(stream, offset, value);
- value = *(S32 *)&vector.mV[VX];
- integer2bytestream(stream, offset, value);
-}
-
-inline void bytestream2quaternion(LLQuaternion &quat, const U8 *stream, S32 &offset)
-{
- S32 value = bytestream2integer(stream, offset);
- quat.mQ[VS] = *(F32 *)&value;
- if (!llfinite(quat.mQ[VS]))
- {
- quat.mQ[VS] = 0;
- set_fault(stream, LSRF_MATH);
- }
- value = bytestream2integer(stream, offset);
- quat.mQ[VZ] = *(F32 *)&value;
- if (!llfinite(quat.mQ[VZ]))
- {
- quat.mQ[VZ] = 0;
- set_fault(stream, LSRF_MATH);
- }
- value = bytestream2integer(stream, offset);
- quat.mQ[VY] = *(F32 *)&value;
- if (!llfinite(quat.mQ[VY]))
- {
- quat.mQ[VY] = 0;
- set_fault(stream, LSRF_MATH);
- }
- value = bytestream2integer(stream, offset);
- quat.mQ[VX] = *(F32 *)&value;
- if (!llfinite(quat.mQ[VX]))
- {
- quat.mQ[VX] = 0;
- set_fault(stream, LSRF_MATH);
- }
-}
-
-inline void quaternion2bytestream(U8 *stream, S32 &offset, const LLQuaternion &quat)
-{
- S32 value = *(S32 *)&quat.mQ[VS];
- integer2bytestream(stream, offset, value);
- value = *(S32 *)&quat.mQ[VZ];
- integer2bytestream(stream, offset, value);
- value = *(S32 *)&quat.mQ[VY];
- integer2bytestream(stream, offset, value);
- value = *(S32 *)&quat.mQ[VX];
- integer2bytestream(stream, offset, value);
-}
-
-inline S32 get_register(const U8 *stream, LSCRIPTRegisters reg)
-{
- S32 offset = gLSCRIPTRegisterAddresses[reg];
- return bytestream2integer(stream, offset);
-}
-
-inline F32 get_register_fp(U8 *stream, LSCRIPTRegisters reg)
-{
- S32 offset = gLSCRIPTRegisterAddresses[reg];
- F32 value = bytestream2float(stream, offset);
- if (!llfinite(value))
- {
- value = 0;
- set_fault(stream, LSRF_MATH);
- }
- return value;
-}
-inline U64 get_register_u64(U8 *stream, LSCRIPTRegisters reg)
-{
- S32 offset = gLSCRIPTRegisterAddresses[reg];
- return bytestream2u64(stream, offset);
-}
-
-inline U64 get_event_register(U8 *stream, LSCRIPTRegisters reg, S32 major_version)
-{
- if (major_version == 1)
- {
- S32 offset = gLSCRIPTRegisterAddresses[reg];
- return (U64)bytestream2integer(stream, offset);
- }
- else if (major_version == 2)
- {
- S32 offset = gLSCRIPTRegisterAddresses[reg + (LREG_NCE - LREG_CE)];
- return bytestream2u64(stream, offset);
- }
- else
- {
- S32 offset = gLSCRIPTRegisterAddresses[reg];
- return (U64)bytestream2integer(stream, offset);
- }
-}
-
-inline void set_register(U8 *stream, LSCRIPTRegisters reg, S32 value)
-{
- S32 offset = gLSCRIPTRegisterAddresses[reg];
- integer2bytestream(stream, offset, value);
-}
-
-inline void set_register_fp(U8 *stream, LSCRIPTRegisters reg, F32 value)
-{
- S32 offset = gLSCRIPTRegisterAddresses[reg];
- float2bytestream(stream, offset, value);
-}
-
-inline void set_register_u64(U8 *stream, LSCRIPTRegisters reg, U64 value)
-{
- S32 offset = gLSCRIPTRegisterAddresses[reg];
- u642bytestream(stream, offset, value);
-}
-
-inline void set_event_register(U8 *stream, LSCRIPTRegisters reg, U64 value, S32 major_version)
-{
- if (major_version == 1)
- {
- S32 offset = gLSCRIPTRegisterAddresses[reg];
- integer2bytestream(stream, offset, (S32)value);
- }
- else if (major_version == 2)
- {
- S32 offset = gLSCRIPTRegisterAddresses[reg + (LREG_NCE - LREG_CE)];
- u642bytestream(stream, offset, value);
- }
- else
- {
- S32 offset = gLSCRIPTRegisterAddresses[reg];
- integer2bytestream(stream, offset, (S32)value);
- }
-}
-
-
-inline F32 add_register_fp(U8 *stream, LSCRIPTRegisters reg, F32 value)
-{
- S32 offset = gLSCRIPTRegisterAddresses[reg];
- F32 newvalue = bytestream2float(stream, offset);
- newvalue += value;
- if (!llfinite(newvalue))
- {
- newvalue = 0;
- set_fault(stream, LSRF_MATH);
- }
- offset = gLSCRIPTRegisterAddresses[reg];
- float2bytestream(stream, offset, newvalue);
- return newvalue;
-}
-
-void lsa_print_heap(U8 *buffer);
-
-
-inline void set_fault(const U8 *stream, LSCRIPTRunTimeFaults fault)
-{
- S32 fr = get_register(stream, LREG_FR);
- // record the first error
- if (!fr)
- {
- if ( (fault == LSRF_HEAP_ERROR)
- ||(fault == LSRF_STACK_HEAP_COLLISION)
- ||(fault == LSRF_BOUND_CHECK_ERROR))
- {
- reset_hp_to_safe_spot(stream);
-// lsa_print_heap((U8 *)stream);
- }
- fr = fault;
- set_register((U8 *)stream, LREG_FR, fr);
- }
-}
-
-inline BOOL set_ip(U8 *stream, S32 ip)
-{
- // Verify that the Instruction Pointer is in a valid
- // code area (between the Global Function Register
- // and Heap Register).
- S32 gfr = get_register(stream, LREG_GFR);
- if (ip == 0)
- {
- set_register(stream, LREG_IP, ip);
- return TRUE;
- }
- if (ip < gfr)
- {
- set_fault(stream, LSRF_BOUND_CHECK_ERROR);
- return FALSE;
- }
- S32 hr = get_register(stream, LREG_HR);
- if (ip >= hr)
- {
- set_fault(stream, LSRF_BOUND_CHECK_ERROR);
- return FALSE;
- }
- set_register(stream, LREG_IP, ip);
- return TRUE;
-}
-
-inline BOOL set_bp(U8 *stream, S32 bp)
-{
- // Verify that the Base Pointer is in a valid
- // data area (between the Heap Pointer and
- // the Top of Memory, and below the
- // Stack Pointer).
- S32 hp = get_register(stream, LREG_HP);
- if (bp <= hp)
- {
- set_fault(stream, LSRF_STACK_HEAP_COLLISION);
- return FALSE;
- }
- S32 tm = get_register(stream, LREG_TM);
- if (bp >= tm)
- {
- set_fault(stream, LSRF_BOUND_CHECK_ERROR);
- return FALSE;
- }
- S32 sp = get_register(stream, LREG_SP);
- if (bp < sp)
- {
- set_fault(stream, LSRF_BOUND_CHECK_ERROR);
- return FALSE;
- }
- set_register(stream, LREG_BP, bp);
- return TRUE;
-}
-
-inline BOOL set_sp(U8 *stream, S32 sp)
-{
- // Verify that the Stack Pointer is in a valid
- // data area (between the Heap Pointer and
- // the Top of Memory).
- S32 hp = get_register(stream, LREG_HP);
- if (sp <= hp)
- {
- set_fault(stream, LSRF_STACK_HEAP_COLLISION);
- return FALSE;
- }
- S32 tm = get_register(stream, LREG_TM);
- if (sp >= tm)
- {
- set_fault(stream, LSRF_BOUND_CHECK_ERROR);
- return FALSE;
- }
- set_register(stream, LREG_SP, sp);
- return TRUE;
-}
-
-inline void lscript_push(U8 *stream, U8 value)
-{
- S32 sp = get_register(stream, LREG_SP);
- sp -= 1;
-
- if (set_sp(stream, sp))
- {
- *(stream + sp) = value;
- }
-}
-
-inline void lscript_push(U8 *stream, S32 value)
-{
- S32 sp = get_register(stream, LREG_SP);
- sp -= LSCRIPTDataSize[LST_INTEGER];
-
- if (set_sp(stream, sp))
- {
- integer2bytestream(stream, sp, value);
- }
-}
-
-inline void lscript_push(U8 *stream, F32 value)
-{
- S32 sp = get_register(stream, LREG_SP);
- sp -= LSCRIPTDataSize[LST_FLOATINGPOINT];
-
- if (set_sp(stream, sp))
- {
- float2bytestream(stream, sp, value);
- }
-}
-
-inline void lscript_push(U8 *stream, const LLVector3 &value)
-{
- S32 sp = get_register(stream, LREG_SP);
- sp -= LSCRIPTDataSize[LST_VECTOR];
-
- if (set_sp(stream, sp))
- {
- vector2bytestream(stream, sp, value);
- }
-}
-
-inline void lscript_push(U8 *stream, const LLQuaternion &value)
-{
- S32 sp = get_register(stream, LREG_SP);
- sp -= LSCRIPTDataSize[LST_QUATERNION];
-
- if (set_sp(stream, sp))
- {
- quaternion2bytestream(stream, sp, value);
- }
-}
-
-inline void lscript_pusharg(U8 *stream, S32 arg)
-{
- S32 sp = get_register(stream, LREG_SP);
- sp -= arg;
-
- set_sp(stream, sp);
-}
-
-inline void lscript_poparg(U8 *stream, S32 arg)
-{
- S32 sp = get_register(stream, LREG_SP);
- sp += arg;
-
- set_sp(stream, sp);
-}
-
-inline U8 lscript_pop_char(U8 *stream)
-{
- S32 sp = get_register(stream, LREG_SP);
- U8 value = *(stream + sp++);
- set_sp(stream, sp);
- return value;
-}
-
-inline S32 lscript_pop_int(U8 *stream)
-{
- S32 sp = get_register(stream, LREG_SP);
- S32 value = bytestream2integer(stream, sp);
- set_sp(stream, sp);
- return value;
-}
-
-inline F32 lscript_pop_float(U8 *stream)
-{
- S32 sp = get_register(stream, LREG_SP);
- F32 value = bytestream2float(stream, sp);
- if (!llfinite(value))
- {
- value = 0;
- set_fault(stream, LSRF_MATH);
- }
- set_sp(stream, sp);
- return value;
-}
-
-inline void lscript_pop_vector(U8 *stream, LLVector3 &value)
-{
- S32 sp = get_register(stream, LREG_SP);
- bytestream2vector(value, stream, sp);
- set_sp(stream, sp);
-}
-
-inline void lscript_pop_quaternion(U8 *stream, LLQuaternion &value)
-{
- S32 sp = get_register(stream, LREG_SP);
- bytestream2quaternion(value, stream, sp);
- set_sp(stream, sp);
-}
-
-inline void lscript_pusharge(U8 *stream, S32 value)
-{
- S32 sp = get_register(stream, LREG_SP);
- sp -= value;
- if (set_sp(stream, sp))
- {
- S32 i;
- for (i = 0; i < value; i++)
- {
- *(stream + sp++) = 0;
- }
- }
-}
-
-inline BOOL lscript_check_local(U8 *stream, S32 &address, S32 size)
-{
- S32 sp = get_register(stream, LREG_SP);
- S32 bp = get_register(stream, LREG_BP);
-
- address += size;
- address = bp - address;
-
- if (address < sp - size)
- {
- set_fault(stream, LSRF_BOUND_CHECK_ERROR);
- return FALSE;
- }
- S32 tm = get_register(stream, LREG_TM);
- if (address + size > tm)
- {
- set_fault(stream, LSRF_BOUND_CHECK_ERROR);
- return FALSE;
- }
- return TRUE;
-}
-
-inline BOOL lscript_check_global(U8 *stream, S32 &address, S32 size)
-{
- S32 gvr = get_register(stream, LREG_GVR);
-
- // Possibility of overwriting registers? -- DK 09/07/04
- if (address < 0)
- {
- set_fault(stream, LSRF_BOUND_CHECK_ERROR);
- return FALSE;
- }
-
- address += gvr;
- S32 gfr = get_register(stream, LREG_GFR);
-
- if (address + size > gfr)
- {
- set_fault(stream, LSRF_BOUND_CHECK_ERROR);
- return FALSE;
- }
- return TRUE;
-}
-
-inline void lscript_local_store(U8 *stream, S32 address, S32 value)
-{
- if (lscript_check_local(stream, address, LSCRIPTDataSize[LST_INTEGER]))
- integer2bytestream(stream, address, value);
-}
-
-inline void lscript_local_store(U8 *stream, S32 address, F32 value)
-{
- if (lscript_check_local(stream, address, LSCRIPTDataSize[LST_FLOATINGPOINT]))
- float2bytestream(stream, address, value);
-}
-
-inline void lscript_local_store(U8 *stream, S32 address, const LLVector3 value)
-{
- if (lscript_check_local(stream, address, LSCRIPTDataSize[LST_VECTOR]))
- vector2bytestream(stream, address, value);
-}
-
-inline void lscript_local_store(U8 *stream, S32 address, const LLQuaternion value)
-{
- if (lscript_check_local(stream, address, LSCRIPTDataSize[LST_QUATERNION]))
- quaternion2bytestream(stream, address, value);
-}
-
-inline void lscript_global_store(U8 *stream, S32 address, S32 value)
-{
- if (lscript_check_global(stream, address, LSCRIPTDataSize[LST_INTEGER]))
- integer2bytestream(stream, address, value);
-}
-
-inline void lscript_global_store(U8 *stream, S32 address, F32 value)
-{
- if (lscript_check_global(stream, address, LSCRIPTDataSize[LST_FLOATINGPOINT]))
- float2bytestream(stream, address, value);
-}
-
-inline void lscript_global_store(U8 *stream, S32 address, const LLVector3 value)
-{
- if (lscript_check_global(stream, address, LSCRIPTDataSize[LST_VECTOR]))
- vector2bytestream(stream, address, value);
-}
-
-inline void lscript_global_store(U8 *stream, S32 address, const LLQuaternion value)
-{
- if (lscript_check_global(stream, address, LSCRIPTDataSize[LST_QUATERNION]))
- quaternion2bytestream(stream, address, value);
-}
-
-inline S32 lscript_local_get(U8 *stream, S32 address)
-{
- if (lscript_check_local(stream, address, LSCRIPTDataSize[LST_INTEGER]))
- return bytestream2integer(stream, address);
- return 0;
-}
-
-inline void lscript_local_get(U8 *stream, S32 address, F32 &value)
-{
- if (lscript_check_local(stream, address, LSCRIPTDataSize[LST_FLOATINGPOINT]))
- value = bytestream2float(stream, address);
- if (!llfinite(value))
- {
- value = 0;
- set_fault(stream, LSRF_MATH);
- }
-}
-
-inline void lscript_local_get(U8 *stream, S32 address, LLVector3 &value)
-{
- if (lscript_check_local(stream, address, LSCRIPTDataSize[LST_VECTOR]))
- bytestream2vector(value, stream, address);
-}
-
-inline void lscript_local_get(U8 *stream, S32 address, LLQuaternion &value)
-{
- if (lscript_check_local(stream, address, LSCRIPTDataSize[LST_QUATERNION]))
- bytestream2quaternion(value, stream, address);
-}
-
-inline S32 lscript_global_get(U8 *stream, S32 address)
-{
- if (lscript_check_global(stream, address, LSCRIPTDataSize[LST_INTEGER]))
- return bytestream2integer(stream, address);
- return 0;
-}
-
-inline void lscript_global_get(U8 *stream, S32 address, F32 &value)
-{
- if (lscript_check_global(stream, address, LSCRIPTDataSize[LST_FLOATINGPOINT]))
- value = bytestream2float(stream, address);
- if (!llfinite(value))
- {
- value = 0;
- set_fault(stream, LSRF_MATH);
- }
-}
-
-inline void lscript_global_get(U8 *stream, S32 address, LLVector3 &value)
-{
- if (lscript_check_global(stream, address, LSCRIPTDataSize[LST_VECTOR]))
- bytestream2vector(value, stream, address);
-}
-
-inline void lscript_global_get(U8 *stream, S32 address, LLQuaternion &value)
-{
- if (lscript_check_global(stream, address, LSCRIPTDataSize[LST_QUATERNION]))
- bytestream2quaternion(value, stream, address);
-}
-
-
-
-inline S32 get_state_event_opcoode_start(U8 *stream, S32 state, LSCRIPTStateEventType event)
-{
- // get the start of the state table
- S32 sr = get_register(stream, LREG_SR);
-
- // get the position of the jump to the desired state
- S32 value = get_register(stream, LREG_VN);
-
- S32 state_offset_offset = 0;
- S32 major_version = 0;
- if (value == LSL2_VERSION1_END_NUMBER)
- {
- major_version = LSL2_MAJOR_VERSION_ONE;
- state_offset_offset = sr + LSCRIPTDataSize[LST_INTEGER] + LSCRIPTDataSize[LST_INTEGER]*2*state;
- }
- else if (value == LSL2_VERSION_NUMBER)
- {
- major_version = LSL2_MAJOR_VERSION_TWO;
- state_offset_offset = sr + LSCRIPTDataSize[LST_INTEGER] + LSCRIPTDataSize[LST_INTEGER]*3*state;
- }
- if ( state_offset_offset < 0 || state_offset_offset > TOP_OF_MEMORY )
- {
- return -1;
- }
-
- // get the actual position in memory of the desired state
- S32 state_offset = sr + bytestream2integer(stream, state_offset_offset);
- if ( state_offset < 0 || state_offset > TOP_OF_MEMORY )
- {
- return -1;
- }
-
- // save that value
- S32 state_offset_base = state_offset;
-
- // jump past the state name
- S32 event_jump_offset = state_offset_base + bytestream2integer(stream, state_offset);
-
- // get the location of the event offset
- S32 event_offset = event_jump_offset + LSCRIPTDataSize[LST_INTEGER]*2*get_event_handler_jump_position(get_event_register(stream, LREG_ER, major_version), event);
- if ( event_offset < 0 || event_offset > TOP_OF_MEMORY )
- {
- return -1;
- }
-
- // now, jump to the event
- S32 event_start = bytestream2integer(stream, event_offset);
- if ( event_start < 0 || event_start > TOP_OF_MEMORY )
- {
- return -1;
- }
- event_start += event_jump_offset;
-
- S32 event_start_original = event_start;
-
- // now skip past the parameters
- S32 opcode_offset = bytestream2integer(stream, event_start);
- if ( opcode_offset < 0 || opcode_offset > TOP_OF_MEMORY )
- {
- return -1;
- }
-
- return opcode_offset + event_start_original;
-}
-
-
-inline U64 get_handled_events(U8 *stream, S32 state)
-{
- U64 retvalue = 0;
- // get the start of the state table
- S32 sr = get_register(stream, LREG_SR);
-
- // get the position of the jump to the desired state
- S32 value = get_register(stream, LREG_VN);
- S32 state_handled_offset = 0;
- if (value == LSL2_VERSION1_END_NUMBER)
- {
- state_handled_offset = sr + LSCRIPTDataSize[LST_INTEGER]*2*state + 2*LSCRIPTDataSize[LST_INTEGER];
- retvalue = bytestream2integer(stream, state_handled_offset);
- }
- else if (value == LSL2_VERSION_NUMBER)
- {
- state_handled_offset = sr + LSCRIPTDataSize[LST_INTEGER]*3*state + 2*LSCRIPTDataSize[LST_INTEGER];
- retvalue = bytestream2u64(stream, state_handled_offset);
- }
-
- // get the handled events
- return retvalue;
-}
-
-// Returns -1 on error
-inline S32 get_event_stack_size(U8 *stream, S32 state, LSCRIPTStateEventType event)
-{
- // get the start of the state table
- S32 sr = get_register(stream, LREG_SR);
-
- // get state offset
- S32 value = get_register(stream, LREG_VN);
- S32 state_offset_offset = 0;
- S32 major_version = 0;
- if (value == LSL2_VERSION1_END_NUMBER)
- {
- major_version = LSL2_MAJOR_VERSION_ONE;
- state_offset_offset = sr + LSCRIPTDataSize[LST_INTEGER] + LSCRIPTDataSize[LST_INTEGER]*2*state;
- }
- else if (value == LSL2_VERSION_NUMBER)
- {
- major_version = LSL2_MAJOR_VERSION_TWO;
- state_offset_offset = sr + LSCRIPTDataSize[LST_INTEGER] + LSCRIPTDataSize[LST_INTEGER]*3*state;
- }
-
- if ( state_offset_offset < 0 || state_offset_offset > TOP_OF_MEMORY )
- {
- return -1;
- }
-
- S32 state_offset = bytestream2integer(stream, state_offset_offset);
- state_offset += sr;
-
- state_offset_offset = state_offset;
- if ( state_offset_offset < 0 || state_offset_offset > TOP_OF_MEMORY )
- {
- return -1;
- }
-
- // skip to jump table
- S32 jump_table = bytestream2integer(stream, state_offset_offset);
-
- jump_table += state_offset;
- if ( jump_table < 0 || jump_table > TOP_OF_MEMORY )
- {
- return -1;
- }
-
- // get the position of the jump to the desired state
- 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];
-
- // get the handled events
- S32 stack_size = bytestream2integer(stream, stack_size_offset);
- if ( stack_size < 0 || stack_size > TOP_OF_MEMORY )
- {
- return -1;
- }
-
- return stack_size;
-}
-
-inline LSCRIPTStateEventType return_first_event(S32 event)
-{
- S32 count = 1;
- while (count < LSTT_EOF)
- {
- if (event & 0x1)
- {
- return (LSCRIPTStateEventType) count;
- }
- else
- {
- event >>= 1;
- count++;
- }
- }
- return LSTT_NULL;
-}
-
-
-// the safe instruction versions of these commands will only work if offset is between
-// GFR and HR, meaning that it is an instruction (more or less) in global functions or event handlers
-
-inline BOOL safe_instruction_check_address(U8 *stream, S32 offset, S32 size)
-{
- S32 gfr = get_register(stream, LREG_GFR);
- if (offset < gfr)
- {
- set_fault(stream, LSRF_BOUND_CHECK_ERROR);
- return FALSE;
- }
- else
- {
- S32 hr = get_register(stream, LREG_HR);
- if (offset + size > hr)
- {
- set_fault(stream, LSRF_BOUND_CHECK_ERROR);
- return FALSE;
- }
- else
- {
- return TRUE;
- }
- }
-}
-
-inline BOOL safe_heap_check_address(U8 *stream, S32 offset, S32 size)
-{
- S32 hr = get_register(stream, LREG_HR);
- if (offset < hr)
- {
- set_fault(stream, LSRF_BOUND_CHECK_ERROR);
- return FALSE;
- }
- else
- {
- S32 hp = get_register(stream, LREG_HP);
- if (offset + size > hp)
- {
- set_fault(stream, LSRF_BOUND_CHECK_ERROR);
- return FALSE;
- }
- else
- {
- return TRUE;
- }
- }
-}
-
-inline U8 safe_instruction_bytestream2byte(U8 *stream, S32 &offset)
-{
- if (safe_instruction_check_address(stream, offset, 1))
- {
- return *(stream + offset++);
- }
- else
- {
- return 0;
- }
-}
-
-inline void safe_instruction_byte2bytestream(U8 *stream, S32 &offset, U8 byte)
-{
- if (safe_instruction_check_address(stream, offset, 1))
- {
- *(stream + offset++) = byte;
- }
-}
-
-inline S32 safe_instruction_bytestream2integer(U8 *stream, S32 &offset)
-{
- if (safe_instruction_check_address(stream, offset, LSCRIPTDataSize[LST_INTEGER]))
- {
- return (bytestream2integer(stream, offset));
- }
- else
- {
- return 0;
- }
-}
-
-inline void safe_instruction_integer2bytestream(U8 *stream, S32 &offset, S32 value)
-{
- if (safe_instruction_check_address(stream, offset, LSCRIPTDataSize[LST_INTEGER]))
- {
- integer2bytestream(stream, offset, value);
- }
-}
-
-inline U16 safe_instruction_bytestream2u16(U8 *stream, S32 &offset)
-{
- if (safe_instruction_check_address(stream, offset, 2))
- {
- return (bytestream2u16(stream, offset));
- }
- else
- {
- return 0;
- }
-}
-
-inline void safe_instruction_u162bytestream(U8 *stream, S32 &offset, U16 value)
-{
- if (safe_instruction_check_address(stream, offset, 2))
- {
- u162bytestream(stream, offset, value);
- }
-}
-
-inline F32 safe_instruction_bytestream2float(U8 *stream, S32 &offset)
-{
- if (safe_instruction_check_address(stream, offset, LSCRIPTDataSize[LST_INTEGER]))
- {
- F32 value = bytestream2float(stream, offset);
- if (!llfinite(value))
- {
- value = 0;
- set_fault(stream, LSRF_MATH);
- }
- return value;
- }
- else
- {
- return 0;
- }
-}
-
-inline void safe_instruction_float2bytestream(U8 *stream, S32 &offset, F32 value)
-{
- if (safe_instruction_check_address(stream, offset, LSCRIPTDataSize[LST_FLOATINGPOINT]))
- {
- float2bytestream(stream, offset, value);
- }
-}
-
-inline void safe_instruction_bytestream2char(char *buffer, U8 *stream, S32 &offset, S32 buffsize)
-{
- // This varies from the old method. Previously, we would copy up until we got an error,
- // then halt the script via safe_isntruction_check_address. Now we don't bother
- // copying a thing if there's an error.
-
- if( safe_instruction_check_address(stream, offset, strlen( (const char *)stream + offset ) + 1 ) )
- {
- // Takes the same parms as this function. Won't overread, per above check.
- bytestream2char( buffer, stream, offset, buffsize );
- }
- else
- {
- // Truncate - no point in copying
- *buffer = 0;
- }
-}
-
-inline void safe_instruction_bytestream_count_char(U8 *stream, S32 &offset)
-{
- while ( (safe_instruction_check_address(stream, offset, 1))
- &&(*(stream + offset++)))
- ;
-}
-
-inline void safe_heap_bytestream_count_char(U8 *stream, S32 &offset)
-{
- while ( (safe_heap_check_address(stream, offset, 1))
- &&(*(stream + offset++)))
- ;
-}
-
-inline void safe_instruction_char2bytestream(U8 *stream, S32 &offset, const char* buffer)
-{
- while ( (safe_instruction_check_address(stream, offset, 1))
- &&(*(stream + offset++) = *buffer++))
- ;
-}
-
-inline void safe_instruction_bytestream2vector(LLVector3 &value, U8 *stream, S32 &offset)
-{
- if (safe_instruction_check_address(stream, offset, LSCRIPTDataSize[LST_VECTOR]))
- {
- bytestream2vector(value, stream, offset);
- }
-}
-
-inline void safe_instruction_vector2bytestream(U8 *stream, S32 &offset, const LLVector3 &value)
-{
- if (safe_instruction_check_address(stream, offset, LSCRIPTDataSize[LST_VECTOR]))
- {
- vector2bytestream(stream, offset, value);
- }
-}
-
-inline void safe_instruction_bytestream2quaternion(LLQuaternion &value, U8 *stream, S32 &offset)
-{
- if (safe_instruction_check_address(stream, offset, LSCRIPTDataSize[LST_QUATERNION]))
- {
- bytestream2quaternion(value, stream, offset);
- }
-}
-
-inline void safe_instruction_quaternion2bytestream(U8 *stream, S32 &offset, const LLQuaternion &value)
-{
- if (safe_instruction_check_address(stream, offset, LSCRIPTDataSize[LST_QUATERNION]))
- {
- quaternion2bytestream(stream, offset, value);
- }
-}
-
-static inline LSCRIPTType char2type(char type)
-{
- switch(type)
- {
- case 'i':
- return LST_INTEGER;
- case 'f':
- return LST_FLOATINGPOINT;
- case 's':
- return LST_STRING;
- case 'k':
- return LST_KEY;
- case 'v':
- return LST_VECTOR;
- case 'q':
- return LST_QUATERNION;
- case 'l':
- return LST_LIST;
- default:
- return LST_NULL;
- }
-}
-
-#endif