lscript_execute.cpp
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:106k
源码类别:

游戏引擎

开发平台:

C++ Builder

  1. /**
  2.  * @file lscript_execute.cpp
  3.  * @brief classes to execute bytecode
  4.  *
  5.  * $LicenseInfo:firstyear=2002&license=viewergpl$
  6.  * 
  7.  * Copyright (c) 2002-2010, Linden Research, Inc.
  8.  * 
  9.  * Second Life Viewer Source Code
  10.  * The source code in this file ("Source Code") is provided by Linden Lab
  11.  * to you under the terms of the GNU General Public License, version 2.0
  12.  * ("GPL"), unless you have obtained a separate licensing agreement
  13.  * ("Other License"), formally executed by you and Linden Lab.  Terms of
  14.  * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15.  * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16.  * 
  17.  * There are special exceptions to the terms and conditions of the GPL as
  18.  * it is applied to this Source Code. View the full text of the exception
  19.  * in the file doc/FLOSS-exception.txt in this software distribution, or
  20.  * online at
  21.  * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22.  * 
  23.  * By copying, modifying or distributing this software, you acknowledge
  24.  * that you have read and understood your obligations described above,
  25.  * and agree to abide by those obligations.
  26.  * 
  27.  * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28.  * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29.  * COMPLETENESS OR PERFORMANCE.
  30.  * $/LicenseInfo$
  31.  */
  32. #include "linden_common.h"
  33. #include <algorithm>
  34. #include <sstream>
  35. #include "lscript_execute.h"
  36. #include "lltimer.h"
  37. #include "lscript_readlso.h"
  38. #include "lscript_library.h"
  39. #include "lscript_heapruntime.h"
  40. #include "lscript_alloc.h"
  41. #include "llstat.h"
  42. // Static
  43. const S32 DEFAULT_SCRIPT_TIMER_CHECK_SKIP = 4;
  44. S32 LLScriptExecute::sTimerCheckSkip = DEFAULT_SCRIPT_TIMER_CHECK_SKIP;
  45. void (*binary_operations[LST_EOF][LST_EOF])(U8 *buffer, LSCRIPTOpCodesEnum opcode);
  46. void (*unary_operations[LST_EOF])(U8 *buffer, LSCRIPTOpCodesEnum opcode);
  47. const char* LSCRIPTRunTimeFaultStrings[LSRF_EOF] = /*Flawfinder: ignore*/
  48. {
  49. "Invalid", // LSRF_INVALID,
  50. "Math Error", // LSRF_MATH,
  51. "Stack-Heap Collision", // LSRF_STACK_HEAP_COLLISION,
  52. "Bounds Check Error", // LSRF_BOUND_CHECK_ERROR,
  53. "Heap Error", // LSRF_HEAP_ERROR,
  54. "Version Mismatch", // LSRF_VERSION_MISMATCH,
  55. "Missing Inventory", // LSRF_MISSING_INVENTORY,
  56. "Hit Sandbox Limit", // LSRF_SANDBOX,
  57. "Chat Overrun", // LSRF_CHAT_OVERRUN,
  58. "Too Many Listens",   // LSRF_TOO_MANY_LISTENS,
  59. "Lists may not contain lists", // LSRF_NESTING_LISTS,
  60. "CLI Exception" // LSRF_CLI
  61. };
  62. void LLScriptExecuteLSL2::startRunning() {}
  63. void LLScriptExecuteLSL2::stopRunning() {}
  64. const char* URL_REQUEST_GRANTED = "URL_REQUEST_GRANTED";
  65. const char* URL_REQUEST_DENIED = "URL_REQUEST_DENIED";
  66. // HTTP Requests to LSL scripts will time out after 25 seconds.
  67. const U64 LSL_HTTP_REQUEST_TIMEOUT_USEC = 25 * USEC_PER_SEC; 
  68. LLScriptExecuteLSL2::LLScriptExecuteLSL2(LLFILE *fp)
  69. {
  70. U8  sizearray[4];
  71. size_t filesize;
  72. S32 pos = 0;
  73. if (fread(&sizearray, 1, 4, fp) != 4)
  74. {
  75. llwarns << "Short read" << llendl;
  76. filesize = 0;
  77. } else {
  78. filesize = bytestream2integer(sizearray, pos);
  79. }
  80. mBuffer = new U8[filesize];
  81. fseek(fp, 0, SEEK_SET);
  82. if (fread(mBuffer, 1, filesize, fp) != filesize)
  83. {
  84. llwarns << "Short read" << llendl;
  85. }
  86. fclose(fp);
  87. init();
  88. }
  89. LLScriptExecuteLSL2::LLScriptExecuteLSL2(const U8* bytecode, U32 bytecode_size)
  90. {
  91. mBuffer = new U8[TOP_OF_MEMORY];
  92. memset(mBuffer + bytecode_size, 0, TOP_OF_MEMORY - bytecode_size);
  93. S32 src_offset = 0;
  94. S32 dest_offset = 0;
  95. bytestream2bytestream(mBuffer, dest_offset, bytecode, src_offset, bytecode_size);
  96. mBytecodeSize = bytecode_size;
  97. mBytecode = new U8[mBytecodeSize];
  98. memcpy(mBytecode, bytecode, mBytecodeSize);
  99. init();
  100. }
  101. LLScriptExecute::~LLScriptExecute() {}
  102. LLScriptExecuteLSL2::~LLScriptExecuteLSL2()
  103. {
  104. delete[] mBuffer;
  105. delete[] mBytecode;
  106. }
  107. void LLScriptExecuteLSL2::init()
  108. {
  109. S32 i, j;
  110. mInstructionCount = 0;
  111. for (i = 0; i < 256; i++)
  112. {
  113. mExecuteFuncs[i] = run_noop;
  114. }
  115. mExecuteFuncs[LSCRIPTOpCodes[LOPC_NOOP]] = run_noop;
  116. mExecuteFuncs[LSCRIPTOpCodes[LOPC_POP]] = run_pop;
  117. mExecuteFuncs[LSCRIPTOpCodes[LOPC_POPS]] = run_pops;
  118. mExecuteFuncs[LSCRIPTOpCodes[LOPC_POPL]] = run_popl;
  119. mExecuteFuncs[LSCRIPTOpCodes[LOPC_POPV]] = run_popv;
  120. mExecuteFuncs[LSCRIPTOpCodes[LOPC_POPQ]] = run_popq;
  121. mExecuteFuncs[LSCRIPTOpCodes[LOPC_POPARG]] = run_poparg;
  122. mExecuteFuncs[LSCRIPTOpCodes[LOPC_POPIP]] = run_popip;
  123. mExecuteFuncs[LSCRIPTOpCodes[LOPC_POPBP]] = run_popbp;
  124. mExecuteFuncs[LSCRIPTOpCodes[LOPC_POPSP]] = run_popsp;
  125. mExecuteFuncs[LSCRIPTOpCodes[LOPC_POPSLR]] = run_popslr;
  126. mExecuteFuncs[LSCRIPTOpCodes[LOPC_DUP]] = run_dup;
  127. mExecuteFuncs[LSCRIPTOpCodes[LOPC_DUPS]] = run_dups;
  128. mExecuteFuncs[LSCRIPTOpCodes[LOPC_DUPL]] = run_dupl;
  129. mExecuteFuncs[LSCRIPTOpCodes[LOPC_DUPV]] = run_dupv;
  130. mExecuteFuncs[LSCRIPTOpCodes[LOPC_DUPQ]] = run_dupq;
  131. mExecuteFuncs[LSCRIPTOpCodes[LOPC_STORE]] = run_store;
  132. mExecuteFuncs[LSCRIPTOpCodes[LOPC_STORES]] = run_stores;
  133. mExecuteFuncs[LSCRIPTOpCodes[LOPC_STOREL]] = run_storel;
  134. mExecuteFuncs[LSCRIPTOpCodes[LOPC_STOREV]] = run_storev;
  135. mExecuteFuncs[LSCRIPTOpCodes[LOPC_STOREQ]] = run_storeq;
  136. mExecuteFuncs[LSCRIPTOpCodes[LOPC_STOREG]] = run_storeg;
  137. mExecuteFuncs[LSCRIPTOpCodes[LOPC_STOREGL]] = run_storegl;
  138. mExecuteFuncs[LSCRIPTOpCodes[LOPC_STOREGS]] = run_storegs;
  139. mExecuteFuncs[LSCRIPTOpCodes[LOPC_STOREGV]] = run_storegv;
  140. mExecuteFuncs[LSCRIPTOpCodes[LOPC_STOREGQ]] = run_storegq;
  141. mExecuteFuncs[LSCRIPTOpCodes[LOPC_LOADP]] = run_loadp;
  142. mExecuteFuncs[LSCRIPTOpCodes[LOPC_LOADSP]] = run_loadsp;
  143. mExecuteFuncs[LSCRIPTOpCodes[LOPC_LOADLP]] = run_loadlp;
  144. mExecuteFuncs[LSCRIPTOpCodes[LOPC_LOADVP]] = run_loadvp;
  145. mExecuteFuncs[LSCRIPTOpCodes[LOPC_LOADQP]] = run_loadqp;
  146. mExecuteFuncs[LSCRIPTOpCodes[LOPC_LOADGP]] = run_loadgp;
  147. mExecuteFuncs[LSCRIPTOpCodes[LOPC_LOADGSP]] = run_loadgsp;
  148. mExecuteFuncs[LSCRIPTOpCodes[LOPC_LOADGLP]] = run_loadglp;
  149. mExecuteFuncs[LSCRIPTOpCodes[LOPC_LOADGVP]] = run_loadgvp;
  150. mExecuteFuncs[LSCRIPTOpCodes[LOPC_LOADGQP]] = run_loadgqp;
  151. mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSH]] = run_push;
  152. mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHS]] = run_pushs;
  153. mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHL]] = run_pushl;
  154. mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHV]] = run_pushv;
  155. mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHQ]] = run_pushq;
  156. mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHG]] = run_pushg;
  157. mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHGS]] = run_pushgs;
  158. mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHGL]] = run_pushgl;
  159. mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHGV]] = run_pushgv;
  160. mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHGQ]] = run_pushgq;
  161. mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHIP]] = run_puship;
  162. mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHSP]] = run_pushsp;
  163. mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHBP]] = run_pushbp;
  164. mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHARGB]] = run_pushargb;
  165. mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHARGI]] = run_pushargi;
  166. mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHARGF]] = run_pushargf;
  167. mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHARGS]] = run_pushargs;
  168. mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHARGV]] = run_pushargv;
  169. mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHARGQ]] = run_pushargq;
  170. mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHE]] = run_pushe;
  171. mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHEV]] = run_pushev;
  172. mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHEQ]] = run_pusheq;
  173. mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHARGE]] = run_pusharge;
  174. mExecuteFuncs[LSCRIPTOpCodes[LOPC_ADD]] = run_add;
  175. mExecuteFuncs[LSCRIPTOpCodes[LOPC_SUB]] = run_sub;
  176. mExecuteFuncs[LSCRIPTOpCodes[LOPC_MUL]] = run_mul;
  177. mExecuteFuncs[LSCRIPTOpCodes[LOPC_DIV]] = run_div;
  178. mExecuteFuncs[LSCRIPTOpCodes[LOPC_MOD]] = run_mod;
  179. mExecuteFuncs[LSCRIPTOpCodes[LOPC_EQ]] = run_eq;
  180. mExecuteFuncs[LSCRIPTOpCodes[LOPC_NEQ]] = run_neq;
  181. mExecuteFuncs[LSCRIPTOpCodes[LOPC_LEQ]] = run_leq;
  182. mExecuteFuncs[LSCRIPTOpCodes[LOPC_GEQ]] = run_geq;
  183. mExecuteFuncs[LSCRIPTOpCodes[LOPC_LESS]] = run_less;
  184. mExecuteFuncs[LSCRIPTOpCodes[LOPC_GREATER]] = run_greater;
  185. mExecuteFuncs[LSCRIPTOpCodes[LOPC_BITAND]] = run_bitand;
  186. mExecuteFuncs[LSCRIPTOpCodes[LOPC_BITOR]] = run_bitor;
  187. mExecuteFuncs[LSCRIPTOpCodes[LOPC_BITXOR]] = run_bitxor;
  188. mExecuteFuncs[LSCRIPTOpCodes[LOPC_BOOLAND]] = run_booland;
  189. mExecuteFuncs[LSCRIPTOpCodes[LOPC_BOOLOR]] = run_boolor;
  190. mExecuteFuncs[LSCRIPTOpCodes[LOPC_SHL]] = run_shl;
  191. mExecuteFuncs[LSCRIPTOpCodes[LOPC_SHR]] = run_shr;
  192. mExecuteFuncs[LSCRIPTOpCodes[LOPC_NEG]] = run_neg;
  193. mExecuteFuncs[LSCRIPTOpCodes[LOPC_BITNOT]] = run_bitnot;
  194. mExecuteFuncs[LSCRIPTOpCodes[LOPC_BOOLNOT]] = run_boolnot;
  195. mExecuteFuncs[LSCRIPTOpCodes[LOPC_JUMP]] = run_jump;
  196. mExecuteFuncs[LSCRIPTOpCodes[LOPC_JUMPIF]] = run_jumpif;
  197. mExecuteFuncs[LSCRIPTOpCodes[LOPC_JUMPNIF]] = run_jumpnif;
  198. mExecuteFuncs[LSCRIPTOpCodes[LOPC_STATE]] = run_state;
  199. mExecuteFuncs[LSCRIPTOpCodes[LOPC_CALL]] = run_call;
  200. mExecuteFuncs[LSCRIPTOpCodes[LOPC_RETURN]] = run_return;
  201. mExecuteFuncs[LSCRIPTOpCodes[LOPC_CAST]] = run_cast;
  202. mExecuteFuncs[LSCRIPTOpCodes[LOPC_STACKTOS]] = run_stacktos;
  203. mExecuteFuncs[LSCRIPTOpCodes[LOPC_STACKTOL]] = run_stacktol;
  204. mExecuteFuncs[LSCRIPTOpCodes[LOPC_PRINT]] = run_print;
  205. mExecuteFuncs[LSCRIPTOpCodes[LOPC_CALLLIB]] = run_calllib;
  206. mExecuteFuncs[LSCRIPTOpCodes[LOPC_CALLLIB_TWO_BYTE]] = run_calllib_two_byte;
  207. for (i = 0; i < LST_EOF; i++)
  208. {
  209. for (j = 0; j < LST_EOF; j++)
  210. {
  211. binary_operations[i][j] = unknown_operation;
  212. }
  213. }
  214. binary_operations[LST_INTEGER][LST_INTEGER] = integer_integer_operation;
  215. binary_operations[LST_INTEGER][LST_FLOATINGPOINT] = integer_float_operation;
  216. binary_operations[LST_INTEGER][LST_VECTOR] = integer_vector_operation;
  217. binary_operations[LST_FLOATINGPOINT][LST_INTEGER] = float_integer_operation;
  218. binary_operations[LST_FLOATINGPOINT][LST_FLOATINGPOINT] = float_float_operation;
  219. binary_operations[LST_FLOATINGPOINT][LST_VECTOR] = float_vector_operation;
  220. binary_operations[LST_STRING][LST_STRING] = string_string_operation;
  221. binary_operations[LST_STRING][LST_KEY] = string_key_operation;
  222. binary_operations[LST_KEY][LST_STRING] = key_string_operation;
  223. binary_operations[LST_KEY][LST_KEY] = key_key_operation;
  224. binary_operations[LST_VECTOR][LST_INTEGER] = vector_integer_operation;
  225. binary_operations[LST_VECTOR][LST_FLOATINGPOINT] = vector_float_operation;
  226. binary_operations[LST_VECTOR][LST_VECTOR] = vector_vector_operation;
  227. binary_operations[LST_VECTOR][LST_QUATERNION] = vector_quaternion_operation;
  228. binary_operations[LST_QUATERNION][LST_QUATERNION] = quaternion_quaternion_operation;
  229. binary_operations[LST_INTEGER][LST_LIST] = integer_list_operation;
  230. binary_operations[LST_FLOATINGPOINT][LST_LIST] = float_list_operation;
  231. binary_operations[LST_STRING][LST_LIST] = string_list_operation;
  232. binary_operations[LST_KEY][LST_LIST] = key_list_operation;
  233. binary_operations[LST_VECTOR][LST_LIST] = vector_list_operation;
  234. binary_operations[LST_QUATERNION][LST_LIST] = quaternion_list_operation;
  235. binary_operations[LST_LIST][LST_INTEGER] = list_integer_operation;
  236. binary_operations[LST_LIST][LST_FLOATINGPOINT] = list_float_operation;
  237. binary_operations[LST_LIST][LST_STRING] = list_string_operation;
  238. binary_operations[LST_LIST][LST_KEY] = list_key_operation;
  239. binary_operations[LST_LIST][LST_VECTOR] = list_vector_operation;
  240. binary_operations[LST_LIST][LST_QUATERNION] = list_quaternion_operation;
  241. binary_operations[LST_LIST][LST_LIST] = list_list_operation;
  242. for (i = 0; i < LST_EOF; i++)
  243. {
  244. unary_operations[i] = unknown_operation;
  245. }
  246. unary_operations[LST_INTEGER] = integer_operation;
  247. unary_operations[LST_FLOATINGPOINT] = float_operation;
  248. unary_operations[LST_VECTOR] = vector_operation;
  249. unary_operations[LST_QUATERNION] = quaternion_operation;
  250. }
  251. // Utility routine for when there's a boundary error parsing bytecode
  252. void LLScriptExecuteLSL2::recordBoundaryError( const LLUUID &id )
  253. {
  254. set_fault(mBuffer, LSRF_BOUND_CHECK_ERROR);
  255. llwarns << "Script boundary error for ID " << id << llendl;
  256. }
  257. // set IP to the event handler with some error checking
  258. void LLScriptExecuteLSL2::setStateEventOpcoodeStartSafely( S32 state, LSCRIPTStateEventType event, const LLUUID &id )
  259. {
  260. S32 opcode_start = get_state_event_opcoode_start( mBuffer, state, event );
  261. if ( opcode_start == -1 )
  262. {
  263. recordBoundaryError( id );
  264. }
  265. else
  266. {
  267. set_ip( mBuffer, opcode_start );
  268. }
  269. }
  270. S32 lscript_push_variable(LLScriptLibData *data, U8 *buffer);
  271. void LLScriptExecuteLSL2::resumeEventHandler(BOOL b_print, const LLUUID &id, F32 time_slice)
  272. {
  273. // call opcode run function pointer with buffer and IP
  274. mInstructionCount++;
  275. S32 value = get_register(mBuffer, LREG_IP);
  276. S32 tvalue = value;
  277. S32 opcode = safe_instruction_bytestream2byte(mBuffer, tvalue);
  278. mExecuteFuncs[opcode](mBuffer, value, b_print, id);
  279. set_ip(mBuffer, value);
  280. add_register_fp(mBuffer, LREG_ESR, -0.1f);
  281. // lsa_print_heap(mBuffer);
  282. if (b_print)
  283. {
  284. lsa_print_heap(mBuffer);
  285. printf("ip: 0x%Xn", get_register(mBuffer, LREG_IP));
  286. printf("sp: 0x%Xn", get_register(mBuffer, LREG_SP));
  287. printf("bp: 0x%Xn", get_register(mBuffer, LREG_BP));
  288. printf("hr: 0x%Xn", get_register(mBuffer, LREG_HR));
  289. printf("hp: 0x%Xn", get_register(mBuffer, LREG_HP));
  290. }
  291. // NOTE: Babbage: all mExecuteFuncs return false.
  292. }
  293. void LLScriptExecuteLSL2::callEventHandler(LSCRIPTStateEventType event, const LLUUID &id, F32 time_slice)
  294. {
  295. S32 major_version = getMajorVersion();
  296. // push a zero to be popped
  297. lscript_push(mBuffer, 0);
  298. // push sp as current bp
  299. S32 sp = get_register(mBuffer, LREG_SP);
  300. lscript_push(mBuffer, sp);
  301. // Update current handler and current events registers.
  302. set_event_register(mBuffer, LREG_IE, LSCRIPTStateBitField[event], major_version);
  303. U64 current_events = get_event_register(mBuffer, LREG_CE, major_version);
  304. current_events &= ~LSCRIPTStateBitField[event];
  305. set_event_register(mBuffer, LREG_CE, current_events, major_version);
  306. // now, push any additional stack space
  307. U32 current_state = get_register(mBuffer, LREG_CS);
  308. S32 additional_size = get_event_stack_size(mBuffer, current_state, event);
  309. lscript_pusharge(mBuffer, additional_size);
  310. // now set the bp correctly
  311. sp = get_register(mBuffer, LREG_SP);
  312. sp += additional_size;
  313. set_bp(mBuffer, sp);
  314. // set IP to the function
  315. S32 opcode_start = get_state_event_opcoode_start(mBuffer, current_state, event);
  316. set_ip(mBuffer, opcode_start);
  317. }
  318. //void callStateExitHandler()
  319. //{
  320. // // push a zero to be popped
  321. // lscript_push(mBuffer, 0);
  322. // // push sp as current bp
  323. // S32 sp = get_register(mBuffer, LREG_SP);
  324. // lscript_push(mBuffer, sp);
  325. //
  326. // // now, push any additional stack space
  327. // S32 additional_size = get_event_stack_size(mBuffer, current_state, LSTT_STATE_EXIT);
  328. // lscript_pusharge(mBuffer, additional_size);
  329. //
  330. // sp = get_register(mBuffer, LREG_SP);
  331. // sp += additional_size;
  332. // set_bp(mBuffer, sp);
  333. //
  334. // // set IP to the event handler
  335. // S32 opcode_start = get_state_event_opcoode_start(mBuffer, current_state, LSTT_STATE_EXIT);
  336. // set_ip(mBuffer, opcode_start);
  337. //}
  338. //
  339. //void callStateEntryHandler()
  340. //{
  341. // // push a zero to be popped
  342. // lscript_push(mBuffer, 0);
  343. // // push sp as current bp
  344. // S32 sp = get_register(mBuffer, LREG_SP);
  345. // lscript_push(mBuffer, sp);
  346. //
  347. // event = return_first_event((S32)LSCRIPTStateBitField[LSTT_STATE_ENTRY]);
  348. // set_event_register(mBuffer, LREG_IE, LSCRIPTStateBitField[event], major_version);
  349. // current_events &= ~LSCRIPTStateBitField[event];
  350. // set_event_register(mBuffer, LREG_CE, current_events, major_version);
  351. //
  352. // // now, push any additional stack space
  353. // S32 additional_size = get_event_stack_size(mBuffer, current_state, event) - size;
  354. // lscript_pusharge(mBuffer, additional_size);
  355. //
  356. // // now set the bp correctly
  357. // sp = get_register(mBuffer, LREG_SP);
  358. // sp += additional_size + size;
  359. // set_bp(mBuffer, sp);
  360. // // set IP to the function
  361. // S32 opcode_start = get_state_event_opcoode_start(mBuffer, current_state, event);
  362. // set_ip(mBuffer, opcode_start);
  363. //}
  364. void LLScriptExecuteLSL2::callQueuedEventHandler(LSCRIPTStateEventType event, const LLUUID &id, F32 time_slice)
  365. {
  366. S32 major_version = getMajorVersion();
  367. LLScriptDataCollection* eventdata;
  368. for (eventdata = mEventData.mEventDataList.getFirstData(); eventdata; eventdata = mEventData.mEventDataList.getNextData())
  369. {
  370. if (eventdata->mType == event)
  371. {
  372. // push a zero to be popped
  373. lscript_push(mBuffer, 0);
  374. // push sp as current bp
  375. S32 sp = get_register(mBuffer, LREG_SP);
  376. lscript_push(mBuffer, sp);
  377. // Update current handler and current events registers.
  378. set_event_register(mBuffer, LREG_IE, LSCRIPTStateBitField[event], major_version);
  379. U64 current_events = get_event_register(mBuffer, LREG_CE, major_version);
  380. current_events &= ~LSCRIPTStateBitField[event];
  381. set_event_register(mBuffer, LREG_CE, current_events, major_version);
  382. // push any arguments that need to be pushed onto the stack
  383. // last piece of data will be type LST_NULL
  384. LLScriptLibData *data = eventdata->mData;
  385. U32 size = 0;
  386. while (data->mType)
  387. {
  388. size += lscript_push_variable(data, mBuffer);
  389. data++;
  390. }
  391. // now, push any additional stack space
  392. U32 current_state = get_register(mBuffer, LREG_CS);
  393. S32 additional_size = get_event_stack_size(mBuffer, current_state, event) - size;
  394. lscript_pusharge(mBuffer, additional_size);
  395. // now set the bp correctly
  396. sp = get_register(mBuffer, LREG_SP);
  397. sp += additional_size + size;
  398. set_bp(mBuffer, sp);
  399. // set IP to the function
  400. S32 opcode_start = get_state_event_opcoode_start(mBuffer, current_state, event);
  401. set_ip(mBuffer, opcode_start);
  402. mEventData.mEventDataList.deleteCurrentData();
  403. break;
  404. }
  405. }
  406. }
  407. void LLScriptExecuteLSL2::callNextQueuedEventHandler(U64 event_register, const LLUUID &id, F32 time_slice)
  408. {
  409. S32 major_version = getMajorVersion();
  410. LLScriptDataCollection* eventdata = mEventData.getNextEvent();
  411. if (eventdata)
  412. {
  413. LSCRIPTStateEventType event = eventdata->mType;
  414. // make sure that we can actually handle this one
  415. if (LSCRIPTStateBitField[event] & event_register)
  416. {
  417. // push a zero to be popped
  418. lscript_push(mBuffer, 0);
  419. // push sp as current bp
  420. S32 sp = get_register(mBuffer, LREG_SP);
  421. lscript_push(mBuffer, sp);
  422. // Update current handler and current events registers.
  423. set_event_register(mBuffer, LREG_IE, LSCRIPTStateBitField[event], major_version);
  424. U64 current_events = get_event_register(mBuffer, LREG_CE, major_version);
  425. current_events &= ~LSCRIPTStateBitField[event];
  426. set_event_register(mBuffer, LREG_CE, current_events, major_version);
  427. // push any arguments that need to be pushed onto the stack
  428. // last piece of data will be type LST_NULL
  429. LLScriptLibData *data = eventdata->mData;
  430. U32 size = 0;
  431. while (data->mType)
  432. {
  433. size += lscript_push_variable(data, mBuffer);
  434. data++;
  435. }
  436. // now, push any additional stack space
  437. U32 current_state = get_register(mBuffer, LREG_CS);
  438. S32 additional_size = get_event_stack_size(mBuffer, current_state, event) - size;
  439. lscript_pusharge(mBuffer, additional_size);
  440. // now set the bp correctly
  441. sp = get_register(mBuffer, LREG_SP);
  442. sp += additional_size + size;
  443. set_bp(mBuffer, sp);
  444. // set IP to the function
  445. S32 opcode_start = get_state_event_opcoode_start(mBuffer, current_state, event);
  446. set_ip(mBuffer, opcode_start);
  447. }
  448. else
  449. {
  450. llwarns << "Shit, somehow got an event that we're not registered for!" << llendl;
  451. }
  452. delete eventdata;
  453. }
  454. }
  455. U64 LLScriptExecuteLSL2::nextState()
  456. {
  457. // copy NS to CS
  458. S32 next_state = get_register(mBuffer, LREG_NS);
  459. set_register(mBuffer, LREG_CS, next_state);
  460. // copy new state's handled events into ER (SR + CS*4 + 4)
  461. return get_handled_events(mBuffer, next_state);
  462. }
  463. //virtual 
  464. void LLScriptExecuteLSL2::addEvent(LLScriptDataCollection* event)
  465. {
  466. mEventData.addEventData(event);
  467. }
  468. //virtual 
  469. void LLScriptExecuteLSL2::removeEventType(LSCRIPTStateEventType event_type)
  470. {
  471. mEventData.removeEventType(event_type);
  472. }
  473. //virtual 
  474. F32 LLScriptExecuteLSL2::getSleep() const
  475. {
  476. return get_register_fp(mBuffer, LREG_SLR);
  477. }
  478. //virtual 
  479. void LLScriptExecuteLSL2::setSleep(F32 value)
  480. {
  481. set_register_fp(mBuffer, LREG_SLR, value);
  482. }
  483. //virtual 
  484. U64 LLScriptExecuteLSL2::getCurrentHandler()
  485. {
  486. return get_event_register(mBuffer, LREG_IE, getMajorVersion());
  487. }
  488. //virtual 
  489. F32 LLScriptExecuteLSL2::getEnergy() const
  490. {
  491. return get_register_fp(mBuffer, LREG_ESR);
  492. }
  493. //virtual 
  494. void LLScriptExecuteLSL2::setEnergy(F32 value)
  495. {
  496. set_register_fp(mBuffer, LREG_ESR, value);
  497. }
  498. //virtual 
  499. U32 LLScriptExecuteLSL2::getFreeMemory()
  500. {
  501. return get_register(mBuffer, LREG_SP) - get_register(mBuffer, LREG_HP);
  502. }
  503. //virtual 
  504. S32 LLScriptExecuteLSL2::getParameter()
  505. {
  506. return get_register(mBuffer, LREG_PR);
  507. }
  508. //virtual 
  509. void LLScriptExecuteLSL2::setParameter(S32 value)
  510. {
  511. set_register(mBuffer, LREG_PR, value);
  512. }
  513. S32 LLScriptExecuteLSL2::writeState(U8 **dest, U32 header_size, U32 footer_size)
  514. {
  515. // data format:
  516. // 4 bytes of size of Registers, Name and Description, and Global Variables
  517. // Registers, Name and Description, and Global Variables data
  518. // 4 bytes of size of Heap
  519. // Heap data
  520. // 4 bytes of stack size
  521. // Stack data
  522. S32 registers_size = get_register(mBuffer, LREG_GFR);
  523. if (get_register(mBuffer, LREG_HP) > TOP_OF_MEMORY)
  524. reset_hp_to_safe_spot(mBuffer);
  525. S32 heap_size = get_register(mBuffer, LREG_HP) - get_register(mBuffer, LREG_HR);
  526. S32 stack_size = get_register(mBuffer, LREG_TM) - get_register(mBuffer, LREG_SP);
  527. S32 total_size = registers_size + LSCRIPTDataSize[LST_INTEGER] + 
  528. heap_size + LSCRIPTDataSize[LST_INTEGER] + 
  529. stack_size + LSCRIPTDataSize[LST_INTEGER];
  530. // actually allocate data
  531. delete[] *dest;
  532. *dest = new U8[header_size + total_size + footer_size];
  533. memset(*dest, 0, header_size + total_size + footer_size);
  534. S32 dest_offset = header_size;
  535. S32 src_offset = 0;
  536. // registers
  537. integer2bytestream(*dest, dest_offset, registers_size);
  538. // llinfos << "Writing CE: " << getCurrentEvents() << llendl;
  539. bytestream2bytestream(*dest, dest_offset, mBuffer, src_offset, registers_size);
  540. // heap
  541. integer2bytestream(*dest, dest_offset, heap_size);
  542. src_offset = get_register(mBuffer, LREG_HR);
  543. bytestream2bytestream(*dest, dest_offset, mBuffer, src_offset, heap_size);
  544. // stack
  545. integer2bytestream(*dest, dest_offset, stack_size);
  546. src_offset = get_register(mBuffer, LREG_SP);
  547. bytestream2bytestream(*dest, dest_offset, mBuffer, src_offset, stack_size);
  548. return total_size;
  549. }
  550. S32 LLScriptExecuteLSL2::writeBytecode(U8 **dest)
  551. {
  552. // data format:
  553. // registers through top of heap
  554. // Heap data
  555. S32 total_size = get_register(mBuffer, LREG_HP);
  556. // actually allocate data
  557. delete [] *dest;
  558. *dest = new U8[total_size];
  559. S32 dest_offset = 0;
  560. S32 src_offset = 0;
  561. bytestream2bytestream(*dest, dest_offset, mBuffer, src_offset, total_size);
  562. return total_size;
  563. }
  564. S32 LLScriptExecuteLSL2::readState(U8 *src)
  565. {
  566. // first, blitz heap and stack
  567. S32 hr = get_register(mBuffer, LREG_HR);
  568. S32 tm = get_register(mBuffer, LREG_TM);
  569. memset(mBuffer + hr, 0, tm - hr);
  570. S32 src_offset = 0;
  571. S32 dest_offset = 0;
  572. S32 size;
  573. // read register size
  574. size = bytestream2integer(src, src_offset);
  575. // copy data into register area
  576. bytestream2bytestream(mBuffer, dest_offset, src, src_offset, size);
  577. // llinfos << "Read CE: " << getCurrentEvents() << llendl;
  578. if (get_register(mBuffer, LREG_TM) != TOP_OF_MEMORY)
  579. {
  580. llwarns << "Invalid state. Top of memory register does not match"
  581. << " constant." << llendl;
  582. reset_hp_to_safe_spot(mBuffer);
  583. return -1;
  584. }
  585. // read heap size
  586. size = bytestream2integer(src, src_offset);
  587. // set dest offset
  588. dest_offset = get_register(mBuffer, LREG_HR);
  589. if (dest_offset + size > TOP_OF_MEMORY)
  590. {
  591. reset_hp_to_safe_spot(mBuffer);
  592. return -1;
  593. }
  594. // copy data into heap area
  595. bytestream2bytestream(mBuffer, dest_offset, src, src_offset, size);
  596. // read stack size
  597. size = bytestream2integer(src, src_offset);
  598. // set dest offset
  599. dest_offset = get_register(mBuffer, LREG_SP);
  600. if (dest_offset + size > TOP_OF_MEMORY)
  601. {
  602. reset_hp_to_safe_spot(mBuffer);
  603. return -1;
  604. }
  605. // copy data into heap area
  606. bytestream2bytestream(mBuffer, dest_offset, src, src_offset, size);
  607. // Return offset to first byte after read data.
  608. return src_offset;
  609. }
  610. void LLScriptExecuteLSL2::reset()
  611. {
  612. LLScriptExecute::reset();
  613. const U8 *src = getBytecode();
  614. S32 size = getBytecodeSize();
  615. if (!src)
  616. return;
  617. // first, blitz heap and stack
  618. S32 hr = get_register(mBuffer, LREG_HR);
  619. S32 tm = get_register(mBuffer, LREG_TM);
  620. memset(mBuffer + hr, 0, tm - hr);
  621. S32 dest_offset = 0;
  622. S32 src_offset = 0;
  623. bytestream2bytestream(mBuffer, dest_offset, src, src_offset, size);
  624. }
  625. S32 LLScriptExecuteLSL2::getMajorVersion() const
  626. {
  627. S32 version = getVersion();
  628. S32 major_version = 0;
  629. if (version == LSL2_VERSION1_END_NUMBER){
  630. major_version = 1;
  631. }
  632. else if (version == LSL2_VERSION_NUMBER)
  633. {
  634. major_version = 2;
  635. }
  636. return major_version;
  637. }
  638. U32 LLScriptExecuteLSL2::getUsedMemory()
  639. {
  640. return getBytecodeSize();
  641. }
  642. LLScriptExecute::LLScriptExecute() :
  643. mReset(FALSE)
  644. {
  645. }
  646. void LLScriptExecute::reset()
  647. {
  648. mReset = FALSE;
  649. }
  650. bool LLScriptExecute::isYieldDue() const
  651. {
  652. if(mReset)
  653. {
  654. return true;
  655. }
  656. if(getSleep() > 0.f)
  657. {
  658. return true;
  659. }
  660. if(isFinished())
  661. {
  662. return true;
  663. }
  664. // State changes can occur within a single time slice,
  665. // but LLScriptData's clean up is required. Yield here
  666. // to allow LLScriptData to perform cleanup and then call
  667. // runQuanta again.
  668. if(isStateChangePending())
  669. {
  670. return true;
  671. }
  672. return false;
  673. }
  674. // Run smallest number of instructions possible: 
  675. // a single instruction for LSL2, a segment between save tests for Mono
  676. void LLScriptExecute::runInstructions(BOOL b_print, const LLUUID &id, 
  677.  const char **errorstr, 
  678.  U32& events_processed,
  679.  F32 quanta)
  680. {
  681. //  is there a fault?
  682. // if yes, print out message and exit
  683. S32 value = getVersion();
  684. S32 major_version = 0;
  685. if (value == LSL2_VERSION1_END_NUMBER)
  686. {
  687. major_version = 1;
  688. }
  689. else if (value == LSL2_VERSION_NUMBER)
  690. {
  691. major_version = 2;
  692. }
  693. else
  694. {
  695. setFault(LSRF_VERSION_MISMATCH);
  696. }
  697. value = getFaults();
  698. if (value > LSRF_INVALID && value < LSRF_EOF)
  699. {
  700. if (b_print)
  701. {
  702. printf("Error!n");
  703. }
  704. *errorstr = LSCRIPTRunTimeFaultStrings[value];
  705. return;
  706. }
  707. else
  708. {
  709. *errorstr = NULL;
  710. }
  711. if (! isFinished())
  712. {
  713. resumeEventHandler(b_print, id, quanta);
  714. return;
  715. }
  716. else
  717. {
  718. // make sure that IE is zero
  719. setCurrentHandler(0);
  720. // if no, we're in a state and waiting for an event
  721. U64 current_events = getCurrentEvents();
  722. U64 event_register = getEventHandlers();
  723. // check NS to see if need to switch states (NS != CS)
  724. if (isStateChangePending())
  725. {
  726. // ok, blow away any pending events
  727. deleteAllEvents();
  728. // if yes, check state exit flag is set
  729. if (current_events & LSCRIPTStateBitField[LSTT_STATE_EXIT])
  730. {
  731. // if yes, clear state exit flag
  732. setCurrentHandler(LSCRIPTStateBitField[LSTT_STATE_EXIT]);
  733. current_events &= ~LSCRIPTStateBitField[LSTT_STATE_EXIT];
  734. setCurrentEvents(current_events);
  735. // check state exit event handler
  736. // if there is a handler, call it
  737. if (event_register & LSCRIPTStateBitField[LSTT_STATE_EXIT])
  738. {
  739. ++events_processed;
  740. callEventHandler(LSTT_STATE_EXIT, id, quanta);
  741. return;
  742. }
  743. }
  744. // if no handler or no state exit flag switch to new state
  745. // set state entry flag and clear other CE flags
  746. current_events = LSCRIPTStateBitField[LSTT_STATE_ENTRY];
  747. setCurrentEvents(current_events);
  748. U64 handled_events = nextState();
  749. setEventHandlers(handled_events);
  750. }
  751. // try to get next event from stack
  752. BOOL b_done = FALSE;
  753. LSCRIPTStateEventType event = LSTT_NULL;
  754. current_events = getCurrentEvents();
  755. event_register = getEventHandlers();
  756. // first, check to see if state_entry or onrez are raised and handled
  757. if ((current_events & LSCRIPTStateBitField[LSTT_STATE_ENTRY])
  758. &&(current_events & event_register))
  759. {
  760. ++events_processed;
  761. callEventHandler(LSTT_STATE_ENTRY, id, quanta);
  762. b_done = TRUE;
  763. }
  764. else if ((current_events & LSCRIPTStateBitField[LSTT_REZ])
  765.  &&(current_events & event_register))
  766. {
  767. ++events_processed;
  768. callQueuedEventHandler(LSTT_REZ, id, quanta);
  769. b_done = TRUE;
  770. }
  771. if (!b_done)
  772. {
  773. // Call handler for next queued event.
  774. if(getEventCount() > 0)
  775. {
  776. ++events_processed;
  777. callNextQueuedEventHandler(event_register, id, quanta);
  778. }
  779. else
  780. {
  781. // if no data waiting, do it the old way:
  782. U64 handled_current = current_events & event_register;
  783. if (handled_current)
  784. {
  785. event = return_first_event((S32)handled_current);
  786. ++events_processed;
  787. callEventHandler(event, id, quanta);
  788. }
  789. }
  790. b_done = TRUE;
  791. }
  792. }
  793. }
  794. // Run for a single timeslice, or until a yield or state transition is due
  795. F32 LLScriptExecute::runQuanta(BOOL b_print, const LLUUID &id, const char **errorstr, F32 quanta, U32& events_processed, LLTimer& timer)
  796. {
  797. S32 timer_checks = 0;
  798. F32 inloop = 0;
  799. // Loop while not finished, yield not due and time remaining
  800. // NOTE: Default implementation does not do adaptive timer skipping
  801. // to preserve current LSL behaviour and not break scripts that rely
  802. // on current execution speed.
  803. while(true)
  804. {
  805. runInstructions(b_print, id, errorstr,
  806. events_processed, quanta);
  807. if(isYieldDue())
  808. {
  809. break;
  810. }
  811. else if(timer_checks++ >= LLScriptExecute::sTimerCheckSkip)
  812. {
  813. inloop = timer.getElapsedTimeF32();
  814. if(inloop > quanta)
  815. {
  816. break;
  817. }
  818. timer_checks = 0;
  819. }
  820. }
  821. if (inloop == 0.0f)
  822. {
  823. inloop = timer.getElapsedTimeF32();
  824. }
  825. return inloop;
  826. }
  827. F32 LLScriptExecute::runNested(BOOL b_print, const LLUUID &id, const char **errorstr, F32 quanta, U32& events_processed, LLTimer& timer)
  828. {
  829. return LLScriptExecute::runQuanta(b_print, id, errorstr, quanta, events_processed, timer);
  830. }
  831. BOOL run_noop(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  832. {
  833. if (b_print)
  834. printf("[0x%X]tNOOPn", offset);
  835. offset++;
  836. return FALSE;
  837. }
  838. BOOL run_pop(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  839. {
  840. if (b_print)
  841. printf("[0x%X]tPOPn", offset);
  842. offset++;
  843. lscript_poparg(buffer, LSCRIPTDataSize[LST_INTEGER]);
  844. return FALSE;
  845. }
  846. BOOL run_pops(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  847. {
  848. if (b_print)
  849. printf("[0x%X]tPOPSn", offset);
  850. offset++;
  851. S32 address = lscript_pop_int(buffer);
  852. if (address)
  853. lsa_decrease_ref_count(buffer, address);
  854. return FALSE;
  855. }
  856. BOOL run_popl(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  857. {
  858. if (b_print)
  859. printf("[0x%X]tPOPLn", offset);
  860. offset++;
  861. S32 address = lscript_pop_int(buffer);
  862. if (address)
  863. lsa_decrease_ref_count(buffer, address);
  864. return FALSE;
  865. }
  866. BOOL run_popv(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  867. {
  868. if (b_print)
  869. printf("[0x%X]tPOPVn", offset);
  870. offset++;
  871. lscript_poparg(buffer, LSCRIPTDataSize[LST_VECTOR]);
  872. return FALSE;
  873. }
  874. BOOL run_popq(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  875. {
  876. if (b_print)
  877. printf("[0x%X]tPOPQn", offset);
  878. offset++;
  879. lscript_poparg(buffer, LSCRIPTDataSize[LST_QUATERNION]);
  880. return FALSE;
  881. }
  882. BOOL run_poparg(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  883. {
  884. if (b_print)
  885. printf("[0x%X]tPOPARG ", offset);
  886. offset++;
  887. S32 arg = safe_instruction_bytestream2integer(buffer, offset);
  888. if (b_print)
  889. printf("%dn", arg);
  890. lscript_poparg(buffer, arg);
  891. return FALSE;
  892. }
  893. BOOL run_popip(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  894. {
  895. if (b_print)
  896. printf("[0x%X]tPOPIPn", offset);
  897. offset++;
  898. offset = lscript_pop_int(buffer);
  899. return FALSE;
  900. }
  901. BOOL run_popbp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  902. {
  903. if (b_print)
  904. printf("[0x%X]tPOPBPn", offset);
  905. offset++;
  906. S32 bp = lscript_pop_int(buffer);
  907. set_bp(buffer, bp);
  908. return FALSE;
  909. }
  910. BOOL run_popsp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  911. {
  912. if (b_print)
  913. printf("[0x%X]tPOPSPn", offset);
  914. offset++;
  915. S32 sp = lscript_pop_int(buffer);
  916. set_sp(buffer, sp);
  917. return FALSE;
  918. }
  919. BOOL run_popslr(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  920. {
  921. if (b_print)
  922. printf("[0x%X]tPOPSLRn", offset);
  923. offset++;
  924. S32 slr = lscript_pop_int(buffer);
  925. set_register(buffer, LREG_SLR, slr);
  926. return FALSE;
  927. }
  928. BOOL run_dup(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  929. {
  930. if (b_print)
  931. printf("[0x%X]tDUPn", offset);
  932. offset++;
  933. S32 sp = get_register(buffer, LREG_SP);
  934. S32 value = bytestream2integer(buffer, sp);
  935. lscript_push(buffer, value);
  936. return FALSE;
  937. }
  938. BOOL run_dups(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  939. {
  940. if (b_print)
  941. printf("[0x%X]tDUPSn", offset);
  942. offset++;
  943. S32 sp = get_register(buffer, LREG_SP);
  944. S32 value = bytestream2integer(buffer, sp);
  945. lscript_push(buffer, value);
  946. lsa_increase_ref_count(buffer, value);
  947. return FALSE;
  948. }
  949. BOOL run_dupl(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  950. {
  951. if (b_print)
  952. printf("[0x%X]tDUPLn", offset);
  953. offset++;
  954. S32 sp = get_register(buffer, LREG_SP);
  955. S32 value = bytestream2integer(buffer, sp);
  956. lscript_push(buffer, value);
  957. lsa_increase_ref_count(buffer, value);
  958. return FALSE;
  959. }
  960. BOOL run_dupv(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  961. {
  962. if (b_print)
  963. printf("[0x%X]tDUPVn", offset);
  964. offset++;
  965. S32 sp = get_register(buffer, LREG_SP);
  966. LLVector3 value;
  967. bytestream2vector(value, buffer, sp);
  968. lscript_push(buffer, value);
  969. return FALSE;
  970. }
  971. BOOL run_dupq(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  972. {
  973. if (b_print)
  974. printf("[0x%X]tDUPVn", offset);
  975. offset++;
  976. S32 sp = get_register(buffer, LREG_SP);
  977. LLQuaternion value;
  978. bytestream2quaternion(value, buffer, sp);
  979. lscript_push(buffer, value);
  980. return FALSE;
  981. }
  982. BOOL run_store(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  983. {
  984. if (b_print)
  985. printf("[0x%X]tSTORE ", offset);
  986. offset++;
  987. S32 arg = safe_instruction_bytestream2integer(buffer, offset);
  988. if (b_print)
  989. printf("0x%Xn", arg);
  990. S32 sp = get_register(buffer, LREG_SP);
  991. S32 value = bytestream2integer(buffer, sp);
  992. lscript_local_store(buffer, arg, value);
  993. return FALSE;
  994. }
  995. BOOL run_stores(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  996. {
  997. if (b_print)
  998. printf("[0x%X]tSTORES ", offset);
  999. offset++;
  1000. S32 arg = safe_instruction_bytestream2integer(buffer, offset);
  1001. if (b_print)
  1002. printf("0x%Xn", arg);
  1003. S32 sp = get_register(buffer, LREG_SP);
  1004. S32 value = bytestream2integer(buffer, sp);
  1005. S32 address = lscript_local_get(buffer, arg);
  1006. lscript_local_store(buffer, arg, value);
  1007. lsa_increase_ref_count(buffer, value);
  1008. if (address)
  1009. lsa_decrease_ref_count(buffer, address);
  1010. return FALSE;
  1011. }
  1012. BOOL run_storel(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  1013. {
  1014. if (b_print)
  1015. printf("[0x%X]tSTOREL ", offset);
  1016. offset++;
  1017. S32 arg = safe_instruction_bytestream2integer(buffer, offset);
  1018. if (b_print)
  1019. printf("0x%Xn", arg);
  1020. S32 sp = get_register(buffer, LREG_SP);
  1021. S32 value = bytestream2integer(buffer, sp);
  1022. S32 address = lscript_local_get(buffer, arg);
  1023. lscript_local_store(buffer, arg, value);
  1024. lsa_increase_ref_count(buffer, value);
  1025. if (address)
  1026. lsa_decrease_ref_count(buffer, address);
  1027. return FALSE;
  1028. }
  1029. BOOL run_storev(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  1030. {
  1031. if (b_print)
  1032. printf("[0x%X]tSTOREV ", offset);
  1033. offset++;
  1034. S32 arg = safe_instruction_bytestream2integer(buffer, offset);
  1035. if (b_print)
  1036. printf("0x%Xn", arg);
  1037. LLVector3 value;
  1038. S32 sp = get_register(buffer, LREG_SP);
  1039. bytestream2vector(value, buffer, sp);
  1040. lscript_local_store(buffer, arg, value);
  1041. return FALSE;
  1042. }
  1043. BOOL run_storeq(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  1044. {
  1045. if (b_print)
  1046. printf("[0x%X]tSTOREQ ", offset);
  1047. offset++;
  1048. S32 arg = safe_instruction_bytestream2integer(buffer, offset);
  1049. if (b_print)
  1050. printf("0x%Xn", arg);
  1051. LLQuaternion value;
  1052. S32 sp = get_register(buffer, LREG_SP);
  1053. bytestream2quaternion(value, buffer, sp);
  1054. lscript_local_store(buffer, arg, value);
  1055. return FALSE;
  1056. }
  1057. BOOL run_storeg(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  1058. {
  1059. if (b_print)
  1060. printf("[0x%X]tSTOREG ", offset);
  1061. offset++;
  1062. S32 arg = safe_instruction_bytestream2integer(buffer, offset);
  1063. if (b_print)
  1064. printf("0x%Xn", arg);
  1065. S32 sp = get_register(buffer, LREG_SP);
  1066. S32 value = bytestream2integer(buffer, sp);
  1067. lscript_global_store(buffer, arg, value);
  1068. return FALSE;
  1069. }
  1070. BOOL run_storegs(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  1071. {
  1072. if (b_print)
  1073. printf("[0x%X]tSTOREGS ", offset);
  1074. offset++;
  1075. S32 arg = safe_instruction_bytestream2integer(buffer, offset);
  1076. if (b_print)
  1077. printf("0x%Xn", arg);
  1078. S32 sp = get_register(buffer, LREG_SP);
  1079. S32 value = bytestream2integer(buffer, sp);
  1080. S32 address = lscript_global_get(buffer, arg);
  1081. lscript_global_store(buffer, arg, value);
  1082. lsa_increase_ref_count(buffer, value);
  1083. if (address)
  1084. lsa_decrease_ref_count(buffer, address);
  1085. return FALSE;
  1086. }
  1087. BOOL run_storegl(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  1088. {
  1089. if (b_print)
  1090. printf("[0x%X]tSTOREGL ", offset);
  1091. offset++;
  1092. S32 arg = safe_instruction_bytestream2integer(buffer, offset);
  1093. if (b_print)
  1094. printf("0x%Xn", arg);
  1095. S32 sp = get_register(buffer, LREG_SP);
  1096. S32 value = bytestream2integer(buffer, sp);
  1097. S32 address = lscript_global_get(buffer, arg);
  1098. lscript_global_store(buffer, arg, value);
  1099. lsa_increase_ref_count(buffer, value);
  1100. if (address)
  1101. lsa_decrease_ref_count(buffer, address);
  1102. return FALSE;
  1103. }
  1104. BOOL run_storegv(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  1105. {
  1106. if (b_print)
  1107. printf("[0x%X]tSTOREGV ", offset);
  1108. offset++;
  1109. S32 arg = safe_instruction_bytestream2integer(buffer, offset);
  1110. if (b_print)
  1111. printf("0x%Xn", arg);
  1112. LLVector3 value;
  1113. S32 sp = get_register(buffer, LREG_SP);
  1114. bytestream2vector(value, buffer, sp);
  1115. lscript_global_store(buffer, arg, value);
  1116. return FALSE;
  1117. }
  1118. BOOL run_storegq(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  1119. {
  1120. if (b_print)
  1121. printf("[0x%X]tSTOREGQ ", offset);
  1122. offset++;
  1123. S32 arg = safe_instruction_bytestream2integer(buffer, offset);
  1124. if (b_print)
  1125. printf("0x%Xn", arg);
  1126. LLQuaternion value;
  1127. S32 sp = get_register(buffer, LREG_SP);
  1128. bytestream2quaternion(value, buffer, sp);
  1129. lscript_global_store(buffer, arg, value);
  1130. return FALSE;
  1131. }
  1132. BOOL run_loadp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  1133. {
  1134. if (b_print)
  1135. printf("[0x%X]tSTOREP ", offset);
  1136. offset++;
  1137. S32 arg = safe_instruction_bytestream2integer(buffer, offset);
  1138. if (b_print)
  1139. printf("0x%Xn", arg);
  1140. S32 value = lscript_pop_int(buffer);
  1141. lscript_local_store(buffer, arg, value);
  1142. return FALSE;
  1143. }
  1144. BOOL run_loadsp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  1145. {
  1146. if (b_print)
  1147. printf("[0x%X]tSTORESP ", offset);
  1148. offset++;
  1149. S32 arg = safe_instruction_bytestream2integer(buffer, offset);
  1150. if (b_print)
  1151. printf("0x%Xn", arg);
  1152. S32 value = lscript_pop_int(buffer);
  1153. S32 address = lscript_local_get(buffer, arg);
  1154. if (address)
  1155. lsa_decrease_ref_count(buffer, address);
  1156. lscript_local_store(buffer, arg, value);
  1157. return FALSE;
  1158. }
  1159. BOOL run_loadlp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  1160. {
  1161. if (b_print)
  1162. printf("[0x%X]tSTORELP ", offset);
  1163. offset++;
  1164. S32 arg = safe_instruction_bytestream2integer(buffer, offset);
  1165. if (b_print)
  1166. printf("0x%Xn", arg);
  1167. S32 value = lscript_pop_int(buffer);
  1168. S32 address = lscript_local_get(buffer, arg);
  1169. if (address)
  1170. lsa_decrease_ref_count(buffer, address);
  1171. lscript_local_store(buffer, arg, value);
  1172. return FALSE;
  1173. }
  1174. BOOL run_loadvp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  1175. {
  1176. if (b_print)
  1177. printf("[0x%X]tSTOREVP ", offset);
  1178. offset++;
  1179. S32 arg = safe_instruction_bytestream2integer(buffer, offset);
  1180. if (b_print)
  1181. printf("0x%Xn", arg);
  1182. LLVector3 value;
  1183. lscript_pop_vector(buffer, value);
  1184. lscript_local_store(buffer, arg, value);
  1185. return FALSE;
  1186. }
  1187. BOOL run_loadqp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  1188. {
  1189. if (b_print)
  1190. printf("[0x%X]tSTOREQP ", offset);
  1191. offset++;
  1192. S32 arg = safe_instruction_bytestream2integer(buffer, offset);
  1193. if (b_print)
  1194. printf("0x%Xn", arg);
  1195. LLQuaternion value;
  1196. lscript_pop_quaternion(buffer, value);
  1197. lscript_local_store(buffer, arg, value);
  1198. return FALSE;
  1199. }
  1200. BOOL run_loadgp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  1201. {
  1202. if (b_print)
  1203. printf("[0x%X]tSTOREGP ", offset);
  1204. offset++;
  1205. S32 arg = safe_instruction_bytestream2integer(buffer, offset);
  1206. if (b_print)
  1207. printf("0x%Xn", arg);
  1208. S32 value = lscript_pop_int(buffer);
  1209. lscript_global_store(buffer, arg, value);
  1210. return FALSE;
  1211. }
  1212. BOOL run_loadgsp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  1213. {
  1214. if (b_print)
  1215. printf("[0x%X]tSTOREGSP ", offset);
  1216. offset++;
  1217. S32 arg = safe_instruction_bytestream2integer(buffer, offset);
  1218. if (b_print)
  1219. printf("%dn", arg);
  1220. S32 value = lscript_pop_int(buffer);
  1221. S32 address = lscript_global_get(buffer, arg);
  1222. if (address)
  1223. lsa_decrease_ref_count(buffer, address);
  1224. lscript_global_store(buffer, arg, value);
  1225. return FALSE;
  1226. }
  1227. BOOL run_loadglp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  1228. {
  1229. if (b_print)
  1230. printf("[0x%X]tSTOREGLP ", offset);
  1231. offset++;
  1232. S32 arg = safe_instruction_bytestream2integer(buffer, offset);
  1233. if (b_print)
  1234. printf("0x%Xn", arg);
  1235. S32 value = lscript_pop_int(buffer);
  1236. S32 address = lscript_global_get(buffer, arg);
  1237. if (address)
  1238. lsa_decrease_ref_count(buffer, address);
  1239. lscript_global_store(buffer, arg, value);
  1240. return FALSE;
  1241. }
  1242. BOOL run_loadgvp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  1243. {
  1244. if (b_print)
  1245. printf("[0x%X]tSTOREGVP ", offset);
  1246. offset++;
  1247. S32 arg = safe_instruction_bytestream2integer(buffer, offset);
  1248. if (b_print)
  1249. printf("0x%Xn", arg);
  1250. LLVector3 value;
  1251. lscript_pop_vector(buffer, value);
  1252. lscript_global_store(buffer, arg, value);
  1253. return FALSE;
  1254. }
  1255. BOOL run_loadgqp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  1256. {
  1257. if (b_print)
  1258. printf("[0x%X]tSTOREGQP ", offset);
  1259. offset++;
  1260. S32 arg = safe_instruction_bytestream2integer(buffer, offset);
  1261. if (b_print)
  1262. printf("0x%Xn", arg);
  1263. LLQuaternion value;
  1264. lscript_pop_quaternion(buffer, value);
  1265. lscript_global_store(buffer, arg, value);
  1266. return FALSE;
  1267. }
  1268. BOOL run_push(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  1269. {
  1270. if (b_print)
  1271. printf("[0x%X]tPUSH ", offset);
  1272. offset++;
  1273. S32 arg = safe_instruction_bytestream2integer(buffer, offset);
  1274. if (b_print)
  1275. printf("0x%Xn", arg);
  1276. S32 value = lscript_local_get(buffer, arg);
  1277. lscript_push(buffer, value);
  1278. return FALSE;
  1279. }
  1280. BOOL run_pushs(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  1281. {
  1282. if (b_print)
  1283. printf("[0x%X]tPUSHS ", offset);
  1284. offset++;
  1285. S32 arg = safe_instruction_bytestream2integer(buffer, offset);
  1286. if (b_print)
  1287. printf("0x%Xn", arg);
  1288. S32 value = lscript_local_get(buffer, arg);
  1289. lscript_push(buffer, value);
  1290. lsa_increase_ref_count(buffer, value);
  1291. return FALSE;
  1292. }
  1293. BOOL run_pushl(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  1294. {
  1295. if (b_print)
  1296. printf("[0x%X]tPUSHL ", offset);
  1297. offset++;
  1298. S32 arg = safe_instruction_bytestream2integer(buffer, offset);
  1299. if (b_print)
  1300. printf("0x%Xn", arg);
  1301. S32 value = lscript_local_get(buffer, arg);
  1302. lscript_push(buffer, value);
  1303. lsa_increase_ref_count(buffer, value);
  1304. return FALSE;
  1305. }
  1306. BOOL run_pushv(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  1307. {
  1308. if (b_print)
  1309. printf("[0x%X]tPUSHV ", offset);
  1310. offset++;
  1311. S32 arg = safe_instruction_bytestream2integer(buffer, offset);
  1312. if (b_print)
  1313. printf("0x%Xn", arg);
  1314. LLVector3 value;
  1315. lscript_local_get(buffer, arg, value);
  1316. lscript_push(buffer, value);
  1317. return FALSE;
  1318. }
  1319. BOOL run_pushq(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  1320. {
  1321. if (b_print)
  1322. printf("[0x%X]tPUSHQ ", offset);
  1323. offset++;
  1324. S32 arg = safe_instruction_bytestream2integer(buffer, offset);
  1325. if (b_print)
  1326. printf("0x%Xn", arg);
  1327. LLQuaternion value;
  1328. lscript_local_get(buffer, arg, value);
  1329. lscript_push(buffer, value);
  1330. return FALSE;
  1331. }
  1332. BOOL run_pushg(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  1333. {
  1334. if (b_print)
  1335. printf("[0x%X]tPUSHG ", offset);
  1336. offset++;
  1337. S32 arg = safe_instruction_bytestream2integer(buffer, offset);
  1338. if (b_print)
  1339. printf("0x%Xn", arg);
  1340. S32 value = lscript_global_get(buffer, arg);
  1341. lscript_push(buffer, value);
  1342. return FALSE;
  1343. }
  1344. BOOL run_pushgs(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  1345. {
  1346. if (b_print)
  1347. printf("[0x%X]tPUSHGS ", offset);
  1348. offset++;
  1349. S32 arg = safe_instruction_bytestream2integer(buffer, offset);
  1350. if (b_print)
  1351. printf("0x%Xn", arg);
  1352. S32 value = lscript_global_get(buffer, arg);
  1353. lscript_push(buffer, value);
  1354. lsa_increase_ref_count(buffer, value);
  1355. return FALSE;
  1356. }
  1357. BOOL run_pushgl(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  1358. {
  1359. if (b_print)
  1360. printf("[0x%X]tPUSHGL ", offset);
  1361. offset++;
  1362. S32 arg = safe_instruction_bytestream2integer(buffer, offset);
  1363. if (b_print)
  1364. printf("0x%Xn", arg);
  1365. S32 value = lscript_global_get(buffer, arg);
  1366. lscript_push(buffer, value);
  1367. lsa_increase_ref_count(buffer, value);
  1368. return FALSE;
  1369. }
  1370. BOOL run_pushgv(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  1371. {
  1372. if (b_print)
  1373. printf("[0x%X]tPUSHGV ", offset);
  1374. offset++;
  1375. S32 arg = safe_instruction_bytestream2integer(buffer, offset);
  1376. if (b_print)
  1377. printf("0x%Xn", arg);
  1378. LLVector3 value;
  1379. lscript_global_get(buffer, arg, value);
  1380. lscript_push(buffer, value);
  1381. return FALSE;
  1382. }
  1383. BOOL run_pushgq(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  1384. {
  1385. if (b_print)
  1386. printf("[0x%X]tPUSHGQ ", offset);
  1387. offset++;
  1388. S32 arg = safe_instruction_bytestream2integer(buffer, offset);
  1389. if (b_print)
  1390. printf("0x%Xn", arg);
  1391. LLQuaternion value;
  1392. lscript_global_get(buffer, arg, value);
  1393. lscript_push(buffer, value);
  1394. return FALSE;
  1395. }
  1396. BOOL run_puship(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  1397. {
  1398. if (b_print)
  1399. printf("[0x%X]tPUSHIPn", offset);
  1400. offset++;
  1401. lscript_push(buffer, offset);
  1402. return FALSE;
  1403. }
  1404. BOOL run_pushbp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  1405. {
  1406. if (b_print)
  1407. printf("[0x%X]tPUSHBPn", offset);
  1408. offset++;
  1409. lscript_push(buffer, get_register(buffer, LREG_BP));
  1410. return FALSE;
  1411. }
  1412. BOOL run_pushsp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  1413. {
  1414. if (b_print)
  1415. printf("[0x%X]tPUSHSPn", offset);
  1416. offset++;
  1417. lscript_push(buffer, get_register(buffer, LREG_SP));
  1418. return FALSE;
  1419. }
  1420. BOOL run_pushargb(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  1421. {
  1422. if (b_print)
  1423. printf("[0x%X]tPUSHGARGB ", offset);
  1424. offset++;
  1425. U8 arg = safe_instruction_bytestream2byte(buffer, offset);
  1426. if (b_print)
  1427. printf("%dn", (U32)arg);
  1428. lscript_push(buffer, arg);
  1429. return FALSE;
  1430. }
  1431. BOOL run_pushargi(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  1432. {
  1433. if (b_print)
  1434. printf("[0x%X]tPUSHARGI ", offset);
  1435. offset++;
  1436. S32 arg = safe_instruction_bytestream2integer(buffer, offset);
  1437. if (b_print)
  1438. printf("%dn", arg);
  1439. lscript_push(buffer, arg);
  1440. return FALSE;
  1441. }
  1442. BOOL run_pushargf(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  1443. {
  1444. if (b_print)
  1445. printf("[0x%X]tPUSHARGF ", offset);
  1446. offset++;
  1447. F32 arg = safe_instruction_bytestream2float(buffer, offset);
  1448. if (b_print)
  1449. printf("%fn", arg);
  1450. lscript_push(buffer, arg);
  1451. return FALSE;
  1452. }
  1453. BOOL run_pushargs(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  1454. {
  1455. if (b_print)
  1456. printf("[0x%X]tPUSHARGS ", offset);
  1457. S32 toffset = offset;
  1458. safe_instruction_bytestream_count_char(buffer, toffset);
  1459. S32 size = toffset - offset;
  1460. char *arg = new char[size];
  1461. offset++;
  1462. safe_instruction_bytestream2char(arg, buffer, offset, size);
  1463. if (b_print)
  1464. printf("%sn", arg);
  1465. S32 address = lsa_heap_add_data(buffer, new LLScriptLibData(arg), get_max_heap_size(buffer), TRUE);
  1466. lscript_push(buffer, address);
  1467. delete [] arg;
  1468. return FALSE;
  1469. }
  1470. BOOL run_pushargv(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  1471. {
  1472. if (b_print)
  1473. printf("[0x%X]tPUSHARGV ", offset);
  1474. offset++;
  1475. LLVector3 arg;
  1476. safe_instruction_bytestream2vector(arg, buffer, offset);
  1477. if (b_print)
  1478. printf("< %f, %f, %f >n", arg.mV[VX], arg.mV[VY], arg.mV[VZ]);
  1479. lscript_push(buffer, arg);
  1480. return FALSE;
  1481. }
  1482. BOOL run_pushargq(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  1483. {
  1484. if (b_print)
  1485. printf("[0x%X]tPUSHARGQ ", offset);
  1486. offset++;
  1487. LLQuaternion arg;
  1488. safe_instruction_bytestream2quaternion(arg, buffer, offset);
  1489. if (b_print)
  1490. printf("< %f, %f, %f, %f >n", arg.mQ[VX], arg.mQ[VY], arg.mQ[VZ], arg.mQ[VS]);
  1491. lscript_push(buffer, arg);
  1492. return FALSE;
  1493. }
  1494. BOOL run_pushe(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  1495. {
  1496. if (b_print)
  1497. printf("[0x%X]tPUSHEn", offset);
  1498. offset++;
  1499. lscript_pusharge(buffer, LSCRIPTDataSize[LST_INTEGER]);
  1500. return FALSE;
  1501. }
  1502. BOOL run_pushev(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  1503. {
  1504. if (b_print)
  1505. printf("[0x%X]tPUSHEVn", offset);
  1506. offset++;
  1507. lscript_pusharge(buffer, LSCRIPTDataSize[LST_VECTOR]);
  1508. return FALSE;
  1509. }
  1510. BOOL run_pusheq(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  1511. {
  1512. if (b_print)
  1513. printf("[0x%X]tPUSHEQn", offset);
  1514. offset++;
  1515. lscript_pusharge(buffer, LSCRIPTDataSize[LST_QUATERNION]);
  1516. return FALSE;
  1517. }
  1518. BOOL run_pusharge(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  1519. {
  1520. if (b_print)
  1521. printf("[0x%X]tPUSHARGE ", offset);
  1522. offset++;
  1523. S32 arg = safe_instruction_bytestream2integer(buffer, offset);
  1524. if (b_print)
  1525. printf("%dn", arg);
  1526. lscript_pusharge(buffer, arg);
  1527. return FALSE;
  1528. }
  1529. void print_type(U8 type)
  1530. {
  1531. if (type == LSCRIPTTypeByte[LST_INTEGER])
  1532. {
  1533. printf("integer");
  1534. }
  1535. else if (type == LSCRIPTTypeByte[LST_FLOATINGPOINT])
  1536. {
  1537. printf("float");
  1538. }
  1539. else if (type == LSCRIPTTypeByte[LST_STRING])
  1540. {
  1541. printf("string");
  1542. }
  1543. else if (type == LSCRIPTTypeByte[LST_KEY])
  1544. {
  1545. printf("key");
  1546. }
  1547. else if (type == LSCRIPTTypeByte[LST_VECTOR])
  1548. {
  1549. printf("vector");
  1550. }
  1551. else if (type == LSCRIPTTypeByte[LST_QUATERNION])
  1552. {
  1553. printf("quaternion");
  1554. }
  1555. else if (type == LSCRIPTTypeByte[LST_LIST])
  1556. {
  1557. printf("list");
  1558. }
  1559. }
  1560. void unknown_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
  1561. {
  1562. printf("Unknown arithmetic operation!n");
  1563. }
  1564. void integer_integer_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
  1565. {
  1566. S32 lside = lscript_pop_int(buffer);
  1567. S32 rside = lscript_pop_int(buffer);
  1568. S32 result = 0;
  1569. switch(opcode)
  1570. {
  1571. case LOPC_ADD:
  1572. result = lside + rside;
  1573. break;
  1574. case LOPC_SUB:
  1575. result = lside - rside;
  1576. break;
  1577. case LOPC_MUL:
  1578. result = lside * rside;
  1579. break;
  1580. case LOPC_DIV:
  1581. if (rside){
  1582. if( ( rside == -1 ) || ( rside == (S32) 0xffffffff ) )// division by -1 can have funny results: multiplication is OK: SL-31252
  1583. {
  1584. result = -1 * lside;
  1585. }
  1586. else
  1587. {
  1588. result = lside / rside;
  1589. }
  1590. }
  1591. else
  1592. set_fault(buffer, LSRF_MATH);
  1593. break;
  1594. case LOPC_MOD:
  1595. if (rside)
  1596. {
  1597. if (rside == -1 || rside == 1 )  // mod(1) = mod(-1) = 0: SL-31252
  1598. {
  1599. result = 0;
  1600. }
  1601. else
  1602. {
  1603. result = lside % rside;
  1604. }
  1605. }
  1606. else
  1607. set_fault(buffer, LSRF_MATH);
  1608. break;
  1609. case LOPC_EQ:
  1610. result = (lside == rside);
  1611. break;
  1612. case LOPC_NEQ:
  1613. result = (lside != rside);
  1614. break;
  1615. case LOPC_LEQ:
  1616. result = (lside <= rside);
  1617. break;
  1618. case LOPC_GEQ:
  1619. result = (lside >= rside);
  1620. break;
  1621. case LOPC_LESS:
  1622. result = (lside < rside);
  1623. break;
  1624. case LOPC_GREATER:
  1625. result = (lside > rside);
  1626. break;
  1627. case LOPC_BITAND:
  1628. result = (lside & rside);
  1629. break;
  1630. case LOPC_BITOR:
  1631. result = (lside | rside);
  1632. break;
  1633. case LOPC_BITXOR:
  1634. result = (lside ^ rside);
  1635. break;
  1636. case LOPC_BOOLAND:
  1637. result = (lside && rside);
  1638. break;
  1639. case LOPC_BOOLOR:
  1640. result = (lside || rside);
  1641. break;
  1642. case LOPC_SHL:
  1643. result = (lside << rside);
  1644. break;
  1645. case LOPC_SHR:
  1646. result = (lside >> rside);
  1647. break;
  1648. default:
  1649. break;
  1650. }
  1651. lscript_push(buffer, result);
  1652. }
  1653. void integer_float_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
  1654. {
  1655. S32 lside = lscript_pop_int(buffer);
  1656. F32 rside = lscript_pop_float(buffer);
  1657. S32 resulti = 0;
  1658. F32 resultf = 0;
  1659. switch(opcode)
  1660. {
  1661. case LOPC_ADD:
  1662. resultf = lside + rside;
  1663. lscript_push(buffer, resultf);
  1664. break;
  1665. case LOPC_SUB:
  1666. resultf = lside - rside;
  1667. lscript_push(buffer, resultf);
  1668. break;
  1669. case LOPC_MUL:
  1670. resultf = lside * rside;
  1671. lscript_push(buffer, resultf);
  1672. break;
  1673. case LOPC_DIV:
  1674. if (rside)
  1675. resultf = lside / rside;
  1676. else
  1677. set_fault(buffer, LSRF_MATH);
  1678. lscript_push(buffer, resultf);
  1679. break;
  1680. case LOPC_EQ:
  1681. resulti = (lside == rside);
  1682. lscript_push(buffer, resulti);
  1683. break;
  1684. case LOPC_NEQ:
  1685. resulti = (lside != rside);
  1686. lscript_push(buffer, resulti);
  1687. break;
  1688. case LOPC_LEQ:
  1689. resulti = (lside <= rside);
  1690. lscript_push(buffer, resulti);
  1691. break;
  1692. case LOPC_GEQ:
  1693. resulti = (lside >= rside);
  1694. lscript_push(buffer, resulti);
  1695. break;
  1696. case LOPC_LESS:
  1697. resulti = (lside < rside);
  1698. lscript_push(buffer, resulti);
  1699. break;
  1700. case LOPC_GREATER:
  1701. resulti = (lside > rside);
  1702. lscript_push(buffer, resulti);
  1703. break;
  1704. default:
  1705. break;
  1706. }
  1707. }
  1708. void integer_vector_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
  1709. {
  1710. S32 lside = lscript_pop_int(buffer);
  1711. LLVector3 rside;
  1712. lscript_pop_vector(buffer, rside);
  1713. switch(opcode)
  1714. {
  1715. case LOPC_MUL:
  1716. rside *= (F32)lside;
  1717. lscript_push(buffer, rside);
  1718. break;
  1719. default:
  1720. break;
  1721. }
  1722. }
  1723. void float_integer_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
  1724. {
  1725. F32 lside = lscript_pop_float(buffer);
  1726. S32 rside = lscript_pop_int(buffer);
  1727. S32 resulti = 0;
  1728. F32 resultf = 0;
  1729. switch(opcode)
  1730. {
  1731. case LOPC_ADD:
  1732. resultf = lside + rside;
  1733. lscript_push(buffer, resultf);
  1734. break;
  1735. case LOPC_SUB:
  1736. resultf = lside - rside;
  1737. lscript_push(buffer, resultf);
  1738. break;
  1739. case LOPC_MUL:
  1740. resultf = lside * rside;
  1741. lscript_push(buffer, resultf);
  1742. break;
  1743. case LOPC_DIV:
  1744. if (rside)
  1745. resultf = lside / rside;
  1746. else
  1747. set_fault(buffer, LSRF_MATH);
  1748. lscript_push(buffer, resultf);
  1749. break;
  1750. case LOPC_EQ:
  1751. resulti = (lside == rside);
  1752. lscript_push(buffer, resulti);
  1753. break;
  1754. case LOPC_NEQ:
  1755. resulti = (lside != rside);
  1756. lscript_push(buffer, resulti);
  1757. break;
  1758. case LOPC_LEQ:
  1759. resulti = (lside <= rside);
  1760. lscript_push(buffer, resulti);
  1761. break;
  1762. case LOPC_GEQ:
  1763. resulti = (lside >= rside);
  1764. lscript_push(buffer, resulti);
  1765. break;
  1766. case LOPC_LESS:
  1767. resulti = (lside < rside);
  1768. lscript_push(buffer, resulti);
  1769. break;
  1770. case LOPC_GREATER:
  1771. resulti = (lside > rside);
  1772. lscript_push(buffer, resulti);
  1773. break;
  1774. default:
  1775. break;
  1776. }
  1777. }
  1778. void float_float_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
  1779. {
  1780. F32 lside = lscript_pop_float(buffer);
  1781. F32 rside = lscript_pop_float(buffer);
  1782. F32 resultf = 0;
  1783. S32 resulti = 0;
  1784. switch(opcode)
  1785. {
  1786. case LOPC_ADD:
  1787. resultf = lside + rside;
  1788. lscript_push(buffer, resultf);
  1789. break;
  1790. case LOPC_SUB:
  1791. resultf = lside - rside;
  1792. lscript_push(buffer, resultf);
  1793. break;
  1794. case LOPC_MUL:
  1795. resultf = lside * rside;
  1796. lscript_push(buffer, resultf);
  1797. break;
  1798. case LOPC_DIV:
  1799. if (rside)
  1800. resultf = lside / rside;
  1801. else
  1802. set_fault(buffer, LSRF_MATH);
  1803. lscript_push(buffer, resultf);
  1804. break;
  1805. case LOPC_EQ:
  1806. resulti = (lside == rside);
  1807. lscript_push(buffer, resulti);
  1808. break;
  1809. case LOPC_NEQ:
  1810. resulti = (lside != rside);
  1811. lscript_push(buffer, resulti);
  1812. break;
  1813. case LOPC_LEQ:
  1814. resulti = (lside <= rside);
  1815. lscript_push(buffer, resulti);
  1816. break;
  1817. case LOPC_GEQ:
  1818. resulti = (lside >= rside);
  1819. lscript_push(buffer, resulti);
  1820. break;
  1821. case LOPC_LESS:
  1822. resulti = (lside < rside);
  1823. lscript_push(buffer, resulti);
  1824. break;
  1825. case LOPC_GREATER:
  1826. resulti = (lside > rside);
  1827. lscript_push(buffer, resulti);
  1828. break;
  1829. default:
  1830. break;
  1831. }
  1832. }
  1833. void float_vector_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
  1834. {
  1835. F32 lside = lscript_pop_float(buffer);
  1836. LLVector3 rside;
  1837. lscript_pop_vector(buffer, rside);
  1838. switch(opcode)
  1839. {
  1840. case LOPC_MUL:
  1841. rside *= lside;
  1842. lscript_push(buffer, rside);
  1843. break;
  1844. default:
  1845. break;
  1846. }
  1847. }
  1848. void string_string_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
  1849. {
  1850. S32 lside = lscript_pop_int(buffer);
  1851. S32 rside = lscript_pop_int(buffer);
  1852. S32 resulti;
  1853. S32 address;
  1854. switch(opcode)
  1855. {
  1856. case LOPC_ADD:
  1857. address = lsa_cat_strings(buffer, lside, rside, get_max_heap_size(buffer));
  1858. lscript_push(buffer, address);
  1859. break;
  1860. case LOPC_EQ:
  1861. resulti = !lsa_cmp_strings(buffer, lside, rside);
  1862. lscript_push(buffer, resulti);
  1863. break;
  1864. case LOPC_NEQ:
  1865. resulti = lsa_cmp_strings(buffer, lside, rside);
  1866. lscript_push(buffer, resulti);
  1867. break;
  1868. default:
  1869. break;
  1870. }
  1871. }
  1872. void string_key_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
  1873. {
  1874. S32 lside = lscript_pop_int(buffer);
  1875. S32 rside = lscript_pop_int(buffer);
  1876. S32 resulti;
  1877. switch(opcode)
  1878. {
  1879. case LOPC_NEQ:
  1880. resulti = lsa_cmp_strings(buffer, lside, rside);
  1881. lscript_push(buffer, resulti);
  1882. break;
  1883. case LOPC_EQ:
  1884. resulti = !lsa_cmp_strings(buffer, lside, rside);
  1885. lscript_push(buffer, resulti);
  1886. break;
  1887. default:
  1888. break;
  1889. }
  1890. }
  1891. void key_string_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
  1892. {
  1893. S32 lside = lscript_pop_int(buffer);
  1894. S32 rside = lscript_pop_int(buffer);
  1895. S32 resulti;
  1896. switch(opcode)
  1897. {
  1898. case LOPC_NEQ:
  1899. resulti = lsa_cmp_strings(buffer, lside, rside);
  1900. lscript_push(buffer, resulti);
  1901. break;
  1902. case LOPC_EQ:
  1903. resulti = !lsa_cmp_strings(buffer, lside, rside);
  1904. lscript_push(buffer, resulti);
  1905. break;
  1906. default:
  1907. break;
  1908. }
  1909. }
  1910. void key_key_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
  1911. {
  1912. S32 lside = lscript_pop_int(buffer);
  1913. S32 rside = lscript_pop_int(buffer);
  1914. S32 resulti;
  1915. switch(opcode)
  1916. {
  1917. case LOPC_EQ:
  1918. resulti = !lsa_cmp_strings(buffer, lside, rside);
  1919. lscript_push(buffer, resulti);
  1920. break;
  1921. case LOPC_NEQ:
  1922. resulti = lsa_cmp_strings(buffer, lside, rside);
  1923. lscript_push(buffer, resulti);
  1924. break;
  1925. default:
  1926. break;
  1927. }
  1928. }
  1929. void vector_integer_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
  1930. {
  1931. LLVector3 lside;
  1932. lscript_pop_vector(buffer, lside);
  1933. S32 rside = lscript_pop_int(buffer);
  1934. switch(opcode)
  1935. {
  1936. case LOPC_MUL:
  1937. lside *= (F32)rside;
  1938. lscript_push(buffer, lside);
  1939. break;
  1940. case LOPC_DIV:
  1941. if (rside)
  1942. lside *= (1.f/rside);
  1943. else
  1944. set_fault(buffer, LSRF_MATH);
  1945. lscript_push(buffer, lside);
  1946. break;
  1947. default:
  1948. break;
  1949. }
  1950. }
  1951. void vector_float_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
  1952. {
  1953. LLVector3 lside;
  1954. lscript_pop_vector(buffer, lside);
  1955. F32 rside = lscript_pop_float(buffer);
  1956. switch(opcode)
  1957. {
  1958. case LOPC_MUL:
  1959. lside *= rside;
  1960. lscript_push(buffer, lside);
  1961. break;
  1962. case LOPC_DIV:
  1963. if (rside)
  1964. lside *= (1.f/rside);
  1965. else
  1966. set_fault(buffer, LSRF_MATH);
  1967. lscript_push(buffer, lside);
  1968. break;
  1969. default:
  1970. break;
  1971. }
  1972. }
  1973. void vector_vector_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
  1974. {
  1975. LLVector3 lside;
  1976. lscript_pop_vector(buffer, lside);
  1977. LLVector3 rside;
  1978. lscript_pop_vector(buffer, rside);
  1979. S32 resulti = 0;
  1980. F32 resultf = 0.f;
  1981. switch(opcode)
  1982. {
  1983. case LOPC_ADD:
  1984. lside += rside;
  1985. lscript_push(buffer, lside);
  1986. break;
  1987. case LOPC_SUB:
  1988. lside -= rside;
  1989. lscript_push(buffer, lside);
  1990. break;
  1991. case LOPC_MUL:
  1992. resultf = lside * rside;
  1993. lscript_push(buffer, resultf);
  1994. break;
  1995. case LOPC_MOD:
  1996. lside = lside % rside;
  1997. lscript_push(buffer, lside);
  1998. break;
  1999. case LOPC_EQ:
  2000. resulti = (lside == rside);
  2001. lscript_push(buffer, resulti);
  2002. break;
  2003. case LOPC_NEQ:
  2004. resulti = (lside != rside);
  2005. lscript_push(buffer, resulti);
  2006. break;
  2007. default:
  2008. break;
  2009. }
  2010. }
  2011. void vector_quaternion_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
  2012. {
  2013. LLVector3 lside;
  2014. lscript_pop_vector(buffer, lside);
  2015. LLQuaternion rside;
  2016. lscript_pop_quaternion(buffer, rside);
  2017. switch(opcode)
  2018. {
  2019. case LOPC_MUL:
  2020. lside = lside * rside;
  2021. lscript_push(buffer, lside);
  2022. break;
  2023. case LOPC_DIV:
  2024. lside = lside * rside.conjQuat();
  2025. lscript_push(buffer, lside);
  2026. break;
  2027. default:
  2028. break;
  2029. }
  2030. }
  2031. void quaternion_quaternion_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
  2032. {
  2033. LLQuaternion lside;
  2034. lscript_pop_quaternion(buffer, lside);
  2035. LLQuaternion rside;
  2036. lscript_pop_quaternion(buffer, rside);
  2037. S32 resulti = 0;
  2038. switch(opcode)
  2039. {
  2040. case LOPC_ADD:
  2041. lside = lside + rside;
  2042. lscript_push(buffer, lside);
  2043. break;
  2044. case LOPC_SUB:
  2045. lside = lside - rside;
  2046. lscript_push(buffer, lside);
  2047. break;
  2048. case LOPC_MUL:
  2049. lside *= rside;
  2050. lscript_push(buffer, lside);
  2051. break;
  2052. case LOPC_DIV:
  2053. lside = lside * rside.conjQuat();
  2054. lscript_push(buffer, lside);
  2055. break;
  2056. case LOPC_EQ:
  2057. resulti = (lside == rside);
  2058. lscript_push(buffer, resulti);
  2059. break;
  2060. case LOPC_NEQ:
  2061. resulti = (lside != rside);
  2062. lscript_push(buffer, resulti);
  2063. break;
  2064. default:
  2065. break;
  2066. }
  2067. }
  2068. void integer_list_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
  2069. {
  2070. S32 lside = lscript_pop_int(buffer);
  2071. S32 rside = lscript_pop_int(buffer);
  2072. S32 address;
  2073. switch(opcode)
  2074. {
  2075. case LOPC_ADD:
  2076. {
  2077. LLScriptLibData *list = new LLScriptLibData;
  2078. list->mType = LST_LIST;
  2079. list->mListp = new LLScriptLibData(lside);
  2080. address = lsa_preadd_lists(buffer, list, rside, get_max_heap_size(buffer));
  2081. lscript_push(buffer, address);
  2082. list->mListp = NULL;
  2083. delete list;
  2084. }
  2085. break;
  2086. default:
  2087. break;
  2088. }
  2089. }
  2090. void float_list_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
  2091. {
  2092. F32 lside = lscript_pop_float(buffer);
  2093. S32 rside = lscript_pop_int(buffer);
  2094. S32 address;
  2095. switch(opcode)
  2096. {
  2097. case LOPC_ADD:
  2098. {
  2099. LLScriptLibData *list = new LLScriptLibData;
  2100. list->mType = LST_LIST;
  2101. list->mListp = new LLScriptLibData(lside);
  2102. address = lsa_preadd_lists(buffer, list, rside, get_max_heap_size(buffer));
  2103. lscript_push(buffer, address);
  2104. list->mListp = NULL;
  2105. delete list;
  2106. }
  2107. break;
  2108. default:
  2109. break;
  2110. }
  2111. }
  2112. void string_list_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
  2113. {
  2114. S32 lside = lscript_pop_int(buffer);
  2115. S32 rside = lscript_pop_int(buffer);
  2116. S32 address;
  2117. switch(opcode)
  2118. {
  2119. case LOPC_ADD:
  2120. {
  2121. LLScriptLibData *string = lsa_get_data(buffer, lside, TRUE);
  2122. LLScriptLibData *list = new LLScriptLibData;
  2123. list->mType = LST_LIST;
  2124. list->mListp = string;
  2125. address = lsa_preadd_lists(buffer, list, rside, get_max_heap_size(buffer));
  2126. lscript_push(buffer, address);
  2127. list->mListp = NULL;
  2128. delete list;
  2129. }
  2130. break;
  2131. default:
  2132. break;
  2133. }
  2134. }
  2135. void key_list_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
  2136. {
  2137. S32 lside = lscript_pop_int(buffer);
  2138. S32 rside = lscript_pop_int(buffer);
  2139. S32 address;
  2140. switch(opcode)
  2141. {
  2142. case LOPC_ADD:
  2143. {
  2144. LLScriptLibData *key = lsa_get_data(buffer, lside, TRUE);
  2145. // need to convert key to key, since it comes out like a string
  2146. if (key->mType == LST_STRING)
  2147. {
  2148. key->mKey = key->mString;
  2149. key->mString = NULL;
  2150. key->mType = LST_KEY;
  2151. }
  2152. LLScriptLibData *list = new LLScriptLibData;
  2153. list->mType = LST_LIST;
  2154. list->mListp = key;
  2155. address = lsa_preadd_lists(buffer, list, rside, get_max_heap_size(buffer));
  2156. lscript_push(buffer, address);
  2157. list->mListp = NULL;
  2158. delete list;
  2159. }
  2160. break;
  2161. default:
  2162. break;
  2163. }
  2164. }
  2165. void vector_list_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
  2166. {
  2167. LLVector3 lside;
  2168. lscript_pop_vector(buffer, lside);
  2169. S32 rside = lscript_pop_int(buffer);
  2170. S32 address;
  2171. switch(opcode)
  2172. {
  2173. case LOPC_ADD:
  2174. {
  2175. LLScriptLibData *list = new LLScriptLibData;
  2176. list->mType = LST_LIST;
  2177. list->mListp = new LLScriptLibData(lside);
  2178. address = lsa_preadd_lists(buffer, list, rside, get_max_heap_size(buffer));
  2179. lscript_push(buffer, address);
  2180. list->mListp = NULL;
  2181. delete list;
  2182. }
  2183. break;
  2184. default:
  2185. break;
  2186. }
  2187. }
  2188. void quaternion_list_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
  2189. {
  2190. LLQuaternion lside;
  2191. lscript_pop_quaternion(buffer, lside);
  2192. S32 rside = lscript_pop_int(buffer);
  2193. S32 address;
  2194. switch(opcode)
  2195. {
  2196. case LOPC_ADD:
  2197. {
  2198. LLScriptLibData *list = new LLScriptLibData;
  2199. list->mType = LST_LIST;
  2200. list->mListp = new LLScriptLibData(lside);
  2201. address = lsa_preadd_lists(buffer, list, rside, get_max_heap_size(buffer));
  2202. lscript_push(buffer, address);
  2203. list->mListp = NULL;
  2204. delete list;
  2205. }
  2206. break;
  2207. default:
  2208. break;
  2209. }
  2210. }
  2211. void list_integer_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
  2212. {
  2213. S32 lside = lscript_pop_int(buffer);
  2214. S32 rside = lscript_pop_int(buffer);
  2215. S32 address;
  2216. switch(opcode)
  2217. {
  2218. case LOPC_ADD:
  2219. {
  2220. LLScriptLibData *list = new LLScriptLibData;
  2221. list->mType = LST_LIST;
  2222. list->mListp = new LLScriptLibData(rside);
  2223. address = lsa_postadd_lists(buffer, lside, list, get_max_heap_size(buffer));
  2224. list->mListp = NULL;
  2225. delete list;
  2226. lscript_push(buffer, address);
  2227. }
  2228. break;
  2229. default:
  2230. break;
  2231. }
  2232. }
  2233. void list_float_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
  2234. {
  2235. S32 lside = lscript_pop_int(buffer);
  2236. F32 rside = lscript_pop_float(buffer);
  2237. S32 address;
  2238. switch(opcode)
  2239. {
  2240. case LOPC_ADD:
  2241. {
  2242. LLScriptLibData *list = new LLScriptLibData;
  2243. list->mType = LST_LIST;
  2244. list->mListp = new LLScriptLibData(rside);
  2245. address = lsa_postadd_lists(buffer, lside, list, get_max_heap_size(buffer));
  2246. list->mListp = NULL;
  2247. delete list;
  2248. lscript_push(buffer, address);
  2249. }
  2250. break;
  2251. default:
  2252. break;
  2253. }
  2254. }
  2255. void list_string_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
  2256. {
  2257. S32 lside = lscript_pop_int(buffer);
  2258. S32 rside = lscript_pop_int(buffer);
  2259. S32 address;
  2260. switch(opcode)
  2261. {
  2262. case LOPC_ADD:
  2263. {
  2264. LLScriptLibData *string = lsa_get_data(buffer, rside, TRUE);
  2265. LLScriptLibData *list = new LLScriptLibData;
  2266. list->mType = LST_LIST;
  2267. list->mListp = string;
  2268. address = lsa_postadd_lists(buffer, lside, list, get_max_heap_size(buffer));
  2269. list->mListp = NULL;
  2270. delete list;
  2271. lscript_push(buffer, address);
  2272. }
  2273. break;
  2274. default:
  2275. break;
  2276. }
  2277. }
  2278. void list_key_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
  2279. {
  2280. S32 lside = lscript_pop_int(buffer);
  2281. S32 rside = lscript_pop_int(buffer);
  2282. S32 address;
  2283. switch(opcode)
  2284. {
  2285. case LOPC_ADD:
  2286. {
  2287. LLScriptLibData *key = lsa_get_data(buffer, rside, TRUE);
  2288. // need to convert key to key, since it comes out like a string
  2289. if (key->mType == LST_STRING)
  2290. {
  2291. key->mKey = key->mString;
  2292. key->mString = NULL;
  2293. key->mType = LST_KEY;
  2294. }
  2295. LLScriptLibData *list = new LLScriptLibData;
  2296. list->mType = LST_LIST;
  2297. list->mListp = key;
  2298. address = lsa_postadd_lists(buffer, lside, list, get_max_heap_size(buffer));
  2299. list->mListp = NULL;
  2300. delete list;
  2301. lscript_push(buffer, address);
  2302. }
  2303. break;
  2304. default:
  2305. break;
  2306. }
  2307. }
  2308. void list_vector_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
  2309. {
  2310. S32 lside = lscript_pop_int(buffer);
  2311. LLVector3 rside;
  2312. lscript_pop_vector(buffer, rside);
  2313. S32 address;
  2314. switch(opcode)
  2315. {
  2316. case LOPC_ADD:
  2317. {
  2318. LLScriptLibData *list = new LLScriptLibData;
  2319. list->mType = LST_LIST;
  2320. list->mListp = new LLScriptLibData(rside);
  2321. address = lsa_postadd_lists(buffer, lside, list, get_max_heap_size(buffer));
  2322. list->mListp = NULL;
  2323. delete list;
  2324. lscript_push(buffer, address);
  2325. }
  2326. break;
  2327. default:
  2328. break;
  2329. }
  2330. }
  2331. void list_quaternion_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
  2332. {
  2333. S32 lside = lscript_pop_int(buffer);
  2334. LLQuaternion rside;
  2335. lscript_pop_quaternion(buffer, rside);
  2336. S32 address;
  2337. switch(opcode)
  2338. {
  2339. case LOPC_ADD:
  2340. {
  2341. LLScriptLibData *list = new LLScriptLibData;
  2342. list->mType = LST_LIST;
  2343. list->mListp = new LLScriptLibData(rside);
  2344. address = lsa_postadd_lists(buffer, lside, list, get_max_heap_size(buffer));
  2345. list->mListp = NULL;
  2346. delete list;
  2347. lscript_push(buffer, address);
  2348. }
  2349. break;
  2350. default:
  2351. break;
  2352. }
  2353. }
  2354. void list_list_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
  2355. {
  2356. S32 lside = lscript_pop_int(buffer);
  2357. S32 rside = lscript_pop_int(buffer);
  2358. S32 resulti;
  2359. S32 address;
  2360. switch(opcode)
  2361. {
  2362. case LOPC_ADD:
  2363. address = lsa_cat_lists(buffer, lside, rside, get_max_heap_size(buffer));
  2364. lscript_push(buffer, address);
  2365. break;
  2366. case LOPC_EQ:
  2367. resulti = !lsa_cmp_lists(buffer, lside, rside);
  2368. lscript_push(buffer, resulti);
  2369. break;
  2370. case LOPC_NEQ:
  2371. resulti = lsa_cmp_lists(buffer, lside, rside);
  2372. lscript_push(buffer, resulti);
  2373. break;
  2374. default:
  2375. break;
  2376. }
  2377. }
  2378. static U8 safe_op_index(U8 index)
  2379. {
  2380. if(index >= LST_EOF)
  2381. {
  2382. // Operations on LST_NULL will always be unknown_operation.
  2383. index = LST_NULL;
  2384. }
  2385. return index;
  2386. }
  2387. BOOL run_add(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  2388. {
  2389. if (b_print)
  2390. printf("[0x%X]tADD ", offset);
  2391. offset++;
  2392. U8 arg = safe_instruction_bytestream2byte(buffer, offset);
  2393. U8 arg1 = safe_op_index(arg >> 4);
  2394. U8 arg2 = safe_op_index(arg & 0xf);
  2395. if (b_print)
  2396. {
  2397. print_type(arg1);
  2398. printf(", ");
  2399. print_type(arg2);
  2400. printf("n");
  2401. }
  2402. binary_operations[arg1][arg2](buffer, LOPC_ADD);
  2403. return FALSE;
  2404. }
  2405. BOOL run_sub(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  2406. {
  2407. if (b_print)
  2408. printf("[0x%X]tSUB ", offset);
  2409. offset++;
  2410. U8 arg = safe_instruction_bytestream2byte(buffer, offset);
  2411. U8 arg1 = safe_op_index(arg >> 4);
  2412. U8 arg2 = safe_op_index(arg & 0xf);
  2413. if (b_print)
  2414. {
  2415. print_type(arg1);
  2416. printf(", ");
  2417. print_type(arg2);
  2418. printf("n");
  2419. }
  2420. binary_operations[arg1][arg2](buffer, LOPC_SUB);
  2421. return FALSE;
  2422. }
  2423. BOOL run_mul(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  2424. {
  2425. if (b_print)
  2426. printf("[0x%X]tMUL ", offset);
  2427. offset++;
  2428. U8 arg = safe_instruction_bytestream2byte(buffer, offset);
  2429. U8 arg1 = safe_op_index(arg >> 4);
  2430. U8 arg2 = safe_op_index(arg & 0xf);
  2431. if (b_print)
  2432. {
  2433. print_type(arg1);
  2434. printf(", ");
  2435. print_type(arg2);
  2436. printf("n");
  2437. }
  2438. binary_operations[arg1][arg2](buffer, LOPC_MUL);
  2439. return FALSE;
  2440. }
  2441. BOOL run_div(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  2442. {
  2443. if (b_print)
  2444. printf("[0x%X]tDIV ", offset);
  2445. offset++;
  2446. U8 arg = safe_instruction_bytestream2byte(buffer, offset);
  2447. U8 arg1 = safe_op_index(arg >> 4);
  2448. U8 arg2 = safe_op_index(arg & 0xf);
  2449. if (b_print)
  2450. {
  2451. print_type(arg1);
  2452. printf(", ");
  2453. print_type(arg2);
  2454. printf("n");
  2455. }
  2456. binary_operations[arg1][arg2](buffer, LOPC_DIV);
  2457. return FALSE;
  2458. }
  2459. BOOL run_mod(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  2460. {
  2461. if (b_print)
  2462. printf("[0x%X]tMOD ", offset);
  2463. offset++;
  2464. U8 arg = safe_instruction_bytestream2byte(buffer, offset);
  2465. U8 arg1 = safe_op_index(arg >> 4);
  2466. U8 arg2 = safe_op_index(arg & 0xf);
  2467. if (b_print)
  2468. {
  2469. print_type(arg1);
  2470. printf(", ");
  2471. print_type(arg2);
  2472. printf("n");
  2473. }
  2474. binary_operations[arg1][arg2](buffer, LOPC_MOD);
  2475. return FALSE;
  2476. }
  2477. BOOL run_eq(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  2478. {
  2479. if (b_print)
  2480. printf("[0x%X]tEQ ", offset);
  2481. offset++;
  2482. U8 arg = safe_instruction_bytestream2byte(buffer, offset);
  2483. U8 arg1 = safe_op_index(arg >> 4);
  2484. U8 arg2 = safe_op_index(arg & 0xf);
  2485. if (b_print)
  2486. {
  2487. print_type(arg1);
  2488. printf(", ");
  2489. print_type(arg2);
  2490. printf("n");
  2491. }
  2492. binary_operations[arg1][arg2](buffer, LOPC_EQ);
  2493. return FALSE;
  2494. }
  2495. BOOL run_neq(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  2496. {
  2497. if (b_print)
  2498. printf("[0x%X]tNEQ ", offset);
  2499. offset++;
  2500. U8 arg = safe_instruction_bytestream2byte(buffer, offset);
  2501. U8 arg1 = safe_op_index(arg >> 4);
  2502. U8 arg2 = safe_op_index(arg & 0xf);
  2503. if (b_print)
  2504. {
  2505. print_type(arg1);
  2506. printf(", ");
  2507. print_type(arg2);
  2508. printf("n");
  2509. }
  2510. binary_operations[arg1][arg2](buffer, LOPC_NEQ);
  2511. return FALSE;
  2512. }
  2513. BOOL run_leq(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  2514. {
  2515. if (b_print)
  2516. printf("[0x%X]tLEQ ", offset);
  2517. offset++;
  2518. U8 arg = safe_instruction_bytestream2byte(buffer, offset);
  2519. U8 arg1 = safe_op_index(arg >> 4);
  2520. U8 arg2 = safe_op_index(arg & 0xf);
  2521. if (b_print)
  2522. {
  2523. print_type(arg1);
  2524. printf(", ");
  2525. print_type(arg2);
  2526. printf("n");
  2527. }
  2528. binary_operations[arg1][arg2](buffer, LOPC_LEQ);
  2529. return FALSE;
  2530. }
  2531. BOOL run_geq(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  2532. {
  2533. if (b_print)
  2534. printf("[0x%X]tGEQ ", offset);
  2535. offset++;
  2536. U8 arg = safe_instruction_bytestream2byte(buffer, offset);
  2537. U8 arg1 = safe_op_index(arg >> 4);
  2538. U8 arg2 = safe_op_index(arg & 0xf);
  2539. if (b_print)
  2540. {
  2541. print_type(arg1);
  2542. printf(", ");
  2543. print_type(arg2);
  2544. printf("n");
  2545. }
  2546. binary_operations[arg1][arg2](buffer, LOPC_GEQ);
  2547. return FALSE;
  2548. }
  2549. BOOL run_less(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  2550. {
  2551. if (b_print)
  2552. printf("[0x%X]tLESS ", offset);
  2553. offset++;
  2554. U8 arg = safe_instruction_bytestream2byte(buffer, offset);
  2555. U8 arg1 = safe_op_index(arg >> 4);
  2556. U8 arg2 = safe_op_index(arg & 0xf);
  2557. if (b_print)
  2558. {
  2559. print_type(arg1);
  2560. printf(", ");
  2561. print_type(arg2);
  2562. printf("n");
  2563. }
  2564. binary_operations[arg1][arg2](buffer, LOPC_LESS);
  2565. return FALSE;
  2566. }
  2567. BOOL run_greater(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  2568. {
  2569. if (b_print)
  2570. printf("[0x%X]tGREATER ", offset);
  2571. offset++;
  2572. U8 arg = safe_instruction_bytestream2byte(buffer, offset);
  2573. U8 arg1 = safe_op_index(arg >> 4);
  2574. U8 arg2 = safe_op_index(arg & 0xf);
  2575. if (b_print)
  2576. {
  2577. print_type(arg1);
  2578. printf(", ");
  2579. print_type(arg2);
  2580. printf("n");
  2581. }
  2582. binary_operations[arg1][arg2](buffer, LOPC_GREATER);
  2583. return FALSE;
  2584. }
  2585. BOOL run_bitand(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  2586. {
  2587. if (b_print)
  2588. printf("[0x%X]tBITANDn", offset);
  2589. offset++;
  2590. binary_operations[LST_INTEGER][LST_INTEGER](buffer, LOPC_BITAND);
  2591. return FALSE;
  2592. }
  2593. BOOL run_bitor(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  2594. {
  2595. if (b_print)
  2596. printf("[0x%X]tBITORn", offset);
  2597. offset++;
  2598. binary_operations[LST_INTEGER][LST_INTEGER](buffer, LOPC_BITOR);
  2599. return FALSE;
  2600. }
  2601. BOOL run_bitxor(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  2602. {
  2603. if (b_print)
  2604. printf("[0x%X]tBITXORn", offset);
  2605. offset++;
  2606. binary_operations[LST_INTEGER][LST_INTEGER](buffer, LOPC_BITXOR);
  2607. return FALSE;
  2608. }
  2609. BOOL run_booland(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  2610. {
  2611. if (b_print)
  2612. printf("[0x%X]tBOOLANDn", offset);
  2613. offset++;
  2614. binary_operations[LST_INTEGER][LST_INTEGER](buffer, LOPC_BOOLAND);
  2615. return FALSE;
  2616. }
  2617. BOOL run_boolor(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  2618. {
  2619. if (b_print)
  2620. printf("[0x%X]tBOOLORn", offset);
  2621. offset++;
  2622. binary_operations[LST_INTEGER][LST_INTEGER](buffer, LOPC_BOOLOR);
  2623. return FALSE;
  2624. }
  2625. BOOL run_shl(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  2626. {
  2627. if (b_print)
  2628. printf("[0x%X]tSHLn", offset);
  2629. offset++;
  2630. binary_operations[LST_INTEGER][LST_INTEGER](buffer, LOPC_SHL);
  2631. return FALSE;
  2632. }
  2633. BOOL run_shr(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  2634. {
  2635. if (b_print)
  2636. printf("[0x%X]tSHRn", offset);
  2637. offset++;
  2638. binary_operations[LST_INTEGER][LST_INTEGER](buffer, LOPC_SHR);
  2639. return FALSE;
  2640. }
  2641. void integer_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
  2642. {
  2643. S32 lside = lscript_pop_int(buffer);
  2644. S32 result = 0;
  2645. switch(opcode)
  2646. {
  2647. case LOPC_NEG:
  2648. result = -lside;
  2649. break;
  2650. case LOPC_BITNOT:
  2651. result = ~lside;
  2652. break;
  2653. case LOPC_BOOLNOT:
  2654. result = !lside;
  2655. break;
  2656. default:
  2657. break;
  2658. }
  2659. lscript_push(buffer, result);
  2660. }
  2661. void float_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
  2662. {
  2663. F32 lside = lscript_pop_float(buffer);
  2664. F32 result = 0;
  2665. switch(opcode)
  2666. {
  2667. case LOPC_NEG:
  2668. result = -lside;
  2669. lscript_push(buffer, result);
  2670. break;
  2671. default:
  2672. break;
  2673. }
  2674. }
  2675. void vector_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
  2676. {
  2677. LLVector3 lside;
  2678. lscript_pop_vector(buffer, lside);
  2679. LLVector3 result;
  2680. switch(opcode)
  2681. {
  2682. case LOPC_NEG:
  2683. result = -lside;
  2684. lscript_push(buffer, result);
  2685. break;
  2686. default:
  2687. break;
  2688. }
  2689. }
  2690. void quaternion_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
  2691. {
  2692. LLQuaternion lside;
  2693. lscript_pop_quaternion(buffer, lside);
  2694. LLQuaternion result;
  2695. switch(opcode)
  2696. {
  2697. case LOPC_NEG:
  2698. result = -lside;
  2699. lscript_push(buffer, result);
  2700. break;
  2701. default:
  2702. break;
  2703. }
  2704. }
  2705. BOOL run_neg(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  2706. {
  2707. if (b_print)
  2708. printf("[0x%X]tNEG ", offset);
  2709. offset++;
  2710. U8 arg = safe_op_index(safe_instruction_bytestream2byte(buffer, offset));
  2711. if (b_print)
  2712. {
  2713. print_type(arg);
  2714. printf("n");
  2715. }
  2716. unary_operations[arg](buffer, LOPC_NEG);
  2717. return FALSE;
  2718. }
  2719. BOOL run_bitnot(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  2720. {
  2721. if (b_print)
  2722. printf("[0x%X]tBITNOTn", offset);
  2723. offset++;
  2724. unary_operations[LST_INTEGER](buffer, LOPC_BITNOT);
  2725. return FALSE;
  2726. }
  2727. BOOL run_boolnot(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  2728. {
  2729. if (b_print)
  2730. printf("[0x%X]tBOOLNOTn", offset);
  2731. offset++;
  2732. unary_operations[LST_INTEGER](buffer, LOPC_BOOLNOT);
  2733. return FALSE;
  2734. }
  2735. BOOL run_jump(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  2736. {
  2737. if (b_print)
  2738. printf("[0x%X]tJUMP ", offset);
  2739. offset++;
  2740. S32 arg = safe_instruction_bytestream2integer(buffer, offset);
  2741. if (b_print)
  2742. printf("%dn", arg);
  2743. offset += arg;
  2744. return FALSE;
  2745. }
  2746. BOOL run_jumpif(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  2747. {
  2748. if (b_print)
  2749. printf("[0x%X]tJUMPIF ", offset);
  2750. offset++;
  2751. U8 type = safe_instruction_bytestream2byte(buffer, offset);
  2752. if (b_print)
  2753. {
  2754. print_type(type);
  2755. printf(", ");
  2756. }
  2757. S32 arg = safe_instruction_bytestream2integer(buffer, offset);
  2758. if (b_print)
  2759. printf("%dn", arg);
  2760. if (type == LST_INTEGER)
  2761. {
  2762. S32 test = lscript_pop_int(buffer);
  2763. if (test)
  2764. {
  2765. offset += arg;
  2766. }
  2767. }
  2768. else if (type == LST_FLOATINGPOINT)
  2769. {
  2770. F32 test = lscript_pop_float(buffer);
  2771. if (test)
  2772. {
  2773. offset += arg;
  2774. }
  2775. }
  2776. else if (type == LST_VECTOR)
  2777. {
  2778. LLVector3 test;
  2779. lscript_pop_vector(buffer, test);
  2780. if (!test.isExactlyZero())
  2781. {
  2782. offset += arg;
  2783. }
  2784. }
  2785. else if (type == LST_QUATERNION)
  2786. {
  2787. LLQuaternion test;
  2788. lscript_pop_quaternion(buffer, test);
  2789. if (!test.isIdentity())
  2790. {
  2791. offset += arg;
  2792. }
  2793. }
  2794. else if (type == LST_STRING)
  2795. {
  2796. S32 base_address = lscript_pop_int(buffer);
  2797. // this bit of nastiness is to get around that code paths to
  2798. // local variables can result in lack of initialization and
  2799. // function clean up of ref counts isn't based on scope (a
  2800. // mistake, I know)
  2801. S32 address = base_address + get_register(buffer, LREG_HR) - 1;
  2802. if (address)
  2803. {
  2804. S32 string = address;
  2805. string += SIZEOF_SCRIPT_ALLOC_ENTRY;
  2806. if (safe_heap_check_address(buffer, string, 1))
  2807. {
  2808. S32 toffset = string;
  2809. safe_heap_bytestream_count_char(buffer, toffset);
  2810. S32 size = toffset - string;
  2811. char *sdata = new char[size];
  2812. bytestream2char(sdata, buffer, string, size);
  2813. if (strlen(sdata)) /*Flawfinder: ignore*/
  2814. {
  2815. offset += arg;
  2816. }
  2817. delete [] sdata;
  2818. }
  2819. lsa_decrease_ref_count(buffer, base_address);
  2820. }
  2821. }
  2822. else if (type == LST_KEY)
  2823. {
  2824. S32 base_address = lscript_pop_int(buffer);
  2825. // this bit of nastiness is to get around that code paths to
  2826. // local variables can result in lack of initialization and
  2827. // function clean up of ref counts isn't based on scope (a
  2828. // mistake, I know)
  2829. S32 address = base_address + get_register(buffer, LREG_HR) - 1;
  2830. if (address)
  2831. {
  2832. S32 string = address;
  2833. string += SIZEOF_SCRIPT_ALLOC_ENTRY;
  2834. if (safe_heap_check_address(buffer, string, 1))
  2835. {
  2836. S32 toffset = string;
  2837. safe_heap_bytestream_count_char(buffer, toffset);
  2838. S32 size = toffset - string;
  2839. char *sdata = new char[size];
  2840. bytestream2char(sdata, buffer, string, size);
  2841. if (strlen(sdata)) /*Flawfinder: ignore*/
  2842. {
  2843. LLUUID id;
  2844. if (id.set(sdata) && id.notNull())
  2845. offset += arg;
  2846. }
  2847. delete [] sdata;
  2848. }
  2849. lsa_decrease_ref_count(buffer, base_address);
  2850. }
  2851. }
  2852. else if (type == LST_LIST)
  2853. {
  2854. S32 base_address = lscript_pop_int(buffer);
  2855. S32 address = base_address + get_register(buffer, LREG_HR) - 1;
  2856. if (address)
  2857. {
  2858. if (safe_heap_check_address(buffer, address + SIZEOF_SCRIPT_ALLOC_ENTRY, 1))
  2859. {
  2860. LLScriptLibData *list = lsa_get_list_ptr(buffer, base_address, TRUE);
  2861. if (list && list->getListLength())
  2862. {
  2863. offset += arg;
  2864. }
  2865. delete list;
  2866. }
  2867. }
  2868. }
  2869. return FALSE;
  2870. }
  2871. BOOL run_jumpnif(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  2872. {
  2873. if (b_print)
  2874. printf("[0x%X]tJUMPNIF ", offset);
  2875. offset++;
  2876. U8 type = safe_instruction_bytestream2byte(buffer, offset);
  2877. if (b_print)
  2878. {
  2879. print_type(type);
  2880. printf(", ");
  2881. }
  2882. S32 arg = safe_instruction_bytestream2integer(buffer, offset);
  2883. if (b_print)
  2884. printf("%dn", arg);
  2885. if (type == LST_INTEGER)
  2886. {
  2887. S32 test = lscript_pop_int(buffer);
  2888. if (!test)
  2889. {
  2890. offset += arg;
  2891. }
  2892. }
  2893. else if (type == LST_FLOATINGPOINT)
  2894. {
  2895. F32 test = lscript_pop_float(buffer);
  2896. if (!test)
  2897. {
  2898. offset += arg;
  2899. }
  2900. }
  2901. else if (type == LST_VECTOR)
  2902. {
  2903. LLVector3 test;
  2904. lscript_pop_vector(buffer, test);
  2905. if (test.isExactlyZero())
  2906. {
  2907. offset += arg;
  2908. }
  2909. }
  2910. else if (type == LST_QUATERNION)
  2911. {
  2912. LLQuaternion test;
  2913. lscript_pop_quaternion(buffer, test);
  2914. if (test.isIdentity())
  2915. {
  2916. offset += arg;
  2917. }
  2918. }
  2919. else if (type == LST_STRING)
  2920. {
  2921. S32 base_address = lscript_pop_int(buffer);
  2922. // this bit of nastiness is to get around that code paths to
  2923. // local variables can result in lack of initialization and
  2924. // function clean up of ref counts isn't based on scope (a
  2925. // mistake, I know)
  2926. S32 address = base_address + get_register(buffer, LREG_HR) - 1;
  2927. if (address)
  2928. {
  2929. S32 string = address;
  2930. string += SIZEOF_SCRIPT_ALLOC_ENTRY;
  2931. if (safe_heap_check_address(buffer, string, 1))
  2932. {
  2933. S32 toffset = string;
  2934. safe_heap_bytestream_count_char(buffer, toffset);
  2935. S32 size = toffset - string;
  2936. char *sdata = new char[size];
  2937. bytestream2char(sdata, buffer, string, size);
  2938. if (!strlen(sdata)) /*Flawfinder: ignore*/
  2939. {
  2940. offset += arg;
  2941. }
  2942. delete [] sdata;
  2943. }
  2944. lsa_decrease_ref_count(buffer, base_address);
  2945. }
  2946. }
  2947. else if (type == LST_KEY)
  2948. {
  2949. S32 base_address = lscript_pop_int(buffer);
  2950. // this bit of nastiness is to get around that code paths to
  2951. // local variables can result in lack of initialization and
  2952. // function clean up of ref counts isn't based on scope (a
  2953. // mistake, I know)
  2954. S32 address = base_address + get_register(buffer, LREG_HR) - 1;
  2955. if (address)
  2956. {
  2957. S32 string = address;
  2958. string += SIZEOF_SCRIPT_ALLOC_ENTRY;
  2959. if (safe_heap_check_address(buffer, string, 1))
  2960. {
  2961. S32 toffset = string;
  2962. safe_heap_bytestream_count_char(buffer, toffset);
  2963. S32 size = toffset - string;
  2964. char *sdata = new char[size];
  2965. bytestream2char(sdata, buffer, string, size);
  2966. if (strlen(sdata)) /*Flawfinder: ignore*/
  2967. {
  2968. LLUUID id;
  2969. if (!id.set(sdata) || id.isNull())
  2970. offset += arg;
  2971. }
  2972. else
  2973. {
  2974. offset += arg;
  2975. }
  2976. delete [] sdata;
  2977. }
  2978. lsa_decrease_ref_count(buffer, base_address);
  2979. }
  2980. }
  2981. else if (type == LST_LIST)
  2982. {
  2983. S32 base_address = lscript_pop_int(buffer);
  2984. // this bit of nastiness is to get around that code paths to
  2985. // local variables can result in lack of initialization and
  2986. // function clean up of ref counts isn't based on scope (a
  2987. // mistake, I know)
  2988. S32 address = base_address + get_register(buffer, LREG_HR) - 1;
  2989. if (address)
  2990. {
  2991. if (safe_heap_check_address(buffer, address + SIZEOF_SCRIPT_ALLOC_ENTRY, 1))
  2992. {
  2993. LLScriptLibData *list = lsa_get_list_ptr(buffer, base_address, TRUE);
  2994. if (!list || !list->getListLength())
  2995. {
  2996. offset += arg;
  2997. }
  2998. delete list;
  2999. }
  3000. }
  3001. }
  3002. return FALSE;
  3003. }
  3004. BOOL run_state(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  3005. {
  3006. if (b_print)
  3007. printf("[0x%X]tSTATE ", offset);
  3008. offset++;
  3009. S32 state = safe_instruction_bytestream2integer(buffer, offset);
  3010. if (b_print)
  3011. printf("%dn", state);
  3012. S32 bp = lscript_pop_int(buffer);
  3013. set_bp(buffer, bp);
  3014. offset = lscript_pop_int(buffer);
  3015. S32 major_version = 0;
  3016. S32 value = get_register(buffer, LREG_VN);
  3017. if (value == LSL2_VERSION1_END_NUMBER)
  3018. {
  3019. major_version = 1;
  3020. }
  3021. else if (value == LSL2_VERSION_NUMBER)
  3022. {
  3023. major_version = 2;
  3024. }
  3025. S32 current_state = get_register(buffer, LREG_CS);
  3026. if (state != current_state)
  3027. {
  3028. U64 ce = get_event_register(buffer, LREG_CE, major_version);
  3029. ce |= LSCRIPTStateBitField[LSTT_STATE_EXIT];
  3030. set_event_register(buffer, LREG_CE, ce, major_version);
  3031. }
  3032. set_register(buffer, LREG_NS, state);
  3033. return FALSE;
  3034. }
  3035. BOOL run_call(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  3036. {
  3037. if (b_print)
  3038. printf("[0x%X]tCALL ", offset);
  3039. offset++;
  3040. S32 func = safe_instruction_bytestream2integer(buffer, offset);
  3041. if (b_print)
  3042. printf("%dn", func);
  3043. lscript_local_store(buffer, -8, offset);
  3044. S32 minimum = get_register(buffer, LREG_GFR);
  3045. S32 maximum = get_register(buffer, LREG_SR);
  3046. S32 lookup = minimum + func*4 + 4;
  3047. S32 function;
  3048. if (  (lookup >= minimum)
  3049. &&(lookup < maximum))
  3050. {
  3051. function = bytestream2integer(buffer, lookup) + minimum;
  3052. if (  (lookup >= minimum)
  3053. &&(lookup < maximum))
  3054. {
  3055. offset = function;
  3056. offset += bytestream2integer(buffer, function);
  3057. }
  3058. else
  3059. {
  3060. set_fault(buffer, LSRF_BOUND_CHECK_ERROR);
  3061. }
  3062. }
  3063. else
  3064. {
  3065. set_fault(buffer, LSRF_BOUND_CHECK_ERROR);
  3066. }
  3067. return FALSE;
  3068. }
  3069. BOOL run_return(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  3070. {
  3071. if (b_print)
  3072. printf("[0x%X]tRETURNn", offset);
  3073. offset++;
  3074. // SEC-53: babbage: broken instructions may allow inbalanced pushes and
  3075. // pops which can cause caller BP and return IP to be corrupted, so restore
  3076. // SP from BP before popping caller BP and IP.
  3077. S32 bp = get_register(buffer, LREG_BP);
  3078. set_sp(buffer, bp);
  3079. bp = lscript_pop_int(buffer);
  3080. set_bp(buffer, bp);
  3081. offset = lscript_pop_int(buffer);
  3082. return FALSE;
  3083. }
  3084. BOOL run_cast(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  3085. {
  3086. char caststr[1024]; /*Flawfinder: ignore*/
  3087. if (b_print)
  3088. printf("[0x%X]tCAST ", offset);
  3089. offset++;
  3090. U8 arg = safe_instruction_bytestream2byte(buffer, offset);
  3091. U8 from = arg >> 4;
  3092. U8 to = arg & 0xf;
  3093. if (b_print)
  3094. {
  3095. print_type(from);
  3096. printf(", ");
  3097. print_type(to);
  3098. printf("n");
  3099. }
  3100. switch(from)
  3101. {
  3102. case LST_INTEGER:
  3103. {
  3104. switch(to)
  3105. {
  3106. case LST_INTEGER:
  3107. break;
  3108. case LST_FLOATINGPOINT:
  3109. {
  3110. S32 source = lscript_pop_int(buffer);
  3111. F32 dest = (F32)source;
  3112. lscript_push(buffer, dest);
  3113. }
  3114. break;
  3115. case LST_STRING:
  3116. {
  3117. S32 address, source = lscript_pop_int(buffer);
  3118. snprintf(caststr, sizeof(caststr), "%d", source); /* Flawfinder: ignore */
  3119. address = lsa_heap_add_data(buffer, new LLScriptLibData(caststr), get_max_heap_size(buffer), TRUE);
  3120. lscript_push(buffer, address);
  3121. }
  3122. break;
  3123. case LST_LIST:
  3124. {
  3125. S32 address, source = lscript_pop_int(buffer);
  3126. LLScriptLibData *list = new LLScriptLibData;
  3127. list->mType = LST_LIST;
  3128. list->mListp = new LLScriptLibData(source);
  3129. address = lsa_heap_add_data(buffer, list, get_max_heap_size(buffer), TRUE);
  3130. lscript_push(buffer, address);
  3131. }
  3132. break;
  3133. default:
  3134. break;
  3135. }
  3136. }
  3137. break;
  3138. case LST_FLOATINGPOINT:
  3139. {
  3140. switch(to)
  3141. {
  3142. case LST_INTEGER:
  3143. {
  3144. F32 source = lscript_pop_float(buffer);
  3145. S32 dest = (S32)source;
  3146. lscript_push(buffer, dest);
  3147. }
  3148. break;
  3149. case LST_FLOATINGPOINT:
  3150. break;
  3151. case LST_STRING:
  3152. {
  3153. S32 address;
  3154. F32 source = lscript_pop_float(buffer);
  3155. snprintf(caststr, sizeof(caststr), "%f", source); /* Flawfinder: ignore */
  3156. address = lsa_heap_add_data(buffer, new LLScriptLibData(caststr), get_max_heap_size(buffer), TRUE);
  3157. lscript_push(buffer, address);
  3158. }
  3159. break;
  3160. case LST_LIST:
  3161. {
  3162. S32 address;
  3163. F32 source = lscript_pop_float(buffer);
  3164. LLScriptLibData *list = new LLScriptLibData;
  3165. list->mType = LST_LIST;
  3166. list->mListp = new LLScriptLibData(source);
  3167. address = lsa_heap_add_data(buffer, list, get_max_heap_size(buffer), TRUE);
  3168. lscript_push(buffer, address);
  3169. }
  3170. break;
  3171. default:
  3172. break;
  3173. }
  3174. }
  3175. break;
  3176. case LST_STRING:
  3177. {
  3178. switch(to)
  3179. {
  3180. case LST_INTEGER:
  3181. {
  3182. S32 base_address = lscript_pop_int(buffer);
  3183. // this bit of nastiness is to get around that code paths to local variables can result in lack of initialization
  3184. // and function clean up of ref counts isn't based on scope (a mistake, I know)
  3185. S32 address = base_address + get_register(buffer, LREG_HR) - 1;
  3186. if (address)
  3187. {
  3188. S32 string = address;
  3189. string += SIZEOF_SCRIPT_ALLOC_ENTRY;
  3190. if (safe_heap_check_address(buffer, string, 1))
  3191. {
  3192. S32 toffset = string;
  3193. safe_heap_bytestream_count_char(buffer, toffset);
  3194. S32 size = toffset - string;
  3195. char *arg = new char[size];
  3196. bytestream2char(arg, buffer, string, size);
  3197. // S32 length = strlen(arg);
  3198. S32 dest;
  3199. S32 base;
  3200. // Check to see if this is a hexidecimal number.
  3201. if (  (arg[0] == '0') &&
  3202.   (arg[1] == 'x' || arg[1] == 'X') )
  3203. {
  3204. // Let strtoul do a hex conversion.
  3205. base = 16;
  3206. }
  3207. else
  3208. {
  3209. // Force base-10, so octal is never used.
  3210. base = 10;
  3211. }
  3212. dest = strtoul(arg, NULL, base);
  3213. lscript_push(buffer, dest);
  3214. delete [] arg;
  3215. }
  3216. lsa_decrease_ref_count(buffer, base_address);
  3217. }
  3218. }
  3219. break;
  3220. case LST_FLOATINGPOINT:
  3221. {
  3222. S32 base_address = lscript_pop_int(buffer);
  3223. // this bit of nastiness is to get around that code paths to local variables can result in lack of initialization
  3224. // and function clean up of ref counts isn't based on scope (a mistake, I know)
  3225. S32 address = base_address + get_register(buffer, LREG_HR) - 1;
  3226. if (address)
  3227. {
  3228. S32 string = address;
  3229. string += SIZEOF_SCRIPT_ALLOC_ENTRY;
  3230. if (safe_heap_check_address(buffer, string, 1))
  3231. {
  3232. S32 toffset = string;
  3233. safe_heap_bytestream_count_char(buffer, toffset);
  3234. S32 size = toffset - string;
  3235. char *arg = new char[size];
  3236. bytestream2char(arg, buffer, string, size);
  3237. F32 dest = (F32)atof(arg);
  3238. lscript_push(buffer, dest);
  3239. delete [] arg;
  3240. }
  3241. lsa_decrease_ref_count(buffer, base_address);
  3242. }
  3243. }
  3244. break;
  3245. case LST_STRING:
  3246. break;
  3247. case LST_LIST:
  3248. {
  3249. S32 saddress = lscript_pop_int(buffer);
  3250. LLScriptLibData *string = lsa_get_data(buffer, saddress, TRUE);
  3251. LLScriptLibData *list = new LLScriptLibData;
  3252. list->mType = LST_LIST;
  3253. list->mListp = string;
  3254. S32 address = lsa_heap_add_data(buffer, list, get_max_heap_size(buffer), TRUE);
  3255. lscript_push(buffer, address);
  3256. }
  3257. break;
  3258. case LST_VECTOR:
  3259. {
  3260. S32 base_address = lscript_pop_int(buffer);
  3261. // this bit of nastiness is to get around that code paths to local variables can result in lack of initialization
  3262. // and function clean up of ref counts isn't based on scope (a mistake, I know)
  3263. S32 address = base_address + get_register(buffer, LREG_HR) - 1;
  3264. if (address)
  3265. {
  3266. S32 string = address;
  3267. string += SIZEOF_SCRIPT_ALLOC_ENTRY;
  3268. if (safe_heap_check_address(buffer, string, 1))
  3269. {
  3270. S32 toffset = string;
  3271. safe_heap_bytestream_count_char(buffer, toffset);
  3272. S32 size = toffset - string;
  3273. char *arg = new char[size];
  3274. bytestream2char(arg, buffer, string, size);
  3275. LLVector3 vec;
  3276. S32 num = sscanf(arg, "<%f, %f, %f>", &vec.mV[VX], &vec.mV[VY], &vec.mV[VZ]);
  3277. if (num != 3)
  3278. {
  3279. vec = LLVector3::zero;
  3280. }
  3281. lscript_push(buffer, vec);
  3282. delete [] arg;
  3283. }
  3284. lsa_decrease_ref_count(buffer, base_address);
  3285. }
  3286. }
  3287. break;
  3288. case LST_QUATERNION:
  3289. {
  3290. S32 base_address = lscript_pop_int(buffer);
  3291. // this bit of nastiness is to get around that code paths to local variables can result in lack of initialization
  3292. // and function clean up of ref counts isn't based on scope (a mistake, I know)
  3293. S32 address = base_address + get_register(buffer, LREG_HR) - 1;
  3294. if (address)
  3295. {
  3296. S32 string = address;
  3297. string += SIZEOF_SCRIPT_ALLOC_ENTRY;
  3298. if (safe_heap_check_address(buffer, string, 1))
  3299. {
  3300. S32 toffset = string;
  3301. safe_heap_bytestream_count_char(buffer, toffset);
  3302. S32 size = toffset - string;
  3303. char *arg = new char[size];
  3304. bytestream2char(arg, buffer, string, size);
  3305. LLQuaternion quat;
  3306. S32 num = sscanf(arg, "<%f, %f, %f, %f>", &quat.mQ[VX], &quat.mQ[VY], &quat.mQ[VZ], &quat.mQ[VW]);
  3307. if (num != 4)
  3308. {
  3309. quat = LLQuaternion::DEFAULT;
  3310. }
  3311. lscript_push(buffer, quat);
  3312. delete [] arg;
  3313. }
  3314. lsa_decrease_ref_count(buffer, base_address);
  3315. }
  3316. }
  3317. break;
  3318. default:
  3319. break;
  3320. }
  3321. }
  3322. break;
  3323. case LST_KEY:
  3324. {
  3325. switch(to)
  3326. {
  3327. case LST_KEY:
  3328. break;
  3329. case LST_STRING:
  3330. break;
  3331. case LST_LIST:
  3332. {
  3333. S32 saddress = lscript_pop_int(buffer);
  3334. LLScriptLibData *string = lsa_get_data(buffer, saddress, TRUE);
  3335. LLScriptLibData *list = new LLScriptLibData;
  3336. list->mType = LST_LIST;
  3337. list->mListp = string;
  3338. S32 address = lsa_heap_add_data(buffer, list, get_max_heap_size(buffer), TRUE);
  3339. lscript_push(buffer, address);
  3340. }
  3341. break;
  3342. default:
  3343. break;
  3344. }
  3345. }
  3346. break;
  3347. case LST_VECTOR:
  3348. {
  3349. switch(to)
  3350. {
  3351. case LST_VECTOR:
  3352. break;
  3353. case LST_STRING:
  3354. {
  3355. S32 address;
  3356. LLVector3 source;
  3357. lscript_pop_vector(buffer, source);
  3358. snprintf(caststr, sizeof(caststr), "<%5.5f, %5.5f, %5.5f>", source.mV[VX], source.mV[VY], source.mV[VZ]); /* Flawfinder: ignore */
  3359. address = lsa_heap_add_data(buffer, new LLScriptLibData(caststr), get_max_heap_size(buffer), TRUE);
  3360. lscript_push(buffer, address);
  3361. }
  3362. break;
  3363. case LST_LIST:
  3364. {
  3365. S32 address;
  3366. LLVector3 source;
  3367. lscript_pop_vector(buffer, source);
  3368. LLScriptLibData *list = new LLScriptLibData;
  3369. list->mType = LST_LIST;
  3370. list->mListp = new LLScriptLibData(source);
  3371. address = lsa_heap_add_data(buffer, list, get_max_heap_size(buffer), TRUE);
  3372. lscript_push(buffer, address);
  3373. }
  3374. break;
  3375. default:
  3376. break;
  3377. }
  3378. }
  3379. break;
  3380. case LST_QUATERNION:
  3381. {
  3382. switch(to)
  3383. {
  3384. case LST_QUATERNION:
  3385. break;
  3386. case LST_STRING:
  3387. {
  3388. S32 address;
  3389. LLQuaternion source;
  3390. lscript_pop_quaternion(buffer, source);
  3391. 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 */
  3392. address = lsa_heap_add_data(buffer, new LLScriptLibData(caststr), get_max_heap_size(buffer), TRUE);
  3393. lscript_push(buffer, address);
  3394. }
  3395. break;
  3396. case LST_LIST:
  3397. {
  3398. S32 address;
  3399. LLQuaternion source;
  3400. lscript_pop_quaternion(buffer, source);
  3401. LLScriptLibData *list = new LLScriptLibData;
  3402. list->mType = LST_LIST;
  3403. list->mListp = new LLScriptLibData(source);
  3404. address = lsa_heap_add_data(buffer, list, get_max_heap_size(buffer), TRUE);
  3405. lscript_push(buffer, address);
  3406. }
  3407. break;
  3408. default:
  3409. break;
  3410. }
  3411. }
  3412. break;
  3413. case LST_LIST:
  3414. {
  3415. switch(to)
  3416. {
  3417. case LST_LIST:
  3418. break;
  3419. case LST_STRING:
  3420. {
  3421. S32 address = lscript_pop_int(buffer);
  3422. LLScriptLibData *list = lsa_get_data(buffer, address, TRUE);
  3423. LLScriptLibData *list_root = list;
  3424. std::ostringstream dest;
  3425. while (list)
  3426. {
  3427. list->print(dest, FALSE);
  3428. list = list->mListp;
  3429. }
  3430. delete list_root;
  3431. char *tmp = strdup(dest.str().c_str());
  3432. LLScriptLibData *string = new LLScriptLibData(tmp);
  3433. free(tmp);
  3434. tmp = NULL;
  3435. S32 destaddress = lsa_heap_add_data(buffer, string, get_max_heap_size(buffer), TRUE);
  3436. lscript_push(buffer, destaddress);
  3437. }
  3438. break;
  3439. default:
  3440. break;
  3441. }
  3442. }
  3443. break;
  3444. default:
  3445. break;
  3446. }
  3447. return FALSE;
  3448. }
  3449. BOOL run_stacktos(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  3450. {
  3451. offset++;
  3452. S32 length = lscript_pop_int(buffer);
  3453. S32 i;
  3454. char *arg = new char[length];
  3455. S32 fault;
  3456. for (i = 0; i < length; i++)
  3457. {
  3458. fault = get_register(buffer, LREG_FR);
  3459. if (fault)
  3460. break;
  3461. arg[length - i - 1] = lscript_pop_char(buffer);
  3462. }
  3463. S32 address = lsa_heap_add_data(buffer, new LLScriptLibData(arg), get_max_heap_size(buffer), TRUE);
  3464. lscript_push(buffer, address);
  3465. delete [] arg;
  3466. return FALSE;
  3467. }
  3468. void lscript_stacktol_pop_variable(LLScriptLibData *data, U8 *buffer, char type)
  3469. {
  3470. S32 address, string;
  3471. S32 base_address;
  3472. switch(type)
  3473. {
  3474. case LST_INTEGER:
  3475. data->mType = LST_INTEGER;
  3476. data->mInteger = lscript_pop_int(buffer);
  3477. break;
  3478. case LST_FLOATINGPOINT:
  3479. data->mType = LST_FLOATINGPOINT;
  3480. data->mFP = lscript_pop_float(buffer);
  3481. break;
  3482. case LST_KEY:
  3483. data->mType = LST_KEY;
  3484. base_address = lscript_pop_int(buffer);
  3485. // this bit of nastiness is to get around that code paths to local variables can result in lack of initialization
  3486. // and function clean up of ref counts isn't based on scope (a mistake, I know)
  3487. address = base_address + get_register(buffer, LREG_HR) - 1;
  3488. if (address)
  3489. {
  3490. string = address + SIZEOF_SCRIPT_ALLOC_ENTRY;
  3491. if (safe_heap_check_address(buffer, string, 1))
  3492. {
  3493. S32 toffset = string;
  3494. safe_heap_bytestream_count_char(buffer, toffset);
  3495. S32 size = toffset - string;
  3496. data->mKey = new char[size];
  3497. bytestream2char(data->mKey, buffer, string, size);
  3498. }
  3499. lsa_decrease_ref_count(buffer, base_address);
  3500. }
  3501. else
  3502. {
  3503. data->mKey = new char[1];
  3504. data->mKey[0] = 0;
  3505. }
  3506. break;
  3507. case LST_STRING:
  3508. data->mType = LST_STRING;
  3509. base_address = lscript_pop_int(buffer);
  3510. // this bit of nastiness is to get around that code paths to local variables can result in lack of initialization
  3511. // and function clean up of ref counts isn't based on scope (a mistake, I know)
  3512. address = base_address + get_register(buffer, LREG_HR) - 1;
  3513. if (address)
  3514. {
  3515. string = address + SIZEOF_SCRIPT_ALLOC_ENTRY;
  3516. if (safe_heap_check_address(buffer, string, 1))
  3517. {
  3518. S32 toffset = string;
  3519. safe_heap_bytestream_count_char(buffer, toffset);
  3520. S32 size = toffset - string;
  3521. data->mString = new char[size];
  3522. bytestream2char(data->mString, buffer, string, size);
  3523. }
  3524. lsa_decrease_ref_count(buffer, base_address);
  3525. }
  3526. else
  3527. {
  3528. data->mString = new char[1];
  3529. data->mString[0] = 0;
  3530. }
  3531. break;
  3532. case LST_VECTOR:
  3533. data->mType = LST_VECTOR;
  3534. lscript_pop_vector(buffer, data->mVec);
  3535. break;
  3536. case LST_QUATERNION:
  3537. data->mType = LST_QUATERNION;
  3538. lscript_pop_quaternion(buffer, data->mQuat);
  3539. break;
  3540. case LST_LIST:
  3541. data->mType = LST_LIST;
  3542. address = lscript_pop_int(buffer);
  3543. data->mListp = lsa_get_data(buffer, address, TRUE);
  3544. break;
  3545. }
  3546. }
  3547. BOOL run_stacktol(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  3548. {
  3549. offset++;
  3550. S32 length = safe_instruction_bytestream2integer(buffer, offset);
  3551. S32 i;
  3552. S32 fault;
  3553. S8 type;
  3554. LLScriptLibData *data = new LLScriptLibData, *tail;
  3555. data->mType = LST_LIST;
  3556. for (i = 0; i < length; i++)
  3557. {
  3558. fault = get_register(buffer, LREG_FR);
  3559. if (fault)
  3560. break;
  3561. type = lscript_pop_char(buffer);
  3562. tail = new LLScriptLibData;
  3563. lscript_stacktol_pop_variable(tail, buffer, type);
  3564. tail->mListp = data->mListp;
  3565. data->mListp = tail;
  3566. }
  3567. S32 address = lsa_heap_add_data(buffer,data, get_max_heap_size(buffer), TRUE);
  3568. lscript_push(buffer, address);
  3569. return FALSE;
  3570. }
  3571. BOOL run_print(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  3572. {
  3573. if (b_print)
  3574. printf("[0x%X]tPRINT ", offset);
  3575. offset++;
  3576. U8 type = safe_instruction_bytestream2byte(buffer, offset);
  3577. if (b_print)
  3578. {
  3579. print_type(type);
  3580. printf("n");
  3581. }
  3582. switch(type)
  3583. {
  3584. case LST_INTEGER:
  3585. {
  3586. S32 source = lscript_pop_int(buffer);
  3587. printf("%dn", source);
  3588. }
  3589. break;
  3590. case LST_FLOATINGPOINT:
  3591. {
  3592. F32 source = lscript_pop_float(buffer);
  3593. printf("%fn", source);
  3594. }
  3595. break;
  3596. case LST_STRING:
  3597. {
  3598. S32 base_address = lscript_pop_int(buffer);
  3599. // this bit of nastiness is to get around that code paths to local variables can result in lack of initialization
  3600. // and function clean up of ref counts isn't based on scope (a mistake, I know)
  3601. S32 address = base_address + get_register(buffer, LREG_HR) - 1;
  3602. if (address)
  3603. {
  3604. S32 string = address;
  3605. string += SIZEOF_SCRIPT_ALLOC_ENTRY;
  3606. if (safe_heap_check_address(buffer, string, 1))
  3607. {
  3608. S32 toffset = string;
  3609. safe_heap_bytestream_count_char(buffer, toffset);
  3610. S32 size = toffset - string;
  3611. char *arg = new char[size];
  3612. bytestream2char(arg, buffer, string, size);
  3613. printf("%sn", arg);
  3614. delete [] arg;
  3615. }
  3616. lsa_decrease_ref_count(buffer, base_address);
  3617. }
  3618. }
  3619. break;
  3620. case LST_VECTOR:
  3621. {
  3622. LLVector3 source;
  3623. lscript_pop_vector(buffer, source);
  3624. printf("< %f, %f, %f >n", source.mV[VX], source.mV[VY], source.mV[VZ]);
  3625. }
  3626. break;
  3627. case LST_QUATERNION:
  3628. {
  3629. LLQuaternion source;
  3630. lscript_pop_quaternion(buffer, source);
  3631. printf("< %f, %f, %f, %f >n", source.mQ[VX], source.mQ[VY], source.mQ[VZ], source.mQ[VS]);
  3632. }
  3633. break;
  3634. case LST_LIST:
  3635. {
  3636. S32 base_address = lscript_pop_int(buffer);
  3637. LLScriptLibData *data = lsa_get_data(buffer, base_address, TRUE);
  3638. LLScriptLibData *print = data;
  3639. printf("listn");
  3640. while (print)
  3641. {
  3642. switch(print->mType)
  3643. {
  3644. case LST_INTEGER:
  3645. {
  3646. printf("%dn", print->mInteger);
  3647. }
  3648. break;
  3649. case LST_FLOATINGPOINT:
  3650. {
  3651. printf("%fn", print->mFP);
  3652. }
  3653. break;
  3654. case LST_STRING:
  3655. {
  3656. printf("%sn", print->mString);
  3657. }
  3658. break;
  3659. case LST_KEY:
  3660. {
  3661. printf("%sn", print->mKey);
  3662. }
  3663. break;
  3664. case LST_VECTOR:
  3665. {
  3666. printf("< %f, %f, %f >n", print->mVec.mV[VX], print->mVec.mV[VY], print->mVec.mV[VZ]);
  3667. }
  3668. break;
  3669. case LST_QUATERNION:
  3670. {
  3671. printf("< %f, %f, %f, %f >n", print->mQuat.mQ[VX], print->mQuat.mQ[VY], print->mQuat.mQ[VZ], print->mQuat.mQ[VS]);
  3672. }
  3673. break;
  3674. default:
  3675. break;
  3676. }
  3677. print = print->mListp;
  3678. }
  3679. delete data;
  3680. }
  3681. break;
  3682. default:
  3683. break;
  3684. }
  3685. return FALSE;
  3686. }
  3687. void lscript_run(const std::string& filename, BOOL b_debug)
  3688. {
  3689. LLTimer timer;
  3690. const char *error;
  3691. LLScriptExecuteLSL2 *execute = NULL;
  3692. if (filename.empty())
  3693. {
  3694. llerrs << "filename is NULL" << llendl;
  3695. // Just reporting error is likely not enough. Need
  3696. // to check how to abort or error out gracefully
  3697. // from this function. XXXTBD
  3698. }
  3699. LLFILE* file = LLFile::fopen(filename, "r");  /* Flawfinder: ignore */
  3700. if(file)
  3701. {
  3702. execute = new LLScriptExecuteLSL2(file);
  3703. fclose(file);
  3704. }
  3705. if (execute)
  3706. {
  3707. timer.reset();
  3708. F32 time_slice = 3600.0f; // 1 hr.
  3709. U32 events_processed = 0;
  3710. do {
  3711. LLTimer timer2;
  3712. execute->runQuanta(b_debug, LLUUID::null, &error,
  3713.    time_slice, events_processed, timer2);
  3714. } while (!execute->isFinished());
  3715. F32 time = timer.getElapsedTimeF32();
  3716. F32 ips = execute->mInstructionCount / time;
  3717. llinfos << execute->mInstructionCount << " instructions in " << time << " seconds" << llendl;
  3718. llinfos << ips/1000 << "K instructions per second" << llendl;
  3719. printf("ip: 0x%Xn", get_register(execute->mBuffer, LREG_IP));
  3720. printf("sp: 0x%Xn", get_register(execute->mBuffer, LREG_SP));
  3721. printf("bp: 0x%Xn", get_register(execute->mBuffer, LREG_BP));
  3722. printf("hr: 0x%Xn", get_register(execute->mBuffer, LREG_HR));
  3723. printf("hp: 0x%Xn", get_register(execute->mBuffer, LREG_HP));
  3724. delete execute;
  3725. fclose(file);
  3726. }
  3727. }
  3728. void lscript_pop_variable(LLScriptLibData *data, U8 *buffer, char type)
  3729. {
  3730. S32 address, string;
  3731. S32 base_address;
  3732. switch(type)
  3733. {
  3734. case 'i':
  3735. data->mType = LST_INTEGER;
  3736. data->mInteger = lscript_pop_int(buffer);
  3737. break;
  3738. case 'f':
  3739. data->mType = LST_FLOATINGPOINT;
  3740. data->mFP = lscript_pop_float(buffer);
  3741. break;
  3742. case 'k':
  3743. data->mType = LST_KEY;
  3744. data->mKey = NULL;
  3745. base_address = lscript_pop_int(buffer);
  3746. // this bit of nastiness is to get around that code paths to local variables can result in lack of initialization
  3747. // and function clean up of ref counts isn't based on scope (a mistake, I know)
  3748. address = base_address + get_register(buffer, LREG_HR) - 1;
  3749. if (address)
  3750. {
  3751. string = address + SIZEOF_SCRIPT_ALLOC_ENTRY;
  3752. if (safe_heap_check_address(buffer, string, 1))
  3753. {
  3754. S32 toffset = string;
  3755. safe_heap_bytestream_count_char(buffer, toffset);
  3756. S32 size = toffset - string;
  3757. data->mKey = new char[size];
  3758. bytestream2char(data->mKey, buffer, string, size);
  3759. }
  3760. lsa_decrease_ref_count(buffer, base_address);
  3761. }
  3762. if (data->mKey == NULL)
  3763. {
  3764. data->mKey = new char[1];
  3765. data->mKey[0] = 0;
  3766. }
  3767. break;
  3768. case 's':
  3769. data->mType = LST_STRING;
  3770. data->mString = NULL;
  3771. base_address = lscript_pop_int(buffer);
  3772. // this bit of nastiness is to get around that code paths to local variables can result in lack of initialization
  3773. // and function clean up of ref counts isn't based on scope (a mistake, I know)
  3774. address = base_address + get_register(buffer, LREG_HR) - 1;
  3775. if (address)
  3776. {
  3777. string = address + SIZEOF_SCRIPT_ALLOC_ENTRY;
  3778. if (safe_heap_check_address(buffer, string, 1))
  3779. {
  3780. S32 toffset = string;
  3781. safe_heap_bytestream_count_char(buffer, toffset);
  3782. S32 size = toffset - string;
  3783. data->mString = new char[size];
  3784. bytestream2char(data->mString, buffer, string, size);
  3785. }
  3786. lsa_decrease_ref_count(buffer, base_address);
  3787. }
  3788. if (data->mString == NULL)
  3789. {
  3790. data->mString = new char[1];
  3791. data->mString[0] = 0;
  3792. }
  3793. break;
  3794. case 'l':
  3795. {
  3796. S32 base_address = lscript_pop_int(buffer);
  3797. data->mType = LST_LIST;
  3798. data->mListp = lsa_get_list_ptr(buffer, base_address, TRUE);
  3799. }
  3800. break;
  3801. case 'v':
  3802. data->mType = LST_VECTOR;
  3803. lscript_pop_vector(buffer, data->mVec);
  3804. break;
  3805. case 'q':
  3806. data->mType = LST_QUATERNION;
  3807. lscript_pop_quaternion(buffer, data->mQuat);
  3808. break;
  3809. }
  3810. }
  3811. void lscript_push_return_variable(LLScriptLibData *data, U8 *buffer)
  3812. {
  3813. S32 address;
  3814. switch(data->mType)
  3815. {
  3816. case LST_INTEGER:
  3817. lscript_local_store(buffer, -12, data->mInteger);
  3818. break;
  3819. case LST_FLOATINGPOINT:
  3820. lscript_local_store(buffer, -12, data->mFP);
  3821. break;
  3822. case LST_KEY:
  3823. address = lsa_heap_add_data(buffer, data, get_max_heap_size(buffer), FALSE);
  3824. lscript_local_store(buffer, -12, address);
  3825. break;
  3826. case LST_STRING:
  3827. address = lsa_heap_add_data(buffer, data, get_max_heap_size(buffer), FALSE);
  3828. lscript_local_store(buffer, -12, address);
  3829. break;
  3830. case LST_LIST:
  3831. address = lsa_heap_add_data(buffer, data, get_max_heap_size(buffer), FALSE);
  3832. lscript_local_store(buffer, -12, address);
  3833. break;
  3834. case LST_VECTOR:
  3835. lscript_local_store(buffer, -20, data->mVec);
  3836. break;
  3837. case LST_QUATERNION:
  3838. lscript_local_store(buffer, -24, data->mQuat);
  3839. break;
  3840. default:
  3841. break;
  3842. }
  3843. }
  3844. S32 lscript_push_variable(LLScriptLibData *data, U8 *buffer)
  3845. {
  3846. S32 address;
  3847. switch(data->mType)
  3848. {
  3849. case LST_INTEGER:
  3850. lscript_push(buffer, data->mInteger);
  3851. break;
  3852. case LST_FLOATINGPOINT:
  3853. lscript_push(buffer, data->mFP);
  3854. return 4;
  3855. break;
  3856. case LST_KEY:
  3857. address = lsa_heap_add_data(buffer, data, get_max_heap_size(buffer), FALSE);
  3858. lscript_push(buffer, address);
  3859. return 4;
  3860. break;
  3861. case LST_STRING:
  3862. address = lsa_heap_add_data(buffer, data, get_max_heap_size(buffer), FALSE);
  3863. lscript_push(buffer, address);
  3864. return 4;
  3865. break;
  3866. case LST_LIST:
  3867. address = lsa_heap_add_data(buffer, data, get_max_heap_size(buffer), FALSE);
  3868. lscript_push(buffer, address);
  3869. return 4;
  3870. break;
  3871. case LST_VECTOR:
  3872. lscript_push(buffer, data->mVec);
  3873. return 12;
  3874. break;
  3875. case LST_QUATERNION:
  3876. lscript_push(buffer, data->mQuat);
  3877. return 16;
  3878. break;
  3879. default:
  3880. break;
  3881. }
  3882. return 4;
  3883. }
  3884. // Shared code for run_calllib() and run_calllib_two_byte()
  3885. BOOL run_calllib_common(U8 *buffer, S32 &offset, const LLUUID &id, U16 arg)
  3886. {
  3887. if (arg >= gScriptLibrary.mFunctions.size())
  3888. {
  3889. set_fault(buffer, LSRF_BOUND_CHECK_ERROR);
  3890. return FALSE;
  3891. }
  3892. LLScriptLibraryFunction const & function = gScriptLibrary.mFunctions[arg];
  3893. // pull out the arguments and the return values
  3894. LLScriptLibData *arguments = NULL;
  3895. LLScriptLibData *returnvalue = NULL;
  3896. S32 i, number;
  3897. if (function.mReturnType)
  3898. {
  3899. returnvalue = new LLScriptLibData;
  3900. }
  3901. if (function.mArgs)
  3902. {
  3903. number = (S32)strlen(function.mArgs); //Flawfinder: ignore
  3904. arguments = new LLScriptLibData[number];
  3905. }
  3906. else
  3907. {
  3908. number = 0;
  3909. }
  3910. for (i = number - 1; i >= 0; i--)
  3911. {
  3912. lscript_pop_variable(&arguments[i], buffer, function.mArgs[i]);
  3913. }
  3914. // Actually execute the function call
  3915. function.mExecFunc(returnvalue, arguments, id);
  3916. add_register_fp(buffer, LREG_ESR, -(function.mEnergyUse));
  3917. add_register_fp(buffer, LREG_SLR, function.mSleepTime);
  3918. if (returnvalue)
  3919. {
  3920. returnvalue->mType = char2type(*function.mReturnType);
  3921. lscript_push_return_variable(returnvalue, buffer);
  3922. }
  3923. delete [] arguments;
  3924. delete returnvalue;
  3925. // reset the BP after calling the library files
  3926. S32 bp = lscript_pop_int(buffer);
  3927. set_bp(buffer, bp);
  3928. // pop off the spot for the instruction pointer
  3929. lscript_poparg(buffer, 4);
  3930. return FALSE;
  3931. }
  3932. BOOL run_calllib(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  3933. {
  3934. offset++;
  3935. U16 arg = (U16) safe_instruction_bytestream2byte(buffer, offset);
  3936. if (b_print &&
  3937. arg < gScriptLibrary.mFunctions.size())
  3938. {
  3939. printf("[0x%X]tCALLLIB ", offset);
  3940. LLScriptLibraryFunction const & function = gScriptLibrary.mFunctions[arg];
  3941. printf("%d (%s)n", (U32)arg, function.mName);
  3942. //printf("%sn", function.mDesc);
  3943. }
  3944. return run_calllib_common(buffer, offset, id, arg);
  3945. }
  3946. BOOL run_calllib_two_byte(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
  3947. {
  3948. offset++;
  3949. U16 arg = safe_instruction_bytestream2u16(buffer, offset);
  3950. if (b_print &&
  3951. arg < gScriptLibrary.mFunctions.size())
  3952. {
  3953. printf("[0x%X]tCALLLIB ", (offset-1));
  3954. LLScriptLibraryFunction const & function = gScriptLibrary.mFunctions[arg];
  3955. printf("%d (%s)n", (U32)arg, function.mName);
  3956. //printf("%sn", function.mDesc);
  3957. }
  3958. return run_calllib_common(buffer, offset, id, arg);
  3959. }