PageRenderTime 42ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/indra/lscript/lscript_byteconvert.h

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