PageRenderTime 144ms CodeModel.GetById 12ms app.highlight 121ms RepoModel.GetById 1ms app.codeStats 1ms

/indra/lscript/lscript_execute/lscript_execute.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 2573 lines | 2132 code | 271 blank | 170 comment | 218 complexity | 4cc2cbaf9c9efb150b48760b7912722d MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1/**
   2 * @file lscript_execute.cpp
   3 * @brief classes to execute bytecode
   4 *
   5 * $LicenseInfo:firstyear=2002&license=viewerlgpl$
   6 * Second Life Viewer Source Code
   7 * Copyright (C) 2010, Linden Research, Inc.
   8 * 
   9 * This library is free software; you can redistribute it and/or
  10 * modify it under the terms of the GNU Lesser General Public
  11 * License as published by the Free Software Foundation;
  12 * version 2.1 of the License only.
  13 * 
  14 * This library is distributed in the hope that it will be useful,
  15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  17 * Lesser General Public License for more details.
  18 * 
  19 * You should have received a copy of the GNU Lesser General Public
  20 * License along with this library; if not, write to the Free Software
  21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  22 * 
  23 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  24 * $/LicenseInfo$
  25 */
  26
  27#include "linden_common.h"
  28
  29#include <algorithm>
  30#include <sstream>
  31
  32#include "lscript_execute.h"
  33#include "lltimer.h"
  34#include "lscript_readlso.h"
  35#include "lscript_library.h"
  36#include "lscript_heapruntime.h"
  37#include "lscript_alloc.h"
  38#include "llstat.h"
  39
  40
  41// Static
  42const	S32	DEFAULT_SCRIPT_TIMER_CHECK_SKIP = 4;
  43S32		LLScriptExecute::sTimerCheckSkip = DEFAULT_SCRIPT_TIMER_CHECK_SKIP;
  44
  45void (*binary_operations[LST_EOF][LST_EOF])(U8 *buffer, LSCRIPTOpCodesEnum opcode);
  46void (*unary_operations[LST_EOF])(U8 *buffer, LSCRIPTOpCodesEnum opcode);
  47
  48const char* LSCRIPTRunTimeFaultStrings[LSRF_EOF] =		/*Flawfinder: ignore*/
  49{
  50	"Invalid",				//	LSRF_INVALID,
  51	"Math Error",			//	LSRF_MATH,
  52	"Stack-Heap Collision",	//	LSRF_STACK_HEAP_COLLISION,
  53	"Bounds Check Error",	//	LSRF_BOUND_CHECK_ERROR,
  54	"Heap Error",			//	LSRF_HEAP_ERROR,
  55	"Version Mismatch",		//	LSRF_VERSION_MISMATCH,
  56	"Missing Inventory",	//	LSRF_MISSING_INVENTORY,
  57	"Hit Sandbox Limit",	//	LSRF_SANDBOX,
  58	"Chat Overrun",			//	LSRF_CHAT_OVERRUN,
  59	"Too Many Listens",			  //	LSRF_TOO_MANY_LISTENS,
  60	"Lists may not contain lists", //	LSRF_NESTING_LISTS,
  61	"CLI Exception" // LSRF_CLI
  62};
  63
  64void LLScriptExecuteLSL2::startRunning() {}
  65void LLScriptExecuteLSL2::stopRunning() {}
  66
  67const char* URL_REQUEST_GRANTED = "URL_REQUEST_GRANTED";
  68const char* URL_REQUEST_DENIED = "URL_REQUEST_DENIED";
  69
  70// HTTP Requests to LSL scripts will time out after 25 seconds.
  71const U64 LSL_HTTP_REQUEST_TIMEOUT_USEC = 25 * USEC_PER_SEC; 
  72
  73LLScriptExecuteLSL2::LLScriptExecuteLSL2(LLFILE *fp)
  74{
  75	U8  sizearray[4];
  76	size_t filesize;
  77	S32 pos = 0;
  78	if (fread(&sizearray, 1, 4, fp) != 4)
  79	{
  80		llwarns << "Short read" << llendl;
  81		filesize = 0;
  82	} else {
  83		filesize = bytestream2integer(sizearray, pos);
  84	}
  85	mBuffer = new U8[filesize];
  86	fseek(fp, 0, SEEK_SET);
  87	if (fread(mBuffer, 1, filesize, fp) != filesize)
  88	{
  89		llwarns << "Short read" << llendl;
  90	}
  91	fclose(fp);
  92
  93	init();
  94}
  95
  96LLScriptExecuteLSL2::LLScriptExecuteLSL2(const U8* bytecode, U32 bytecode_size)
  97{
  98	mBuffer = new U8[TOP_OF_MEMORY];
  99	memset(mBuffer + bytecode_size, 0, TOP_OF_MEMORY - bytecode_size);
 100	S32 src_offset = 0;
 101	S32 dest_offset = 0;
 102	bytestream2bytestream(mBuffer, dest_offset, bytecode, src_offset, bytecode_size);
 103	mBytecodeSize = bytecode_size;
 104	mBytecode = new U8[mBytecodeSize];
 105	memcpy(mBytecode, bytecode, mBytecodeSize);
 106	init();
 107}
 108
 109LLScriptExecute::~LLScriptExecute() {}
 110LLScriptExecuteLSL2::~LLScriptExecuteLSL2()
 111{
 112	delete[] mBuffer;
 113	delete[] mBytecode;
 114}
 115
 116void LLScriptExecuteLSL2::init()
 117{
 118	S32 i, j;
 119
 120	mInstructionCount = 0;
 121
 122	for (i = 0; i < 256; i++)
 123	{
 124		mExecuteFuncs[i] = run_noop;
 125	}
 126	mExecuteFuncs[LSCRIPTOpCodes[LOPC_NOOP]] = run_noop;
 127
 128	mExecuteFuncs[LSCRIPTOpCodes[LOPC_POP]] = run_pop;
 129	mExecuteFuncs[LSCRIPTOpCodes[LOPC_POPS]] = run_pops;
 130	mExecuteFuncs[LSCRIPTOpCodes[LOPC_POPL]] = run_popl;
 131	mExecuteFuncs[LSCRIPTOpCodes[LOPC_POPV]] = run_popv;
 132	mExecuteFuncs[LSCRIPTOpCodes[LOPC_POPQ]] = run_popq;
 133	mExecuteFuncs[LSCRIPTOpCodes[LOPC_POPARG]] = run_poparg;
 134	mExecuteFuncs[LSCRIPTOpCodes[LOPC_POPIP]] = run_popip;
 135	mExecuteFuncs[LSCRIPTOpCodes[LOPC_POPBP]] = run_popbp;
 136	mExecuteFuncs[LSCRIPTOpCodes[LOPC_POPSP]] = run_popsp;
 137	mExecuteFuncs[LSCRIPTOpCodes[LOPC_POPSLR]] = run_popslr;
 138
 139	mExecuteFuncs[LSCRIPTOpCodes[LOPC_DUP]] = run_dup;
 140	mExecuteFuncs[LSCRIPTOpCodes[LOPC_DUPS]] = run_dups;
 141	mExecuteFuncs[LSCRIPTOpCodes[LOPC_DUPL]] = run_dupl;
 142	mExecuteFuncs[LSCRIPTOpCodes[LOPC_DUPV]] = run_dupv;
 143	mExecuteFuncs[LSCRIPTOpCodes[LOPC_DUPQ]] = run_dupq;
 144
 145	mExecuteFuncs[LSCRIPTOpCodes[LOPC_STORE]] = run_store;
 146	mExecuteFuncs[LSCRIPTOpCodes[LOPC_STORES]] = run_stores;
 147	mExecuteFuncs[LSCRIPTOpCodes[LOPC_STOREL]] = run_storel;
 148	mExecuteFuncs[LSCRIPTOpCodes[LOPC_STOREV]] = run_storev;
 149	mExecuteFuncs[LSCRIPTOpCodes[LOPC_STOREQ]] = run_storeq;
 150	mExecuteFuncs[LSCRIPTOpCodes[LOPC_STOREG]] = run_storeg;
 151	mExecuteFuncs[LSCRIPTOpCodes[LOPC_STOREGL]] = run_storegl;
 152	mExecuteFuncs[LSCRIPTOpCodes[LOPC_STOREGS]] = run_storegs;
 153	mExecuteFuncs[LSCRIPTOpCodes[LOPC_STOREGV]] = run_storegv;
 154	mExecuteFuncs[LSCRIPTOpCodes[LOPC_STOREGQ]] = run_storegq;
 155	mExecuteFuncs[LSCRIPTOpCodes[LOPC_LOADP]] = run_loadp;
 156	mExecuteFuncs[LSCRIPTOpCodes[LOPC_LOADSP]] = run_loadsp;
 157	mExecuteFuncs[LSCRIPTOpCodes[LOPC_LOADLP]] = run_loadlp;
 158	mExecuteFuncs[LSCRIPTOpCodes[LOPC_LOADVP]] = run_loadvp;
 159	mExecuteFuncs[LSCRIPTOpCodes[LOPC_LOADQP]] = run_loadqp;
 160	mExecuteFuncs[LSCRIPTOpCodes[LOPC_LOADGP]] = run_loadgp;
 161	mExecuteFuncs[LSCRIPTOpCodes[LOPC_LOADGSP]] = run_loadgsp;
 162	mExecuteFuncs[LSCRIPTOpCodes[LOPC_LOADGLP]] = run_loadglp;
 163	mExecuteFuncs[LSCRIPTOpCodes[LOPC_LOADGVP]] = run_loadgvp;
 164	mExecuteFuncs[LSCRIPTOpCodes[LOPC_LOADGQP]] = run_loadgqp;
 165
 166	mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSH]] = run_push;
 167	mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHS]] = run_pushs;
 168	mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHL]] = run_pushl;
 169	mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHV]] = run_pushv;
 170	mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHQ]] = run_pushq;
 171	mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHG]] = run_pushg;
 172	mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHGS]] = run_pushgs;
 173	mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHGL]] = run_pushgl;
 174	mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHGV]] = run_pushgv;
 175	mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHGQ]] = run_pushgq;
 176	mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHIP]] = run_puship;
 177	mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHSP]] = run_pushsp;
 178	mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHBP]] = run_pushbp;
 179	mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHARGB]] = run_pushargb;
 180	mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHARGI]] = run_pushargi;
 181	mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHARGF]] = run_pushargf;
 182	mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHARGS]] = run_pushargs;
 183	mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHARGV]] = run_pushargv;
 184	mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHARGQ]] = run_pushargq;
 185	mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHE]] = run_pushe;
 186	mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHEV]] = run_pushev;
 187	mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHEQ]] = run_pusheq;
 188	mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHARGE]] = run_pusharge;
 189
 190	mExecuteFuncs[LSCRIPTOpCodes[LOPC_ADD]] = run_add;
 191	mExecuteFuncs[LSCRIPTOpCodes[LOPC_SUB]] = run_sub;
 192	mExecuteFuncs[LSCRIPTOpCodes[LOPC_MUL]] = run_mul;
 193	mExecuteFuncs[LSCRIPTOpCodes[LOPC_DIV]] = run_div;
 194	mExecuteFuncs[LSCRIPTOpCodes[LOPC_MOD]] = run_mod;
 195
 196	mExecuteFuncs[LSCRIPTOpCodes[LOPC_EQ]] = run_eq;
 197	mExecuteFuncs[LSCRIPTOpCodes[LOPC_NEQ]] = run_neq;
 198	mExecuteFuncs[LSCRIPTOpCodes[LOPC_LEQ]] = run_leq;
 199	mExecuteFuncs[LSCRIPTOpCodes[LOPC_GEQ]] = run_geq;
 200	mExecuteFuncs[LSCRIPTOpCodes[LOPC_LESS]] = run_less;
 201	mExecuteFuncs[LSCRIPTOpCodes[LOPC_GREATER]] = run_greater;
 202
 203	mExecuteFuncs[LSCRIPTOpCodes[LOPC_BITAND]] = run_bitand;
 204	mExecuteFuncs[LSCRIPTOpCodes[LOPC_BITOR]] = run_bitor;
 205	mExecuteFuncs[LSCRIPTOpCodes[LOPC_BITXOR]] = run_bitxor;
 206
 207	mExecuteFuncs[LSCRIPTOpCodes[LOPC_BOOLAND]] = run_booland;
 208	mExecuteFuncs[LSCRIPTOpCodes[LOPC_BOOLOR]] = run_boolor;
 209
 210	mExecuteFuncs[LSCRIPTOpCodes[LOPC_SHL]] = run_shl;
 211	mExecuteFuncs[LSCRIPTOpCodes[LOPC_SHR]] = run_shr;
 212
 213	mExecuteFuncs[LSCRIPTOpCodes[LOPC_NEG]] = run_neg;
 214	mExecuteFuncs[LSCRIPTOpCodes[LOPC_BITNOT]] = run_bitnot;
 215	mExecuteFuncs[LSCRIPTOpCodes[LOPC_BOOLNOT]] = run_boolnot;
 216
 217	mExecuteFuncs[LSCRIPTOpCodes[LOPC_JUMP]] = run_jump;
 218	mExecuteFuncs[LSCRIPTOpCodes[LOPC_JUMPIF]] = run_jumpif;
 219	mExecuteFuncs[LSCRIPTOpCodes[LOPC_JUMPNIF]] = run_jumpnif;
 220
 221	mExecuteFuncs[LSCRIPTOpCodes[LOPC_STATE]] = run_state;
 222	mExecuteFuncs[LSCRIPTOpCodes[LOPC_CALL]] = run_call;
 223	mExecuteFuncs[LSCRIPTOpCodes[LOPC_RETURN]] = run_return;
 224	mExecuteFuncs[LSCRIPTOpCodes[LOPC_CAST]] = run_cast;
 225	mExecuteFuncs[LSCRIPTOpCodes[LOPC_STACKTOS]] = run_stacktos;
 226	mExecuteFuncs[LSCRIPTOpCodes[LOPC_STACKTOL]] = run_stacktol;
 227
 228	mExecuteFuncs[LSCRIPTOpCodes[LOPC_PRINT]] = run_print;
 229
 230	mExecuteFuncs[LSCRIPTOpCodes[LOPC_CALLLIB]] = run_calllib;
 231	mExecuteFuncs[LSCRIPTOpCodes[LOPC_CALLLIB_TWO_BYTE]] = run_calllib_two_byte;
 232
 233	for (i = 0; i < LST_EOF; i++)
 234	{
 235		for (j = 0; j < LST_EOF; j++)
 236		{
 237			binary_operations[i][j] = unknown_operation;
 238		}
 239	}
 240
 241	binary_operations[LST_INTEGER][LST_INTEGER] = integer_integer_operation;
 242	binary_operations[LST_INTEGER][LST_FLOATINGPOINT] = integer_float_operation;
 243	binary_operations[LST_INTEGER][LST_VECTOR] = integer_vector_operation;
 244
 245	binary_operations[LST_FLOATINGPOINT][LST_INTEGER] = float_integer_operation;
 246	binary_operations[LST_FLOATINGPOINT][LST_FLOATINGPOINT] = float_float_operation;
 247	binary_operations[LST_FLOATINGPOINT][LST_VECTOR] = float_vector_operation;
 248
 249	binary_operations[LST_STRING][LST_STRING] = string_string_operation;
 250	binary_operations[LST_STRING][LST_KEY] = string_key_operation;
 251
 252	binary_operations[LST_KEY][LST_STRING] = key_string_operation;
 253	binary_operations[LST_KEY][LST_KEY] = key_key_operation;
 254
 255	binary_operations[LST_VECTOR][LST_INTEGER] = vector_integer_operation;
 256	binary_operations[LST_VECTOR][LST_FLOATINGPOINT] = vector_float_operation;
 257	binary_operations[LST_VECTOR][LST_VECTOR] = vector_vector_operation;
 258	binary_operations[LST_VECTOR][LST_QUATERNION] = vector_quaternion_operation;
 259
 260	binary_operations[LST_QUATERNION][LST_QUATERNION] = quaternion_quaternion_operation;
 261
 262	binary_operations[LST_INTEGER][LST_LIST] = integer_list_operation;
 263	binary_operations[LST_FLOATINGPOINT][LST_LIST] = float_list_operation;
 264	binary_operations[LST_STRING][LST_LIST] = string_list_operation;
 265	binary_operations[LST_KEY][LST_LIST] = key_list_operation;
 266	binary_operations[LST_VECTOR][LST_LIST] = vector_list_operation;
 267	binary_operations[LST_QUATERNION][LST_LIST] = quaternion_list_operation;
 268	binary_operations[LST_LIST][LST_INTEGER] = list_integer_operation;
 269	binary_operations[LST_LIST][LST_FLOATINGPOINT] = list_float_operation;
 270	binary_operations[LST_LIST][LST_STRING] = list_string_operation;
 271	binary_operations[LST_LIST][LST_KEY] = list_key_operation;
 272	binary_operations[LST_LIST][LST_VECTOR] = list_vector_operation;
 273	binary_operations[LST_LIST][LST_QUATERNION] = list_quaternion_operation;
 274	binary_operations[LST_LIST][LST_LIST] = list_list_operation;
 275
 276	for (i = 0; i < LST_EOF; i++)
 277	{
 278		unary_operations[i] = unknown_operation;
 279	}
 280
 281	unary_operations[LST_INTEGER] = integer_operation;
 282	unary_operations[LST_FLOATINGPOINT] = float_operation;
 283	unary_operations[LST_VECTOR] = vector_operation;
 284	unary_operations[LST_QUATERNION] = quaternion_operation;
 285
 286}
 287
 288
 289// Utility routine for when there's a boundary error parsing bytecode
 290void LLScriptExecuteLSL2::recordBoundaryError( const LLUUID &id )
 291{
 292	set_fault(mBuffer, LSRF_BOUND_CHECK_ERROR);
 293	llwarns << "Script boundary error for ID " << id << llendl;
 294}
 295
 296
 297//	set IP to the event handler with some error checking
 298void LLScriptExecuteLSL2::setStateEventOpcoodeStartSafely( S32 state, LSCRIPTStateEventType event, const LLUUID &id )
 299{
 300	S32			opcode_start = get_state_event_opcoode_start( mBuffer, state, event );
 301	if ( opcode_start == -1 )
 302	{
 303		recordBoundaryError( id );
 304	}
 305	else
 306	{
 307		set_ip( mBuffer, opcode_start );
 308	}
 309}
 310
 311
 312
 313
 314S32 lscript_push_variable(LLScriptLibData *data, U8 *buffer);
 315
 316void LLScriptExecuteLSL2::resumeEventHandler(BOOL b_print, const LLUUID &id, F32 time_slice)
 317{
 318	//	call opcode run function pointer with buffer and IP
 319	mInstructionCount++;
 320	S32 value = get_register(mBuffer, LREG_IP);
 321	S32 tvalue = value;
 322	S32	opcode = safe_instruction_bytestream2byte(mBuffer, tvalue);
 323	mExecuteFuncs[opcode](mBuffer, value, b_print, id);
 324	set_ip(mBuffer, value);
 325	add_register_fp(mBuffer, LREG_ESR, -0.1f);
 326	//	lsa_print_heap(mBuffer);
 327
 328	if (b_print)
 329	{
 330		lsa_print_heap(mBuffer);
 331		printf("ip: 0x%X\n", get_register(mBuffer, LREG_IP));
 332		printf("sp: 0x%X\n", get_register(mBuffer, LREG_SP));
 333		printf("bp: 0x%X\n", get_register(mBuffer, LREG_BP));
 334		printf("hr: 0x%X\n", get_register(mBuffer, LREG_HR));
 335		printf("hp: 0x%X\n", get_register(mBuffer, LREG_HP));
 336	}
 337
 338	// NOTE: Babbage: all mExecuteFuncs return false.
 339}
 340
 341void LLScriptExecuteLSL2::callEventHandler(LSCRIPTStateEventType event, const LLUUID &id, F32 time_slice)
 342{
 343	S32 major_version = getMajorVersion();
 344	// push a zero to be popped
 345	lscript_push(mBuffer, 0);
 346	// push sp as current bp
 347	S32 sp = get_register(mBuffer, LREG_SP);
 348	lscript_push(mBuffer, sp);
 349
 350	// Update current handler and current events registers.
 351	set_event_register(mBuffer, LREG_IE, LSCRIPTStateBitField[event], major_version);
 352	U64 current_events = get_event_register(mBuffer, LREG_CE, major_version);
 353	current_events &= ~LSCRIPTStateBitField[event];
 354	set_event_register(mBuffer, LREG_CE, current_events, major_version);
 355
 356	// now, push any additional stack space
 357	U32 current_state = get_register(mBuffer, LREG_CS);
 358	S32 additional_size = get_event_stack_size(mBuffer, current_state, event);
 359	lscript_pusharge(mBuffer, additional_size);
 360
 361	// now set the bp correctly
 362	sp = get_register(mBuffer, LREG_SP);
 363	sp += additional_size;
 364	set_bp(mBuffer, sp);
 365
 366	// set IP to the function
 367	S32			opcode_start = get_state_event_opcoode_start(mBuffer, current_state, event);
 368	set_ip(mBuffer, opcode_start);
 369}
 370
 371//void callStateExitHandler()
 372//{
 373//	// push a zero to be popped
 374//	lscript_push(mBuffer, 0);
 375//	// push sp as current bp
 376//	S32 sp = get_register(mBuffer, LREG_SP);
 377//	lscript_push(mBuffer, sp);
 378//
 379//	// now, push any additional stack space
 380//	S32 additional_size = get_event_stack_size(mBuffer, current_state, LSTT_STATE_EXIT);
 381//	lscript_pusharge(mBuffer, additional_size);
 382//
 383//	sp = get_register(mBuffer, LREG_SP);
 384//	sp += additional_size;
 385//	set_bp(mBuffer, sp);
 386//
 387//	// set IP to the event handler
 388//	S32			opcode_start = get_state_event_opcoode_start(mBuffer, current_state, LSTT_STATE_EXIT);
 389//	set_ip(mBuffer, opcode_start);
 390//}
 391//
 392//void callStateEntryHandler()
 393//{
 394//	// push a zero to be popped
 395//	lscript_push(mBuffer, 0);
 396//	// push sp as current bp
 397//	S32 sp = get_register(mBuffer, LREG_SP);
 398//	lscript_push(mBuffer, sp);
 399//
 400//	event = return_first_event((S32)LSCRIPTStateBitField[LSTT_STATE_ENTRY]);
 401//	set_event_register(mBuffer, LREG_IE, LSCRIPTStateBitField[event], major_version);
 402//	current_events &= ~LSCRIPTStateBitField[event];
 403//	set_event_register(mBuffer, LREG_CE, current_events, major_version);
 404//
 405//	// now, push any additional stack space
 406//	S32 additional_size = get_event_stack_size(mBuffer, current_state, event) - size;
 407//	lscript_pusharge(mBuffer, additional_size);
 408//
 409//	// now set the bp correctly
 410//	sp = get_register(mBuffer, LREG_SP);
 411//	sp += additional_size + size;
 412//	set_bp(mBuffer, sp);
 413//	// set IP to the function
 414//	S32			opcode_start = get_state_event_opcoode_start(mBuffer, current_state, event);
 415//	set_ip(mBuffer, opcode_start);
 416//}
 417
 418void LLScriptExecuteLSL2::callQueuedEventHandler(LSCRIPTStateEventType event, const LLUUID &id, F32 time_slice)
 419{
 420	S32 major_version = getMajorVersion();
 421	LLScriptDataCollection* eventdata;
 422
 423	for (eventdata = mEventData.mEventDataList.getFirstData(); eventdata; eventdata = mEventData.mEventDataList.getNextData())
 424	{
 425		if (eventdata->mType == event)
 426		{
 427			// push a zero to be popped
 428			lscript_push(mBuffer, 0);
 429			// push sp as current bp
 430			S32 sp = get_register(mBuffer, LREG_SP);
 431			lscript_push(mBuffer, sp);
 432
 433			// Update current handler and current events registers.
 434			set_event_register(mBuffer, LREG_IE, LSCRIPTStateBitField[event], major_version);
 435			U64 current_events = get_event_register(mBuffer, LREG_CE, major_version);
 436			current_events &= ~LSCRIPTStateBitField[event];
 437			set_event_register(mBuffer, LREG_CE, current_events, major_version);
 438
 439			// push any arguments that need to be pushed onto the stack
 440			// last piece of data will be type LST_NULL
 441			LLScriptLibData	*data = eventdata->mData;
 442			U32 size = 0;
 443			while (data->mType)
 444			{
 445				size += lscript_push_variable(data, mBuffer);
 446				data++;
 447			}
 448			// now, push any additional stack space
 449			U32 current_state = get_register(mBuffer, LREG_CS);
 450			S32 additional_size = get_event_stack_size(mBuffer, current_state, event) - size;
 451			lscript_pusharge(mBuffer, additional_size);
 452
 453			// now set the bp correctly
 454			sp = get_register(mBuffer, LREG_SP);
 455			sp += additional_size + size;
 456			set_bp(mBuffer, sp);
 457
 458			// set IP to the function
 459			S32			opcode_start = get_state_event_opcoode_start(mBuffer, current_state, event);
 460			set_ip(mBuffer, opcode_start);
 461
 462			mEventData.mEventDataList.deleteCurrentData();
 463			break;
 464		}
 465	}
 466}
 467
 468void LLScriptExecuteLSL2::callNextQueuedEventHandler(U64 event_register, const LLUUID &id, F32 time_slice)
 469{
 470	S32 major_version = getMajorVersion();
 471	LLScriptDataCollection* eventdata = mEventData.getNextEvent();
 472	if (eventdata)
 473	{
 474		LSCRIPTStateEventType event = eventdata->mType;
 475
 476		// make sure that we can actually handle this one
 477		if (LSCRIPTStateBitField[event] & event_register)
 478		{
 479			// push a zero to be popped
 480			lscript_push(mBuffer, 0);
 481			// push sp as current bp
 482			S32 sp = get_register(mBuffer, LREG_SP);
 483			lscript_push(mBuffer, sp);
 484
 485			// Update current handler and current events registers.
 486			set_event_register(mBuffer, LREG_IE, LSCRIPTStateBitField[event], major_version);
 487			U64 current_events = get_event_register(mBuffer, LREG_CE, major_version);
 488			current_events &= ~LSCRIPTStateBitField[event];
 489			set_event_register(mBuffer, LREG_CE, current_events, major_version);
 490
 491			// push any arguments that need to be pushed onto the stack
 492			// last piece of data will be type LST_NULL
 493			LLScriptLibData	*data = eventdata->mData;
 494			U32 size = 0;
 495			while (data->mType)
 496			{
 497				size += lscript_push_variable(data, mBuffer);
 498				data++;
 499			}
 500
 501			// now, push any additional stack space
 502			U32 current_state = get_register(mBuffer, LREG_CS);
 503			S32 additional_size = get_event_stack_size(mBuffer, current_state, event) - size;
 504			lscript_pusharge(mBuffer, additional_size);
 505
 506			// now set the bp correctly
 507			sp = get_register(mBuffer, LREG_SP);
 508			sp += additional_size + size;
 509			set_bp(mBuffer, sp);
 510
 511			// set IP to the function
 512			S32			opcode_start = get_state_event_opcoode_start(mBuffer, current_state, event);
 513			set_ip(mBuffer, opcode_start);
 514		}
 515		else
 516		{
 517			llwarns << "Somehow got an event that we're not registered for!" << llendl;
 518		}
 519		delete eventdata;
 520	}
 521}
 522
 523U64 LLScriptExecuteLSL2::nextState()
 524{
 525	// copy NS to CS
 526	S32 next_state = get_register(mBuffer, LREG_NS);
 527	set_register(mBuffer, LREG_CS, next_state);
 528
 529	// copy new state's handled events into ER (SR + CS*4 + 4)
 530	return get_handled_events(mBuffer, next_state);
 531}
 532
 533//virtual 
 534void LLScriptExecuteLSL2::addEvent(LLScriptDataCollection* event)
 535{
 536	mEventData.addEventData(event);
 537}
 538
 539//virtual 
 540void LLScriptExecuteLSL2::removeEventType(LSCRIPTStateEventType event_type)
 541{
 542	mEventData.removeEventType(event_type);
 543}
 544
 545//virtual 
 546F32 LLScriptExecuteLSL2::getSleep() const
 547{
 548	return get_register_fp(mBuffer, LREG_SLR);
 549}
 550
 551//virtual 
 552void LLScriptExecuteLSL2::setSleep(F32 value)
 553{
 554	set_register_fp(mBuffer, LREG_SLR, value);
 555}
 556
 557//virtual 
 558U64 LLScriptExecuteLSL2::getCurrentHandler()
 559{
 560	return get_event_register(mBuffer, LREG_IE, getMajorVersion());
 561}
 562
 563//virtual 
 564F32 LLScriptExecuteLSL2::getEnergy() const
 565{
 566	return get_register_fp(mBuffer, LREG_ESR);
 567}
 568
 569//virtual 
 570void LLScriptExecuteLSL2::setEnergy(F32 value)
 571{
 572	set_register_fp(mBuffer, LREG_ESR, value);
 573}
 574
 575//virtual 
 576U32 LLScriptExecuteLSL2::getFreeMemory()
 577{
 578	return get_register(mBuffer, LREG_SP) - get_register(mBuffer, LREG_HP);
 579}
 580
 581//virtual 
 582S32 LLScriptExecuteLSL2::getParameter()
 583{
 584	return get_register(mBuffer, LREG_PR);
 585}
 586
 587//virtual 
 588void LLScriptExecuteLSL2::setParameter(S32 value)
 589{
 590	set_register(mBuffer, LREG_PR, value);
 591}
 592
 593
 594S32 LLScriptExecuteLSL2::writeState(U8 **dest, U32 header_size, U32 footer_size)
 595{
 596	// data format:
 597	// 4 bytes of size of Registers, Name and Description, and Global Variables
 598	// Registers, Name and Description, and Global Variables data
 599	// 4 bytes of size of Heap
 600	// Heap data
 601	// 4 bytes of stack size
 602	// Stack data
 603
 604	S32 registers_size = get_register(mBuffer, LREG_GFR);
 605
 606	if (get_register(mBuffer, LREG_HP) > TOP_OF_MEMORY)
 607		reset_hp_to_safe_spot(mBuffer);
 608
 609	S32 heap_size = get_register(mBuffer, LREG_HP) - get_register(mBuffer, LREG_HR);
 610	S32 stack_size = get_register(mBuffer, LREG_TM) - get_register(mBuffer, LREG_SP);
 611	S32 total_size = registers_size + LSCRIPTDataSize[LST_INTEGER] + 
 612						heap_size + LSCRIPTDataSize[LST_INTEGER] + 
 613						stack_size + LSCRIPTDataSize[LST_INTEGER];
 614
 615	// actually allocate data
 616	delete[] *dest;
 617	*dest = new U8[header_size + total_size + footer_size];
 618	memset(*dest, 0, header_size + total_size + footer_size);
 619	S32 dest_offset = header_size;
 620	S32 src_offset = 0;
 621
 622	// registers
 623	integer2bytestream(*dest, dest_offset, registers_size);
 624
 625	// llinfos << "Writing CE: " << getCurrentEvents() << llendl;
 626	bytestream2bytestream(*dest, dest_offset, mBuffer, src_offset, registers_size);
 627
 628	// heap
 629	integer2bytestream(*dest, dest_offset, heap_size);
 630
 631	src_offset = get_register(mBuffer, LREG_HR);
 632	bytestream2bytestream(*dest, dest_offset, mBuffer, src_offset, heap_size);
 633
 634	// stack
 635	integer2bytestream(*dest, dest_offset, stack_size);
 636
 637	src_offset = get_register(mBuffer, LREG_SP);
 638	bytestream2bytestream(*dest, dest_offset, mBuffer, src_offset, stack_size);
 639
 640	return total_size;
 641}
 642
 643S32 LLScriptExecuteLSL2::writeBytecode(U8 **dest)
 644{
 645	// data format:
 646	// registers through top of heap
 647	// Heap data
 648	S32 total_size = get_register(mBuffer, LREG_HP);
 649
 650	// actually allocate data
 651	delete [] *dest;
 652	*dest = new U8[total_size];
 653	S32 dest_offset = 0;
 654	S32 src_offset = 0;
 655
 656	bytestream2bytestream(*dest, dest_offset, mBuffer, src_offset, total_size);
 657
 658	return total_size;
 659}
 660
 661S32 LLScriptExecuteLSL2::readState(U8 *src)
 662{
 663	// first, blitz heap and stack
 664	S32 hr = get_register(mBuffer, LREG_HR);
 665	S32 tm = get_register(mBuffer, LREG_TM);
 666	memset(mBuffer + hr, 0, tm - hr);
 667
 668	S32 src_offset = 0;
 669	S32 dest_offset = 0;
 670	S32 size;
 671
 672	// read register size
 673	size = bytestream2integer(src, src_offset);
 674
 675	// copy data into register area
 676	bytestream2bytestream(mBuffer, dest_offset, src, src_offset, size);
 677//	llinfos << "Read CE: " << getCurrentEvents() << llendl;
 678	if (get_register(mBuffer, LREG_TM) != TOP_OF_MEMORY)
 679	{
 680		llwarns << "Invalid state. Top of memory register does not match"
 681				<< " constant." << llendl;
 682		reset_hp_to_safe_spot(mBuffer);
 683		return -1;
 684	}
 685	
 686	// read heap size
 687	size = bytestream2integer(src, src_offset);
 688
 689	// set dest offset
 690	dest_offset = get_register(mBuffer, LREG_HR);
 691
 692	if (dest_offset + size > TOP_OF_MEMORY)
 693	{
 694		reset_hp_to_safe_spot(mBuffer);
 695		return -1;
 696	}
 697
 698	// copy data into heap area
 699	bytestream2bytestream(mBuffer, dest_offset, src, src_offset, size);
 700
 701	// read stack size
 702	size = bytestream2integer(src, src_offset);
 703
 704	// set dest offset
 705	dest_offset = get_register(mBuffer, LREG_SP);
 706
 707	if (dest_offset + size > TOP_OF_MEMORY)
 708	{
 709		reset_hp_to_safe_spot(mBuffer);
 710		return -1;
 711	}
 712
 713	// copy data into heap area
 714	bytestream2bytestream(mBuffer, dest_offset, src, src_offset, size);
 715
 716	// Return offset to first byte after read data.
 717	return src_offset;
 718}
 719
 720void LLScriptExecuteLSL2::reset()
 721{
 722	LLScriptExecute::reset();
 723
 724	const U8 *src = getBytecode();
 725	S32 size = getBytecodeSize();
 726
 727	if (!src)
 728		return;
 729
 730	// first, blitz heap and stack
 731	S32 hr = get_register(mBuffer, LREG_HR);
 732	S32 tm = get_register(mBuffer, LREG_TM);
 733	memset(mBuffer + hr, 0, tm - hr);
 734
 735	S32 dest_offset = 0;
 736	S32 src_offset = 0;
 737
 738	bytestream2bytestream(mBuffer, dest_offset, src, src_offset, size);
 739}
 740
 741S32 LLScriptExecuteLSL2::getMajorVersion() const
 742{
 743	S32 version = getVersion();
 744	S32 major_version = 0;
 745	if (version == LSL2_VERSION1_END_NUMBER){
 746		major_version = 1;
 747	}
 748	else if (version == LSL2_VERSION_NUMBER)
 749	{
 750		major_version = 2;
 751	}
 752	return major_version;
 753}
 754
 755U32 LLScriptExecuteLSL2::getUsedMemory()
 756{
 757	return getBytecodeSize();
 758}
 759
 760LLScriptExecute::LLScriptExecute() :
 761	mReset(FALSE)
 762{
 763}
 764
 765void LLScriptExecute::reset()
 766{
 767	mReset = FALSE;
 768}
 769
 770bool LLScriptExecute::isYieldDue() const
 771{
 772	if(mReset)
 773	{
 774		return true;
 775	}
 776			
 777	if(getSleep() > 0.f)
 778	{
 779		return true;
 780	}
 781
 782	if(isFinished())
 783	{
 784		return true;
 785	}
 786
 787	// State changes can occur within a single time slice,
 788	// but LLScriptData's clean up is required. Yield here
 789	// to allow LLScriptData to perform cleanup and then call
 790	// runQuanta again.
 791	if(isStateChangePending())
 792	{
 793		return true;
 794	}
 795
 796	return false;
 797}
 798
 799// Run smallest number of instructions possible: 
 800// a single instruction for LSL2, a segment between save tests for Mono
 801void LLScriptExecute::runInstructions(BOOL b_print, const LLUUID &id, 
 802									 const char **errorstr, 
 803									 U32& events_processed,
 804									 F32 quanta)
 805{
 806	//  is there a fault?
 807	//	if yes, print out message and exit
 808	S32 value = getVersion();
 809	S32 major_version = 0;
 810	if (value == LSL2_VERSION1_END_NUMBER)
 811	{
 812		major_version = 1;
 813	}
 814	else if (value == LSL2_VERSION_NUMBER)
 815	{
 816		major_version = 2;
 817	}
 818	else
 819	{
 820		setFault(LSRF_VERSION_MISMATCH);
 821	}
 822	value = getFaults();
 823	if (value > LSRF_INVALID && value < LSRF_EOF)
 824	{
 825		if (b_print)
 826		{
 827			printf("Error!\n");
 828		}
 829		*errorstr = LSCRIPTRunTimeFaultStrings[value];
 830		return;
 831	}
 832	else
 833	{
 834		*errorstr = NULL;
 835	}
 836
 837	if (! isFinished())
 838	{
 839		resumeEventHandler(b_print, id, quanta);
 840		return;
 841	}
 842	else
 843	{
 844		// make sure that IE is zero
 845		setCurrentHandler(0);
 846
 847		//	if no, we're in a state and waiting for an event
 848		U64 current_events = getCurrentEvents();
 849		U64 event_register = getEventHandlers();
 850
 851		//	check NS to see if need to switch states (NS != CS)
 852		if (isStateChangePending())
 853		{
 854			// ok, blow away any pending events
 855			deleteAllEvents();
 856
 857			// if yes, check state exit flag is set
 858			if (current_events & LSCRIPTStateBitField[LSTT_STATE_EXIT])
 859			{
 860				// if yes, clear state exit flag
 861				setCurrentHandler(LSCRIPTStateBitField[LSTT_STATE_EXIT]);
 862				current_events &= ~LSCRIPTStateBitField[LSTT_STATE_EXIT];
 863				setCurrentEvents(current_events);
 864
 865				// check state exit event handler
 866				// if there is a handler, call it
 867				if (event_register & LSCRIPTStateBitField[LSTT_STATE_EXIT])
 868				{
 869					++events_processed;
 870					callEventHandler(LSTT_STATE_EXIT, id, quanta);
 871					return;
 872				}
 873			}
 874
 875			// if no handler or no state exit flag switch to new state
 876			// set state entry flag and clear other CE flags
 877			current_events = LSCRIPTStateBitField[LSTT_STATE_ENTRY];
 878			setCurrentEvents(current_events);
 879
 880			U64 handled_events = nextState();
 881			setEventHandlers(handled_events);
 882		}
 883
 884		// try to get next event from stack
 885		BOOL b_done = FALSE;
 886		LSCRIPTStateEventType event = LSTT_NULL;
 887
 888		current_events = getCurrentEvents();
 889		event_register = getEventHandlers();
 890
 891		// first, check to see if state_entry or onrez are raised and handled
 892		if ((current_events & LSCRIPTStateBitField[LSTT_STATE_ENTRY])
 893			&&(current_events & event_register))
 894		{
 895			++events_processed;
 896			callEventHandler(LSTT_STATE_ENTRY, id, quanta);
 897			b_done = TRUE;
 898		}
 899		else if ((current_events & LSCRIPTStateBitField[LSTT_REZ])
 900				 &&(current_events & event_register))
 901		{
 902			++events_processed;
 903			callQueuedEventHandler(LSTT_REZ, id, quanta);
 904			b_done = TRUE;
 905		}
 906
 907		if (!b_done)
 908		{
 909			// Call handler for next queued event.
 910			if(getEventCount() > 0)
 911			{
 912				++events_processed;
 913				callNextQueuedEventHandler(event_register, id, quanta);
 914			}
 915			else
 916			{
 917				// if no data waiting, do it the old way:
 918				U64 handled_current = current_events & event_register;
 919				if (handled_current)
 920				{
 921					event = return_first_event((S32)handled_current);
 922					++events_processed;
 923					callEventHandler(event, id, quanta);
 924				}
 925			}
 926			b_done = TRUE;
 927		}
 928	}
 929}
 930
 931// Run for a single timeslice, or until a yield or state transition is due
 932F32 LLScriptExecute::runQuanta(BOOL b_print, const LLUUID &id, const char **errorstr, F32 quanta, U32& events_processed, LLTimer& timer)
 933{
 934	S32 timer_checks = 0;
 935	F32 inloop = 0;
 936
 937	// Loop while not finished, yield not due and time remaining
 938	// NOTE: Default implementation does not do adaptive timer skipping
 939	// to preserve current LSL behaviour and not break scripts that rely
 940	// on current execution speed.
 941	while(true)
 942	{
 943		runInstructions(b_print, id, errorstr,
 944						events_processed, quanta);
 945		
 946		if(isYieldDue())
 947		{
 948			break;
 949		}
 950		else if(timer_checks++ >= LLScriptExecute::sTimerCheckSkip)
 951		{
 952			inloop = timer.getElapsedTimeF32();
 953			if(inloop > quanta)
 954			{
 955				break;
 956			}
 957			timer_checks = 0;
 958		}
 959	}
 960	if (inloop == 0.0f)
 961	{
 962		inloop = timer.getElapsedTimeF32();
 963	}
 964	return inloop;
 965}
 966
 967F32 LLScriptExecute::runNested(BOOL b_print, const LLUUID &id, const char **errorstr, F32 quanta, U32& events_processed, LLTimer& timer)
 968{
 969	return LLScriptExecute::runQuanta(b_print, id, errorstr, quanta, events_processed, timer);
 970}
 971
 972BOOL run_noop(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
 973{
 974	if (b_print)
 975		printf("[0x%X]\tNOOP\n", offset);
 976	offset++;
 977	return FALSE;
 978}
 979
 980BOOL run_pop(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
 981{
 982	if (b_print)
 983		printf("[0x%X]\tPOP\n", offset);
 984	offset++;
 985	lscript_poparg(buffer, LSCRIPTDataSize[LST_INTEGER]);
 986	return FALSE;
 987}
 988
 989BOOL run_pops(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
 990{
 991	if (b_print)
 992		printf("[0x%X]\tPOPS\n", offset);
 993	offset++;
 994	S32 address = lscript_pop_int(buffer);
 995	if (address)
 996		lsa_decrease_ref_count(buffer, address);
 997	return FALSE;
 998}
 999
1000BOOL run_popl(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1001{
1002	if (b_print)
1003		printf("[0x%X]\tPOPL\n", offset);
1004	offset++;
1005	S32 address = lscript_pop_int(buffer);
1006	if (address)
1007		lsa_decrease_ref_count(buffer, address);
1008	return FALSE;
1009}
1010
1011BOOL run_popv(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1012{
1013	if (b_print)
1014		printf("[0x%X]\tPOPV\n", offset);
1015	offset++;
1016	lscript_poparg(buffer, LSCRIPTDataSize[LST_VECTOR]);
1017	return FALSE;
1018}
1019
1020BOOL run_popq(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1021{
1022	if (b_print)
1023		printf("[0x%X]\tPOPQ\n", offset);
1024	offset++;
1025	lscript_poparg(buffer, LSCRIPTDataSize[LST_QUATERNION]);
1026	return FALSE;
1027}
1028
1029BOOL run_poparg(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1030{
1031	if (b_print)
1032		printf("[0x%X]\tPOPARG ", offset);
1033	offset++;
1034	S32 arg = safe_instruction_bytestream2integer(buffer, offset);
1035	if (b_print)
1036		printf("%d\n", arg);
1037	lscript_poparg(buffer, arg);
1038	return FALSE;
1039}
1040
1041BOOL run_popip(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1042{
1043	if (b_print)
1044		printf("[0x%X]\tPOPIP\n", offset);
1045	offset++;
1046	offset = lscript_pop_int(buffer);
1047	return FALSE;
1048}
1049
1050BOOL run_popbp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1051{
1052	if (b_print)
1053		printf("[0x%X]\tPOPBP\n", offset);
1054	offset++;
1055	S32 bp = lscript_pop_int(buffer);
1056	set_bp(buffer, bp);
1057	return FALSE;
1058}
1059
1060BOOL run_popsp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1061{
1062	if (b_print)
1063		printf("[0x%X]\tPOPSP\n", offset);
1064	offset++;
1065	S32 sp = lscript_pop_int(buffer);
1066	set_sp(buffer, sp);
1067	return FALSE;
1068}
1069
1070BOOL run_popslr(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1071{
1072	if (b_print)
1073		printf("[0x%X]\tPOPSLR\n", offset);
1074	offset++;
1075	S32 slr = lscript_pop_int(buffer);
1076	set_register(buffer, LREG_SLR, slr);
1077	return FALSE;
1078}
1079
1080BOOL run_dup(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1081{
1082	if (b_print)
1083		printf("[0x%X]\tDUP\n", offset);
1084	offset++;
1085	S32 sp = get_register(buffer, LREG_SP);
1086	S32 value = bytestream2integer(buffer, sp);
1087	lscript_push(buffer, value);
1088	return FALSE;
1089}
1090
1091BOOL run_dups(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1092{
1093	if (b_print)
1094		printf("[0x%X]\tDUPS\n", offset);
1095	offset++;
1096	S32 sp = get_register(buffer, LREG_SP);
1097	S32 value = bytestream2integer(buffer, sp);
1098	lscript_push(buffer, value);
1099	lsa_increase_ref_count(buffer, value);
1100	return FALSE;
1101}
1102
1103BOOL run_dupl(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1104{
1105	if (b_print)
1106		printf("[0x%X]\tDUPL\n", offset);
1107	offset++;
1108	S32 sp = get_register(buffer, LREG_SP);
1109	S32 value = bytestream2integer(buffer, sp);
1110	lscript_push(buffer, value);
1111	lsa_increase_ref_count(buffer, value);
1112	return FALSE;
1113}
1114
1115BOOL run_dupv(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1116{
1117	if (b_print)
1118		printf("[0x%X]\tDUPV\n", offset);
1119	offset++;
1120	S32 sp = get_register(buffer, LREG_SP);
1121	LLVector3 value;
1122	bytestream2vector(value, buffer, sp);
1123	lscript_push(buffer, value);
1124	return FALSE;
1125}
1126
1127BOOL run_dupq(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1128{
1129	if (b_print)
1130		printf("[0x%X]\tDUPV\n", offset);
1131	offset++;
1132	S32 sp = get_register(buffer, LREG_SP);
1133	LLQuaternion value;
1134	bytestream2quaternion(value, buffer, sp);
1135	lscript_push(buffer, value);
1136	return FALSE;
1137}
1138
1139BOOL run_store(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1140{
1141	if (b_print)
1142		printf("[0x%X]\tSTORE ", offset);
1143	offset++;
1144	S32 arg = safe_instruction_bytestream2integer(buffer, offset);
1145	if (b_print)
1146		printf("0x%X\n", arg);
1147	S32 sp = get_register(buffer, LREG_SP);
1148	S32 value = bytestream2integer(buffer, sp);
1149	lscript_local_store(buffer, arg, value);
1150	return FALSE;
1151}
1152
1153BOOL run_stores(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1154{
1155	if (b_print)
1156		printf("[0x%X]\tSTORES ", offset);
1157	offset++;
1158	S32 arg = safe_instruction_bytestream2integer(buffer, offset);
1159	if (b_print)
1160		printf("0x%X\n", arg);
1161	S32 sp = get_register(buffer, LREG_SP);
1162	S32 value = bytestream2integer(buffer, sp);
1163
1164	S32 address = lscript_local_get(buffer, arg);
1165
1166	lscript_local_store(buffer, arg, value);
1167	lsa_increase_ref_count(buffer, value);
1168	if (address)
1169		lsa_decrease_ref_count(buffer, address);
1170	return FALSE;
1171}
1172
1173BOOL run_storel(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1174{
1175	if (b_print)
1176		printf("[0x%X]\tSTOREL ", offset);
1177	offset++;
1178	S32 arg = safe_instruction_bytestream2integer(buffer, offset);
1179	if (b_print)
1180		printf("0x%X\n", arg);
1181	S32 sp = get_register(buffer, LREG_SP);
1182	S32 value = bytestream2integer(buffer, sp);
1183
1184	S32 address = lscript_local_get(buffer, arg);
1185
1186	lscript_local_store(buffer, arg, value);
1187	lsa_increase_ref_count(buffer, value);
1188	if (address)
1189		lsa_decrease_ref_count(buffer, address);
1190	return FALSE;
1191}
1192
1193BOOL run_storev(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1194{
1195	if (b_print)
1196		printf("[0x%X]\tSTOREV ", offset);
1197	offset++;
1198	S32 arg = safe_instruction_bytestream2integer(buffer, offset);
1199	if (b_print)
1200		printf("0x%X\n", arg);
1201	LLVector3 value;
1202	S32 sp = get_register(buffer, LREG_SP);
1203	bytestream2vector(value, buffer, sp);
1204	lscript_local_store(buffer, arg, value);
1205	return FALSE;
1206}
1207
1208BOOL run_storeq(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1209{
1210	if (b_print)
1211		printf("[0x%X]\tSTOREQ ", offset);
1212	offset++;
1213	S32 arg = safe_instruction_bytestream2integer(buffer, offset);
1214	if (b_print)
1215		printf("0x%X\n", arg);
1216	LLQuaternion value;
1217	S32 sp = get_register(buffer, LREG_SP);
1218	bytestream2quaternion(value, buffer, sp);
1219	lscript_local_store(buffer, arg, value);
1220	return FALSE;
1221}
1222
1223BOOL run_storeg(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1224{
1225	if (b_print)
1226		printf("[0x%X]\tSTOREG ", offset);
1227	offset++;
1228	S32 arg = safe_instruction_bytestream2integer(buffer, offset);
1229	if (b_print)
1230		printf("0x%X\n", arg);
1231	S32 sp = get_register(buffer, LREG_SP);
1232	S32 value = bytestream2integer(buffer, sp);
1233	lscript_global_store(buffer, arg, value);
1234	return FALSE;
1235}
1236
1237BOOL run_storegs(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1238{
1239	if (b_print)
1240		printf("[0x%X]\tSTOREGS ", offset);
1241	offset++;
1242	S32 arg = safe_instruction_bytestream2integer(buffer, offset);
1243	if (b_print)
1244		printf("0x%X\n", arg);
1245	S32 sp = get_register(buffer, LREG_SP);
1246	S32 value = bytestream2integer(buffer, sp);
1247
1248	S32 address = lscript_global_get(buffer, arg);
1249
1250	lscript_global_store(buffer, arg, value);
1251
1252	lsa_increase_ref_count(buffer, value);
1253	if (address)
1254		lsa_decrease_ref_count(buffer, address);
1255	return FALSE;
1256}
1257
1258BOOL run_storegl(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1259{
1260	if (b_print)
1261		printf("[0x%X]\tSTOREGL ", offset);
1262	offset++;
1263	S32 arg = safe_instruction_bytestream2integer(buffer, offset);
1264	if (b_print)
1265		printf("0x%X\n", arg);
1266	S32 sp = get_register(buffer, LREG_SP);
1267	S32 value = bytestream2integer(buffer, sp);
1268
1269	S32 address = lscript_global_get(buffer, arg);
1270
1271	lscript_global_store(buffer, arg, value);
1272
1273	lsa_increase_ref_count(buffer, value);
1274	if (address)
1275		lsa_decrease_ref_count(buffer, address);
1276	return FALSE;
1277}
1278
1279BOOL run_storegv(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1280{
1281	if (b_print)
1282		printf("[0x%X]\tSTOREGV ", offset);
1283	offset++;
1284	S32 arg = safe_instruction_bytestream2integer(buffer, offset);
1285	if (b_print)
1286		printf("0x%X\n", arg);
1287	LLVector3 value;
1288	S32 sp = get_register(buffer, LREG_SP);
1289	bytestream2vector(value, buffer, sp);
1290	lscript_global_store(buffer, arg, value);
1291	return FALSE;
1292}
1293
1294BOOL run_storegq(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1295{
1296	if (b_print)
1297		printf("[0x%X]\tSTOREGQ ", offset);
1298	offset++;
1299	S32 arg = safe_instruction_bytestream2integer(buffer, offset);
1300	if (b_print)
1301		printf("0x%X\n", arg);
1302	LLQuaternion value;
1303	S32 sp = get_register(buffer, LREG_SP);
1304	bytestream2quaternion(value, buffer, sp);
1305	lscript_global_store(buffer, arg, value);
1306	return FALSE;
1307}
1308
1309BOOL run_loadp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1310{
1311	if (b_print)
1312		printf("[0x%X]\tSTOREP ", offset);
1313	offset++;
1314	S32 arg = safe_instruction_bytestream2integer(buffer, offset);
1315	if (b_print)
1316		printf("0x%X\n", arg);
1317	S32 value = lscript_pop_int(buffer);
1318	lscript_local_store(buffer, arg, value);
1319	return FALSE;
1320}
1321
1322BOOL run_loadsp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1323{
1324	if (b_print)
1325		printf("[0x%X]\tSTORESP ", offset);
1326	offset++;
1327	S32 arg = safe_instruction_bytestream2integer(buffer, offset);
1328	if (b_print)
1329		printf("0x%X\n", arg);
1330	S32 value = lscript_pop_int(buffer);
1331
1332	S32 address = lscript_local_get(buffer, arg);
1333	if (address)
1334		lsa_decrease_ref_count(buffer, address);
1335
1336	lscript_local_store(buffer, arg, value);
1337	return FALSE;
1338}
1339
1340BOOL run_loadlp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1341{
1342	if (b_print)
1343		printf("[0x%X]\tSTORELP ", offset);
1344	offset++;
1345	S32 arg = safe_instruction_bytestream2integer(buffer, offset);
1346	if (b_print)
1347		printf("0x%X\n", arg);
1348	S32 value = lscript_pop_int(buffer);
1349
1350	S32 address = lscript_local_get(buffer, arg);
1351	if (address)
1352		lsa_decrease_ref_count(buffer, address);
1353
1354	lscript_local_store(buffer, arg, value);
1355	return FALSE;
1356}
1357
1358BOOL run_loadvp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1359{
1360	if (b_print)
1361		printf("[0x%X]\tSTOREVP ", offset);
1362	offset++;
1363	S32 arg = safe_instruction_bytestream2integer(buffer, offset);
1364	if (b_print)
1365		printf("0x%X\n", arg);
1366	LLVector3 value;
1367	lscript_pop_vector(buffer, value);
1368	lscript_local_store(buffer, arg, value);
1369	return FALSE;
1370}
1371
1372BOOL run_loadqp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1373{
1374	if (b_print)
1375		printf("[0x%X]\tSTOREQP ", offset);
1376	offset++;
1377	S32 arg = safe_instruction_bytestream2integer(buffer, offset);
1378	if (b_print)
1379		printf("0x%X\n", arg);
1380	LLQuaternion value;
1381	lscript_pop_quaternion(buffer, value);
1382	lscript_local_store(buffer, arg, value);
1383	return FALSE;
1384}
1385
1386BOOL run_loadgp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1387{
1388	if (b_print)
1389		printf("[0x%X]\tSTOREGP ", offset);
1390	offset++;
1391	S32 arg = safe_instruction_bytestream2integer(buffer, offset);
1392	if (b_print)
1393		printf("0x%X\n", arg);
1394	S32 value = lscript_pop_int(buffer);
1395	lscript_global_store(buffer, arg, value);
1396	return FALSE;
1397}
1398
1399BOOL run_loadgsp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1400{
1401	if (b_print)
1402		printf("[0x%X]\tSTOREGSP ", offset);
1403	offset++;
1404	S32 arg = safe_instruction_bytestream2integer(buffer, offset);
1405	if (b_print)
1406		printf("%d\n", arg);
1407	S32 value = lscript_pop_int(buffer);
1408
1409	S32 address = lscript_global_get(buffer, arg);
1410	if (address)
1411		lsa_decrease_ref_count(buffer, address);
1412
1413	lscript_global_store(buffer, arg, value);
1414	return FALSE;
1415}
1416
1417BOOL run_loadglp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1418{
1419	if (b_print)
1420		printf("[0x%X]\tSTOREGLP ", offset);
1421	offset++;
1422	S32 arg = safe_instruction_bytestream2integer(buffer, offset);
1423	if (b_print)
1424		printf("0x%X\n", arg);
1425	S32 value = lscript_pop_int(buffer);
1426
1427	S32 address = lscript_global_get(buffer, arg);
1428	if (address)
1429		lsa_decrease_ref_count(buffer, address);
1430
1431	lscript_global_store(buffer, arg, value);
1432	return FALSE;
1433}
1434
1435BOOL run_loadgvp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1436{
1437	if (b_print)
1438		printf("[0x%X]\tSTOREGVP ", offset);
1439	offset++;
1440	S32 arg = safe_instruction_bytestream2integer(buffer, offset);
1441	if (b_print)
1442		printf("0x%X\n", arg);
1443	LLVector3 value;
1444	lscript_pop_vector(buffer, value);
1445	lscript_global_store(buffer, arg, value);
1446	return FALSE;
1447}
1448
1449BOOL run_loadgqp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1450{
1451	if (b_print)
1452		printf("[0x%X]\tSTOREGQP ", offset);
1453	offset++;
1454	S32 arg = safe_instruction_bytestream2integer(buffer, offset);
1455	if (b_print)
1456		printf("0x%X\n", arg);
1457	LLQuaternion value;
1458	lscript_pop_quaternion(buffer, value);
1459	lscript_global_store(buffer, arg, value);
1460	return FALSE;
1461}
1462
1463BOOL run_push(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1464{
1465	if (b_print)
1466		printf("[0x%X]\tPUSH ", offset);
1467	offset++;
1468	S32 arg = safe_instruction_bytestream2integer(buffer, offset);
1469	if (b_print)
1470		printf("0x%X\n", arg);
1471	S32 value = lscript_local_get(buffer, arg);
1472	lscript_push(buffer, value);
1473	return FALSE;
1474}
1475
1476BOOL run_pushs(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1477{
1478	if (b_print)
1479		printf("[0x%X]\tPUSHS ", offset);
1480	offset++;
1481	S32 arg = safe_instruction_bytestream2integer(buffer, offset);
1482	if (b_print)
1483		printf("0x%X\n", arg);
1484	S32 value = lscript_local_get(buffer, arg);
1485	lscript_push(buffer, value);
1486	lsa_increase_ref_count(buffer, value);
1487	return FALSE;
1488}
1489
1490BOOL run_pushl(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1491{
1492	if (b_print)
1493		printf("[0x%X]\tPUSHL ", offset);
1494	offset++;
1495	S32 arg = safe_instruction_bytestream2integer(buffer, offset);
1496	if (b_print)
1497		printf("0x%X\n", arg);
1498	S32 value = lscript_local_get(buffer, arg);
1499	lscript_push(buffer, value);
1500	lsa_increase_ref_count(buffer, value);
1501	return FALSE;
1502}
1503
1504BOOL run_pushv(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1505{
1506	if (b_print)
1507		printf("[0x%X]\tPUSHV ", offset);
1508	offset++;
1509	S32 arg = safe_instruction_bytestream2integer(buffer, offset);
1510	if (b_print)
1511		printf("0x%X\n", arg);
1512	LLVector3 value;
1513	lscript_local_get(buffer, arg, value);
1514	lscript_push(buffer, value);
1515	return FALSE;
1516}
1517
1518BOOL run_pushq(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1519{
1520	if (b_print)
1521		printf("[0x%X]\tPUSHQ ", offset);
1522	offset++;
1523	S32 arg = safe_instruction_bytestream2integer(buffer, offset);
1524	if (b_print)
1525		printf("0x%X\n", arg);
1526	LLQuaternion value;
1527	lscript_local_get(buffer, arg, value);
1528	lscript_push(buffer, value);
1529	return FALSE;
1530}
1531
1532BOOL run_pushg(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1533{
1534	if (b_print)
1535		printf("[0x%X]\tPUSHG ", offset);
1536	offset++;
1537	S32 arg = safe_instruction_bytestream2integer(buffer, offset);
1538	if (b_print)
1539		printf("0x%X\n", arg);
1540	S32 value = lscript_global_get(buffer, arg);
1541	lscript_push(buffer, value);
1542	return FALSE;
1543}
1544
1545BOOL run_pushgs(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1546{
1547	if (b_print)
1548		printf("[0x%X]\tPUSHGS ", offset);
1549	offset++;
1550	S32 arg = safe_instruction_bytestream2integer(buffer, offset);
1551	if (b_print)
1552		printf("0x%X\n", arg);
1553	S32 value = lscript_global_get(buffer, arg);
1554	lscript_push(buffer, value);
1555	lsa_increase_ref_count(buffer, value);
1556	return FALSE;
1557}
1558
1559BOOL run_pushgl(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1560{
1561	if (b_print)
1562		printf("[0x%X]\tPUSHGL ", offset);
1563	offset++;
1564	S32 arg = safe_instruction_bytestream2integer(buffer, offset);
1565	if (b_print)
1566		printf("0x%X\n", arg);
1567	S32 value = lscript_global_get(buffer, arg);
1568	lscript_push(buffer, value);
1569	lsa_increase_ref_count(buffer, value);
1570	return FALSE;
1571}
1572
1573BOOL run_pushgv(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1574{
1575	if (b_print)
1576		printf("[0x%X]\tPUSHGV ", offset);
1577	offset++;
1578	S32 arg = safe_instruction_bytestream2integer(buffer, offset);
1579	if (b_print)
1580		printf("0x%X\n", arg);
1581	LLVector3 value;
1582	lscript_global_get(buffer, arg, value);
1583	lscript_push(buffer, value);
1584	return FALSE;
1585}
1586
1587BOOL run_pushgq(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1588{
1589	if (b_print)
1590		printf("[0x%X]\tPUSHGQ ", offset);
1591	offset++;
1592	S32 arg = safe_instruction_bytestream2integer(buffer, offset);
1593	if (b_print)
1594		printf("0x%X\n", arg);
1595	LLQuaternion value;
1596	lscript_global_get(buffer, arg, value);
1597	lscript_push(buffer, value);
1598	return FALSE;
1599}
1600
1601BOOL run_puship(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1602{
1603	if (b_print)
1604		printf("[0x%X]\tPUSHIP\n", offset);
1605	offset++;
1606	lscript_push(buffer, offset);
1607	return FALSE;
1608}
1609
1610BOOL run_pushbp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1611{
1612	if (b_print)
1613		printf("[0x%X]\tPUSHBP\n", offset);
1614	offset++;
1615	lscript_push(buffer, get_register(buffer, LREG_BP));
1616	return FALSE;
1617}
1618
1619BOOL run_pushsp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1620{
1621	if (b_print)
1622		printf("[0x%X]\tPUSHSP\n", offset);
1623	offset++;
1624	lscript_push(buffer, get_register(buffer, LREG_SP));
1625	return FALSE;
1626}
1627
1628BOOL run_pushargb(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1629{
1630	if (b_print)
1631		printf("[0x%X]\tPUSHGARGB ", offset);
1632	offset++;
1633	U8 arg = safe_instruction_bytestream2byte(buffer, offset);
1634	if (b_print)
1635		printf("%d\n", (U32)arg);
1636	lscript_push(buffer, arg);
1637	return FALSE;
1638}
1639
1640BOOL run_pushargi(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1641{
1642	if (b_print)
1643		printf("[0x%X]\tPUSHARGI ", offset);
1644	offset++;
1645	S32 arg = safe_instruction_bytestream2integer(buffer, offset);
1646	if (b_print)
1647		printf("%d\n", arg);
1648	lscript_push(buffer, arg);
1649	return FALSE;
1650}
1651
1652BOOL run_pushargf(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1653{
1654	if (b_print)
1655		printf("[0x%X]\tPUSHARGF ", offset);
1656	offset++;
1657	F32 arg = safe_instruction_bytestream2float(buffer, offset);
1658	if (b_print)
1659		printf("%f\n", arg);
1660	lscript_push(buffer, arg);
1661	return FALSE;
1662}
1663
1664BOOL run_pushargs(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1665{
1666	if (b_print)
1667		printf("[0x%X]\tPUSHARGS ", offset);
1668	S32 toffset = offset;
1669	safe_instruction_bytestream_count_char(buffer, toffset);
1670	S32 size = toffset - offset;
1671	char *arg = new char[size];
1672	offset++;
1673	safe_instruction_bytestream2char(arg, buffer, offset, size);
1674	if (b_print)
1675		printf("%s\n", arg);
1676	S32 address = lsa_heap_add_data(buffer, new LLScriptLibData(arg), get_max_heap_size(buffer), TRUE);
1677	lscript_push(buffer, address);
1678	delete [] arg;
1679	return FALSE;
1680}
1681
1682BOOL run_pushargv(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1683{
1684	if (b_print)
1685		printf("[0x%X]\tPUSHARGV ", offset);
1686	offset++;
1687	LLVector3 arg;
1688	safe_instruction_bytestream2vector(arg, buffer, offset);
1689	if (b_print)
1690		printf("< %f, %f, %f >\n", arg.mV[VX], arg.mV[VY], arg.mV[VZ]);
1691	lscript_push(buffer, arg);
1692	return FALSE;
1693}
1694BOOL run_pushargq(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1695{
1696	if (b_print)
1697		printf("[0x%X]\tPUSHARGQ ", offset);
1698	offset++;
1699	LLQuaternion arg;
1700	safe_instruction_bytestream2quaternion(arg, buffer, offset);
1701	if (b_print)
1702		printf("< %f, %f, %f, %f >\n", arg.mQ[VX], arg.mQ[VY], arg.mQ[VZ], arg.mQ[VS]);
1703	lscript_push(buffer, arg);
1704	return FALSE;
1705}
1706BOOL run_pushe(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1707{
1708	if (b_print)
1709		printf("[0x%X]\tPUSHE\n", offset);
1710	offset++;
1711	lscript_pusharge(buffer, LSCRIPTDataSize[LST_INTEGER]);
1712	return FALSE;
1713}
1714BOOL run_pushev(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1715{
1716	if (b_print)
1717		printf("[0x%X]\tPUSHEV\n", offset);
1718	offset++;
1719	lscript_pusharge(buffer, LSCRIPTDataSize[LST_VECTOR]);
1720	return FALSE;
1721}
1722BOOL run_pusheq(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1723{
1724	if (b_print)
1725		printf("[0x%X]\tPUSHEQ\n", offset);
1726	offset++;
1727	lscript_pusharge(buffer, LSCRIPTDataSize[LST_QUATERNION]);
1728	return FALSE;
1729}
1730BOOL run_pusharge(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1731{
1732	if (b_print)
1733		printf("[0x%X]\tPUSHARGE ", offset);
1734	offset++;
1735	S32 arg = safe_instruction_bytestream2integer(buffer, offset);
1736	if (b_print)
1737		printf("%d\n", arg);
1738	lscript_pusharge(buffer, arg);
1739	return FALSE;
1740}
1741
1742void print_type(U8 type)
1743{
1744	if (type == LSCRIPTTypeByte[LST_INTEGER])
1745	{
1746		printf("integer");
1747	}
1748	else if (type == LSCRIPTTypeByte[LST_FLOATINGPOINT])
1749	{
1750		printf("float");
1751	}
1752	else if (type == LSCRIPTTypeByte[LST_STRING])
1753	{
1754		printf("string");
1755	}
1756	else if (type == LSCRIPTTypeByte[LST_KEY])
1757	{
1758		printf("key");
1759	}
1760	else if (type == LSCRIPTTypeByte[LST_VECTOR])
1761	{
1762		printf("vector");
1763	}
1764	else if (type == LSCRIPTTypeByte[LST_QUATERNION])
1765	{
1766		printf("quaternion");
1767	}
1768	else if (type == LSCRIPTTypeByte[LST_LIST])
1769	{
1770		printf("list");
1771	}
1772}
1773
1774void unknown_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
1775{
1776	printf("Unknown arithmetic operation!\n");
1777}
1778
1779void integer_integer_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
1780{
1781	S32 lside = lscript_pop_int(buffer);
1782	S32 rside = lscript_pop_int(buffer);
1783	S32 result = 0;
1784
1785	switch(opcode)
1786	{
1787	case LOPC_ADD:
1788		result = lside + rside;
1789		break;
1790	case LOPC_SUB:
1791		result = lside - rside;
1792		break;
1793	case LOPC_MUL:
1794		result = lside * rside;
1795		break;
1796	case LOPC_DIV:
1797		if (rside){
1798			if( ( rside == -1 ) || ( rside == (S

Large files files are truncated, but you can click here to view the full file