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

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file lscript_byteconvert.h
  3.  * @brief Shared code for compiler and assembler for LSL
  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. // data shared between compiler/assembler
  33. // used to convert data between byte stream and outside data types
  34. #ifndef LL_LSCRIPT_BYTECONVERT_H
  35. #define LL_LSCRIPT_BYTECONVERT_H
  36. #include "stdtypes.h"
  37. #include "v3math.h"
  38. #include "llquaternion.h"
  39. #include "lscript_byteformat.h"
  40. #include "lluuid.h"
  41. void reset_hp_to_safe_spot(const U8 *buffer);
  42. // remember that LScript byte stream is BigEndian
  43. void set_fault(const U8 *stream, LSCRIPTRunTimeFaults fault);
  44. inline S32 bytestream2integer(const U8 *stream, S32 &offset)
  45. {
  46. stream += offset;
  47. offset += 4;
  48. return (*stream<<24) | (*(stream + 1)<<16) | (*(stream + 2)<<8) | *(stream + 3);
  49. }
  50. inline U32 bytestream2unsigned_integer(const U8 *stream, S32 &offset)
  51. {
  52. stream += offset;
  53. offset += 4;
  54. return (*stream<<24) | (*(stream + 1)<<16) | (*(stream + 2)<<8) | *(stream + 3);
  55. }
  56. inline U64 bytestream2u64(const U8 *stream, S32 &offset)
  57. {
  58. stream += offset;
  59. offset += 8;
  60. return ((U64)(*stream)<<56)| ((U64)(*(stream + 1))<<48) | ((U64)(*(stream + 2))<<40) | ((U64)(*(stream + 3))<<32) | 
  61.    ((U64)(*(stream + 4))<<24) | ((U64)(*(stream + 5))<<16) | ((U64)(*(stream + 6))<<8) | (U64)(*(stream + 7));
  62. }
  63. inline void integer2bytestream(U8 *stream, S32 &offset, S32 integer)
  64. {
  65. stream += offset;
  66. offset += 4;
  67. *(stream) = (integer >> 24);
  68. *(stream + 1) = (integer >> 16) & 0xff;
  69. *(stream + 2) = (integer >> 8) & 0xff;
  70. *(stream + 3) = (integer) & 0xff;
  71. }
  72. inline void unsigned_integer2bytestream(U8 *stream, S32 &offset, U32 integer)
  73. {
  74. stream += offset;
  75. offset += 4;
  76. *(stream) = (integer >> 24);
  77. *(stream + 1) = (integer >> 16) & 0xff;
  78. *(stream + 2) = (integer >> 8) & 0xff;
  79. *(stream + 3) = (integer) & 0xff;
  80. }
  81. inline void u642bytestream(U8 *stream, S32 &offset, U64 integer)
  82. {
  83. stream += offset;
  84. offset += 8;
  85. *(stream) = (U8)(integer >> 56);
  86. *(stream + 1) = (U8)((integer >> 48) & 0xff);
  87. *(stream + 2) = (U8)((integer >> 40) & 0xff);
  88. *(stream + 3) = (U8)((integer >> 32) & 0xff);
  89. *(stream + 4) = (U8)((integer >> 24) & 0xff);
  90. *(stream + 5) = (U8)((integer >> 16) & 0xff);
  91. *(stream + 6) = (U8)((integer >> 8) & 0xff);
  92. *(stream + 7) = (U8)((integer) & 0xff);
  93. }
  94. inline S16 bytestream2s16(const U8 *stream, S32 &offset)
  95. {
  96. stream += offset;
  97. offset += 2;
  98. return (*stream<<8) | *(stream + 1);
  99. }
  100. inline void s162bytestream(U8 *stream, S32 &offset, S16 integer)
  101. {
  102. stream += offset;
  103. offset += 2;
  104. *(stream) = (integer >> 8);
  105. *(stream + 1) = (integer) & 0xff;
  106. }
  107. inline U16 bytestream2u16(const U8 *stream, S32 &offset)
  108. {
  109. stream += offset;
  110. offset += 2;
  111. return (*stream<<8) | *(stream + 1);
  112. }
  113. inline void u162bytestream(U8 *stream, S32 &offset, U16 integer)
  114. {
  115. stream += offset;
  116. offset += 2;
  117. *(stream) = (integer >> 8);
  118. *(stream + 1) = (integer) & 0xff;
  119. }
  120. inline F32 bytestream2float(const U8 *stream, S32 &offset)
  121. {
  122. S32 value = bytestream2integer(stream, offset);
  123. F32 fpvalue = *(F32 *)&value;
  124. if (!llfinite(fpvalue))
  125. {
  126. fpvalue = 0;
  127. set_fault(stream, LSRF_MATH);
  128. }
  129. return fpvalue;
  130. }
  131. inline void float2bytestream(U8 *stream, S32 &offset, F32 floatingpoint)
  132. {
  133. S32 value = *(S32 *)&floatingpoint;
  134. integer2bytestream(stream, offset, value);
  135. }
  136. inline void bytestream_int2float(U8 *stream, S32 &offset)
  137. {
  138. S32 value = bytestream2integer(stream, offset);
  139. offset -= 4;
  140. F32 fpvalue = (F32)value;
  141. if (!llfinite(fpvalue))
  142. {
  143. fpvalue = 0;
  144. set_fault(stream, LSRF_MATH);
  145. }
  146. float2bytestream(stream, offset, fpvalue);
  147. }
  148. // Returns true on success, return false and clip copy on buffer overflow
  149. inline bool bytestream2char(char *buffer, const U8 *stream, S32 &offset, S32 buffsize)
  150. {
  151. S32 source_len = strlen( (const char *)stream+offset );
  152. S32 copy_len = buffsize - 1;
  153. if( copy_len > source_len )
  154. {
  155. copy_len = source_len;
  156. }
  157. // strncpy without  padding overhead
  158. memcpy( buffer, stream+offset, copy_len );
  159. buffer[copy_len] = 0;
  160. offset += source_len + 1; // advance past source string, include terminating ''
  161. return source_len < buffsize;
  162. }
  163. inline void char2bytestream(U8 *stream, S32 &offset, const char *buffer)
  164. {
  165. while ((*(stream + offset++) = *buffer++))
  166. ;
  167. }
  168. inline U8 bytestream2byte(const U8 *stream, S32 &offset)
  169. {
  170. return *(stream + offset++);
  171. }
  172. inline void byte2bytestream(U8 *stream, S32 &offset, U8 byte)
  173. {
  174. *(stream + offset++) = byte;
  175. }
  176. inline void bytestream2bytestream(U8 *dest, S32 &dest_offset, const U8 *src, S32 &src_offset, S32 count)
  177. {
  178. while (count)
  179. {
  180. (*(dest + dest_offset++)) = (*(src + src_offset++));
  181. count--;
  182. }
  183. }
  184. inline void uuid2bytestream(U8 *stream, S32 &offset, const LLUUID &uuid)
  185. {
  186. S32 i;
  187. for (i = 0; i < UUID_BYTES; i++)
  188. {
  189. *(stream + offset++) = uuid.mData[i];
  190. }
  191. }
  192. inline void bytestream2uuid(U8 *stream, S32 &offset, LLUUID &uuid)
  193. {
  194. S32 i;
  195. for (i = 0; i < UUID_BYTES; i++)
  196. {
  197. uuid.mData[i] = *(stream + offset++);
  198. }
  199. }
  200. // vectors and quaternions and encoded in backwards order to match the way in which they are stored on the stack
  201. inline void bytestream2vector(LLVector3 &vector, const U8 *stream, S32 &offset)
  202. {
  203. S32 value = bytestream2integer(stream, offset);
  204. vector.mV[VZ] = *(F32 *)&value;
  205. if (!llfinite(vector.mV[VZ]))
  206. {
  207. vector.mV[VZ] = 0;
  208. set_fault(stream, LSRF_MATH);
  209. }
  210. value = bytestream2integer(stream, offset);
  211. vector.mV[VY] = *(F32 *)&value;
  212. if (!llfinite(vector.mV[VY]))
  213. {
  214. vector.mV[VY] = 0;
  215. set_fault(stream, LSRF_MATH);
  216. }
  217. value = bytestream2integer(stream, offset);
  218. vector.mV[VX] = *(F32 *)&value;
  219. if (!llfinite(vector.mV[VX]))
  220. {
  221. vector.mV[VX] = 0;
  222. set_fault(stream, LSRF_MATH);
  223. }
  224. }
  225. inline void vector2bytestream(U8 *stream, S32 &offset, const LLVector3 &vector)
  226. {
  227. S32 value = *(S32 *)&vector.mV[VZ];
  228. integer2bytestream(stream, offset, value);
  229. value = *(S32 *)&vector.mV[VY];
  230. integer2bytestream(stream, offset, value);
  231. value = *(S32 *)&vector.mV[VX];
  232. integer2bytestream(stream, offset, value);
  233. }
  234. inline void bytestream2quaternion(LLQuaternion &quat, const U8 *stream, S32 &offset)
  235. {
  236. S32 value = bytestream2integer(stream, offset);
  237. quat.mQ[VS] = *(F32 *)&value;
  238. if (!llfinite(quat.mQ[VS]))
  239. {
  240. quat.mQ[VS] = 0;
  241. set_fault(stream, LSRF_MATH);
  242. }
  243. value = bytestream2integer(stream, offset);
  244. quat.mQ[VZ] = *(F32 *)&value;
  245. if (!llfinite(quat.mQ[VZ]))
  246. {
  247. quat.mQ[VZ] = 0;
  248. set_fault(stream, LSRF_MATH);
  249. }
  250. value = bytestream2integer(stream, offset);
  251. quat.mQ[VY] = *(F32 *)&value;
  252. if (!llfinite(quat.mQ[VY]))
  253. {
  254. quat.mQ[VY] = 0;
  255. set_fault(stream, LSRF_MATH);
  256. }
  257. value = bytestream2integer(stream, offset);
  258. quat.mQ[VX] = *(F32 *)&value;
  259. if (!llfinite(quat.mQ[VX]))
  260. {
  261. quat.mQ[VX] = 0;
  262. set_fault(stream, LSRF_MATH);
  263. }
  264. }
  265. inline void quaternion2bytestream(U8 *stream, S32 &offset, const LLQuaternion &quat)
  266. {
  267. S32 value = *(S32 *)&quat.mQ[VS];
  268. integer2bytestream(stream, offset, value);
  269. value = *(S32 *)&quat.mQ[VZ];
  270. integer2bytestream(stream, offset, value);
  271. value = *(S32 *)&quat.mQ[VY];
  272. integer2bytestream(stream, offset, value);
  273. value = *(S32 *)&quat.mQ[VX];
  274. integer2bytestream(stream, offset, value);
  275. }
  276. inline S32 get_register(const U8 *stream, LSCRIPTRegisters reg)
  277. {
  278. S32 offset = gLSCRIPTRegisterAddresses[reg];
  279. return bytestream2integer(stream, offset);
  280. }
  281. inline F32 get_register_fp(U8 *stream, LSCRIPTRegisters reg)
  282. {
  283. S32 offset = gLSCRIPTRegisterAddresses[reg];
  284. F32 value = bytestream2float(stream, offset);
  285. if (!llfinite(value))
  286. {
  287. value = 0;
  288. set_fault(stream, LSRF_MATH);
  289. }
  290. return value;
  291. }
  292. inline U64 get_register_u64(U8 *stream, LSCRIPTRegisters reg)
  293. {
  294. S32 offset = gLSCRIPTRegisterAddresses[reg];
  295. return bytestream2u64(stream, offset);
  296. }
  297. inline U64 get_event_register(U8 *stream, LSCRIPTRegisters reg, S32 major_version)
  298. {
  299. if (major_version == 1)
  300. {
  301. S32 offset = gLSCRIPTRegisterAddresses[reg];
  302. return (U64)bytestream2integer(stream, offset);
  303. }
  304. else if (major_version == 2)
  305. {
  306. S32 offset = gLSCRIPTRegisterAddresses[reg + (LREG_NCE - LREG_CE)];
  307. return bytestream2u64(stream, offset);
  308. }
  309. else
  310. {
  311. S32 offset = gLSCRIPTRegisterAddresses[reg];
  312. return (U64)bytestream2integer(stream, offset);
  313. }
  314. }
  315. inline void set_register(U8 *stream, LSCRIPTRegisters reg, S32 value)
  316. {
  317. S32 offset = gLSCRIPTRegisterAddresses[reg];
  318. integer2bytestream(stream, offset, value);
  319. }
  320. inline void set_register_fp(U8 *stream, LSCRIPTRegisters reg, F32 value)
  321. {
  322. S32 offset = gLSCRIPTRegisterAddresses[reg];
  323. float2bytestream(stream, offset, value);
  324. }
  325. inline void set_register_u64(U8 *stream, LSCRIPTRegisters reg, U64 value)
  326. {
  327. S32 offset = gLSCRIPTRegisterAddresses[reg];
  328. u642bytestream(stream, offset, value);
  329. }
  330. inline void set_event_register(U8 *stream, LSCRIPTRegisters reg, U64 value, S32 major_version)
  331. {
  332. if (major_version == 1)
  333. {
  334. S32 offset = gLSCRIPTRegisterAddresses[reg];
  335. integer2bytestream(stream, offset, (S32)value);
  336. }
  337. else if (major_version == 2)
  338. {
  339. S32 offset = gLSCRIPTRegisterAddresses[reg + (LREG_NCE - LREG_CE)];
  340. u642bytestream(stream, offset, value);
  341. }
  342. else
  343. {
  344. S32 offset = gLSCRIPTRegisterAddresses[reg];
  345. integer2bytestream(stream, offset, (S32)value);
  346. }
  347. }
  348. inline F32 add_register_fp(U8 *stream, LSCRIPTRegisters reg, F32 value)
  349. {
  350. S32 offset = gLSCRIPTRegisterAddresses[reg];
  351. F32 newvalue = bytestream2float(stream, offset);
  352. newvalue += value;
  353. if (!llfinite(newvalue))
  354. {
  355. newvalue = 0;
  356. set_fault(stream, LSRF_MATH);
  357. }
  358. offset = gLSCRIPTRegisterAddresses[reg];
  359. float2bytestream(stream, offset, newvalue);
  360. return newvalue;
  361. }
  362. void lsa_print_heap(U8 *buffer);
  363. inline void set_fault(const U8 *stream, LSCRIPTRunTimeFaults fault)
  364. {
  365.    S32 fr = get_register(stream, LREG_FR);
  366.    // record the first error
  367.    if (!fr)
  368.    {
  369.    if (  (fault == LSRF_HEAP_ERROR)
  370.    ||(fault == LSRF_STACK_HEAP_COLLISION)
  371.    ||(fault == LSRF_BOUND_CHECK_ERROR))
  372.    {
  373. reset_hp_to_safe_spot(stream);
  374. //     lsa_print_heap((U8 *)stream);
  375.    }
  376.        fr = fault;
  377.        set_register((U8 *)stream, LREG_FR, fr);
  378.    }
  379. }
  380. inline BOOL set_ip(U8 *stream, S32 ip)
  381. {
  382. // Verify that the Instruction Pointer is in a valid
  383. // code area (between the Global Function Register
  384. // and Heap Register).
  385. S32 gfr = get_register(stream, LREG_GFR);
  386. if (ip == 0)
  387. {
  388. set_register(stream, LREG_IP, ip);
  389. return TRUE;
  390. }
  391. if (ip < gfr)
  392. {
  393. set_fault(stream, LSRF_BOUND_CHECK_ERROR);
  394. return FALSE;
  395. }
  396. S32 hr = get_register(stream, LREG_HR);
  397. if (ip >= hr)
  398. {
  399. set_fault(stream, LSRF_BOUND_CHECK_ERROR);
  400. return FALSE;
  401. }
  402. set_register(stream, LREG_IP, ip);
  403. return TRUE;
  404. }
  405. inline BOOL set_bp(U8 *stream, S32 bp)
  406. {
  407. // Verify that the Base Pointer is in a valid
  408. // data area (between the Heap Pointer and
  409. // the Top of Memory, and below the
  410. // Stack Pointer).
  411. S32 hp = get_register(stream, LREG_HP);
  412. if (bp <= hp)
  413. {
  414. set_fault(stream, LSRF_STACK_HEAP_COLLISION);
  415. return FALSE;
  416. }
  417. S32 tm = get_register(stream, LREG_TM);
  418. if (bp >= tm)
  419. {
  420. set_fault(stream, LSRF_BOUND_CHECK_ERROR);
  421. return FALSE;
  422. }
  423. S32 sp = get_register(stream, LREG_SP);
  424. if (bp < sp)
  425. {
  426. set_fault(stream, LSRF_BOUND_CHECK_ERROR);
  427. return FALSE;
  428. }
  429. set_register(stream, LREG_BP, bp);
  430. return TRUE;
  431. }
  432. inline BOOL set_sp(U8 *stream, S32 sp)
  433. {
  434. // Verify that the Stack Pointer is in a valid
  435. // data area (between the Heap Pointer and
  436. // the Top of Memory).
  437. S32 hp = get_register(stream, LREG_HP);
  438. if (sp <= hp)
  439. {
  440. set_fault(stream, LSRF_STACK_HEAP_COLLISION);
  441. return FALSE;
  442. }
  443. S32 tm = get_register(stream, LREG_TM);
  444. if (sp >= tm)
  445. {
  446. set_fault(stream, LSRF_BOUND_CHECK_ERROR);
  447. return FALSE;
  448. }
  449. set_register(stream, LREG_SP, sp);
  450. return TRUE;
  451. }
  452. inline void lscript_push(U8 *stream, U8 value)
  453. {
  454. S32 sp = get_register(stream, LREG_SP);
  455. sp -= 1;
  456. if (set_sp(stream, sp))
  457. {
  458. *(stream + sp) = value;
  459. }
  460. }
  461. inline void lscript_push(U8 *stream, S32 value)
  462. {
  463. S32 sp = get_register(stream, LREG_SP);
  464. sp -= LSCRIPTDataSize[LST_INTEGER];
  465. if (set_sp(stream, sp))
  466. {
  467. integer2bytestream(stream, sp, value);
  468. }
  469. }
  470. inline void lscript_push(U8 *stream, F32 value)
  471. {
  472. S32 sp = get_register(stream, LREG_SP);
  473. sp -= LSCRIPTDataSize[LST_FLOATINGPOINT];
  474. if (set_sp(stream, sp))
  475. {
  476. float2bytestream(stream, sp, value);
  477. }
  478. }
  479. inline void lscript_push(U8 *stream, const LLVector3 &value)
  480. {
  481. S32 sp = get_register(stream, LREG_SP);
  482. sp -= LSCRIPTDataSize[LST_VECTOR];
  483. if (set_sp(stream, sp))
  484. {
  485. vector2bytestream(stream, sp, value);
  486. }
  487. }
  488. inline void lscript_push(U8 *stream, const LLQuaternion &value)
  489. {
  490. S32 sp = get_register(stream, LREG_SP);
  491. sp -= LSCRIPTDataSize[LST_QUATERNION];
  492. if (set_sp(stream, sp))
  493. {
  494. quaternion2bytestream(stream, sp, value);
  495. }
  496. }
  497. inline void lscript_pusharg(U8 *stream, S32 arg)
  498. {
  499. S32 sp = get_register(stream, LREG_SP);
  500. sp -= arg;
  501. set_sp(stream, sp);
  502. }
  503. inline void lscript_poparg(U8 *stream, S32 arg)
  504. {
  505. S32 sp = get_register(stream, LREG_SP);
  506. sp += arg;
  507. set_sp(stream, sp);
  508. }
  509. inline U8 lscript_pop_char(U8 *stream)
  510. {
  511. S32 sp = get_register(stream, LREG_SP);
  512. U8 value = *(stream + sp++);
  513. set_sp(stream, sp);
  514. return value;
  515. }
  516. inline S32 lscript_pop_int(U8 *stream)
  517. {
  518. S32 sp = get_register(stream, LREG_SP);
  519. S32 value = bytestream2integer(stream, sp);
  520. set_sp(stream, sp);
  521. return value;
  522. }
  523. inline F32 lscript_pop_float(U8 *stream)
  524. {
  525. S32 sp = get_register(stream, LREG_SP);
  526. F32 value = bytestream2float(stream, sp);
  527. if (!llfinite(value))
  528. {
  529. value = 0;
  530. set_fault(stream, LSRF_MATH);
  531. }
  532. set_sp(stream, sp);
  533. return value;
  534. }
  535. inline void lscript_pop_vector(U8 *stream, LLVector3 &value)
  536. {
  537. S32 sp = get_register(stream, LREG_SP);
  538. bytestream2vector(value, stream, sp);
  539. set_sp(stream, sp);
  540. }
  541. inline void lscript_pop_quaternion(U8 *stream, LLQuaternion &value)
  542. {
  543. S32 sp = get_register(stream, LREG_SP);
  544. bytestream2quaternion(value, stream, sp);
  545. set_sp(stream, sp);
  546. }
  547. inline void lscript_pusharge(U8 *stream, S32 value)
  548. {
  549. S32 sp = get_register(stream, LREG_SP);
  550. sp -= value;
  551. if (set_sp(stream, sp))
  552. {
  553. S32 i;
  554. for (i = 0; i < value; i++)
  555. {
  556. *(stream + sp++) = 0;
  557. }
  558. }
  559. }
  560. inline BOOL lscript_check_local(U8 *stream, S32 &address, S32 size)
  561. {
  562. S32 sp = get_register(stream, LREG_SP);
  563. S32 bp = get_register(stream, LREG_BP);
  564. address += size;
  565. address = bp - address;
  566. if (address < sp - size)
  567. {
  568. set_fault(stream, LSRF_BOUND_CHECK_ERROR);
  569. return FALSE;
  570. }
  571. S32 tm = get_register(stream, LREG_TM);
  572. if (address + size > tm)
  573. {
  574. set_fault(stream, LSRF_BOUND_CHECK_ERROR);
  575. return FALSE;
  576. }
  577. return TRUE;
  578. }
  579. inline BOOL lscript_check_global(U8 *stream, S32 &address, S32 size)
  580. {
  581. S32 gvr = get_register(stream, LREG_GVR);
  582. // Possibility of overwriting registers?  -- DK 09/07/04
  583. if (address < 0)
  584. {
  585. set_fault(stream, LSRF_BOUND_CHECK_ERROR);
  586. return FALSE;
  587. }
  588. address += gvr;
  589. S32 gfr = get_register(stream, LREG_GFR);
  590. if (address + size > gfr)
  591. {
  592. set_fault(stream, LSRF_BOUND_CHECK_ERROR);
  593. return FALSE;
  594. }
  595. return TRUE;
  596. }
  597. inline void lscript_local_store(U8 *stream, S32 address, S32 value)
  598. {
  599. if (lscript_check_local(stream, address, LSCRIPTDataSize[LST_INTEGER]))
  600. integer2bytestream(stream, address, value);
  601. }
  602. inline void lscript_local_store(U8 *stream, S32 address, F32 value)
  603. {
  604. if (lscript_check_local(stream, address, LSCRIPTDataSize[LST_FLOATINGPOINT]))
  605. float2bytestream(stream, address, value);
  606. }
  607. inline void lscript_local_store(U8 *stream, S32 address, const LLVector3 value)
  608. {
  609. if (lscript_check_local(stream, address, LSCRIPTDataSize[LST_VECTOR]))
  610. vector2bytestream(stream, address, value);
  611. }
  612. inline void lscript_local_store(U8 *stream, S32 address, const LLQuaternion value)
  613. {
  614. if (lscript_check_local(stream, address, LSCRIPTDataSize[LST_QUATERNION]))
  615. quaternion2bytestream(stream, address, value);
  616. }
  617. inline void lscript_global_store(U8 *stream, S32 address, S32 value)
  618. {
  619. if (lscript_check_global(stream, address, LSCRIPTDataSize[LST_INTEGER]))
  620. integer2bytestream(stream, address, value);
  621. }
  622. inline void lscript_global_store(U8 *stream, S32 address, F32 value)
  623. {
  624. if (lscript_check_global(stream, address, LSCRIPTDataSize[LST_FLOATINGPOINT]))
  625. float2bytestream(stream, address, value);
  626. }
  627. inline void lscript_global_store(U8 *stream, S32 address, const LLVector3 value)
  628. {
  629. if (lscript_check_global(stream, address, LSCRIPTDataSize[LST_VECTOR]))
  630. vector2bytestream(stream, address, value);
  631. }
  632. inline void lscript_global_store(U8 *stream, S32 address, const LLQuaternion value)
  633. {
  634. if (lscript_check_global(stream, address, LSCRIPTDataSize[LST_QUATERNION]))
  635. quaternion2bytestream(stream, address, value);
  636. }
  637. inline S32 lscript_local_get(U8 *stream, S32 address)
  638. {
  639. if (lscript_check_local(stream, address, LSCRIPTDataSize[LST_INTEGER]))
  640. return bytestream2integer(stream, address);
  641. return 0;
  642. }
  643. inline void lscript_local_get(U8 *stream, S32 address, F32 &value)
  644. {
  645. if (lscript_check_local(stream, address, LSCRIPTDataSize[LST_FLOATINGPOINT]))
  646. value = bytestream2float(stream, address);
  647. if (!llfinite(value))
  648. {
  649. value = 0;
  650. set_fault(stream, LSRF_MATH);
  651. }
  652. }
  653. inline void lscript_local_get(U8 *stream, S32 address, LLVector3 &value)
  654. {
  655. if (lscript_check_local(stream, address, LSCRIPTDataSize[LST_VECTOR]))
  656. bytestream2vector(value, stream, address);
  657. }
  658. inline void lscript_local_get(U8 *stream, S32 address, LLQuaternion &value)
  659. {
  660. if (lscript_check_local(stream, address, LSCRIPTDataSize[LST_QUATERNION]))
  661. bytestream2quaternion(value, stream, address);
  662. }
  663. inline S32 lscript_global_get(U8 *stream, S32 address)
  664. {
  665. if (lscript_check_global(stream, address, LSCRIPTDataSize[LST_INTEGER]))
  666. return bytestream2integer(stream, address);
  667. return 0;
  668. }
  669. inline void lscript_global_get(U8 *stream, S32 address, F32 &value)
  670. {
  671. if (lscript_check_global(stream, address, LSCRIPTDataSize[LST_FLOATINGPOINT]))
  672. value = bytestream2float(stream, address);
  673. if (!llfinite(value))
  674. {
  675. value = 0;
  676. set_fault(stream, LSRF_MATH);
  677. }
  678. }
  679. inline void lscript_global_get(U8 *stream, S32 address, LLVector3 &value)
  680. {
  681. if (lscript_check_global(stream, address, LSCRIPTDataSize[LST_VECTOR]))
  682. bytestream2vector(value, stream, address);
  683. }
  684. inline void lscript_global_get(U8 *stream, S32 address, LLQuaternion &value)
  685. {
  686. if (lscript_check_global(stream, address, LSCRIPTDataSize[LST_QUATERNION]))
  687. bytestream2quaternion(value, stream, address);
  688. }
  689. inline S32 get_state_event_opcoode_start(U8 *stream, S32 state, LSCRIPTStateEventType event)
  690. {
  691. // get the start of the state table
  692. S32 sr = get_register(stream, LREG_SR);
  693. // get the position of the jump to the desired state
  694. S32 value = get_register(stream, LREG_VN);
  695. S32 state_offset_offset = 0;
  696. S32 major_version = 0;
  697. if (value == LSL2_VERSION1_END_NUMBER)
  698. {
  699. major_version = LSL2_MAJOR_VERSION_ONE;
  700. state_offset_offset = sr + LSCRIPTDataSize[LST_INTEGER] + LSCRIPTDataSize[LST_INTEGER]*2*state;
  701. }
  702. else if (value == LSL2_VERSION_NUMBER)
  703. {
  704. major_version = LSL2_MAJOR_VERSION_TWO;
  705. state_offset_offset = sr + LSCRIPTDataSize[LST_INTEGER] + LSCRIPTDataSize[LST_INTEGER]*3*state;
  706. }
  707. if ( state_offset_offset < 0 || state_offset_offset > TOP_OF_MEMORY )
  708. {
  709. return -1;
  710. }
  711. // get the actual position in memory of the desired state
  712. S32 state_offset = sr + bytestream2integer(stream, state_offset_offset);
  713. if ( state_offset < 0 || state_offset > TOP_OF_MEMORY )
  714. {
  715. return -1;
  716. }
  717. // save that value
  718. S32 state_offset_base = state_offset;
  719. // jump past the state name
  720. S32 event_jump_offset = state_offset_base + bytestream2integer(stream, state_offset);
  721. // get the location of the event offset
  722. S32 event_offset = event_jump_offset + LSCRIPTDataSize[LST_INTEGER]*2*get_event_handler_jump_position(get_event_register(stream, LREG_ER, major_version), event);
  723. if ( event_offset < 0 || event_offset > TOP_OF_MEMORY )
  724. {
  725. return -1;
  726. }
  727. // now, jump to the event
  728. S32 event_start = bytestream2integer(stream, event_offset);
  729. if ( event_start < 0 || event_start > TOP_OF_MEMORY )
  730. {
  731. return -1;
  732. }
  733. event_start += event_jump_offset;
  734. S32 event_start_original = event_start;
  735. // now skip past the parameters
  736. S32 opcode_offset = bytestream2integer(stream, event_start);
  737. if ( opcode_offset < 0 || opcode_offset > TOP_OF_MEMORY )
  738. {
  739. return -1;
  740. }
  741. return opcode_offset + event_start_original;
  742. }
  743. inline U64 get_handled_events(U8 *stream, S32 state)
  744. {
  745. U64 retvalue = 0;
  746. // get the start of the state table
  747. S32 sr = get_register(stream, LREG_SR);
  748. // get the position of the jump to the desired state
  749. S32 value = get_register(stream, LREG_VN);
  750. S32 state_handled_offset = 0;
  751. if (value == LSL2_VERSION1_END_NUMBER)
  752. {
  753. state_handled_offset = sr + LSCRIPTDataSize[LST_INTEGER]*2*state + 2*LSCRIPTDataSize[LST_INTEGER];
  754. retvalue = bytestream2integer(stream, state_handled_offset);
  755. }
  756. else if (value == LSL2_VERSION_NUMBER)
  757. {
  758. state_handled_offset = sr + LSCRIPTDataSize[LST_INTEGER]*3*state + 2*LSCRIPTDataSize[LST_INTEGER];
  759. retvalue = bytestream2u64(stream, state_handled_offset);
  760. }
  761. // get the handled events
  762. return retvalue;
  763. }
  764. // Returns -1 on error
  765. inline S32 get_event_stack_size(U8 *stream, S32 state, LSCRIPTStateEventType event)
  766. {
  767. // get the start of the state table
  768. S32 sr = get_register(stream, LREG_SR);
  769. // get state offset
  770. S32 value = get_register(stream, LREG_VN);
  771. S32 state_offset_offset = 0;
  772. S32 major_version = 0;
  773. if (value == LSL2_VERSION1_END_NUMBER)
  774. {
  775. major_version = LSL2_MAJOR_VERSION_ONE;
  776. state_offset_offset = sr + LSCRIPTDataSize[LST_INTEGER] + LSCRIPTDataSize[LST_INTEGER]*2*state;
  777. }
  778. else if (value == LSL2_VERSION_NUMBER)
  779. {
  780. major_version = LSL2_MAJOR_VERSION_TWO;
  781. state_offset_offset = sr + LSCRIPTDataSize[LST_INTEGER] + LSCRIPTDataSize[LST_INTEGER]*3*state;
  782. }
  783. if ( state_offset_offset < 0 || state_offset_offset > TOP_OF_MEMORY )
  784. {
  785. return -1;
  786. }
  787. S32 state_offset = bytestream2integer(stream, state_offset_offset);
  788. state_offset += sr;
  789. state_offset_offset = state_offset;
  790. if ( state_offset_offset < 0 || state_offset_offset > TOP_OF_MEMORY )
  791. {
  792. return -1;
  793. }
  794. // skip to jump table
  795. S32 jump_table = bytestream2integer(stream, state_offset_offset);
  796. jump_table += state_offset;
  797. if ( jump_table < 0 || jump_table > TOP_OF_MEMORY )
  798. {
  799. return -1;
  800. }
  801. // get the position of the jump to the desired state
  802. S32 stack_size_offset = jump_table + LSCRIPTDataSize[LST_INTEGER]*2*get_event_handler_jump_position(get_event_register(stream, LREG_ER, major_version), event) + LSCRIPTDataSize[LST_INTEGER];
  803. // get the handled events
  804. S32 stack_size = bytestream2integer(stream, stack_size_offset);
  805. if ( stack_size < 0 || stack_size > TOP_OF_MEMORY )
  806. {
  807. return -1;
  808. }
  809. return stack_size;
  810. }
  811. inline LSCRIPTStateEventType return_first_event(S32 event)
  812. {
  813. S32 count = 1;
  814. while (count < LSTT_EOF)
  815. {
  816. if (event & 0x1)
  817. {
  818. return (LSCRIPTStateEventType) count;
  819. }
  820. else
  821. {
  822. event >>= 1;
  823. count++;
  824. }
  825. }
  826. return LSTT_NULL;
  827. }
  828. // the safe instruction versions of these commands will only work if offset is between
  829. // GFR and HR, meaning that it is an instruction (more or less) in global functions or event handlers
  830. inline BOOL safe_instruction_check_address(U8 *stream, S32 offset, S32 size)
  831. {
  832. S32 gfr = get_register(stream, LREG_GFR);
  833. if (offset < gfr)
  834. {
  835. set_fault(stream, LSRF_BOUND_CHECK_ERROR);
  836. return FALSE;
  837. }
  838. else
  839. {
  840. S32 hr = get_register(stream, LREG_HR);
  841. if (offset + size > hr)
  842. {
  843. set_fault(stream, LSRF_BOUND_CHECK_ERROR);
  844. return FALSE;
  845. }
  846. else
  847. {
  848. return TRUE;
  849. }
  850. }
  851. }
  852. inline BOOL safe_heap_check_address(U8 *stream, S32 offset, S32 size)
  853. {
  854. S32 hr = get_register(stream, LREG_HR);
  855. if (offset < hr)
  856. {
  857. set_fault(stream, LSRF_BOUND_CHECK_ERROR);
  858. return FALSE;
  859. }
  860. else
  861. {
  862. S32 hp = get_register(stream, LREG_HP);
  863. if (offset + size > hp)
  864. {
  865. set_fault(stream, LSRF_BOUND_CHECK_ERROR);
  866. return FALSE;
  867. }
  868. else
  869. {
  870. return TRUE;
  871. }
  872. }
  873. }
  874. inline U8 safe_instruction_bytestream2byte(U8 *stream, S32 &offset)
  875. {
  876. if (safe_instruction_check_address(stream, offset, 1))
  877. {
  878. return *(stream + offset++);
  879. }
  880. else
  881. {
  882. return 0;
  883. }
  884. }
  885. inline void safe_instruction_byte2bytestream(U8 *stream, S32 &offset, U8 byte)
  886. {
  887. if (safe_instruction_check_address(stream, offset, 1))
  888. {
  889. *(stream + offset++) = byte;
  890. }
  891. }
  892. inline S32 safe_instruction_bytestream2integer(U8 *stream, S32 &offset)
  893. {
  894. if (safe_instruction_check_address(stream, offset, LSCRIPTDataSize[LST_INTEGER]))
  895. {
  896. return (bytestream2integer(stream, offset));
  897. }
  898. else
  899. {
  900. return 0;
  901. }
  902. }
  903. inline void safe_instruction_integer2bytestream(U8 *stream, S32 &offset, S32 value)
  904. {
  905. if (safe_instruction_check_address(stream, offset, LSCRIPTDataSize[LST_INTEGER]))
  906. {
  907. integer2bytestream(stream, offset, value);
  908. }
  909. }
  910. inline U16 safe_instruction_bytestream2u16(U8 *stream, S32 &offset)
  911. {
  912. if (safe_instruction_check_address(stream, offset, 2))
  913. {
  914. return (bytestream2u16(stream, offset));
  915. }
  916. else
  917. {
  918. return 0;
  919. }
  920. }
  921. inline void safe_instruction_u162bytestream(U8 *stream, S32 &offset, U16 value)
  922. {
  923. if (safe_instruction_check_address(stream, offset, 2))
  924. {
  925. u162bytestream(stream, offset, value);
  926. }
  927. }
  928. inline F32 safe_instruction_bytestream2float(U8 *stream, S32 &offset)
  929. {
  930. if (safe_instruction_check_address(stream, offset, LSCRIPTDataSize[LST_INTEGER]))
  931. {
  932. F32 value = bytestream2float(stream, offset);
  933. if (!llfinite(value))
  934. {
  935. value = 0;
  936. set_fault(stream, LSRF_MATH);
  937. }
  938. return value;
  939. }
  940. else
  941. {
  942. return 0;
  943. }
  944. }
  945. inline void safe_instruction_float2bytestream(U8 *stream, S32 &offset, F32 value)
  946. {
  947. if (safe_instruction_check_address(stream, offset, LSCRIPTDataSize[LST_FLOATINGPOINT]))
  948. {
  949. float2bytestream(stream, offset, value);
  950. }
  951. }
  952. inline void safe_instruction_bytestream2char(char *buffer, U8 *stream, S32 &offset, S32 buffsize)
  953. {
  954. // This varies from the old method. Previously, we would copy up until we got an error,
  955. // then halt the script via safe_isntruction_check_address. Now we don't bother
  956. // copying a thing if there's an error.
  957. if( safe_instruction_check_address(stream, offset, strlen( (const char *)stream + offset ) + 1 ) )
  958. {
  959. // Takes the same parms as this function. Won't overread, per above check.
  960. bytestream2char( buffer, stream, offset, buffsize );
  961. }
  962. else
  963. {
  964. // Truncate - no point in copying
  965. *buffer = 0;
  966. }
  967. }
  968. inline void safe_instruction_bytestream_count_char(U8 *stream, S32 &offset)
  969. {
  970. while (  (safe_instruction_check_address(stream, offset, 1))
  971.    &&(*(stream + offset++)))
  972. ;
  973. }
  974. inline void safe_heap_bytestream_count_char(U8 *stream, S32 &offset)
  975. {
  976. while (  (safe_heap_check_address(stream, offset, 1))
  977.    &&(*(stream + offset++)))
  978. ;
  979. }
  980. inline void safe_instruction_char2bytestream(U8 *stream, S32 &offset, const char* buffer)
  981. {
  982. while (  (safe_instruction_check_address(stream, offset, 1))
  983.    &&(*(stream + offset++) = *buffer++))
  984. ;
  985. }
  986. inline void safe_instruction_bytestream2vector(LLVector3 &value, U8 *stream, S32 &offset)
  987. {
  988. if (safe_instruction_check_address(stream, offset, LSCRIPTDataSize[LST_VECTOR]))
  989. {
  990. bytestream2vector(value, stream, offset);
  991. }
  992. }
  993. inline void safe_instruction_vector2bytestream(U8 *stream, S32 &offset, const LLVector3 &value)
  994. {
  995. if (safe_instruction_check_address(stream, offset, LSCRIPTDataSize[LST_VECTOR]))
  996. {
  997. vector2bytestream(stream, offset, value);
  998. }
  999. }
  1000. inline void safe_instruction_bytestream2quaternion(LLQuaternion &value, U8 *stream, S32 &offset)
  1001. {
  1002. if (safe_instruction_check_address(stream, offset, LSCRIPTDataSize[LST_QUATERNION]))
  1003. {
  1004. bytestream2quaternion(value, stream, offset);
  1005. }
  1006. }
  1007. inline void safe_instruction_quaternion2bytestream(U8 *stream, S32 &offset, const LLQuaternion &value)
  1008. {
  1009. if (safe_instruction_check_address(stream, offset, LSCRIPTDataSize[LST_QUATERNION]))
  1010. {
  1011. quaternion2bytestream(stream, offset, value);
  1012. }
  1013. }
  1014. static inline LSCRIPTType char2type(char type)
  1015. {
  1016. switch(type)
  1017. {
  1018. case 'i':
  1019. return LST_INTEGER;
  1020. case 'f':
  1021. return LST_FLOATINGPOINT;
  1022. case 's':
  1023. return LST_STRING;
  1024. case 'k':
  1025. return LST_KEY;
  1026. case 'v':
  1027. return LST_VECTOR;
  1028. case 'q':
  1029. return LST_QUATERNION;
  1030. case 'l':
  1031. return LST_LIST;
  1032. default:
  1033. return LST_NULL;
  1034. }
  1035. }
  1036. #endif