diff options
author | Cinder <cinder@sdf.org> | 2015-02-08 12:53:39 -0700 |
---|---|---|
committer | Cinder <cinder@sdf.org> | 2015-02-08 12:53:39 -0700 |
commit | ca08bd5aba5e69fce3b0f5b4f861ffec9fe4d2e5 (patch) | |
tree | 16bdd84d4a0911c80d95d5dc04a3bdd342506e55 /indra/lscript/lscript_byteconvert.h | |
parent | ae6440eecc4d6c018a3634c2c06052757bde962f (diff) |
OPEN-292 - Remove lscript from project,
Remove legacy udp script upload methods,
Refactor script runtime perms from three arrays to one struct array so we don't have to juggle array order anymore.
Diffstat (limited to 'indra/lscript/lscript_byteconvert.h')
-rwxr-xr-x | indra/lscript/lscript_byteconvert.h | 1170 |
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 |