lscript_execute.cpp
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:106k
- /**
- * @file lscript_execute.cpp
- * @brief classes to execute bytecode
- *
- * $LicenseInfo:firstyear=2002&license=viewergpl$
- *
- * Copyright (c) 2002-2010, Linden Research, Inc.
- *
- * Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
- *
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at
- * http://secondlifegrid.net/programs/open_source/licensing/flossexception
- *
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
- *
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
- * $/LicenseInfo$
- */
- #include "linden_common.h"
- #include <algorithm>
- #include <sstream>
- #include "lscript_execute.h"
- #include "lltimer.h"
- #include "lscript_readlso.h"
- #include "lscript_library.h"
- #include "lscript_heapruntime.h"
- #include "lscript_alloc.h"
- #include "llstat.h"
- // Static
- const S32 DEFAULT_SCRIPT_TIMER_CHECK_SKIP = 4;
- S32 LLScriptExecute::sTimerCheckSkip = DEFAULT_SCRIPT_TIMER_CHECK_SKIP;
- void (*binary_operations[LST_EOF][LST_EOF])(U8 *buffer, LSCRIPTOpCodesEnum opcode);
- void (*unary_operations[LST_EOF])(U8 *buffer, LSCRIPTOpCodesEnum opcode);
- const char* LSCRIPTRunTimeFaultStrings[LSRF_EOF] = /*Flawfinder: ignore*/
- {
- "Invalid", // LSRF_INVALID,
- "Math Error", // LSRF_MATH,
- "Stack-Heap Collision", // LSRF_STACK_HEAP_COLLISION,
- "Bounds Check Error", // LSRF_BOUND_CHECK_ERROR,
- "Heap Error", // LSRF_HEAP_ERROR,
- "Version Mismatch", // LSRF_VERSION_MISMATCH,
- "Missing Inventory", // LSRF_MISSING_INVENTORY,
- "Hit Sandbox Limit", // LSRF_SANDBOX,
- "Chat Overrun", // LSRF_CHAT_OVERRUN,
- "Too Many Listens", // LSRF_TOO_MANY_LISTENS,
- "Lists may not contain lists", // LSRF_NESTING_LISTS,
- "CLI Exception" // LSRF_CLI
- };
- void LLScriptExecuteLSL2::startRunning() {}
- void LLScriptExecuteLSL2::stopRunning() {}
- const char* URL_REQUEST_GRANTED = "URL_REQUEST_GRANTED";
- const char* URL_REQUEST_DENIED = "URL_REQUEST_DENIED";
- // HTTP Requests to LSL scripts will time out after 25 seconds.
- const U64 LSL_HTTP_REQUEST_TIMEOUT_USEC = 25 * USEC_PER_SEC;
- LLScriptExecuteLSL2::LLScriptExecuteLSL2(LLFILE *fp)
- {
- U8 sizearray[4];
- size_t filesize;
- S32 pos = 0;
- if (fread(&sizearray, 1, 4, fp) != 4)
- {
- llwarns << "Short read" << llendl;
- filesize = 0;
- } else {
- filesize = bytestream2integer(sizearray, pos);
- }
- mBuffer = new U8[filesize];
- fseek(fp, 0, SEEK_SET);
- if (fread(mBuffer, 1, filesize, fp) != filesize)
- {
- llwarns << "Short read" << llendl;
- }
- fclose(fp);
- init();
- }
- LLScriptExecuteLSL2::LLScriptExecuteLSL2(const U8* bytecode, U32 bytecode_size)
- {
- mBuffer = new U8[TOP_OF_MEMORY];
- memset(mBuffer + bytecode_size, 0, TOP_OF_MEMORY - bytecode_size);
- S32 src_offset = 0;
- S32 dest_offset = 0;
- bytestream2bytestream(mBuffer, dest_offset, bytecode, src_offset, bytecode_size);
- mBytecodeSize = bytecode_size;
- mBytecode = new U8[mBytecodeSize];
- memcpy(mBytecode, bytecode, mBytecodeSize);
- init();
- }
- LLScriptExecute::~LLScriptExecute() {}
- LLScriptExecuteLSL2::~LLScriptExecuteLSL2()
- {
- delete[] mBuffer;
- delete[] mBytecode;
- }
- void LLScriptExecuteLSL2::init()
- {
- S32 i, j;
- mInstructionCount = 0;
- for (i = 0; i < 256; i++)
- {
- mExecuteFuncs[i] = run_noop;
- }
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_NOOP]] = run_noop;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_POP]] = run_pop;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_POPS]] = run_pops;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_POPL]] = run_popl;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_POPV]] = run_popv;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_POPQ]] = run_popq;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_POPARG]] = run_poparg;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_POPIP]] = run_popip;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_POPBP]] = run_popbp;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_POPSP]] = run_popsp;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_POPSLR]] = run_popslr;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_DUP]] = run_dup;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_DUPS]] = run_dups;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_DUPL]] = run_dupl;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_DUPV]] = run_dupv;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_DUPQ]] = run_dupq;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_STORE]] = run_store;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_STORES]] = run_stores;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_STOREL]] = run_storel;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_STOREV]] = run_storev;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_STOREQ]] = run_storeq;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_STOREG]] = run_storeg;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_STOREGL]] = run_storegl;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_STOREGS]] = run_storegs;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_STOREGV]] = run_storegv;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_STOREGQ]] = run_storegq;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_LOADP]] = run_loadp;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_LOADSP]] = run_loadsp;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_LOADLP]] = run_loadlp;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_LOADVP]] = run_loadvp;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_LOADQP]] = run_loadqp;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_LOADGP]] = run_loadgp;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_LOADGSP]] = run_loadgsp;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_LOADGLP]] = run_loadglp;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_LOADGVP]] = run_loadgvp;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_LOADGQP]] = run_loadgqp;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSH]] = run_push;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHS]] = run_pushs;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHL]] = run_pushl;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHV]] = run_pushv;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHQ]] = run_pushq;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHG]] = run_pushg;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHGS]] = run_pushgs;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHGL]] = run_pushgl;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHGV]] = run_pushgv;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHGQ]] = run_pushgq;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHIP]] = run_puship;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHSP]] = run_pushsp;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHBP]] = run_pushbp;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHARGB]] = run_pushargb;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHARGI]] = run_pushargi;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHARGF]] = run_pushargf;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHARGS]] = run_pushargs;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHARGV]] = run_pushargv;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHARGQ]] = run_pushargq;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHE]] = run_pushe;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHEV]] = run_pushev;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHEQ]] = run_pusheq;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHARGE]] = run_pusharge;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_ADD]] = run_add;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_SUB]] = run_sub;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_MUL]] = run_mul;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_DIV]] = run_div;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_MOD]] = run_mod;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_EQ]] = run_eq;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_NEQ]] = run_neq;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_LEQ]] = run_leq;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_GEQ]] = run_geq;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_LESS]] = run_less;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_GREATER]] = run_greater;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_BITAND]] = run_bitand;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_BITOR]] = run_bitor;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_BITXOR]] = run_bitxor;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_BOOLAND]] = run_booland;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_BOOLOR]] = run_boolor;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_SHL]] = run_shl;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_SHR]] = run_shr;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_NEG]] = run_neg;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_BITNOT]] = run_bitnot;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_BOOLNOT]] = run_boolnot;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_JUMP]] = run_jump;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_JUMPIF]] = run_jumpif;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_JUMPNIF]] = run_jumpnif;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_STATE]] = run_state;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_CALL]] = run_call;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_RETURN]] = run_return;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_CAST]] = run_cast;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_STACKTOS]] = run_stacktos;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_STACKTOL]] = run_stacktol;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_PRINT]] = run_print;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_CALLLIB]] = run_calllib;
- mExecuteFuncs[LSCRIPTOpCodes[LOPC_CALLLIB_TWO_BYTE]] = run_calllib_two_byte;
- for (i = 0; i < LST_EOF; i++)
- {
- for (j = 0; j < LST_EOF; j++)
- {
- binary_operations[i][j] = unknown_operation;
- }
- }
- binary_operations[LST_INTEGER][LST_INTEGER] = integer_integer_operation;
- binary_operations[LST_INTEGER][LST_FLOATINGPOINT] = integer_float_operation;
- binary_operations[LST_INTEGER][LST_VECTOR] = integer_vector_operation;
- binary_operations[LST_FLOATINGPOINT][LST_INTEGER] = float_integer_operation;
- binary_operations[LST_FLOATINGPOINT][LST_FLOATINGPOINT] = float_float_operation;
- binary_operations[LST_FLOATINGPOINT][LST_VECTOR] = float_vector_operation;
- binary_operations[LST_STRING][LST_STRING] = string_string_operation;
- binary_operations[LST_STRING][LST_KEY] = string_key_operation;
- binary_operations[LST_KEY][LST_STRING] = key_string_operation;
- binary_operations[LST_KEY][LST_KEY] = key_key_operation;
- binary_operations[LST_VECTOR][LST_INTEGER] = vector_integer_operation;
- binary_operations[LST_VECTOR][LST_FLOATINGPOINT] = vector_float_operation;
- binary_operations[LST_VECTOR][LST_VECTOR] = vector_vector_operation;
- binary_operations[LST_VECTOR][LST_QUATERNION] = vector_quaternion_operation;
- binary_operations[LST_QUATERNION][LST_QUATERNION] = quaternion_quaternion_operation;
- binary_operations[LST_INTEGER][LST_LIST] = integer_list_operation;
- binary_operations[LST_FLOATINGPOINT][LST_LIST] = float_list_operation;
- binary_operations[LST_STRING][LST_LIST] = string_list_operation;
- binary_operations[LST_KEY][LST_LIST] = key_list_operation;
- binary_operations[LST_VECTOR][LST_LIST] = vector_list_operation;
- binary_operations[LST_QUATERNION][LST_LIST] = quaternion_list_operation;
- binary_operations[LST_LIST][LST_INTEGER] = list_integer_operation;
- binary_operations[LST_LIST][LST_FLOATINGPOINT] = list_float_operation;
- binary_operations[LST_LIST][LST_STRING] = list_string_operation;
- binary_operations[LST_LIST][LST_KEY] = list_key_operation;
- binary_operations[LST_LIST][LST_VECTOR] = list_vector_operation;
- binary_operations[LST_LIST][LST_QUATERNION] = list_quaternion_operation;
- binary_operations[LST_LIST][LST_LIST] = list_list_operation;
- for (i = 0; i < LST_EOF; i++)
- {
- unary_operations[i] = unknown_operation;
- }
- unary_operations[LST_INTEGER] = integer_operation;
- unary_operations[LST_FLOATINGPOINT] = float_operation;
- unary_operations[LST_VECTOR] = vector_operation;
- unary_operations[LST_QUATERNION] = quaternion_operation;
- }
- // Utility routine for when there's a boundary error parsing bytecode
- void LLScriptExecuteLSL2::recordBoundaryError( const LLUUID &id )
- {
- set_fault(mBuffer, LSRF_BOUND_CHECK_ERROR);
- llwarns << "Script boundary error for ID " << id << llendl;
- }
- // set IP to the event handler with some error checking
- void LLScriptExecuteLSL2::setStateEventOpcoodeStartSafely( S32 state, LSCRIPTStateEventType event, const LLUUID &id )
- {
- S32 opcode_start = get_state_event_opcoode_start( mBuffer, state, event );
- if ( opcode_start == -1 )
- {
- recordBoundaryError( id );
- }
- else
- {
- set_ip( mBuffer, opcode_start );
- }
- }
- S32 lscript_push_variable(LLScriptLibData *data, U8 *buffer);
- void LLScriptExecuteLSL2::resumeEventHandler(BOOL b_print, const LLUUID &id, F32 time_slice)
- {
- // call opcode run function pointer with buffer and IP
- mInstructionCount++;
- S32 value = get_register(mBuffer, LREG_IP);
- S32 tvalue = value;
- S32 opcode = safe_instruction_bytestream2byte(mBuffer, tvalue);
- mExecuteFuncs[opcode](mBuffer, value, b_print, id);
- set_ip(mBuffer, value);
- add_register_fp(mBuffer, LREG_ESR, -0.1f);
- // lsa_print_heap(mBuffer);
- if (b_print)
- {
- lsa_print_heap(mBuffer);
- printf("ip: 0x%Xn", get_register(mBuffer, LREG_IP));
- printf("sp: 0x%Xn", get_register(mBuffer, LREG_SP));
- printf("bp: 0x%Xn", get_register(mBuffer, LREG_BP));
- printf("hr: 0x%Xn", get_register(mBuffer, LREG_HR));
- printf("hp: 0x%Xn", get_register(mBuffer, LREG_HP));
- }
- // NOTE: Babbage: all mExecuteFuncs return false.
- }
- void LLScriptExecuteLSL2::callEventHandler(LSCRIPTStateEventType event, const LLUUID &id, F32 time_slice)
- {
- S32 major_version = getMajorVersion();
- // push a zero to be popped
- lscript_push(mBuffer, 0);
- // push sp as current bp
- S32 sp = get_register(mBuffer, LREG_SP);
- lscript_push(mBuffer, sp);
- // Update current handler and current events registers.
- set_event_register(mBuffer, LREG_IE, LSCRIPTStateBitField[event], major_version);
- U64 current_events = get_event_register(mBuffer, LREG_CE, major_version);
- current_events &= ~LSCRIPTStateBitField[event];
- set_event_register(mBuffer, LREG_CE, current_events, major_version);
- // now, push any additional stack space
- U32 current_state = get_register(mBuffer, LREG_CS);
- S32 additional_size = get_event_stack_size(mBuffer, current_state, event);
- lscript_pusharge(mBuffer, additional_size);
- // now set the bp correctly
- sp = get_register(mBuffer, LREG_SP);
- sp += additional_size;
- set_bp(mBuffer, sp);
- // set IP to the function
- S32 opcode_start = get_state_event_opcoode_start(mBuffer, current_state, event);
- set_ip(mBuffer, opcode_start);
- }
- //void callStateExitHandler()
- //{
- // // push a zero to be popped
- // lscript_push(mBuffer, 0);
- // // push sp as current bp
- // S32 sp = get_register(mBuffer, LREG_SP);
- // lscript_push(mBuffer, sp);
- //
- // // now, push any additional stack space
- // S32 additional_size = get_event_stack_size(mBuffer, current_state, LSTT_STATE_EXIT);
- // lscript_pusharge(mBuffer, additional_size);
- //
- // sp = get_register(mBuffer, LREG_SP);
- // sp += additional_size;
- // set_bp(mBuffer, sp);
- //
- // // set IP to the event handler
- // S32 opcode_start = get_state_event_opcoode_start(mBuffer, current_state, LSTT_STATE_EXIT);
- // set_ip(mBuffer, opcode_start);
- //}
- //
- //void callStateEntryHandler()
- //{
- // // push a zero to be popped
- // lscript_push(mBuffer, 0);
- // // push sp as current bp
- // S32 sp = get_register(mBuffer, LREG_SP);
- // lscript_push(mBuffer, sp);
- //
- // event = return_first_event((S32)LSCRIPTStateBitField[LSTT_STATE_ENTRY]);
- // set_event_register(mBuffer, LREG_IE, LSCRIPTStateBitField[event], major_version);
- // current_events &= ~LSCRIPTStateBitField[event];
- // set_event_register(mBuffer, LREG_CE, current_events, major_version);
- //
- // // now, push any additional stack space
- // S32 additional_size = get_event_stack_size(mBuffer, current_state, event) - size;
- // lscript_pusharge(mBuffer, additional_size);
- //
- // // now set the bp correctly
- // sp = get_register(mBuffer, LREG_SP);
- // sp += additional_size + size;
- // set_bp(mBuffer, sp);
- // // set IP to the function
- // S32 opcode_start = get_state_event_opcoode_start(mBuffer, current_state, event);
- // set_ip(mBuffer, opcode_start);
- //}
- void LLScriptExecuteLSL2::callQueuedEventHandler(LSCRIPTStateEventType event, const LLUUID &id, F32 time_slice)
- {
- S32 major_version = getMajorVersion();
- LLScriptDataCollection* eventdata;
- for (eventdata = mEventData.mEventDataList.getFirstData(); eventdata; eventdata = mEventData.mEventDataList.getNextData())
- {
- if (eventdata->mType == event)
- {
- // push a zero to be popped
- lscript_push(mBuffer, 0);
- // push sp as current bp
- S32 sp = get_register(mBuffer, LREG_SP);
- lscript_push(mBuffer, sp);
- // Update current handler and current events registers.
- set_event_register(mBuffer, LREG_IE, LSCRIPTStateBitField[event], major_version);
- U64 current_events = get_event_register(mBuffer, LREG_CE, major_version);
- current_events &= ~LSCRIPTStateBitField[event];
- set_event_register(mBuffer, LREG_CE, current_events, major_version);
- // push any arguments that need to be pushed onto the stack
- // last piece of data will be type LST_NULL
- LLScriptLibData *data = eventdata->mData;
- U32 size = 0;
- while (data->mType)
- {
- size += lscript_push_variable(data, mBuffer);
- data++;
- }
- // now, push any additional stack space
- U32 current_state = get_register(mBuffer, LREG_CS);
- S32 additional_size = get_event_stack_size(mBuffer, current_state, event) - size;
- lscript_pusharge(mBuffer, additional_size);
- // now set the bp correctly
- sp = get_register(mBuffer, LREG_SP);
- sp += additional_size + size;
- set_bp(mBuffer, sp);
- // set IP to the function
- S32 opcode_start = get_state_event_opcoode_start(mBuffer, current_state, event);
- set_ip(mBuffer, opcode_start);
- mEventData.mEventDataList.deleteCurrentData();
- break;
- }
- }
- }
- void LLScriptExecuteLSL2::callNextQueuedEventHandler(U64 event_register, const LLUUID &id, F32 time_slice)
- {
- S32 major_version = getMajorVersion();
- LLScriptDataCollection* eventdata = mEventData.getNextEvent();
- if (eventdata)
- {
- LSCRIPTStateEventType event = eventdata->mType;
- // make sure that we can actually handle this one
- if (LSCRIPTStateBitField[event] & event_register)
- {
- // push a zero to be popped
- lscript_push(mBuffer, 0);
- // push sp as current bp
- S32 sp = get_register(mBuffer, LREG_SP);
- lscript_push(mBuffer, sp);
- // Update current handler and current events registers.
- set_event_register(mBuffer, LREG_IE, LSCRIPTStateBitField[event], major_version);
- U64 current_events = get_event_register(mBuffer, LREG_CE, major_version);
- current_events &= ~LSCRIPTStateBitField[event];
- set_event_register(mBuffer, LREG_CE, current_events, major_version);
- // push any arguments that need to be pushed onto the stack
- // last piece of data will be type LST_NULL
- LLScriptLibData *data = eventdata->mData;
- U32 size = 0;
- while (data->mType)
- {
- size += lscript_push_variable(data, mBuffer);
- data++;
- }
- // now, push any additional stack space
- U32 current_state = get_register(mBuffer, LREG_CS);
- S32 additional_size = get_event_stack_size(mBuffer, current_state, event) - size;
- lscript_pusharge(mBuffer, additional_size);
- // now set the bp correctly
- sp = get_register(mBuffer, LREG_SP);
- sp += additional_size + size;
- set_bp(mBuffer, sp);
- // set IP to the function
- S32 opcode_start = get_state_event_opcoode_start(mBuffer, current_state, event);
- set_ip(mBuffer, opcode_start);
- }
- else
- {
- llwarns << "Shit, somehow got an event that we're not registered for!" << llendl;
- }
- delete eventdata;
- }
- }
- U64 LLScriptExecuteLSL2::nextState()
- {
- // copy NS to CS
- S32 next_state = get_register(mBuffer, LREG_NS);
- set_register(mBuffer, LREG_CS, next_state);
- // copy new state's handled events into ER (SR + CS*4 + 4)
- return get_handled_events(mBuffer, next_state);
- }
- //virtual
- void LLScriptExecuteLSL2::addEvent(LLScriptDataCollection* event)
- {
- mEventData.addEventData(event);
- }
- //virtual
- void LLScriptExecuteLSL2::removeEventType(LSCRIPTStateEventType event_type)
- {
- mEventData.removeEventType(event_type);
- }
- //virtual
- F32 LLScriptExecuteLSL2::getSleep() const
- {
- return get_register_fp(mBuffer, LREG_SLR);
- }
- //virtual
- void LLScriptExecuteLSL2::setSleep(F32 value)
- {
- set_register_fp(mBuffer, LREG_SLR, value);
- }
- //virtual
- U64 LLScriptExecuteLSL2::getCurrentHandler()
- {
- return get_event_register(mBuffer, LREG_IE, getMajorVersion());
- }
- //virtual
- F32 LLScriptExecuteLSL2::getEnergy() const
- {
- return get_register_fp(mBuffer, LREG_ESR);
- }
- //virtual
- void LLScriptExecuteLSL2::setEnergy(F32 value)
- {
- set_register_fp(mBuffer, LREG_ESR, value);
- }
- //virtual
- U32 LLScriptExecuteLSL2::getFreeMemory()
- {
- return get_register(mBuffer, LREG_SP) - get_register(mBuffer, LREG_HP);
- }
- //virtual
- S32 LLScriptExecuteLSL2::getParameter()
- {
- return get_register(mBuffer, LREG_PR);
- }
- //virtual
- void LLScriptExecuteLSL2::setParameter(S32 value)
- {
- set_register(mBuffer, LREG_PR, value);
- }
- S32 LLScriptExecuteLSL2::writeState(U8 **dest, U32 header_size, U32 footer_size)
- {
- // data format:
- // 4 bytes of size of Registers, Name and Description, and Global Variables
- // Registers, Name and Description, and Global Variables data
- // 4 bytes of size of Heap
- // Heap data
- // 4 bytes of stack size
- // Stack data
- S32 registers_size = get_register(mBuffer, LREG_GFR);
- if (get_register(mBuffer, LREG_HP) > TOP_OF_MEMORY)
- reset_hp_to_safe_spot(mBuffer);
- S32 heap_size = get_register(mBuffer, LREG_HP) - get_register(mBuffer, LREG_HR);
- S32 stack_size = get_register(mBuffer, LREG_TM) - get_register(mBuffer, LREG_SP);
- S32 total_size = registers_size + LSCRIPTDataSize[LST_INTEGER] +
- heap_size + LSCRIPTDataSize[LST_INTEGER] +
- stack_size + LSCRIPTDataSize[LST_INTEGER];
- // actually allocate data
- delete[] *dest;
- *dest = new U8[header_size + total_size + footer_size];
- memset(*dest, 0, header_size + total_size + footer_size);
- S32 dest_offset = header_size;
- S32 src_offset = 0;
- // registers
- integer2bytestream(*dest, dest_offset, registers_size);
- // llinfos << "Writing CE: " << getCurrentEvents() << llendl;
- bytestream2bytestream(*dest, dest_offset, mBuffer, src_offset, registers_size);
- // heap
- integer2bytestream(*dest, dest_offset, heap_size);
- src_offset = get_register(mBuffer, LREG_HR);
- bytestream2bytestream(*dest, dest_offset, mBuffer, src_offset, heap_size);
- // stack
- integer2bytestream(*dest, dest_offset, stack_size);
- src_offset = get_register(mBuffer, LREG_SP);
- bytestream2bytestream(*dest, dest_offset, mBuffer, src_offset, stack_size);
- return total_size;
- }
- S32 LLScriptExecuteLSL2::writeBytecode(U8 **dest)
- {
- // data format:
- // registers through top of heap
- // Heap data
- S32 total_size = get_register(mBuffer, LREG_HP);
- // actually allocate data
- delete [] *dest;
- *dest = new U8[total_size];
- S32 dest_offset = 0;
- S32 src_offset = 0;
- bytestream2bytestream(*dest, dest_offset, mBuffer, src_offset, total_size);
- return total_size;
- }
- S32 LLScriptExecuteLSL2::readState(U8 *src)
- {
- // first, blitz heap and stack
- S32 hr = get_register(mBuffer, LREG_HR);
- S32 tm = get_register(mBuffer, LREG_TM);
- memset(mBuffer + hr, 0, tm - hr);
- S32 src_offset = 0;
- S32 dest_offset = 0;
- S32 size;
- // read register size
- size = bytestream2integer(src, src_offset);
- // copy data into register area
- bytestream2bytestream(mBuffer, dest_offset, src, src_offset, size);
- // llinfos << "Read CE: " << getCurrentEvents() << llendl;
- if (get_register(mBuffer, LREG_TM) != TOP_OF_MEMORY)
- {
- llwarns << "Invalid state. Top of memory register does not match"
- << " constant." << llendl;
- reset_hp_to_safe_spot(mBuffer);
- return -1;
- }
-
- // read heap size
- size = bytestream2integer(src, src_offset);
- // set dest offset
- dest_offset = get_register(mBuffer, LREG_HR);
- if (dest_offset + size > TOP_OF_MEMORY)
- {
- reset_hp_to_safe_spot(mBuffer);
- return -1;
- }
- // copy data into heap area
- bytestream2bytestream(mBuffer, dest_offset, src, src_offset, size);
- // read stack size
- size = bytestream2integer(src, src_offset);
- // set dest offset
- dest_offset = get_register(mBuffer, LREG_SP);
- if (dest_offset + size > TOP_OF_MEMORY)
- {
- reset_hp_to_safe_spot(mBuffer);
- return -1;
- }
- // copy data into heap area
- bytestream2bytestream(mBuffer, dest_offset, src, src_offset, size);
- // Return offset to first byte after read data.
- return src_offset;
- }
- void LLScriptExecuteLSL2::reset()
- {
- LLScriptExecute::reset();
- const U8 *src = getBytecode();
- S32 size = getBytecodeSize();
- if (!src)
- return;
- // first, blitz heap and stack
- S32 hr = get_register(mBuffer, LREG_HR);
- S32 tm = get_register(mBuffer, LREG_TM);
- memset(mBuffer + hr, 0, tm - hr);
- S32 dest_offset = 0;
- S32 src_offset = 0;
- bytestream2bytestream(mBuffer, dest_offset, src, src_offset, size);
- }
- S32 LLScriptExecuteLSL2::getMajorVersion() const
- {
- S32 version = getVersion();
- S32 major_version = 0;
- if (version == LSL2_VERSION1_END_NUMBER){
- major_version = 1;
- }
- else if (version == LSL2_VERSION_NUMBER)
- {
- major_version = 2;
- }
- return major_version;
- }
- U32 LLScriptExecuteLSL2::getUsedMemory()
- {
- return getBytecodeSize();
- }
- LLScriptExecute::LLScriptExecute() :
- mReset(FALSE)
- {
- }
- void LLScriptExecute::reset()
- {
- mReset = FALSE;
- }
- bool LLScriptExecute::isYieldDue() const
- {
- if(mReset)
- {
- return true;
- }
-
- if(getSleep() > 0.f)
- {
- return true;
- }
- if(isFinished())
- {
- return true;
- }
- // State changes can occur within a single time slice,
- // but LLScriptData's clean up is required. Yield here
- // to allow LLScriptData to perform cleanup and then call
- // runQuanta again.
- if(isStateChangePending())
- {
- return true;
- }
- return false;
- }
- // Run smallest number of instructions possible:
- // a single instruction for LSL2, a segment between save tests for Mono
- void LLScriptExecute::runInstructions(BOOL b_print, const LLUUID &id,
- const char **errorstr,
- U32& events_processed,
- F32 quanta)
- {
- // is there a fault?
- // if yes, print out message and exit
- S32 value = getVersion();
- S32 major_version = 0;
- if (value == LSL2_VERSION1_END_NUMBER)
- {
- major_version = 1;
- }
- else if (value == LSL2_VERSION_NUMBER)
- {
- major_version = 2;
- }
- else
- {
- setFault(LSRF_VERSION_MISMATCH);
- }
- value = getFaults();
- if (value > LSRF_INVALID && value < LSRF_EOF)
- {
- if (b_print)
- {
- printf("Error!n");
- }
- *errorstr = LSCRIPTRunTimeFaultStrings[value];
- return;
- }
- else
- {
- *errorstr = NULL;
- }
- if (! isFinished())
- {
- resumeEventHandler(b_print, id, quanta);
- return;
- }
- else
- {
- // make sure that IE is zero
- setCurrentHandler(0);
- // if no, we're in a state and waiting for an event
- U64 current_events = getCurrentEvents();
- U64 event_register = getEventHandlers();
- // check NS to see if need to switch states (NS != CS)
- if (isStateChangePending())
- {
- // ok, blow away any pending events
- deleteAllEvents();
- // if yes, check state exit flag is set
- if (current_events & LSCRIPTStateBitField[LSTT_STATE_EXIT])
- {
- // if yes, clear state exit flag
- setCurrentHandler(LSCRIPTStateBitField[LSTT_STATE_EXIT]);
- current_events &= ~LSCRIPTStateBitField[LSTT_STATE_EXIT];
- setCurrentEvents(current_events);
- // check state exit event handler
- // if there is a handler, call it
- if (event_register & LSCRIPTStateBitField[LSTT_STATE_EXIT])
- {
- ++events_processed;
- callEventHandler(LSTT_STATE_EXIT, id, quanta);
- return;
- }
- }
- // if no handler or no state exit flag switch to new state
- // set state entry flag and clear other CE flags
- current_events = LSCRIPTStateBitField[LSTT_STATE_ENTRY];
- setCurrentEvents(current_events);
- U64 handled_events = nextState();
- setEventHandlers(handled_events);
- }
- // try to get next event from stack
- BOOL b_done = FALSE;
- LSCRIPTStateEventType event = LSTT_NULL;
- current_events = getCurrentEvents();
- event_register = getEventHandlers();
- // first, check to see if state_entry or onrez are raised and handled
- if ((current_events & LSCRIPTStateBitField[LSTT_STATE_ENTRY])
- &&(current_events & event_register))
- {
- ++events_processed;
- callEventHandler(LSTT_STATE_ENTRY, id, quanta);
- b_done = TRUE;
- }
- else if ((current_events & LSCRIPTStateBitField[LSTT_REZ])
- &&(current_events & event_register))
- {
- ++events_processed;
- callQueuedEventHandler(LSTT_REZ, id, quanta);
- b_done = TRUE;
- }
- if (!b_done)
- {
- // Call handler for next queued event.
- if(getEventCount() > 0)
- {
- ++events_processed;
- callNextQueuedEventHandler(event_register, id, quanta);
- }
- else
- {
- // if no data waiting, do it the old way:
- U64 handled_current = current_events & event_register;
- if (handled_current)
- {
- event = return_first_event((S32)handled_current);
- ++events_processed;
- callEventHandler(event, id, quanta);
- }
- }
- b_done = TRUE;
- }
- }
- }
- // Run for a single timeslice, or until a yield or state transition is due
- F32 LLScriptExecute::runQuanta(BOOL b_print, const LLUUID &id, const char **errorstr, F32 quanta, U32& events_processed, LLTimer& timer)
- {
- S32 timer_checks = 0;
- F32 inloop = 0;
- // Loop while not finished, yield not due and time remaining
- // NOTE: Default implementation does not do adaptive timer skipping
- // to preserve current LSL behaviour and not break scripts that rely
- // on current execution speed.
- while(true)
- {
- runInstructions(b_print, id, errorstr,
- events_processed, quanta);
-
- if(isYieldDue())
- {
- break;
- }
- else if(timer_checks++ >= LLScriptExecute::sTimerCheckSkip)
- {
- inloop = timer.getElapsedTimeF32();
- if(inloop > quanta)
- {
- break;
- }
- timer_checks = 0;
- }
- }
- if (inloop == 0.0f)
- {
- inloop = timer.getElapsedTimeF32();
- }
- return inloop;
- }
- F32 LLScriptExecute::runNested(BOOL b_print, const LLUUID &id, const char **errorstr, F32 quanta, U32& events_processed, LLTimer& timer)
- {
- return LLScriptExecute::runQuanta(b_print, id, errorstr, quanta, events_processed, timer);
- }
- BOOL run_noop(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tNOOPn", offset);
- offset++;
- return FALSE;
- }
- BOOL run_pop(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tPOPn", offset);
- offset++;
- lscript_poparg(buffer, LSCRIPTDataSize[LST_INTEGER]);
- return FALSE;
- }
- BOOL run_pops(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tPOPSn", offset);
- offset++;
- S32 address = lscript_pop_int(buffer);
- if (address)
- lsa_decrease_ref_count(buffer, address);
- return FALSE;
- }
- BOOL run_popl(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tPOPLn", offset);
- offset++;
- S32 address = lscript_pop_int(buffer);
- if (address)
- lsa_decrease_ref_count(buffer, address);
- return FALSE;
- }
- BOOL run_popv(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tPOPVn", offset);
- offset++;
- lscript_poparg(buffer, LSCRIPTDataSize[LST_VECTOR]);
- return FALSE;
- }
- BOOL run_popq(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tPOPQn", offset);
- offset++;
- lscript_poparg(buffer, LSCRIPTDataSize[LST_QUATERNION]);
- return FALSE;
- }
- BOOL run_poparg(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tPOPARG ", offset);
- offset++;
- S32 arg = safe_instruction_bytestream2integer(buffer, offset);
- if (b_print)
- printf("%dn", arg);
- lscript_poparg(buffer, arg);
- return FALSE;
- }
- BOOL run_popip(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tPOPIPn", offset);
- offset++;
- offset = lscript_pop_int(buffer);
- return FALSE;
- }
- BOOL run_popbp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tPOPBPn", offset);
- offset++;
- S32 bp = lscript_pop_int(buffer);
- set_bp(buffer, bp);
- return FALSE;
- }
- BOOL run_popsp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tPOPSPn", offset);
- offset++;
- S32 sp = lscript_pop_int(buffer);
- set_sp(buffer, sp);
- return FALSE;
- }
- BOOL run_popslr(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tPOPSLRn", offset);
- offset++;
- S32 slr = lscript_pop_int(buffer);
- set_register(buffer, LREG_SLR, slr);
- return FALSE;
- }
- BOOL run_dup(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tDUPn", offset);
- offset++;
- S32 sp = get_register(buffer, LREG_SP);
- S32 value = bytestream2integer(buffer, sp);
- lscript_push(buffer, value);
- return FALSE;
- }
- BOOL run_dups(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tDUPSn", offset);
- offset++;
- S32 sp = get_register(buffer, LREG_SP);
- S32 value = bytestream2integer(buffer, sp);
- lscript_push(buffer, value);
- lsa_increase_ref_count(buffer, value);
- return FALSE;
- }
- BOOL run_dupl(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tDUPLn", offset);
- offset++;
- S32 sp = get_register(buffer, LREG_SP);
- S32 value = bytestream2integer(buffer, sp);
- lscript_push(buffer, value);
- lsa_increase_ref_count(buffer, value);
- return FALSE;
- }
- BOOL run_dupv(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tDUPVn", offset);
- offset++;
- S32 sp = get_register(buffer, LREG_SP);
- LLVector3 value;
- bytestream2vector(value, buffer, sp);
- lscript_push(buffer, value);
- return FALSE;
- }
- BOOL run_dupq(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tDUPVn", offset);
- offset++;
- S32 sp = get_register(buffer, LREG_SP);
- LLQuaternion value;
- bytestream2quaternion(value, buffer, sp);
- lscript_push(buffer, value);
- return FALSE;
- }
- BOOL run_store(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tSTORE ", offset);
- offset++;
- S32 arg = safe_instruction_bytestream2integer(buffer, offset);
- if (b_print)
- printf("0x%Xn", arg);
- S32 sp = get_register(buffer, LREG_SP);
- S32 value = bytestream2integer(buffer, sp);
- lscript_local_store(buffer, arg, value);
- return FALSE;
- }
- BOOL run_stores(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tSTORES ", offset);
- offset++;
- S32 arg = safe_instruction_bytestream2integer(buffer, offset);
- if (b_print)
- printf("0x%Xn", arg);
- S32 sp = get_register(buffer, LREG_SP);
- S32 value = bytestream2integer(buffer, sp);
- S32 address = lscript_local_get(buffer, arg);
- lscript_local_store(buffer, arg, value);
- lsa_increase_ref_count(buffer, value);
- if (address)
- lsa_decrease_ref_count(buffer, address);
- return FALSE;
- }
- BOOL run_storel(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tSTOREL ", offset);
- offset++;
- S32 arg = safe_instruction_bytestream2integer(buffer, offset);
- if (b_print)
- printf("0x%Xn", arg);
- S32 sp = get_register(buffer, LREG_SP);
- S32 value = bytestream2integer(buffer, sp);
- S32 address = lscript_local_get(buffer, arg);
- lscript_local_store(buffer, arg, value);
- lsa_increase_ref_count(buffer, value);
- if (address)
- lsa_decrease_ref_count(buffer, address);
- return FALSE;
- }
- BOOL run_storev(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tSTOREV ", offset);
- offset++;
- S32 arg = safe_instruction_bytestream2integer(buffer, offset);
- if (b_print)
- printf("0x%Xn", arg);
- LLVector3 value;
- S32 sp = get_register(buffer, LREG_SP);
- bytestream2vector(value, buffer, sp);
- lscript_local_store(buffer, arg, value);
- return FALSE;
- }
- BOOL run_storeq(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tSTOREQ ", offset);
- offset++;
- S32 arg = safe_instruction_bytestream2integer(buffer, offset);
- if (b_print)
- printf("0x%Xn", arg);
- LLQuaternion value;
- S32 sp = get_register(buffer, LREG_SP);
- bytestream2quaternion(value, buffer, sp);
- lscript_local_store(buffer, arg, value);
- return FALSE;
- }
- BOOL run_storeg(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tSTOREG ", offset);
- offset++;
- S32 arg = safe_instruction_bytestream2integer(buffer, offset);
- if (b_print)
- printf("0x%Xn", arg);
- S32 sp = get_register(buffer, LREG_SP);
- S32 value = bytestream2integer(buffer, sp);
- lscript_global_store(buffer, arg, value);
- return FALSE;
- }
- BOOL run_storegs(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tSTOREGS ", offset);
- offset++;
- S32 arg = safe_instruction_bytestream2integer(buffer, offset);
- if (b_print)
- printf("0x%Xn", arg);
- S32 sp = get_register(buffer, LREG_SP);
- S32 value = bytestream2integer(buffer, sp);
- S32 address = lscript_global_get(buffer, arg);
- lscript_global_store(buffer, arg, value);
- lsa_increase_ref_count(buffer, value);
- if (address)
- lsa_decrease_ref_count(buffer, address);
- return FALSE;
- }
- BOOL run_storegl(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tSTOREGL ", offset);
- offset++;
- S32 arg = safe_instruction_bytestream2integer(buffer, offset);
- if (b_print)
- printf("0x%Xn", arg);
- S32 sp = get_register(buffer, LREG_SP);
- S32 value = bytestream2integer(buffer, sp);
- S32 address = lscript_global_get(buffer, arg);
- lscript_global_store(buffer, arg, value);
- lsa_increase_ref_count(buffer, value);
- if (address)
- lsa_decrease_ref_count(buffer, address);
- return FALSE;
- }
- BOOL run_storegv(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tSTOREGV ", offset);
- offset++;
- S32 arg = safe_instruction_bytestream2integer(buffer, offset);
- if (b_print)
- printf("0x%Xn", arg);
- LLVector3 value;
- S32 sp = get_register(buffer, LREG_SP);
- bytestream2vector(value, buffer, sp);
- lscript_global_store(buffer, arg, value);
- return FALSE;
- }
- BOOL run_storegq(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tSTOREGQ ", offset);
- offset++;
- S32 arg = safe_instruction_bytestream2integer(buffer, offset);
- if (b_print)
- printf("0x%Xn", arg);
- LLQuaternion value;
- S32 sp = get_register(buffer, LREG_SP);
- bytestream2quaternion(value, buffer, sp);
- lscript_global_store(buffer, arg, value);
- return FALSE;
- }
- BOOL run_loadp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tSTOREP ", offset);
- offset++;
- S32 arg = safe_instruction_bytestream2integer(buffer, offset);
- if (b_print)
- printf("0x%Xn", arg);
- S32 value = lscript_pop_int(buffer);
- lscript_local_store(buffer, arg, value);
- return FALSE;
- }
- BOOL run_loadsp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tSTORESP ", offset);
- offset++;
- S32 arg = safe_instruction_bytestream2integer(buffer, offset);
- if (b_print)
- printf("0x%Xn", arg);
- S32 value = lscript_pop_int(buffer);
- S32 address = lscript_local_get(buffer, arg);
- if (address)
- lsa_decrease_ref_count(buffer, address);
- lscript_local_store(buffer, arg, value);
- return FALSE;
- }
- BOOL run_loadlp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tSTORELP ", offset);
- offset++;
- S32 arg = safe_instruction_bytestream2integer(buffer, offset);
- if (b_print)
- printf("0x%Xn", arg);
- S32 value = lscript_pop_int(buffer);
- S32 address = lscript_local_get(buffer, arg);
- if (address)
- lsa_decrease_ref_count(buffer, address);
- lscript_local_store(buffer, arg, value);
- return FALSE;
- }
- BOOL run_loadvp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tSTOREVP ", offset);
- offset++;
- S32 arg = safe_instruction_bytestream2integer(buffer, offset);
- if (b_print)
- printf("0x%Xn", arg);
- LLVector3 value;
- lscript_pop_vector(buffer, value);
- lscript_local_store(buffer, arg, value);
- return FALSE;
- }
- BOOL run_loadqp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tSTOREQP ", offset);
- offset++;
- S32 arg = safe_instruction_bytestream2integer(buffer, offset);
- if (b_print)
- printf("0x%Xn", arg);
- LLQuaternion value;
- lscript_pop_quaternion(buffer, value);
- lscript_local_store(buffer, arg, value);
- return FALSE;
- }
- BOOL run_loadgp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tSTOREGP ", offset);
- offset++;
- S32 arg = safe_instruction_bytestream2integer(buffer, offset);
- if (b_print)
- printf("0x%Xn", arg);
- S32 value = lscript_pop_int(buffer);
- lscript_global_store(buffer, arg, value);
- return FALSE;
- }
- BOOL run_loadgsp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tSTOREGSP ", offset);
- offset++;
- S32 arg = safe_instruction_bytestream2integer(buffer, offset);
- if (b_print)
- printf("%dn", arg);
- S32 value = lscript_pop_int(buffer);
- S32 address = lscript_global_get(buffer, arg);
- if (address)
- lsa_decrease_ref_count(buffer, address);
- lscript_global_store(buffer, arg, value);
- return FALSE;
- }
- BOOL run_loadglp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tSTOREGLP ", offset);
- offset++;
- S32 arg = safe_instruction_bytestream2integer(buffer, offset);
- if (b_print)
- printf("0x%Xn", arg);
- S32 value = lscript_pop_int(buffer);
- S32 address = lscript_global_get(buffer, arg);
- if (address)
- lsa_decrease_ref_count(buffer, address);
- lscript_global_store(buffer, arg, value);
- return FALSE;
- }
- BOOL run_loadgvp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tSTOREGVP ", offset);
- offset++;
- S32 arg = safe_instruction_bytestream2integer(buffer, offset);
- if (b_print)
- printf("0x%Xn", arg);
- LLVector3 value;
- lscript_pop_vector(buffer, value);
- lscript_global_store(buffer, arg, value);
- return FALSE;
- }
- BOOL run_loadgqp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tSTOREGQP ", offset);
- offset++;
- S32 arg = safe_instruction_bytestream2integer(buffer, offset);
- if (b_print)
- printf("0x%Xn", arg);
- LLQuaternion value;
- lscript_pop_quaternion(buffer, value);
- lscript_global_store(buffer, arg, value);
- return FALSE;
- }
- BOOL run_push(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tPUSH ", offset);
- offset++;
- S32 arg = safe_instruction_bytestream2integer(buffer, offset);
- if (b_print)
- printf("0x%Xn", arg);
- S32 value = lscript_local_get(buffer, arg);
- lscript_push(buffer, value);
- return FALSE;
- }
- BOOL run_pushs(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tPUSHS ", offset);
- offset++;
- S32 arg = safe_instruction_bytestream2integer(buffer, offset);
- if (b_print)
- printf("0x%Xn", arg);
- S32 value = lscript_local_get(buffer, arg);
- lscript_push(buffer, value);
- lsa_increase_ref_count(buffer, value);
- return FALSE;
- }
- BOOL run_pushl(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tPUSHL ", offset);
- offset++;
- S32 arg = safe_instruction_bytestream2integer(buffer, offset);
- if (b_print)
- printf("0x%Xn", arg);
- S32 value = lscript_local_get(buffer, arg);
- lscript_push(buffer, value);
- lsa_increase_ref_count(buffer, value);
- return FALSE;
- }
- BOOL run_pushv(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tPUSHV ", offset);
- offset++;
- S32 arg = safe_instruction_bytestream2integer(buffer, offset);
- if (b_print)
- printf("0x%Xn", arg);
- LLVector3 value;
- lscript_local_get(buffer, arg, value);
- lscript_push(buffer, value);
- return FALSE;
- }
- BOOL run_pushq(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tPUSHQ ", offset);
- offset++;
- S32 arg = safe_instruction_bytestream2integer(buffer, offset);
- if (b_print)
- printf("0x%Xn", arg);
- LLQuaternion value;
- lscript_local_get(buffer, arg, value);
- lscript_push(buffer, value);
- return FALSE;
- }
- BOOL run_pushg(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tPUSHG ", offset);
- offset++;
- S32 arg = safe_instruction_bytestream2integer(buffer, offset);
- if (b_print)
- printf("0x%Xn", arg);
- S32 value = lscript_global_get(buffer, arg);
- lscript_push(buffer, value);
- return FALSE;
- }
- BOOL run_pushgs(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tPUSHGS ", offset);
- offset++;
- S32 arg = safe_instruction_bytestream2integer(buffer, offset);
- if (b_print)
- printf("0x%Xn", arg);
- S32 value = lscript_global_get(buffer, arg);
- lscript_push(buffer, value);
- lsa_increase_ref_count(buffer, value);
- return FALSE;
- }
- BOOL run_pushgl(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tPUSHGL ", offset);
- offset++;
- S32 arg = safe_instruction_bytestream2integer(buffer, offset);
- if (b_print)
- printf("0x%Xn", arg);
- S32 value = lscript_global_get(buffer, arg);
- lscript_push(buffer, value);
- lsa_increase_ref_count(buffer, value);
- return FALSE;
- }
- BOOL run_pushgv(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tPUSHGV ", offset);
- offset++;
- S32 arg = safe_instruction_bytestream2integer(buffer, offset);
- if (b_print)
- printf("0x%Xn", arg);
- LLVector3 value;
- lscript_global_get(buffer, arg, value);
- lscript_push(buffer, value);
- return FALSE;
- }
- BOOL run_pushgq(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tPUSHGQ ", offset);
- offset++;
- S32 arg = safe_instruction_bytestream2integer(buffer, offset);
- if (b_print)
- printf("0x%Xn", arg);
- LLQuaternion value;
- lscript_global_get(buffer, arg, value);
- lscript_push(buffer, value);
- return FALSE;
- }
- BOOL run_puship(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tPUSHIPn", offset);
- offset++;
- lscript_push(buffer, offset);
- return FALSE;
- }
- BOOL run_pushbp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tPUSHBPn", offset);
- offset++;
- lscript_push(buffer, get_register(buffer, LREG_BP));
- return FALSE;
- }
- BOOL run_pushsp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tPUSHSPn", offset);
- offset++;
- lscript_push(buffer, get_register(buffer, LREG_SP));
- return FALSE;
- }
- BOOL run_pushargb(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tPUSHGARGB ", offset);
- offset++;
- U8 arg = safe_instruction_bytestream2byte(buffer, offset);
- if (b_print)
- printf("%dn", (U32)arg);
- lscript_push(buffer, arg);
- return FALSE;
- }
- BOOL run_pushargi(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tPUSHARGI ", offset);
- offset++;
- S32 arg = safe_instruction_bytestream2integer(buffer, offset);
- if (b_print)
- printf("%dn", arg);
- lscript_push(buffer, arg);
- return FALSE;
- }
- BOOL run_pushargf(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tPUSHARGF ", offset);
- offset++;
- F32 arg = safe_instruction_bytestream2float(buffer, offset);
- if (b_print)
- printf("%fn", arg);
- lscript_push(buffer, arg);
- return FALSE;
- }
- BOOL run_pushargs(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tPUSHARGS ", offset);
- S32 toffset = offset;
- safe_instruction_bytestream_count_char(buffer, toffset);
- S32 size = toffset - offset;
- char *arg = new char[size];
- offset++;
- safe_instruction_bytestream2char(arg, buffer, offset, size);
- if (b_print)
- printf("%sn", arg);
- S32 address = lsa_heap_add_data(buffer, new LLScriptLibData(arg), get_max_heap_size(buffer), TRUE);
- lscript_push(buffer, address);
- delete [] arg;
- return FALSE;
- }
- BOOL run_pushargv(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tPUSHARGV ", offset);
- offset++;
- LLVector3 arg;
- safe_instruction_bytestream2vector(arg, buffer, offset);
- if (b_print)
- printf("< %f, %f, %f >n", arg.mV[VX], arg.mV[VY], arg.mV[VZ]);
- lscript_push(buffer, arg);
- return FALSE;
- }
- BOOL run_pushargq(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tPUSHARGQ ", offset);
- offset++;
- LLQuaternion arg;
- safe_instruction_bytestream2quaternion(arg, buffer, offset);
- if (b_print)
- printf("< %f, %f, %f, %f >n", arg.mQ[VX], arg.mQ[VY], arg.mQ[VZ], arg.mQ[VS]);
- lscript_push(buffer, arg);
- return FALSE;
- }
- BOOL run_pushe(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tPUSHEn", offset);
- offset++;
- lscript_pusharge(buffer, LSCRIPTDataSize[LST_INTEGER]);
- return FALSE;
- }
- BOOL run_pushev(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tPUSHEVn", offset);
- offset++;
- lscript_pusharge(buffer, LSCRIPTDataSize[LST_VECTOR]);
- return FALSE;
- }
- BOOL run_pusheq(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tPUSHEQn", offset);
- offset++;
- lscript_pusharge(buffer, LSCRIPTDataSize[LST_QUATERNION]);
- return FALSE;
- }
- BOOL run_pusharge(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tPUSHARGE ", offset);
- offset++;
- S32 arg = safe_instruction_bytestream2integer(buffer, offset);
- if (b_print)
- printf("%dn", arg);
- lscript_pusharge(buffer, arg);
- return FALSE;
- }
- void print_type(U8 type)
- {
- if (type == LSCRIPTTypeByte[LST_INTEGER])
- {
- printf("integer");
- }
- else if (type == LSCRIPTTypeByte[LST_FLOATINGPOINT])
- {
- printf("float");
- }
- else if (type == LSCRIPTTypeByte[LST_STRING])
- {
- printf("string");
- }
- else if (type == LSCRIPTTypeByte[LST_KEY])
- {
- printf("key");
- }
- else if (type == LSCRIPTTypeByte[LST_VECTOR])
- {
- printf("vector");
- }
- else if (type == LSCRIPTTypeByte[LST_QUATERNION])
- {
- printf("quaternion");
- }
- else if (type == LSCRIPTTypeByte[LST_LIST])
- {
- printf("list");
- }
- }
- void unknown_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
- {
- printf("Unknown arithmetic operation!n");
- }
- void integer_integer_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
- {
- S32 lside = lscript_pop_int(buffer);
- S32 rside = lscript_pop_int(buffer);
- S32 result = 0;
- switch(opcode)
- {
- case LOPC_ADD:
- result = lside + rside;
- break;
- case LOPC_SUB:
- result = lside - rside;
- break;
- case LOPC_MUL:
- result = lside * rside;
- break;
- case LOPC_DIV:
- if (rside){
- if( ( rside == -1 ) || ( rside == (S32) 0xffffffff ) )// division by -1 can have funny results: multiplication is OK: SL-31252
- {
- result = -1 * lside;
- }
- else
- {
- result = lside / rside;
- }
- }
- else
- set_fault(buffer, LSRF_MATH);
- break;
- case LOPC_MOD:
- if (rside)
- {
- if (rside == -1 || rside == 1 ) // mod(1) = mod(-1) = 0: SL-31252
- {
- result = 0;
- }
- else
- {
- result = lside % rside;
- }
- }
- else
- set_fault(buffer, LSRF_MATH);
- break;
- case LOPC_EQ:
- result = (lside == rside);
- break;
- case LOPC_NEQ:
- result = (lside != rside);
- break;
- case LOPC_LEQ:
- result = (lside <= rside);
- break;
- case LOPC_GEQ:
- result = (lside >= rside);
- break;
- case LOPC_LESS:
- result = (lside < rside);
- break;
- case LOPC_GREATER:
- result = (lside > rside);
- break;
- case LOPC_BITAND:
- result = (lside & rside);
- break;
- case LOPC_BITOR:
- result = (lside | rside);
- break;
- case LOPC_BITXOR:
- result = (lside ^ rside);
- break;
- case LOPC_BOOLAND:
- result = (lside && rside);
- break;
- case LOPC_BOOLOR:
- result = (lside || rside);
- break;
- case LOPC_SHL:
- result = (lside << rside);
- break;
- case LOPC_SHR:
- result = (lside >> rside);
- break;
- default:
- break;
- }
- lscript_push(buffer, result);
- }
- void integer_float_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
- {
- S32 lside = lscript_pop_int(buffer);
- F32 rside = lscript_pop_float(buffer);
- S32 resulti = 0;
- F32 resultf = 0;
- switch(opcode)
- {
- case LOPC_ADD:
- resultf = lside + rside;
- lscript_push(buffer, resultf);
- break;
- case LOPC_SUB:
- resultf = lside - rside;
- lscript_push(buffer, resultf);
- break;
- case LOPC_MUL:
- resultf = lside * rside;
- lscript_push(buffer, resultf);
- break;
- case LOPC_DIV:
- if (rside)
- resultf = lside / rside;
- else
- set_fault(buffer, LSRF_MATH);
- lscript_push(buffer, resultf);
- break;
- case LOPC_EQ:
- resulti = (lside == rside);
- lscript_push(buffer, resulti);
- break;
- case LOPC_NEQ:
- resulti = (lside != rside);
- lscript_push(buffer, resulti);
- break;
- case LOPC_LEQ:
- resulti = (lside <= rside);
- lscript_push(buffer, resulti);
- break;
- case LOPC_GEQ:
- resulti = (lside >= rside);
- lscript_push(buffer, resulti);
- break;
- case LOPC_LESS:
- resulti = (lside < rside);
- lscript_push(buffer, resulti);
- break;
- case LOPC_GREATER:
- resulti = (lside > rside);
- lscript_push(buffer, resulti);
- break;
- default:
- break;
- }
- }
- void integer_vector_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
- {
- S32 lside = lscript_pop_int(buffer);
- LLVector3 rside;
- lscript_pop_vector(buffer, rside);
- switch(opcode)
- {
- case LOPC_MUL:
- rside *= (F32)lside;
- lscript_push(buffer, rside);
- break;
- default:
- break;
- }
- }
- void float_integer_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
- {
- F32 lside = lscript_pop_float(buffer);
- S32 rside = lscript_pop_int(buffer);
- S32 resulti = 0;
- F32 resultf = 0;
- switch(opcode)
- {
- case LOPC_ADD:
- resultf = lside + rside;
- lscript_push(buffer, resultf);
- break;
- case LOPC_SUB:
- resultf = lside - rside;
- lscript_push(buffer, resultf);
- break;
- case LOPC_MUL:
- resultf = lside * rside;
- lscript_push(buffer, resultf);
- break;
- case LOPC_DIV:
- if (rside)
- resultf = lside / rside;
- else
- set_fault(buffer, LSRF_MATH);
- lscript_push(buffer, resultf);
- break;
- case LOPC_EQ:
- resulti = (lside == rside);
- lscript_push(buffer, resulti);
- break;
- case LOPC_NEQ:
- resulti = (lside != rside);
- lscript_push(buffer, resulti);
- break;
- case LOPC_LEQ:
- resulti = (lside <= rside);
- lscript_push(buffer, resulti);
- break;
- case LOPC_GEQ:
- resulti = (lside >= rside);
- lscript_push(buffer, resulti);
- break;
- case LOPC_LESS:
- resulti = (lside < rside);
- lscript_push(buffer, resulti);
- break;
- case LOPC_GREATER:
- resulti = (lside > rside);
- lscript_push(buffer, resulti);
- break;
- default:
- break;
- }
- }
- void float_float_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
- {
- F32 lside = lscript_pop_float(buffer);
- F32 rside = lscript_pop_float(buffer);
- F32 resultf = 0;
- S32 resulti = 0;
- switch(opcode)
- {
- case LOPC_ADD:
- resultf = lside + rside;
- lscript_push(buffer, resultf);
- break;
- case LOPC_SUB:
- resultf = lside - rside;
- lscript_push(buffer, resultf);
- break;
- case LOPC_MUL:
- resultf = lside * rside;
- lscript_push(buffer, resultf);
- break;
- case LOPC_DIV:
- if (rside)
- resultf = lside / rside;
- else
- set_fault(buffer, LSRF_MATH);
- lscript_push(buffer, resultf);
- break;
- case LOPC_EQ:
- resulti = (lside == rside);
- lscript_push(buffer, resulti);
- break;
- case LOPC_NEQ:
- resulti = (lside != rside);
- lscript_push(buffer, resulti);
- break;
- case LOPC_LEQ:
- resulti = (lside <= rside);
- lscript_push(buffer, resulti);
- break;
- case LOPC_GEQ:
- resulti = (lside >= rside);
- lscript_push(buffer, resulti);
- break;
- case LOPC_LESS:
- resulti = (lside < rside);
- lscript_push(buffer, resulti);
- break;
- case LOPC_GREATER:
- resulti = (lside > rside);
- lscript_push(buffer, resulti);
- break;
- default:
- break;
- }
- }
- void float_vector_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
- {
- F32 lside = lscript_pop_float(buffer);
- LLVector3 rside;
- lscript_pop_vector(buffer, rside);
- switch(opcode)
- {
- case LOPC_MUL:
- rside *= lside;
- lscript_push(buffer, rside);
- break;
- default:
- break;
- }
- }
- void string_string_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
- {
- S32 lside = lscript_pop_int(buffer);
- S32 rside = lscript_pop_int(buffer);
- S32 resulti;
- S32 address;
- switch(opcode)
- {
- case LOPC_ADD:
- address = lsa_cat_strings(buffer, lside, rside, get_max_heap_size(buffer));
- lscript_push(buffer, address);
- break;
- case LOPC_EQ:
- resulti = !lsa_cmp_strings(buffer, lside, rside);
- lscript_push(buffer, resulti);
- break;
- case LOPC_NEQ:
- resulti = lsa_cmp_strings(buffer, lside, rside);
- lscript_push(buffer, resulti);
- break;
- default:
- break;
- }
- }
- void string_key_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
- {
- S32 lside = lscript_pop_int(buffer);
- S32 rside = lscript_pop_int(buffer);
- S32 resulti;
- switch(opcode)
- {
- case LOPC_NEQ:
- resulti = lsa_cmp_strings(buffer, lside, rside);
- lscript_push(buffer, resulti);
- break;
- case LOPC_EQ:
- resulti = !lsa_cmp_strings(buffer, lside, rside);
- lscript_push(buffer, resulti);
- break;
- default:
- break;
- }
- }
- void key_string_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
- {
- S32 lside = lscript_pop_int(buffer);
- S32 rside = lscript_pop_int(buffer);
- S32 resulti;
- switch(opcode)
- {
- case LOPC_NEQ:
- resulti = lsa_cmp_strings(buffer, lside, rside);
- lscript_push(buffer, resulti);
- break;
- case LOPC_EQ:
- resulti = !lsa_cmp_strings(buffer, lside, rside);
- lscript_push(buffer, resulti);
- break;
- default:
- break;
- }
- }
- void key_key_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
- {
- S32 lside = lscript_pop_int(buffer);
- S32 rside = lscript_pop_int(buffer);
- S32 resulti;
- switch(opcode)
- {
- case LOPC_EQ:
- resulti = !lsa_cmp_strings(buffer, lside, rside);
- lscript_push(buffer, resulti);
- break;
- case LOPC_NEQ:
- resulti = lsa_cmp_strings(buffer, lside, rside);
- lscript_push(buffer, resulti);
- break;
- default:
- break;
- }
- }
- void vector_integer_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
- {
- LLVector3 lside;
- lscript_pop_vector(buffer, lside);
- S32 rside = lscript_pop_int(buffer);
- switch(opcode)
- {
- case LOPC_MUL:
- lside *= (F32)rside;
- lscript_push(buffer, lside);
- break;
- case LOPC_DIV:
- if (rside)
- lside *= (1.f/rside);
- else
- set_fault(buffer, LSRF_MATH);
- lscript_push(buffer, lside);
- break;
- default:
- break;
- }
- }
- void vector_float_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
- {
- LLVector3 lside;
- lscript_pop_vector(buffer, lside);
- F32 rside = lscript_pop_float(buffer);
- switch(opcode)
- {
- case LOPC_MUL:
- lside *= rside;
- lscript_push(buffer, lside);
- break;
- case LOPC_DIV:
- if (rside)
- lside *= (1.f/rside);
- else
- set_fault(buffer, LSRF_MATH);
- lscript_push(buffer, lside);
- break;
- default:
- break;
- }
- }
- void vector_vector_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
- {
- LLVector3 lside;
- lscript_pop_vector(buffer, lside);
- LLVector3 rside;
- lscript_pop_vector(buffer, rside);
- S32 resulti = 0;
- F32 resultf = 0.f;
- switch(opcode)
- {
- case LOPC_ADD:
- lside += rside;
- lscript_push(buffer, lside);
- break;
- case LOPC_SUB:
- lside -= rside;
- lscript_push(buffer, lside);
- break;
- case LOPC_MUL:
- resultf = lside * rside;
- lscript_push(buffer, resultf);
- break;
- case LOPC_MOD:
- lside = lside % rside;
- lscript_push(buffer, lside);
- break;
- case LOPC_EQ:
- resulti = (lside == rside);
- lscript_push(buffer, resulti);
- break;
- case LOPC_NEQ:
- resulti = (lside != rside);
- lscript_push(buffer, resulti);
- break;
- default:
- break;
- }
- }
- void vector_quaternion_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
- {
- LLVector3 lside;
- lscript_pop_vector(buffer, lside);
- LLQuaternion rside;
- lscript_pop_quaternion(buffer, rside);
- switch(opcode)
- {
- case LOPC_MUL:
- lside = lside * rside;
- lscript_push(buffer, lside);
- break;
- case LOPC_DIV:
- lside = lside * rside.conjQuat();
- lscript_push(buffer, lside);
- break;
- default:
- break;
- }
- }
- void quaternion_quaternion_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
- {
- LLQuaternion lside;
- lscript_pop_quaternion(buffer, lside);
- LLQuaternion rside;
- lscript_pop_quaternion(buffer, rside);
- S32 resulti = 0;
- switch(opcode)
- {
- case LOPC_ADD:
- lside = lside + rside;
- lscript_push(buffer, lside);
- break;
- case LOPC_SUB:
- lside = lside - rside;
- lscript_push(buffer, lside);
- break;
- case LOPC_MUL:
- lside *= rside;
- lscript_push(buffer, lside);
- break;
- case LOPC_DIV:
- lside = lside * rside.conjQuat();
- lscript_push(buffer, lside);
- break;
- case LOPC_EQ:
- resulti = (lside == rside);
- lscript_push(buffer, resulti);
- break;
- case LOPC_NEQ:
- resulti = (lside != rside);
- lscript_push(buffer, resulti);
- break;
- default:
- break;
- }
- }
- void integer_list_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
- {
- S32 lside = lscript_pop_int(buffer);
- S32 rside = lscript_pop_int(buffer);
- S32 address;
- switch(opcode)
- {
- case LOPC_ADD:
- {
- LLScriptLibData *list = new LLScriptLibData;
- list->mType = LST_LIST;
- list->mListp = new LLScriptLibData(lside);
- address = lsa_preadd_lists(buffer, list, rside, get_max_heap_size(buffer));
- lscript_push(buffer, address);
- list->mListp = NULL;
- delete list;
- }
- break;
- default:
- break;
- }
- }
- void float_list_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
- {
- F32 lside = lscript_pop_float(buffer);
- S32 rside = lscript_pop_int(buffer);
- S32 address;
- switch(opcode)
- {
- case LOPC_ADD:
- {
- LLScriptLibData *list = new LLScriptLibData;
- list->mType = LST_LIST;
- list->mListp = new LLScriptLibData(lside);
- address = lsa_preadd_lists(buffer, list, rside, get_max_heap_size(buffer));
- lscript_push(buffer, address);
- list->mListp = NULL;
- delete list;
- }
- break;
- default:
- break;
- }
- }
- void string_list_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
- {
- S32 lside = lscript_pop_int(buffer);
- S32 rside = lscript_pop_int(buffer);
- S32 address;
- switch(opcode)
- {
- case LOPC_ADD:
- {
- LLScriptLibData *string = lsa_get_data(buffer, lside, TRUE);
- LLScriptLibData *list = new LLScriptLibData;
- list->mType = LST_LIST;
- list->mListp = string;
- address = lsa_preadd_lists(buffer, list, rside, get_max_heap_size(buffer));
- lscript_push(buffer, address);
- list->mListp = NULL;
- delete list;
- }
- break;
- default:
- break;
- }
- }
- void key_list_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
- {
- S32 lside = lscript_pop_int(buffer);
- S32 rside = lscript_pop_int(buffer);
- S32 address;
- switch(opcode)
- {
- case LOPC_ADD:
- {
- LLScriptLibData *key = lsa_get_data(buffer, lside, TRUE);
- // need to convert key to key, since it comes out like a string
- if (key->mType == LST_STRING)
- {
- key->mKey = key->mString;
- key->mString = NULL;
- key->mType = LST_KEY;
- }
- LLScriptLibData *list = new LLScriptLibData;
- list->mType = LST_LIST;
- list->mListp = key;
- address = lsa_preadd_lists(buffer, list, rside, get_max_heap_size(buffer));
- lscript_push(buffer, address);
- list->mListp = NULL;
- delete list;
- }
- break;
- default:
- break;
- }
- }
- void vector_list_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
- {
- LLVector3 lside;
- lscript_pop_vector(buffer, lside);
- S32 rside = lscript_pop_int(buffer);
- S32 address;
- switch(opcode)
- {
- case LOPC_ADD:
- {
- LLScriptLibData *list = new LLScriptLibData;
- list->mType = LST_LIST;
- list->mListp = new LLScriptLibData(lside);
- address = lsa_preadd_lists(buffer, list, rside, get_max_heap_size(buffer));
- lscript_push(buffer, address);
- list->mListp = NULL;
- delete list;
- }
- break;
- default:
- break;
- }
- }
- void quaternion_list_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
- {
- LLQuaternion lside;
- lscript_pop_quaternion(buffer, lside);
- S32 rside = lscript_pop_int(buffer);
- S32 address;
- switch(opcode)
- {
- case LOPC_ADD:
- {
- LLScriptLibData *list = new LLScriptLibData;
- list->mType = LST_LIST;
- list->mListp = new LLScriptLibData(lside);
- address = lsa_preadd_lists(buffer, list, rside, get_max_heap_size(buffer));
- lscript_push(buffer, address);
- list->mListp = NULL;
- delete list;
- }
- break;
- default:
- break;
- }
- }
- void list_integer_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
- {
- S32 lside = lscript_pop_int(buffer);
- S32 rside = lscript_pop_int(buffer);
- S32 address;
- switch(opcode)
- {
- case LOPC_ADD:
- {
- LLScriptLibData *list = new LLScriptLibData;
- list->mType = LST_LIST;
- list->mListp = new LLScriptLibData(rside);
- address = lsa_postadd_lists(buffer, lside, list, get_max_heap_size(buffer));
- list->mListp = NULL;
- delete list;
- lscript_push(buffer, address);
- }
- break;
- default:
- break;
- }
- }
- void list_float_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
- {
- S32 lside = lscript_pop_int(buffer);
- F32 rside = lscript_pop_float(buffer);
- S32 address;
- switch(opcode)
- {
- case LOPC_ADD:
- {
- LLScriptLibData *list = new LLScriptLibData;
- list->mType = LST_LIST;
- list->mListp = new LLScriptLibData(rside);
- address = lsa_postadd_lists(buffer, lside, list, get_max_heap_size(buffer));
- list->mListp = NULL;
- delete list;
- lscript_push(buffer, address);
- }
- break;
- default:
- break;
- }
- }
- void list_string_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
- {
- S32 lside = lscript_pop_int(buffer);
- S32 rside = lscript_pop_int(buffer);
- S32 address;
- switch(opcode)
- {
- case LOPC_ADD:
- {
- LLScriptLibData *string = lsa_get_data(buffer, rside, TRUE);
- LLScriptLibData *list = new LLScriptLibData;
- list->mType = LST_LIST;
- list->mListp = string;
- address = lsa_postadd_lists(buffer, lside, list, get_max_heap_size(buffer));
- list->mListp = NULL;
- delete list;
- lscript_push(buffer, address);
- }
- break;
- default:
- break;
- }
- }
- void list_key_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
- {
- S32 lside = lscript_pop_int(buffer);
- S32 rside = lscript_pop_int(buffer);
- S32 address;
- switch(opcode)
- {
- case LOPC_ADD:
- {
- LLScriptLibData *key = lsa_get_data(buffer, rside, TRUE);
- // need to convert key to key, since it comes out like a string
- if (key->mType == LST_STRING)
- {
- key->mKey = key->mString;
- key->mString = NULL;
- key->mType = LST_KEY;
- }
- LLScriptLibData *list = new LLScriptLibData;
- list->mType = LST_LIST;
- list->mListp = key;
- address = lsa_postadd_lists(buffer, lside, list, get_max_heap_size(buffer));
- list->mListp = NULL;
- delete list;
- lscript_push(buffer, address);
- }
- break;
- default:
- break;
- }
- }
- void list_vector_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
- {
- S32 lside = lscript_pop_int(buffer);
- LLVector3 rside;
- lscript_pop_vector(buffer, rside);
- S32 address;
- switch(opcode)
- {
- case LOPC_ADD:
- {
- LLScriptLibData *list = new LLScriptLibData;
- list->mType = LST_LIST;
- list->mListp = new LLScriptLibData(rside);
- address = lsa_postadd_lists(buffer, lside, list, get_max_heap_size(buffer));
- list->mListp = NULL;
- delete list;
- lscript_push(buffer, address);
- }
- break;
- default:
- break;
- }
- }
- void list_quaternion_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
- {
- S32 lside = lscript_pop_int(buffer);
- LLQuaternion rside;
- lscript_pop_quaternion(buffer, rside);
- S32 address;
- switch(opcode)
- {
- case LOPC_ADD:
- {
- LLScriptLibData *list = new LLScriptLibData;
- list->mType = LST_LIST;
- list->mListp = new LLScriptLibData(rside);
- address = lsa_postadd_lists(buffer, lside, list, get_max_heap_size(buffer));
- list->mListp = NULL;
- delete list;
- lscript_push(buffer, address);
- }
- break;
- default:
- break;
- }
- }
- void list_list_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
- {
- S32 lside = lscript_pop_int(buffer);
- S32 rside = lscript_pop_int(buffer);
- S32 resulti;
- S32 address;
- switch(opcode)
- {
- case LOPC_ADD:
- address = lsa_cat_lists(buffer, lside, rside, get_max_heap_size(buffer));
- lscript_push(buffer, address);
- break;
- case LOPC_EQ:
- resulti = !lsa_cmp_lists(buffer, lside, rside);
- lscript_push(buffer, resulti);
- break;
- case LOPC_NEQ:
- resulti = lsa_cmp_lists(buffer, lside, rside);
- lscript_push(buffer, resulti);
- break;
- default:
- break;
- }
- }
- static U8 safe_op_index(U8 index)
- {
- if(index >= LST_EOF)
- {
- // Operations on LST_NULL will always be unknown_operation.
- index = LST_NULL;
- }
- return index;
- }
- BOOL run_add(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tADD ", offset);
- offset++;
- U8 arg = safe_instruction_bytestream2byte(buffer, offset);
- U8 arg1 = safe_op_index(arg >> 4);
- U8 arg2 = safe_op_index(arg & 0xf);
- if (b_print)
- {
- print_type(arg1);
- printf(", ");
- print_type(arg2);
- printf("n");
- }
- binary_operations[arg1][arg2](buffer, LOPC_ADD);
- return FALSE;
- }
- BOOL run_sub(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tSUB ", offset);
- offset++;
- U8 arg = safe_instruction_bytestream2byte(buffer, offset);
- U8 arg1 = safe_op_index(arg >> 4);
- U8 arg2 = safe_op_index(arg & 0xf);
- if (b_print)
- {
- print_type(arg1);
- printf(", ");
- print_type(arg2);
- printf("n");
- }
- binary_operations[arg1][arg2](buffer, LOPC_SUB);
- return FALSE;
- }
- BOOL run_mul(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tMUL ", offset);
- offset++;
- U8 arg = safe_instruction_bytestream2byte(buffer, offset);
- U8 arg1 = safe_op_index(arg >> 4);
- U8 arg2 = safe_op_index(arg & 0xf);
- if (b_print)
- {
- print_type(arg1);
- printf(", ");
- print_type(arg2);
- printf("n");
- }
- binary_operations[arg1][arg2](buffer, LOPC_MUL);
- return FALSE;
- }
- BOOL run_div(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tDIV ", offset);
- offset++;
- U8 arg = safe_instruction_bytestream2byte(buffer, offset);
- U8 arg1 = safe_op_index(arg >> 4);
- U8 arg2 = safe_op_index(arg & 0xf);
- if (b_print)
- {
- print_type(arg1);
- printf(", ");
- print_type(arg2);
- printf("n");
- }
- binary_operations[arg1][arg2](buffer, LOPC_DIV);
- return FALSE;
- }
- BOOL run_mod(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tMOD ", offset);
- offset++;
- U8 arg = safe_instruction_bytestream2byte(buffer, offset);
- U8 arg1 = safe_op_index(arg >> 4);
- U8 arg2 = safe_op_index(arg & 0xf);
- if (b_print)
- {
- print_type(arg1);
- printf(", ");
- print_type(arg2);
- printf("n");
- }
- binary_operations[arg1][arg2](buffer, LOPC_MOD);
- return FALSE;
- }
- BOOL run_eq(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tEQ ", offset);
- offset++;
- U8 arg = safe_instruction_bytestream2byte(buffer, offset);
- U8 arg1 = safe_op_index(arg >> 4);
- U8 arg2 = safe_op_index(arg & 0xf);
- if (b_print)
- {
- print_type(arg1);
- printf(", ");
- print_type(arg2);
- printf("n");
- }
- binary_operations[arg1][arg2](buffer, LOPC_EQ);
- return FALSE;
- }
- BOOL run_neq(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tNEQ ", offset);
- offset++;
- U8 arg = safe_instruction_bytestream2byte(buffer, offset);
- U8 arg1 = safe_op_index(arg >> 4);
- U8 arg2 = safe_op_index(arg & 0xf);
- if (b_print)
- {
- print_type(arg1);
- printf(", ");
- print_type(arg2);
- printf("n");
- }
- binary_operations[arg1][arg2](buffer, LOPC_NEQ);
- return FALSE;
- }
- BOOL run_leq(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tLEQ ", offset);
- offset++;
- U8 arg = safe_instruction_bytestream2byte(buffer, offset);
- U8 arg1 = safe_op_index(arg >> 4);
- U8 arg2 = safe_op_index(arg & 0xf);
- if (b_print)
- {
- print_type(arg1);
- printf(", ");
- print_type(arg2);
- printf("n");
- }
- binary_operations[arg1][arg2](buffer, LOPC_LEQ);
- return FALSE;
- }
- BOOL run_geq(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tGEQ ", offset);
- offset++;
- U8 arg = safe_instruction_bytestream2byte(buffer, offset);
- U8 arg1 = safe_op_index(arg >> 4);
- U8 arg2 = safe_op_index(arg & 0xf);
- if (b_print)
- {
- print_type(arg1);
- printf(", ");
- print_type(arg2);
- printf("n");
- }
- binary_operations[arg1][arg2](buffer, LOPC_GEQ);
- return FALSE;
- }
- BOOL run_less(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tLESS ", offset);
- offset++;
- U8 arg = safe_instruction_bytestream2byte(buffer, offset);
- U8 arg1 = safe_op_index(arg >> 4);
- U8 arg2 = safe_op_index(arg & 0xf);
- if (b_print)
- {
- print_type(arg1);
- printf(", ");
- print_type(arg2);
- printf("n");
- }
- binary_operations[arg1][arg2](buffer, LOPC_LESS);
- return FALSE;
- }
- BOOL run_greater(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tGREATER ", offset);
- offset++;
- U8 arg = safe_instruction_bytestream2byte(buffer, offset);
- U8 arg1 = safe_op_index(arg >> 4);
- U8 arg2 = safe_op_index(arg & 0xf);
- if (b_print)
- {
- print_type(arg1);
- printf(", ");
- print_type(arg2);
- printf("n");
- }
- binary_operations[arg1][arg2](buffer, LOPC_GREATER);
- return FALSE;
- }
- BOOL run_bitand(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tBITANDn", offset);
- offset++;
- binary_operations[LST_INTEGER][LST_INTEGER](buffer, LOPC_BITAND);
- return FALSE;
- }
- BOOL run_bitor(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tBITORn", offset);
- offset++;
- binary_operations[LST_INTEGER][LST_INTEGER](buffer, LOPC_BITOR);
- return FALSE;
- }
- BOOL run_bitxor(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tBITXORn", offset);
- offset++;
- binary_operations[LST_INTEGER][LST_INTEGER](buffer, LOPC_BITXOR);
- return FALSE;
- }
- BOOL run_booland(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tBOOLANDn", offset);
- offset++;
- binary_operations[LST_INTEGER][LST_INTEGER](buffer, LOPC_BOOLAND);
- return FALSE;
- }
- BOOL run_boolor(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tBOOLORn", offset);
- offset++;
- binary_operations[LST_INTEGER][LST_INTEGER](buffer, LOPC_BOOLOR);
- return FALSE;
- }
- BOOL run_shl(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tSHLn", offset);
- offset++;
- binary_operations[LST_INTEGER][LST_INTEGER](buffer, LOPC_SHL);
- return FALSE;
- }
- BOOL run_shr(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tSHRn", offset);
- offset++;
- binary_operations[LST_INTEGER][LST_INTEGER](buffer, LOPC_SHR);
- return FALSE;
- }
- void integer_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
- {
- S32 lside = lscript_pop_int(buffer);
- S32 result = 0;
- switch(opcode)
- {
- case LOPC_NEG:
- result = -lside;
- break;
- case LOPC_BITNOT:
- result = ~lside;
- break;
- case LOPC_BOOLNOT:
- result = !lside;
- break;
- default:
- break;
- }
- lscript_push(buffer, result);
- }
- void float_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
- {
- F32 lside = lscript_pop_float(buffer);
- F32 result = 0;
- switch(opcode)
- {
- case LOPC_NEG:
- result = -lside;
- lscript_push(buffer, result);
- break;
- default:
- break;
- }
- }
- void vector_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
- {
- LLVector3 lside;
- lscript_pop_vector(buffer, lside);
- LLVector3 result;
- switch(opcode)
- {
- case LOPC_NEG:
- result = -lside;
- lscript_push(buffer, result);
- break;
- default:
- break;
- }
- }
- void quaternion_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
- {
- LLQuaternion lside;
- lscript_pop_quaternion(buffer, lside);
- LLQuaternion result;
- switch(opcode)
- {
- case LOPC_NEG:
- result = -lside;
- lscript_push(buffer, result);
- break;
- default:
- break;
- }
- }
- BOOL run_neg(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tNEG ", offset);
- offset++;
- U8 arg = safe_op_index(safe_instruction_bytestream2byte(buffer, offset));
- if (b_print)
- {
- print_type(arg);
- printf("n");
- }
- unary_operations[arg](buffer, LOPC_NEG);
- return FALSE;
- }
- BOOL run_bitnot(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tBITNOTn", offset);
- offset++;
- unary_operations[LST_INTEGER](buffer, LOPC_BITNOT);
- return FALSE;
- }
- BOOL run_boolnot(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tBOOLNOTn", offset);
- offset++;
- unary_operations[LST_INTEGER](buffer, LOPC_BOOLNOT);
- return FALSE;
- }
- BOOL run_jump(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tJUMP ", offset);
- offset++;
- S32 arg = safe_instruction_bytestream2integer(buffer, offset);
- if (b_print)
- printf("%dn", arg);
- offset += arg;
- return FALSE;
- }
- BOOL run_jumpif(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tJUMPIF ", offset);
- offset++;
- U8 type = safe_instruction_bytestream2byte(buffer, offset);
- if (b_print)
- {
- print_type(type);
- printf(", ");
- }
- S32 arg = safe_instruction_bytestream2integer(buffer, offset);
- if (b_print)
- printf("%dn", arg);
- if (type == LST_INTEGER)
- {
- S32 test = lscript_pop_int(buffer);
- if (test)
- {
- offset += arg;
- }
- }
- else if (type == LST_FLOATINGPOINT)
- {
- F32 test = lscript_pop_float(buffer);
- if (test)
- {
- offset += arg;
- }
- }
- else if (type == LST_VECTOR)
- {
- LLVector3 test;
- lscript_pop_vector(buffer, test);
- if (!test.isExactlyZero())
- {
- offset += arg;
- }
- }
- else if (type == LST_QUATERNION)
- {
- LLQuaternion test;
- lscript_pop_quaternion(buffer, test);
- if (!test.isIdentity())
- {
- offset += arg;
- }
- }
- else if (type == LST_STRING)
- {
- S32 base_address = lscript_pop_int(buffer);
- // this bit of nastiness is to get around that code paths to
- // local variables can result in lack of initialization and
- // function clean up of ref counts isn't based on scope (a
- // mistake, I know)
- S32 address = base_address + get_register(buffer, LREG_HR) - 1;
- if (address)
- {
- S32 string = address;
- string += SIZEOF_SCRIPT_ALLOC_ENTRY;
- if (safe_heap_check_address(buffer, string, 1))
- {
- S32 toffset = string;
- safe_heap_bytestream_count_char(buffer, toffset);
- S32 size = toffset - string;
- char *sdata = new char[size];
- bytestream2char(sdata, buffer, string, size);
- if (strlen(sdata)) /*Flawfinder: ignore*/
- {
- offset += arg;
- }
- delete [] sdata;
- }
- lsa_decrease_ref_count(buffer, base_address);
- }
- }
- else if (type == LST_KEY)
- {
- S32 base_address = lscript_pop_int(buffer);
- // this bit of nastiness is to get around that code paths to
- // local variables can result in lack of initialization and
- // function clean up of ref counts isn't based on scope (a
- // mistake, I know)
- S32 address = base_address + get_register(buffer, LREG_HR) - 1;
- if (address)
- {
- S32 string = address;
- string += SIZEOF_SCRIPT_ALLOC_ENTRY;
- if (safe_heap_check_address(buffer, string, 1))
- {
- S32 toffset = string;
- safe_heap_bytestream_count_char(buffer, toffset);
- S32 size = toffset - string;
- char *sdata = new char[size];
- bytestream2char(sdata, buffer, string, size);
- if (strlen(sdata)) /*Flawfinder: ignore*/
- {
- LLUUID id;
- if (id.set(sdata) && id.notNull())
- offset += arg;
- }
- delete [] sdata;
- }
- lsa_decrease_ref_count(buffer, base_address);
- }
- }
- else if (type == LST_LIST)
- {
- S32 base_address = lscript_pop_int(buffer);
- S32 address = base_address + get_register(buffer, LREG_HR) - 1;
- if (address)
- {
- if (safe_heap_check_address(buffer, address + SIZEOF_SCRIPT_ALLOC_ENTRY, 1))
- {
- LLScriptLibData *list = lsa_get_list_ptr(buffer, base_address, TRUE);
- if (list && list->getListLength())
- {
- offset += arg;
- }
- delete list;
- }
- }
- }
- return FALSE;
- }
- BOOL run_jumpnif(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tJUMPNIF ", offset);
- offset++;
- U8 type = safe_instruction_bytestream2byte(buffer, offset);
- if (b_print)
- {
- print_type(type);
- printf(", ");
- }
- S32 arg = safe_instruction_bytestream2integer(buffer, offset);
- if (b_print)
- printf("%dn", arg);
- if (type == LST_INTEGER)
- {
- S32 test = lscript_pop_int(buffer);
- if (!test)
- {
- offset += arg;
- }
- }
- else if (type == LST_FLOATINGPOINT)
- {
- F32 test = lscript_pop_float(buffer);
- if (!test)
- {
- offset += arg;
- }
- }
- else if (type == LST_VECTOR)
- {
- LLVector3 test;
- lscript_pop_vector(buffer, test);
- if (test.isExactlyZero())
- {
- offset += arg;
- }
- }
- else if (type == LST_QUATERNION)
- {
- LLQuaternion test;
- lscript_pop_quaternion(buffer, test);
- if (test.isIdentity())
- {
- offset += arg;
- }
- }
- else if (type == LST_STRING)
- {
- S32 base_address = lscript_pop_int(buffer);
- // this bit of nastiness is to get around that code paths to
- // local variables can result in lack of initialization and
- // function clean up of ref counts isn't based on scope (a
- // mistake, I know)
- S32 address = base_address + get_register(buffer, LREG_HR) - 1;
- if (address)
- {
- S32 string = address;
- string += SIZEOF_SCRIPT_ALLOC_ENTRY;
- if (safe_heap_check_address(buffer, string, 1))
- {
- S32 toffset = string;
- safe_heap_bytestream_count_char(buffer, toffset);
- S32 size = toffset - string;
- char *sdata = new char[size];
- bytestream2char(sdata, buffer, string, size);
- if (!strlen(sdata)) /*Flawfinder: ignore*/
- {
- offset += arg;
- }
- delete [] sdata;
- }
- lsa_decrease_ref_count(buffer, base_address);
- }
- }
- else if (type == LST_KEY)
- {
- S32 base_address = lscript_pop_int(buffer);
- // this bit of nastiness is to get around that code paths to
- // local variables can result in lack of initialization and
- // function clean up of ref counts isn't based on scope (a
- // mistake, I know)
- S32 address = base_address + get_register(buffer, LREG_HR) - 1;
- if (address)
- {
- S32 string = address;
- string += SIZEOF_SCRIPT_ALLOC_ENTRY;
- if (safe_heap_check_address(buffer, string, 1))
- {
- S32 toffset = string;
- safe_heap_bytestream_count_char(buffer, toffset);
- S32 size = toffset - string;
- char *sdata = new char[size];
- bytestream2char(sdata, buffer, string, size);
- if (strlen(sdata)) /*Flawfinder: ignore*/
- {
- LLUUID id;
- if (!id.set(sdata) || id.isNull())
- offset += arg;
- }
- else
- {
- offset += arg;
- }
- delete [] sdata;
- }
- lsa_decrease_ref_count(buffer, base_address);
- }
- }
- else if (type == LST_LIST)
- {
- S32 base_address = lscript_pop_int(buffer);
- // this bit of nastiness is to get around that code paths to
- // local variables can result in lack of initialization and
- // function clean up of ref counts isn't based on scope (a
- // mistake, I know)
- S32 address = base_address + get_register(buffer, LREG_HR) - 1;
- if (address)
- {
- if (safe_heap_check_address(buffer, address + SIZEOF_SCRIPT_ALLOC_ENTRY, 1))
- {
- LLScriptLibData *list = lsa_get_list_ptr(buffer, base_address, TRUE);
- if (!list || !list->getListLength())
- {
- offset += arg;
- }
- delete list;
- }
- }
- }
- return FALSE;
- }
- BOOL run_state(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tSTATE ", offset);
- offset++;
- S32 state = safe_instruction_bytestream2integer(buffer, offset);
- if (b_print)
- printf("%dn", state);
- S32 bp = lscript_pop_int(buffer);
- set_bp(buffer, bp);
- offset = lscript_pop_int(buffer);
- S32 major_version = 0;
- S32 value = get_register(buffer, LREG_VN);
- if (value == LSL2_VERSION1_END_NUMBER)
- {
- major_version = 1;
- }
- else if (value == LSL2_VERSION_NUMBER)
- {
- major_version = 2;
- }
-
- S32 current_state = get_register(buffer, LREG_CS);
- if (state != current_state)
- {
- U64 ce = get_event_register(buffer, LREG_CE, major_version);
- ce |= LSCRIPTStateBitField[LSTT_STATE_EXIT];
- set_event_register(buffer, LREG_CE, ce, major_version);
- }
- set_register(buffer, LREG_NS, state);
- return FALSE;
- }
- BOOL run_call(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tCALL ", offset);
- offset++;
- S32 func = safe_instruction_bytestream2integer(buffer, offset);
- if (b_print)
- printf("%dn", func);
- lscript_local_store(buffer, -8, offset);
- S32 minimum = get_register(buffer, LREG_GFR);
- S32 maximum = get_register(buffer, LREG_SR);
- S32 lookup = minimum + func*4 + 4;
- S32 function;
- if ( (lookup >= minimum)
- &&(lookup < maximum))
- {
- function = bytestream2integer(buffer, lookup) + minimum;
- if ( (lookup >= minimum)
- &&(lookup < maximum))
- {
- offset = function;
- offset += bytestream2integer(buffer, function);
- }
- else
- {
- set_fault(buffer, LSRF_BOUND_CHECK_ERROR);
- }
- }
- else
- {
- set_fault(buffer, LSRF_BOUND_CHECK_ERROR);
- }
- return FALSE;
- }
- BOOL run_return(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tRETURNn", offset);
- offset++;
-
- // SEC-53: babbage: broken instructions may allow inbalanced pushes and
- // pops which can cause caller BP and return IP to be corrupted, so restore
- // SP from BP before popping caller BP and IP.
- S32 bp = get_register(buffer, LREG_BP);
- set_sp(buffer, bp);
-
- bp = lscript_pop_int(buffer);
- set_bp(buffer, bp);
- offset = lscript_pop_int(buffer);
- return FALSE;
- }
- BOOL run_cast(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- char caststr[1024]; /*Flawfinder: ignore*/
- if (b_print)
- printf("[0x%X]tCAST ", offset);
- offset++;
- U8 arg = safe_instruction_bytestream2byte(buffer, offset);
- U8 from = arg >> 4;
- U8 to = arg & 0xf;
- if (b_print)
- {
- print_type(from);
- printf(", ");
- print_type(to);
- printf("n");
- }
- switch(from)
- {
- case LST_INTEGER:
- {
- switch(to)
- {
- case LST_INTEGER:
- break;
- case LST_FLOATINGPOINT:
- {
- S32 source = lscript_pop_int(buffer);
- F32 dest = (F32)source;
- lscript_push(buffer, dest);
- }
- break;
- case LST_STRING:
- {
- S32 address, source = lscript_pop_int(buffer);
- snprintf(caststr, sizeof(caststr), "%d", source); /* Flawfinder: ignore */
- address = lsa_heap_add_data(buffer, new LLScriptLibData(caststr), get_max_heap_size(buffer), TRUE);
- lscript_push(buffer, address);
- }
- break;
- case LST_LIST:
- {
- S32 address, source = lscript_pop_int(buffer);
- LLScriptLibData *list = new LLScriptLibData;
- list->mType = LST_LIST;
- list->mListp = new LLScriptLibData(source);
- address = lsa_heap_add_data(buffer, list, get_max_heap_size(buffer), TRUE);
- lscript_push(buffer, address);
- }
- break;
- default:
- break;
- }
- }
- break;
- case LST_FLOATINGPOINT:
- {
- switch(to)
- {
- case LST_INTEGER:
- {
- F32 source = lscript_pop_float(buffer);
- S32 dest = (S32)source;
- lscript_push(buffer, dest);
- }
- break;
- case LST_FLOATINGPOINT:
- break;
- case LST_STRING:
- {
- S32 address;
- F32 source = lscript_pop_float(buffer);
- snprintf(caststr, sizeof(caststr), "%f", source); /* Flawfinder: ignore */
- address = lsa_heap_add_data(buffer, new LLScriptLibData(caststr), get_max_heap_size(buffer), TRUE);
- lscript_push(buffer, address);
- }
- break;
- case LST_LIST:
- {
- S32 address;
- F32 source = lscript_pop_float(buffer);
- LLScriptLibData *list = new LLScriptLibData;
- list->mType = LST_LIST;
- list->mListp = new LLScriptLibData(source);
- address = lsa_heap_add_data(buffer, list, get_max_heap_size(buffer), TRUE);
- lscript_push(buffer, address);
- }
- break;
- default:
- break;
- }
- }
- break;
- case LST_STRING:
- {
- switch(to)
- {
- case LST_INTEGER:
- {
- S32 base_address = lscript_pop_int(buffer);
- // this bit of nastiness is to get around that code paths to local variables can result in lack of initialization
- // and function clean up of ref counts isn't based on scope (a mistake, I know)
- S32 address = base_address + get_register(buffer, LREG_HR) - 1;
- if (address)
- {
- S32 string = address;
- string += SIZEOF_SCRIPT_ALLOC_ENTRY;
- if (safe_heap_check_address(buffer, string, 1))
- {
- S32 toffset = string;
- safe_heap_bytestream_count_char(buffer, toffset);
- S32 size = toffset - string;
- char *arg = new char[size];
- bytestream2char(arg, buffer, string, size);
- // S32 length = strlen(arg);
- S32 dest;
- S32 base;
- // Check to see if this is a hexidecimal number.
- if ( (arg[0] == '0') &&
- (arg[1] == 'x' || arg[1] == 'X') )
- {
- // Let strtoul do a hex conversion.
- base = 16;
- }
- else
- {
- // Force base-10, so octal is never used.
- base = 10;
- }
- dest = strtoul(arg, NULL, base);
- lscript_push(buffer, dest);
- delete [] arg;
- }
- lsa_decrease_ref_count(buffer, base_address);
- }
- }
- break;
- case LST_FLOATINGPOINT:
- {
- S32 base_address = lscript_pop_int(buffer);
- // this bit of nastiness is to get around that code paths to local variables can result in lack of initialization
- // and function clean up of ref counts isn't based on scope (a mistake, I know)
- S32 address = base_address + get_register(buffer, LREG_HR) - 1;
- if (address)
- {
- S32 string = address;
- string += SIZEOF_SCRIPT_ALLOC_ENTRY;
- if (safe_heap_check_address(buffer, string, 1))
- {
- S32 toffset = string;
- safe_heap_bytestream_count_char(buffer, toffset);
- S32 size = toffset - string;
- char *arg = new char[size];
- bytestream2char(arg, buffer, string, size);
- F32 dest = (F32)atof(arg);
- lscript_push(buffer, dest);
- delete [] arg;
- }
- lsa_decrease_ref_count(buffer, base_address);
- }
- }
- break;
- case LST_STRING:
- break;
- case LST_LIST:
- {
- S32 saddress = lscript_pop_int(buffer);
- LLScriptLibData *string = lsa_get_data(buffer, saddress, TRUE);
- LLScriptLibData *list = new LLScriptLibData;
- list->mType = LST_LIST;
- list->mListp = string;
- S32 address = lsa_heap_add_data(buffer, list, get_max_heap_size(buffer), TRUE);
- lscript_push(buffer, address);
- }
- break;
- case LST_VECTOR:
- {
- S32 base_address = lscript_pop_int(buffer);
- // this bit of nastiness is to get around that code paths to local variables can result in lack of initialization
- // and function clean up of ref counts isn't based on scope (a mistake, I know)
- S32 address = base_address + get_register(buffer, LREG_HR) - 1;
- if (address)
- {
- S32 string = address;
- string += SIZEOF_SCRIPT_ALLOC_ENTRY;
- if (safe_heap_check_address(buffer, string, 1))
- {
- S32 toffset = string;
- safe_heap_bytestream_count_char(buffer, toffset);
- S32 size = toffset - string;
- char *arg = new char[size];
- bytestream2char(arg, buffer, string, size);
- LLVector3 vec;
- S32 num = sscanf(arg, "<%f, %f, %f>", &vec.mV[VX], &vec.mV[VY], &vec.mV[VZ]);
- if (num != 3)
- {
- vec = LLVector3::zero;
- }
- lscript_push(buffer, vec);
- delete [] arg;
- }
- lsa_decrease_ref_count(buffer, base_address);
- }
- }
- break;
- case LST_QUATERNION:
- {
- S32 base_address = lscript_pop_int(buffer);
- // this bit of nastiness is to get around that code paths to local variables can result in lack of initialization
- // and function clean up of ref counts isn't based on scope (a mistake, I know)
- S32 address = base_address + get_register(buffer, LREG_HR) - 1;
- if (address)
- {
- S32 string = address;
- string += SIZEOF_SCRIPT_ALLOC_ENTRY;
- if (safe_heap_check_address(buffer, string, 1))
- {
- S32 toffset = string;
- safe_heap_bytestream_count_char(buffer, toffset);
- S32 size = toffset - string;
- char *arg = new char[size];
- bytestream2char(arg, buffer, string, size);
- LLQuaternion quat;
- S32 num = sscanf(arg, "<%f, %f, %f, %f>", &quat.mQ[VX], &quat.mQ[VY], &quat.mQ[VZ], &quat.mQ[VW]);
- if (num != 4)
- {
- quat = LLQuaternion::DEFAULT;
- }
- lscript_push(buffer, quat);
- delete [] arg;
- }
- lsa_decrease_ref_count(buffer, base_address);
- }
- }
- break;
- default:
- break;
- }
- }
- break;
- case LST_KEY:
- {
- switch(to)
- {
- case LST_KEY:
- break;
- case LST_STRING:
- break;
- case LST_LIST:
- {
- S32 saddress = lscript_pop_int(buffer);
- LLScriptLibData *string = lsa_get_data(buffer, saddress, TRUE);
- LLScriptLibData *list = new LLScriptLibData;
- list->mType = LST_LIST;
- list->mListp = string;
- S32 address = lsa_heap_add_data(buffer, list, get_max_heap_size(buffer), TRUE);
- lscript_push(buffer, address);
- }
- break;
- default:
- break;
- }
- }
- break;
- case LST_VECTOR:
- {
- switch(to)
- {
- case LST_VECTOR:
- break;
- case LST_STRING:
- {
- S32 address;
- LLVector3 source;
- lscript_pop_vector(buffer, source);
- snprintf(caststr, sizeof(caststr), "<%5.5f, %5.5f, %5.5f>", source.mV[VX], source.mV[VY], source.mV[VZ]); /* Flawfinder: ignore */
- address = lsa_heap_add_data(buffer, new LLScriptLibData(caststr), get_max_heap_size(buffer), TRUE);
- lscript_push(buffer, address);
- }
- break;
- case LST_LIST:
- {
- S32 address;
- LLVector3 source;
- lscript_pop_vector(buffer, source);
- LLScriptLibData *list = new LLScriptLibData;
- list->mType = LST_LIST;
- list->mListp = new LLScriptLibData(source);
- address = lsa_heap_add_data(buffer, list, get_max_heap_size(buffer), TRUE);
- lscript_push(buffer, address);
- }
- break;
- default:
- break;
- }
- }
- break;
- case LST_QUATERNION:
- {
- switch(to)
- {
- case LST_QUATERNION:
- break;
- case LST_STRING:
- {
- S32 address;
- LLQuaternion source;
- lscript_pop_quaternion(buffer, source);
- snprintf(caststr, sizeof(caststr), "<%5.5f, %5.5f, %5.5f, %5.5f>", source.mQ[VX], source.mQ[VY], source.mQ[VZ], source.mQ[VS]); /* Flawfinder: ignore */
- address = lsa_heap_add_data(buffer, new LLScriptLibData(caststr), get_max_heap_size(buffer), TRUE);
- lscript_push(buffer, address);
- }
- break;
- case LST_LIST:
- {
- S32 address;
- LLQuaternion source;
- lscript_pop_quaternion(buffer, source);
- LLScriptLibData *list = new LLScriptLibData;
- list->mType = LST_LIST;
- list->mListp = new LLScriptLibData(source);
- address = lsa_heap_add_data(buffer, list, get_max_heap_size(buffer), TRUE);
- lscript_push(buffer, address);
- }
- break;
- default:
- break;
- }
- }
- break;
- case LST_LIST:
- {
- switch(to)
- {
- case LST_LIST:
- break;
- case LST_STRING:
- {
- S32 address = lscript_pop_int(buffer);
- LLScriptLibData *list = lsa_get_data(buffer, address, TRUE);
- LLScriptLibData *list_root = list;
- std::ostringstream dest;
- while (list)
- {
- list->print(dest, FALSE);
- list = list->mListp;
- }
- delete list_root;
- char *tmp = strdup(dest.str().c_str());
- LLScriptLibData *string = new LLScriptLibData(tmp);
- free(tmp);
- tmp = NULL;
- S32 destaddress = lsa_heap_add_data(buffer, string, get_max_heap_size(buffer), TRUE);
- lscript_push(buffer, destaddress);
- }
- break;
- default:
- break;
- }
- }
- break;
- default:
- break;
- }
- return FALSE;
- }
- BOOL run_stacktos(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- offset++;
- S32 length = lscript_pop_int(buffer);
- S32 i;
- char *arg = new char[length];
- S32 fault;
- for (i = 0; i < length; i++)
- {
- fault = get_register(buffer, LREG_FR);
- if (fault)
- break;
- arg[length - i - 1] = lscript_pop_char(buffer);
- }
- S32 address = lsa_heap_add_data(buffer, new LLScriptLibData(arg), get_max_heap_size(buffer), TRUE);
- lscript_push(buffer, address);
- delete [] arg;
- return FALSE;
- }
- void lscript_stacktol_pop_variable(LLScriptLibData *data, U8 *buffer, char type)
- {
- S32 address, string;
- S32 base_address;
- switch(type)
- {
- case LST_INTEGER:
- data->mType = LST_INTEGER;
- data->mInteger = lscript_pop_int(buffer);
- break;
- case LST_FLOATINGPOINT:
- data->mType = LST_FLOATINGPOINT;
- data->mFP = lscript_pop_float(buffer);
- break;
- case LST_KEY:
- data->mType = LST_KEY;
- base_address = lscript_pop_int(buffer);
- // this bit of nastiness is to get around that code paths to local variables can result in lack of initialization
- // and function clean up of ref counts isn't based on scope (a mistake, I know)
- address = base_address + get_register(buffer, LREG_HR) - 1;
- if (address)
- {
- string = address + SIZEOF_SCRIPT_ALLOC_ENTRY;
- if (safe_heap_check_address(buffer, string, 1))
- {
- S32 toffset = string;
- safe_heap_bytestream_count_char(buffer, toffset);
- S32 size = toffset - string;
- data->mKey = new char[size];
- bytestream2char(data->mKey, buffer, string, size);
- }
- lsa_decrease_ref_count(buffer, base_address);
- }
- else
- {
- data->mKey = new char[1];
- data->mKey[0] = 0;
- }
- break;
- case LST_STRING:
- data->mType = LST_STRING;
- base_address = lscript_pop_int(buffer);
- // this bit of nastiness is to get around that code paths to local variables can result in lack of initialization
- // and function clean up of ref counts isn't based on scope (a mistake, I know)
- address = base_address + get_register(buffer, LREG_HR) - 1;
- if (address)
- {
- string = address + SIZEOF_SCRIPT_ALLOC_ENTRY;
- if (safe_heap_check_address(buffer, string, 1))
- {
- S32 toffset = string;
- safe_heap_bytestream_count_char(buffer, toffset);
- S32 size = toffset - string;
- data->mString = new char[size];
- bytestream2char(data->mString, buffer, string, size);
- }
- lsa_decrease_ref_count(buffer, base_address);
- }
- else
- {
- data->mString = new char[1];
- data->mString[0] = 0;
- }
- break;
- case LST_VECTOR:
- data->mType = LST_VECTOR;
- lscript_pop_vector(buffer, data->mVec);
- break;
- case LST_QUATERNION:
- data->mType = LST_QUATERNION;
- lscript_pop_quaternion(buffer, data->mQuat);
- break;
- case LST_LIST:
- data->mType = LST_LIST;
- address = lscript_pop_int(buffer);
- data->mListp = lsa_get_data(buffer, address, TRUE);
- break;
- }
- }
- BOOL run_stacktol(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- offset++;
- S32 length = safe_instruction_bytestream2integer(buffer, offset);
- S32 i;
- S32 fault;
- S8 type;
- LLScriptLibData *data = new LLScriptLibData, *tail;
- data->mType = LST_LIST;
- for (i = 0; i < length; i++)
- {
- fault = get_register(buffer, LREG_FR);
- if (fault)
- break;
- type = lscript_pop_char(buffer);
- tail = new LLScriptLibData;
- lscript_stacktol_pop_variable(tail, buffer, type);
- tail->mListp = data->mListp;
- data->mListp = tail;
- }
- S32 address = lsa_heap_add_data(buffer,data, get_max_heap_size(buffer), TRUE);
- lscript_push(buffer, address);
- return FALSE;
- }
- BOOL run_print(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- if (b_print)
- printf("[0x%X]tPRINT ", offset);
- offset++;
- U8 type = safe_instruction_bytestream2byte(buffer, offset);
- if (b_print)
- {
- print_type(type);
- printf("n");
- }
- switch(type)
- {
- case LST_INTEGER:
- {
- S32 source = lscript_pop_int(buffer);
- printf("%dn", source);
- }
- break;
- case LST_FLOATINGPOINT:
- {
- F32 source = lscript_pop_float(buffer);
- printf("%fn", source);
- }
- break;
- case LST_STRING:
- {
- S32 base_address = lscript_pop_int(buffer);
- // this bit of nastiness is to get around that code paths to local variables can result in lack of initialization
- // and function clean up of ref counts isn't based on scope (a mistake, I know)
- S32 address = base_address + get_register(buffer, LREG_HR) - 1;
- if (address)
- {
- S32 string = address;
- string += SIZEOF_SCRIPT_ALLOC_ENTRY;
- if (safe_heap_check_address(buffer, string, 1))
- {
- S32 toffset = string;
- safe_heap_bytestream_count_char(buffer, toffset);
- S32 size = toffset - string;
- char *arg = new char[size];
- bytestream2char(arg, buffer, string, size);
- printf("%sn", arg);
- delete [] arg;
- }
- lsa_decrease_ref_count(buffer, base_address);
- }
- }
- break;
- case LST_VECTOR:
- {
- LLVector3 source;
- lscript_pop_vector(buffer, source);
- printf("< %f, %f, %f >n", source.mV[VX], source.mV[VY], source.mV[VZ]);
- }
- break;
- case LST_QUATERNION:
- {
- LLQuaternion source;
- lscript_pop_quaternion(buffer, source);
- printf("< %f, %f, %f, %f >n", source.mQ[VX], source.mQ[VY], source.mQ[VZ], source.mQ[VS]);
- }
- break;
- case LST_LIST:
- {
- S32 base_address = lscript_pop_int(buffer);
- LLScriptLibData *data = lsa_get_data(buffer, base_address, TRUE);
- LLScriptLibData *print = data;
- printf("listn");
- while (print)
- {
- switch(print->mType)
- {
- case LST_INTEGER:
- {
- printf("%dn", print->mInteger);
- }
- break;
- case LST_FLOATINGPOINT:
- {
- printf("%fn", print->mFP);
- }
- break;
- case LST_STRING:
- {
- printf("%sn", print->mString);
- }
- break;
- case LST_KEY:
- {
- printf("%sn", print->mKey);
- }
- break;
- case LST_VECTOR:
- {
- printf("< %f, %f, %f >n", print->mVec.mV[VX], print->mVec.mV[VY], print->mVec.mV[VZ]);
- }
- break;
- case LST_QUATERNION:
- {
- printf("< %f, %f, %f, %f >n", print->mQuat.mQ[VX], print->mQuat.mQ[VY], print->mQuat.mQ[VZ], print->mQuat.mQ[VS]);
- }
- break;
- default:
- break;
- }
- print = print->mListp;
- }
- delete data;
- }
- break;
- default:
- break;
- }
- return FALSE;
- }
- void lscript_run(const std::string& filename, BOOL b_debug)
- {
- LLTimer timer;
- const char *error;
- LLScriptExecuteLSL2 *execute = NULL;
- if (filename.empty())
- {
- llerrs << "filename is NULL" << llendl;
- // Just reporting error is likely not enough. Need
- // to check how to abort or error out gracefully
- // from this function. XXXTBD
- }
- LLFILE* file = LLFile::fopen(filename, "r"); /* Flawfinder: ignore */
- if(file)
- {
- execute = new LLScriptExecuteLSL2(file);
- fclose(file);
- }
- if (execute)
- {
- timer.reset();
- F32 time_slice = 3600.0f; // 1 hr.
- U32 events_processed = 0;
- do {
- LLTimer timer2;
- execute->runQuanta(b_debug, LLUUID::null, &error,
- time_slice, events_processed, timer2);
- } while (!execute->isFinished());
- F32 time = timer.getElapsedTimeF32();
- F32 ips = execute->mInstructionCount / time;
- llinfos << execute->mInstructionCount << " instructions in " << time << " seconds" << llendl;
- llinfos << ips/1000 << "K instructions per second" << llendl;
- printf("ip: 0x%Xn", get_register(execute->mBuffer, LREG_IP));
- printf("sp: 0x%Xn", get_register(execute->mBuffer, LREG_SP));
- printf("bp: 0x%Xn", get_register(execute->mBuffer, LREG_BP));
- printf("hr: 0x%Xn", get_register(execute->mBuffer, LREG_HR));
- printf("hp: 0x%Xn", get_register(execute->mBuffer, LREG_HP));
- delete execute;
- fclose(file);
- }
- }
- void lscript_pop_variable(LLScriptLibData *data, U8 *buffer, char type)
- {
- S32 address, string;
- S32 base_address;
- switch(type)
- {
- case 'i':
- data->mType = LST_INTEGER;
- data->mInteger = lscript_pop_int(buffer);
- break;
- case 'f':
- data->mType = LST_FLOATINGPOINT;
- data->mFP = lscript_pop_float(buffer);
- break;
- case 'k':
- data->mType = LST_KEY;
- data->mKey = NULL;
-
- base_address = lscript_pop_int(buffer);
- // this bit of nastiness is to get around that code paths to local variables can result in lack of initialization
- // and function clean up of ref counts isn't based on scope (a mistake, I know)
- address = base_address + get_register(buffer, LREG_HR) - 1;
- if (address)
- {
- string = address + SIZEOF_SCRIPT_ALLOC_ENTRY;
- if (safe_heap_check_address(buffer, string, 1))
- {
- S32 toffset = string;
- safe_heap_bytestream_count_char(buffer, toffset);
- S32 size = toffset - string;
- data->mKey = new char[size];
- bytestream2char(data->mKey, buffer, string, size);
- }
- lsa_decrease_ref_count(buffer, base_address);
- }
- if (data->mKey == NULL)
- {
- data->mKey = new char[1];
- data->mKey[0] = 0;
- }
- break;
- case 's':
- data->mType = LST_STRING;
- data->mString = NULL;
- base_address = lscript_pop_int(buffer);
- // this bit of nastiness is to get around that code paths to local variables can result in lack of initialization
- // and function clean up of ref counts isn't based on scope (a mistake, I know)
- address = base_address + get_register(buffer, LREG_HR) - 1;
- if (address)
- {
- string = address + SIZEOF_SCRIPT_ALLOC_ENTRY;
- if (safe_heap_check_address(buffer, string, 1))
- {
- S32 toffset = string;
- safe_heap_bytestream_count_char(buffer, toffset);
- S32 size = toffset - string;
- data->mString = new char[size];
- bytestream2char(data->mString, buffer, string, size);
- }
- lsa_decrease_ref_count(buffer, base_address);
- }
- if (data->mString == NULL)
- {
- data->mString = new char[1];
- data->mString[0] = 0;
- }
- break;
- case 'l':
- {
- S32 base_address = lscript_pop_int(buffer);
- data->mType = LST_LIST;
- data->mListp = lsa_get_list_ptr(buffer, base_address, TRUE);
- }
- break;
- case 'v':
- data->mType = LST_VECTOR;
- lscript_pop_vector(buffer, data->mVec);
- break;
- case 'q':
- data->mType = LST_QUATERNION;
- lscript_pop_quaternion(buffer, data->mQuat);
- break;
- }
- }
- void lscript_push_return_variable(LLScriptLibData *data, U8 *buffer)
- {
- S32 address;
- switch(data->mType)
- {
- case LST_INTEGER:
- lscript_local_store(buffer, -12, data->mInteger);
- break;
- case LST_FLOATINGPOINT:
- lscript_local_store(buffer, -12, data->mFP);
- break;
- case LST_KEY:
- address = lsa_heap_add_data(buffer, data, get_max_heap_size(buffer), FALSE);
- lscript_local_store(buffer, -12, address);
- break;
- case LST_STRING:
- address = lsa_heap_add_data(buffer, data, get_max_heap_size(buffer), FALSE);
- lscript_local_store(buffer, -12, address);
- break;
- case LST_LIST:
- address = lsa_heap_add_data(buffer, data, get_max_heap_size(buffer), FALSE);
- lscript_local_store(buffer, -12, address);
- break;
- case LST_VECTOR:
- lscript_local_store(buffer, -20, data->mVec);
- break;
- case LST_QUATERNION:
- lscript_local_store(buffer, -24, data->mQuat);
- break;
- default:
- break;
- }
- }
- S32 lscript_push_variable(LLScriptLibData *data, U8 *buffer)
- {
- S32 address;
- switch(data->mType)
- {
- case LST_INTEGER:
- lscript_push(buffer, data->mInteger);
- break;
- case LST_FLOATINGPOINT:
- lscript_push(buffer, data->mFP);
- return 4;
- break;
- case LST_KEY:
- address = lsa_heap_add_data(buffer, data, get_max_heap_size(buffer), FALSE);
- lscript_push(buffer, address);
- return 4;
- break;
- case LST_STRING:
- address = lsa_heap_add_data(buffer, data, get_max_heap_size(buffer), FALSE);
- lscript_push(buffer, address);
- return 4;
- break;
- case LST_LIST:
- address = lsa_heap_add_data(buffer, data, get_max_heap_size(buffer), FALSE);
- lscript_push(buffer, address);
- return 4;
- break;
- case LST_VECTOR:
- lscript_push(buffer, data->mVec);
- return 12;
- break;
- case LST_QUATERNION:
- lscript_push(buffer, data->mQuat);
- return 16;
- break;
- default:
- break;
- }
- return 4;
- }
- // Shared code for run_calllib() and run_calllib_two_byte()
- BOOL run_calllib_common(U8 *buffer, S32 &offset, const LLUUID &id, U16 arg)
- {
- if (arg >= gScriptLibrary.mFunctions.size())
- {
- set_fault(buffer, LSRF_BOUND_CHECK_ERROR);
- return FALSE;
- }
- LLScriptLibraryFunction const & function = gScriptLibrary.mFunctions[arg];
- // pull out the arguments and the return values
- LLScriptLibData *arguments = NULL;
- LLScriptLibData *returnvalue = NULL;
- S32 i, number;
- if (function.mReturnType)
- {
- returnvalue = new LLScriptLibData;
- }
- if (function.mArgs)
- {
- number = (S32)strlen(function.mArgs); //Flawfinder: ignore
- arguments = new LLScriptLibData[number];
- }
- else
- {
- number = 0;
- }
- for (i = number - 1; i >= 0; i--)
- {
- lscript_pop_variable(&arguments[i], buffer, function.mArgs[i]);
- }
- // Actually execute the function call
- function.mExecFunc(returnvalue, arguments, id);
- add_register_fp(buffer, LREG_ESR, -(function.mEnergyUse));
- add_register_fp(buffer, LREG_SLR, function.mSleepTime);
- if (returnvalue)
- {
- returnvalue->mType = char2type(*function.mReturnType);
- lscript_push_return_variable(returnvalue, buffer);
- }
- delete [] arguments;
- delete returnvalue;
- // reset the BP after calling the library files
- S32 bp = lscript_pop_int(buffer);
- set_bp(buffer, bp);
- // pop off the spot for the instruction pointer
- lscript_poparg(buffer, 4);
- return FALSE;
- }
- BOOL run_calllib(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- offset++;
- U16 arg = (U16) safe_instruction_bytestream2byte(buffer, offset);
- if (b_print &&
- arg < gScriptLibrary.mFunctions.size())
- {
- printf("[0x%X]tCALLLIB ", offset);
- LLScriptLibraryFunction const & function = gScriptLibrary.mFunctions[arg];
- printf("%d (%s)n", (U32)arg, function.mName);
- //printf("%sn", function.mDesc);
- }
- return run_calllib_common(buffer, offset, id, arg);
- }
- BOOL run_calllib_two_byte(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
- {
- offset++;
- U16 arg = safe_instruction_bytestream2u16(buffer, offset);
- if (b_print &&
- arg < gScriptLibrary.mFunctions.size())
- {
- printf("[0x%X]tCALLLIB ", (offset-1));
- LLScriptLibraryFunction const & function = gScriptLibrary.mFunctions[arg];
- printf("%d (%s)n", (U32)arg, function.mName);
- //printf("%sn", function.mDesc);
- }
- return run_calllib_common(buffer, offset, id, arg);
- }