00001
00032
00033
00034
00035 #ifndef LL_LSCRIPT_BYTECONVERT_H
00036 #define LL_LSCRIPT_BYTECONVERT_H
00037
00038 #include "stdtypes.h"
00039 #include "v3math.h"
00040 #include "llquaternion.h"
00041 #include "lscript_byteformat.h"
00042 #include "lluuid.h"
00043
00044 void reset_hp_to_safe_spot(const U8 *buffer);
00045
00046
00047 void set_fault(const U8 *stream, LSCRIPTRunTimeFaults fault);
00048
00049 inline S32 bytestream2integer(const U8 *stream, S32 &offset)
00050 {
00051 stream += offset;
00052 offset += 4;
00053 return (*stream<<24) | (*(stream + 1)<<16) | (*(stream + 2)<<8) | *(stream + 3);
00054 }
00055
00056 inline U32 bytestream2unsigned_integer(const U8 *stream, S32 &offset)
00057 {
00058 stream += offset;
00059 offset += 4;
00060 return (*stream<<24) | (*(stream + 1)<<16) | (*(stream + 2)<<8) | *(stream + 3);
00061 }
00062
00063 inline U64 bytestream2u64(const U8 *stream, S32 &offset)
00064 {
00065 stream += offset;
00066 offset += 8;
00067 return ((U64)(*stream)<<56)| ((U64)(*(stream + 1))<<48) | ((U64)(*(stream + 2))<<40) | ((U64)(*(stream + 3))<<32) |
00068 ((U64)(*(stream + 4))<<24) | ((U64)(*(stream + 5))<<16) | ((U64)(*(stream + 6))<<8) | (U64)(*(stream + 7));
00069 }
00070
00071 inline void integer2bytestream(U8 *stream, S32 &offset, S32 integer)
00072 {
00073 stream += offset;
00074 offset += 4;
00075 *(stream) = (integer >> 24);
00076 *(stream + 1) = (integer >> 16) & 0xff;
00077 *(stream + 2) = (integer >> 8) & 0xff;
00078 *(stream + 3) = (integer) & 0xff;
00079 }
00080
00081 inline void unsigned_integer2bytestream(U8 *stream, S32 &offset, U32 integer)
00082 {
00083 stream += offset;
00084 offset += 4;
00085 *(stream) = (integer >> 24);
00086 *(stream + 1) = (integer >> 16) & 0xff;
00087 *(stream + 2) = (integer >> 8) & 0xff;
00088 *(stream + 3) = (integer) & 0xff;
00089 }
00090 inline void u642bytestream(U8 *stream, S32 &offset, U64 integer)
00091 {
00092 stream += offset;
00093 offset += 8;
00094 *(stream) = (U8)(integer >> 56);
00095 *(stream + 1) = (U8)((integer >> 48) & 0xff);
00096 *(stream + 2) = (U8)((integer >> 40) & 0xff);
00097 *(stream + 3) = (U8)((integer >> 32) & 0xff);
00098 *(stream + 4) = (U8)((integer >> 24) & 0xff);
00099 *(stream + 5) = (U8)((integer >> 16) & 0xff);
00100 *(stream + 6) = (U8)((integer >> 8) & 0xff);
00101 *(stream + 7) = (U8)((integer) & 0xff);
00102 }
00103
00104 inline S16 bytestream2s16(const U8 *stream, S32 &offset)
00105 {
00106 stream += offset;
00107 offset += 2;
00108 return (*stream<<8) | *(stream + 1);
00109 }
00110
00111 inline void s162bytestream(U8 *stream, S32 &offset, S16 integer)
00112 {
00113 stream += offset;
00114 offset += 2;
00115 *(stream) = (integer >> 8);
00116 *(stream + 1) = (integer) & 0xff;
00117 }
00118
00119 inline U16 bytestream2u16(const U8 *stream, S32 &offset)
00120 {
00121 stream += offset;
00122 offset += 2;
00123 return (*stream<<8) | *(stream + 1);
00124 }
00125
00126 inline void u162bytestream(U8 *stream, S32 &offset, U16 integer)
00127 {
00128 stream += offset;
00129 offset += 2;
00130 *(stream) = (integer >> 8);
00131 *(stream + 1) = (integer) & 0xff;
00132 }
00133
00134 inline F32 bytestream2float(const U8 *stream, S32 &offset)
00135 {
00136 S32 value = bytestream2integer(stream, offset);
00137 F32 fpvalue = *(F32 *)&value;
00138 if (!llfinite(fpvalue))
00139 {
00140 fpvalue = 0;
00141 set_fault(stream, LSRF_MATH);
00142 }
00143 return fpvalue;
00144 }
00145
00146 inline void float2bytestream(U8 *stream, S32 &offset, F32 floatingpoint)
00147 {
00148 S32 value = *(S32 *)&floatingpoint;
00149 integer2bytestream(stream, offset, value);
00150 }
00151
00152 inline void bytestream_int2float(U8 *stream, S32 &offset)
00153 {
00154 S32 value = bytestream2integer(stream, offset);
00155 offset -= 4;
00156 F32 fpvalue = (F32)value;
00157 if (!llfinite(fpvalue))
00158 {
00159 fpvalue = 0;
00160 set_fault(stream, LSRF_MATH);
00161 }
00162 float2bytestream(stream, offset, fpvalue);
00163 }
00164
00165 inline void bytestream2char(char *buffer, const U8 *stream, S32 &offset)
00166 {
00167 while ((*buffer++ = *(stream + offset++)))
00168 ;
00169 }
00170
00171 inline void char2bytestream(U8 *stream, S32 &offset, char *buffer)
00172 {
00173 while ((*(stream + offset++) = *buffer++))
00174 ;
00175 }
00176
00177 inline U8 bytestream2byte(const U8 *stream, S32 &offset)
00178 {
00179 return *(stream + offset++);
00180 }
00181
00182 inline void byte2bytestream(U8 *stream, S32 &offset, U8 byte)
00183 {
00184 *(stream + offset++) = byte;
00185 }
00186
00187 inline void bytestream2bytestream(U8 *dest, S32 &dest_offset, const U8 *src, S32 &src_offset, S32 count)
00188 {
00189 while (count)
00190 {
00191 (*(dest + dest_offset++)) = (*(src + src_offset++));
00192 count--;
00193 }
00194 }
00195
00196 inline void uuid2bytestream(U8 *stream, S32 &offset, const LLUUID &uuid)
00197 {
00198 S32 i;
00199 for (i = 0; i < UUID_BYTES; i++)
00200 {
00201 *(stream + offset++) = uuid.mData[i];
00202 }
00203 }
00204
00205 inline void bytestream2uuid(U8 *stream, S32 &offset, LLUUID &uuid)
00206 {
00207 S32 i;
00208 for (i = 0; i < UUID_BYTES; i++)
00209 {
00210 uuid.mData[i] = *(stream + offset++);
00211 }
00212 }
00213
00214
00215 inline void bytestream2vector(LLVector3 &vector, const U8 *stream, S32 &offset)
00216 {
00217 S32 value = bytestream2integer(stream, offset);
00218 vector.mV[VZ] = *(F32 *)&value;
00219 if (!llfinite(vector.mV[VZ]))
00220 {
00221 vector.mV[VZ] = 0;
00222 set_fault(stream, LSRF_MATH);
00223 }
00224 value = bytestream2integer(stream, offset);
00225 vector.mV[VY] = *(F32 *)&value;
00226 if (!llfinite(vector.mV[VY]))
00227 {
00228 vector.mV[VY] = 0;
00229 set_fault(stream, LSRF_MATH);
00230 }
00231 value = bytestream2integer(stream, offset);
00232 vector.mV[VX] = *(F32 *)&value;
00233 if (!llfinite(vector.mV[VX]))
00234 {
00235 vector.mV[VX] = 0;
00236 set_fault(stream, LSRF_MATH);
00237 }
00238 }
00239
00240 inline void vector2bytestream(U8 *stream, S32 &offset, LLVector3 &vector)
00241 {
00242 S32 value = *(S32 *)&vector.mV[VZ];
00243 integer2bytestream(stream, offset, value);
00244 value = *(S32 *)&vector.mV[VY];
00245 integer2bytestream(stream, offset, value);
00246 value = *(S32 *)&vector.mV[VX];
00247 integer2bytestream(stream, offset, value);
00248 }
00249
00250 inline void bytestream2quaternion(LLQuaternion &quat, const U8 *stream, S32 &offset)
00251 {
00252 S32 value = bytestream2integer(stream, offset);
00253 quat.mQ[VS] = *(F32 *)&value;
00254 if (!llfinite(quat.mQ[VS]))
00255 {
00256 quat.mQ[VS] = 0;
00257 set_fault(stream, LSRF_MATH);
00258 }
00259 value = bytestream2integer(stream, offset);
00260 quat.mQ[VZ] = *(F32 *)&value;
00261 if (!llfinite(quat.mQ[VZ]))
00262 {
00263 quat.mQ[VZ] = 0;
00264 set_fault(stream, LSRF_MATH);
00265 }
00266 value = bytestream2integer(stream, offset);
00267 quat.mQ[VY] = *(F32 *)&value;
00268 if (!llfinite(quat.mQ[VY]))
00269 {
00270 quat.mQ[VY] = 0;
00271 set_fault(stream, LSRF_MATH);
00272 }
00273 value = bytestream2integer(stream, offset);
00274 quat.mQ[VX] = *(F32 *)&value;
00275 if (!llfinite(quat.mQ[VX]))
00276 {
00277 quat.mQ[VX] = 0;
00278 set_fault(stream, LSRF_MATH);
00279 }
00280 }
00281
00282 inline void quaternion2bytestream(U8 *stream, S32 &offset, LLQuaternion &quat)
00283 {
00284 S32 value = *(S32 *)&quat.mQ[VS];
00285 integer2bytestream(stream, offset, value);
00286 value = *(S32 *)&quat.mQ[VZ];
00287 integer2bytestream(stream, offset, value);
00288 value = *(S32 *)&quat.mQ[VY];
00289 integer2bytestream(stream, offset, value);
00290 value = *(S32 *)&quat.mQ[VX];
00291 integer2bytestream(stream, offset, value);
00292 }
00293
00294 inline S32 get_register(const U8 *stream, LSCRIPTRegisters reg)
00295 {
00296 S32 offset = gLSCRIPTRegisterAddresses[reg];
00297 return bytestream2integer(stream, offset);
00298 }
00299
00300 inline F32 get_register_fp(U8 *stream, LSCRIPTRegisters reg)
00301 {
00302 S32 offset = gLSCRIPTRegisterAddresses[reg];
00303 F32 value = bytestream2float(stream, offset);
00304 if (!llfinite(value))
00305 {
00306 value = 0;
00307 set_fault(stream, LSRF_MATH);
00308 }
00309 return value;
00310 }
00311 inline U64 get_register_u64(U8 *stream, LSCRIPTRegisters reg)
00312 {
00313 S32 offset = gLSCRIPTRegisterAddresses[reg];
00314 return bytestream2u64(stream, offset);
00315 }
00316
00317 inline U64 get_event_register(U8 *stream, LSCRIPTRegisters reg, S32 major_version)
00318 {
00319 if (major_version == 1)
00320 {
00321 S32 offset = gLSCRIPTRegisterAddresses[reg];
00322 return (U64)bytestream2integer(stream, offset);
00323 }
00324 else if (major_version == 2)
00325 {
00326 S32 offset = gLSCRIPTRegisterAddresses[reg + (LREG_NCE - LREG_CE)];
00327 return bytestream2u64(stream, offset);
00328 }
00329 else
00330 {
00331 S32 offset = gLSCRIPTRegisterAddresses[reg];
00332 return (U64)bytestream2integer(stream, offset);
00333 }
00334 }
00335
00336 inline void set_register(U8 *stream, LSCRIPTRegisters reg, S32 value)
00337 {
00338 S32 offset = gLSCRIPTRegisterAddresses[reg];
00339 integer2bytestream(stream, offset, value);
00340 }
00341
00342 inline void set_register_fp(U8 *stream, LSCRIPTRegisters reg, F32 value)
00343 {
00344 S32 offset = gLSCRIPTRegisterAddresses[reg];
00345 float2bytestream(stream, offset, value);
00346 }
00347
00348 inline void set_register_u64(U8 *stream, LSCRIPTRegisters reg, U64 value)
00349 {
00350 S32 offset = gLSCRIPTRegisterAddresses[reg];
00351 u642bytestream(stream, offset, value);
00352 }
00353
00354 inline void set_event_register(U8 *stream, LSCRIPTRegisters reg, U64 value, S32 major_version)
00355 {
00356 if (major_version == 1)
00357 {
00358 S32 offset = gLSCRIPTRegisterAddresses[reg];
00359 integer2bytestream(stream, offset, (S32)value);
00360 }
00361 else if (major_version == 2)
00362 {
00363 S32 offset = gLSCRIPTRegisterAddresses[reg + (LREG_NCE - LREG_CE)];
00364 u642bytestream(stream, offset, value);
00365 }
00366 else
00367 {
00368 S32 offset = gLSCRIPTRegisterAddresses[reg];
00369 integer2bytestream(stream, offset, (S32)value);
00370 }
00371 }
00372
00373
00374 inline F32 add_register_fp(U8 *stream, LSCRIPTRegisters reg, F32 value)
00375 {
00376 S32 offset = gLSCRIPTRegisterAddresses[reg];
00377 F32 newvalue = bytestream2float(stream, offset);
00378 newvalue += value;
00379 if (!llfinite(newvalue))
00380 {
00381 newvalue = 0;
00382 set_fault(stream, LSRF_MATH);
00383 }
00384 offset = gLSCRIPTRegisterAddresses[reg];
00385 float2bytestream(stream, offset, newvalue);
00386 return newvalue;
00387 }
00388
00389 void lsa_print_heap(U8 *buffer);
00390
00391
00392 inline void set_fault(const U8 *stream, LSCRIPTRunTimeFaults fault)
00393 {
00394 S32 fr = get_register(stream, LREG_FR);
00395
00396 if (!fr)
00397 {
00398 if ( (fault == LSRF_HEAP_ERROR)
00399 ||(fault == LSRF_STACK_HEAP_COLLISION)
00400 ||(fault == LSRF_BOUND_CHECK_ERROR))
00401 {
00402 reset_hp_to_safe_spot(stream);
00403
00404 }
00405 fr = LSCRIPTRunTimeFaultBits[fault];
00406 set_register((U8 *)stream, LREG_FR, fr);
00407 }
00408 }
00409
00410 inline BOOL set_ip(U8 *stream, S32 ip)
00411 {
00412
00413
00414
00415 S32 gfr = get_register(stream, LREG_GFR);
00416 if (ip == 0)
00417 {
00418 set_register(stream, LREG_IP, ip);
00419 return TRUE;
00420 }
00421 if (ip < gfr)
00422 {
00423 set_fault(stream, LSRF_BOUND_CHECK_ERROR);
00424 return FALSE;
00425 }
00426 S32 hr = get_register(stream, LREG_HR);
00427 if (ip >= hr)
00428 {
00429 set_fault(stream, LSRF_BOUND_CHECK_ERROR);
00430 return FALSE;
00431 }
00432 set_register(stream, LREG_IP, ip);
00433 return TRUE;
00434 }
00435
00436 inline BOOL set_bp(U8 *stream, S32 bp)
00437 {
00438
00439
00440
00441
00442 S32 hp = get_register(stream, LREG_HP);
00443 if (bp <= hp)
00444 {
00445 set_fault(stream, LSRF_STACK_HEAP_COLLISION);
00446 return FALSE;
00447 }
00448 S32 tm = get_register(stream, LREG_TM);
00449 if (bp >= tm)
00450 {
00451 set_fault(stream, LSRF_BOUND_CHECK_ERROR);
00452 return FALSE;
00453 }
00454 S32 sp = get_register(stream, LREG_SP);
00455 if (bp < sp)
00456 {
00457 set_fault(stream, LSRF_BOUND_CHECK_ERROR);
00458 return FALSE;
00459 }
00460 set_register(stream, LREG_BP, bp);
00461 return TRUE;
00462 }
00463
00464 inline BOOL set_sp(U8 *stream, S32 sp)
00465 {
00466
00467
00468
00469 S32 hp = get_register(stream, LREG_HP);
00470 if (sp <= hp)
00471 {
00472 set_fault(stream, LSRF_STACK_HEAP_COLLISION);
00473 return FALSE;
00474 }
00475 S32 tm = get_register(stream, LREG_TM);
00476 if (sp >= tm)
00477 {
00478 set_fault(stream, LSRF_BOUND_CHECK_ERROR);
00479 return FALSE;
00480 }
00481 set_register(stream, LREG_SP, sp);
00482 return TRUE;
00483 }
00484
00485 inline void lscript_push(U8 *stream, U8 value)
00486 {
00487 S32 sp = get_register(stream, LREG_SP);
00488 sp -= 1;
00489
00490 if (set_sp(stream, sp))
00491 {
00492 *(stream + sp) = value;
00493 }
00494 }
00495
00496 inline void lscript_push(U8 *stream, S32 value)
00497 {
00498 S32 sp = get_register(stream, LREG_SP);
00499 sp -= LSCRIPTDataSize[LST_INTEGER];
00500
00501 if (set_sp(stream, sp))
00502 {
00503 integer2bytestream(stream, sp, value);
00504 }
00505 }
00506
00507 inline void lscript_push(U8 *stream, F32 value)
00508 {
00509 S32 sp = get_register(stream, LREG_SP);
00510 sp -= LSCRIPTDataSize[LST_FLOATINGPOINT];
00511
00512 if (set_sp(stream, sp))
00513 {
00514 float2bytestream(stream, sp, value);
00515 }
00516 }
00517
00518 inline void lscript_push(U8 *stream, LLVector3 &value)
00519 {
00520 S32 sp = get_register(stream, LREG_SP);
00521 sp -= LSCRIPTDataSize[LST_VECTOR];
00522
00523 if (set_sp(stream, sp))
00524 {
00525 vector2bytestream(stream, sp, value);
00526 }
00527 }
00528
00529 inline void lscript_push(U8 *stream, LLQuaternion &value)
00530 {
00531 S32 sp = get_register(stream, LREG_SP);
00532 sp -= LSCRIPTDataSize[LST_QUATERNION];
00533
00534 if (set_sp(stream, sp))
00535 {
00536 quaternion2bytestream(stream, sp, value);
00537 }
00538 }
00539
00540 inline void lscript_pusharg(U8 *stream, S32 arg)
00541 {
00542 S32 sp = get_register(stream, LREG_SP);
00543 sp -= arg;
00544
00545 set_sp(stream, sp);
00546 }
00547
00548 inline void lscript_poparg(U8 *stream, S32 arg)
00549 {
00550 S32 sp = get_register(stream, LREG_SP);
00551 sp += arg;
00552
00553 set_sp(stream, sp);
00554 }
00555
00556 inline U8 lscript_pop_char(U8 *stream)
00557 {
00558 S32 sp = get_register(stream, LREG_SP);
00559 U8 value = *(stream + sp++);
00560 set_sp(stream, sp);
00561 return value;
00562 }
00563
00564 inline S32 lscript_pop_int(U8 *stream)
00565 {
00566 S32 sp = get_register(stream, LREG_SP);
00567 S32 value = bytestream2integer(stream, sp);
00568 set_sp(stream, sp);
00569 return value;
00570 }
00571
00572 inline F32 lscript_pop_float(U8 *stream)
00573 {
00574 S32 sp = get_register(stream, LREG_SP);
00575 F32 value = bytestream2float(stream, sp);
00576 if (!llfinite(value))
00577 {
00578 value = 0;
00579 set_fault(stream, LSRF_MATH);
00580 }
00581 set_sp(stream, sp);
00582 return value;
00583 }
00584
00585 inline void lscript_pop_vector(U8 *stream, LLVector3 &value)
00586 {
00587 S32 sp = get_register(stream, LREG_SP);
00588 bytestream2vector(value, stream, sp);
00589 set_sp(stream, sp);
00590 }
00591
00592 inline void lscript_pop_quaternion(U8 *stream, LLQuaternion &value)
00593 {
00594 S32 sp = get_register(stream, LREG_SP);
00595 bytestream2quaternion(value, stream, sp);
00596 set_sp(stream, sp);
00597 }
00598
00599 inline void lscript_pusharge(U8 *stream, S32 value)
00600 {
00601 S32 sp = get_register(stream, LREG_SP);
00602 sp -= value;
00603 if (set_sp(stream, sp))
00604 {
00605 S32 i;
00606 for (i = 0; i < value; i++)
00607 {
00608 *(stream + sp++) = 0;
00609 }
00610 }
00611 }
00612
00613 inline BOOL lscript_check_local(U8 *stream, S32 &address, S32 size)
00614 {
00615 S32 sp = get_register(stream, LREG_SP);
00616 S32 bp = get_register(stream, LREG_BP);
00617
00618 address += size;
00619 address = bp - address;
00620
00621 if (address < sp - size)
00622 {
00623 set_fault(stream, LSRF_BOUND_CHECK_ERROR);
00624 return FALSE;
00625 }
00626 S32 tm = get_register(stream, LREG_TM);
00627 if (address + size > tm)
00628 {
00629 set_fault(stream, LSRF_BOUND_CHECK_ERROR);
00630 return FALSE;
00631 }
00632 return TRUE;
00633 }
00634
00635 inline BOOL lscript_check_global(U8 *stream, S32 &address, S32 size)
00636 {
00637 S32 gvr = get_register(stream, LREG_GVR);
00638
00639
00640 if (address < 0)
00641 {
00642 set_fault(stream, LSRF_BOUND_CHECK_ERROR);
00643 return FALSE;
00644 }
00645
00646 address += gvr;
00647 S32 gfr = get_register(stream, LREG_GFR);
00648
00649 if (address + size > gfr)
00650 {
00651 set_fault(stream, LSRF_BOUND_CHECK_ERROR);
00652 return FALSE;
00653 }
00654 return TRUE;
00655 }
00656
00657 inline void lscript_local_store(U8 *stream, S32 address, S32 value)
00658 {
00659 if (lscript_check_local(stream, address, LSCRIPTDataSize[LST_INTEGER]))
00660 integer2bytestream(stream, address, value);
00661 }
00662
00663 inline void lscript_local_store(U8 *stream, S32 address, F32 value)
00664 {
00665 if (lscript_check_local(stream, address, LSCRIPTDataSize[LST_FLOATINGPOINT]))
00666 float2bytestream(stream, address, value);
00667 }
00668
00669 inline void lscript_local_store(U8 *stream, S32 address, LLVector3 value)
00670 {
00671 if (lscript_check_local(stream, address, LSCRIPTDataSize[LST_VECTOR]))
00672 vector2bytestream(stream, address, value);
00673 }
00674
00675 inline void lscript_local_store(U8 *stream, S32 address, LLQuaternion value)
00676 {
00677 if (lscript_check_local(stream, address, LSCRIPTDataSize[LST_QUATERNION]))
00678 quaternion2bytestream(stream, address, value);
00679 }
00680
00681 inline void lscript_global_store(U8 *stream, S32 address, S32 value)
00682 {
00683 if (lscript_check_global(stream, address, LSCRIPTDataSize[LST_INTEGER]))
00684 integer2bytestream(stream, address, value);
00685 }
00686
00687 inline void lscript_global_store(U8 *stream, S32 address, F32 value)
00688 {
00689 if (lscript_check_global(stream, address, LSCRIPTDataSize[LST_FLOATINGPOINT]))
00690 float2bytestream(stream, address, value);
00691 }
00692
00693 inline void lscript_global_store(U8 *stream, S32 address, LLVector3 value)
00694 {
00695 if (lscript_check_global(stream, address, LSCRIPTDataSize[LST_VECTOR]))
00696 vector2bytestream(stream, address, value);
00697 }
00698
00699 inline void lscript_global_store(U8 *stream, S32 address, LLQuaternion value)
00700 {
00701 if (lscript_check_global(stream, address, LSCRIPTDataSize[LST_QUATERNION]))
00702 quaternion2bytestream(stream, address, value);
00703 }
00704
00705 inline S32 lscript_local_get(U8 *stream, S32 address)
00706 {
00707 if (lscript_check_local(stream, address, LSCRIPTDataSize[LST_INTEGER]))
00708 return bytestream2integer(stream, address);
00709 return 0;
00710 }
00711
00712 inline void lscript_local_get(U8 *stream, S32 address, F32 &value)
00713 {
00714 if (lscript_check_local(stream, address, LSCRIPTDataSize[LST_FLOATINGPOINT]))
00715 value = bytestream2float(stream, address);
00716 if (!llfinite(value))
00717 {
00718 value = 0;
00719 set_fault(stream, LSRF_MATH);
00720 }
00721 }
00722
00723 inline void lscript_local_get(U8 *stream, S32 address, LLVector3 &value)
00724 {
00725 if (lscript_check_local(stream, address, LSCRIPTDataSize[LST_VECTOR]))
00726 bytestream2vector(value, stream, address);
00727 }
00728
00729 inline void lscript_local_get(U8 *stream, S32 address, LLQuaternion &value)
00730 {
00731 if (lscript_check_local(stream, address, LSCRIPTDataSize[LST_QUATERNION]))
00732 bytestream2quaternion(value, stream, address);
00733 }
00734
00735 inline S32 lscript_global_get(U8 *stream, S32 address)
00736 {
00737 if (lscript_check_global(stream, address, LSCRIPTDataSize[LST_INTEGER]))
00738 return bytestream2integer(stream, address);
00739 return 0;
00740 }
00741
00742 inline void lscript_global_get(U8 *stream, S32 address, F32 &value)
00743 {
00744 if (lscript_check_global(stream, address, LSCRIPTDataSize[LST_FLOATINGPOINT]))
00745 value = bytestream2float(stream, address);
00746 if (!llfinite(value))
00747 {
00748 value = 0;
00749 set_fault(stream, LSRF_MATH);
00750 }
00751 }
00752
00753 inline void lscript_global_get(U8 *stream, S32 address, LLVector3 &value)
00754 {
00755 if (lscript_check_global(stream, address, LSCRIPTDataSize[LST_VECTOR]))
00756 bytestream2vector(value, stream, address);
00757 }
00758
00759 inline void lscript_global_get(U8 *stream, S32 address, LLQuaternion &value)
00760 {
00761 if (lscript_check_global(stream, address, LSCRIPTDataSize[LST_QUATERNION]))
00762 bytestream2quaternion(value, stream, address);
00763 }
00764
00765
00766
00767 inline S32 get_state_event_opcoode_start(U8 *stream, S32 state, LSCRIPTStateEventType event)
00768 {
00769
00770 S32 sr = get_register(stream, LREG_SR);
00771
00772
00773 S32 value = get_register(stream, LREG_VN);
00774
00775 S32 state_offset_offset = 0;
00776 S32 major_version = 0;
00777 if (value == LSL2_VERSION1_END_NUMBER)
00778 {
00779 major_version = LSL2_MAJOR_VERSION_ONE;
00780 state_offset_offset = sr + LSCRIPTDataSize[LST_INTEGER] + LSCRIPTDataSize[LST_INTEGER]*2*state;
00781 }
00782 else if (value == LSL2_VERSION_NUMBER)
00783 {
00784 major_version = LSL2_MAJOR_VERSION_TWO;
00785 state_offset_offset = sr + LSCRIPTDataSize[LST_INTEGER] + LSCRIPTDataSize[LST_INTEGER]*3*state;
00786 }
00787 if ( state_offset_offset < 0 || state_offset_offset > TOP_OF_MEMORY )
00788 {
00789 return -1;
00790 }
00791
00792
00793 S32 state_offset = sr + bytestream2integer(stream, state_offset_offset);
00794 if ( state_offset < 0 || state_offset > TOP_OF_MEMORY )
00795 {
00796 return -1;
00797 }
00798
00799
00800 S32 state_offset_base = state_offset;
00801
00802
00803 S32 event_jump_offset = state_offset_base + bytestream2integer(stream, state_offset);
00804
00805
00806 S32 event_offset = event_jump_offset + LSCRIPTDataSize[LST_INTEGER]*2*get_event_handler_jump_position(get_event_register(stream, LREG_ER, major_version), event);
00807 if ( event_offset < 0 || event_offset > TOP_OF_MEMORY )
00808 {
00809 return -1;
00810 }
00811
00812
00813 S32 event_start = bytestream2integer(stream, event_offset);
00814 if ( event_start < 0 || event_start > TOP_OF_MEMORY )
00815 {
00816 return -1;
00817 }
00818 event_start += event_jump_offset;
00819
00820 S32 event_start_original = event_start;
00821
00822
00823 S32 opcode_offset = bytestream2integer(stream, event_start);
00824 if ( opcode_offset < 0 || opcode_offset > TOP_OF_MEMORY )
00825 {
00826 return -1;
00827 }
00828
00829 return opcode_offset + event_start_original;
00830 }
00831
00832
00833 inline U64 get_handled_events(U8 *stream, S32 state)
00834 {
00835 U64 retvalue = 0;
00836
00837 S32 sr = get_register(stream, LREG_SR);
00838
00839
00840 S32 value = get_register(stream, LREG_VN);
00841 S32 state_handled_offset = 0;
00842 if (value == LSL2_VERSION1_END_NUMBER)
00843 {
00844 state_handled_offset = sr + LSCRIPTDataSize[LST_INTEGER]*2*state + 2*LSCRIPTDataSize[LST_INTEGER];
00845 retvalue = bytestream2integer(stream, state_handled_offset);
00846 }
00847 else if (value == LSL2_VERSION_NUMBER)
00848 {
00849 state_handled_offset = sr + LSCRIPTDataSize[LST_INTEGER]*3*state + 2*LSCRIPTDataSize[LST_INTEGER];
00850 retvalue = bytestream2u64(stream, state_handled_offset);
00851 }
00852
00853
00854 return retvalue;
00855 }
00856
00857
00858 inline S32 get_event_stack_size(U8 *stream, S32 state, LSCRIPTStateEventType event)
00859 {
00860
00861 S32 sr = get_register(stream, LREG_SR);
00862
00863
00864 S32 value = get_register(stream, LREG_VN);
00865 S32 state_offset_offset = 0;
00866 S32 major_version = 0;
00867 if (value == LSL2_VERSION1_END_NUMBER)
00868 {
00869 major_version = LSL2_MAJOR_VERSION_ONE;
00870 state_offset_offset = sr + LSCRIPTDataSize[LST_INTEGER] + LSCRIPTDataSize[LST_INTEGER]*2*state;
00871 }
00872 else if (value == LSL2_VERSION_NUMBER)
00873 {
00874 major_version = LSL2_MAJOR_VERSION_TWO;
00875 state_offset_offset = sr + LSCRIPTDataSize[LST_INTEGER] + LSCRIPTDataSize[LST_INTEGER]*3*state;
00876 }
00877
00878 if ( state_offset_offset < 0 || state_offset_offset > TOP_OF_MEMORY )
00879 {
00880 return -1;
00881 }
00882
00883 S32 state_offset = bytestream2integer(stream, state_offset_offset);
00884 state_offset += sr;
00885
00886 state_offset_offset = state_offset;
00887 if ( state_offset_offset < 0 || state_offset_offset > TOP_OF_MEMORY )
00888 {
00889 return -1;
00890 }
00891
00892
00893 S32 jump_table = bytestream2integer(stream, state_offset_offset);
00894
00895 jump_table += state_offset;
00896 if ( jump_table < 0 || jump_table > TOP_OF_MEMORY )
00897 {
00898 return -1;
00899 }
00900
00901
00902 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];
00903
00904
00905 S32 stack_size = bytestream2integer(stream, stack_size_offset);
00906 if ( stack_size < 0 || stack_size > TOP_OF_MEMORY )
00907 {
00908 return -1;
00909 }
00910
00911 return stack_size;
00912 }
00913
00914 inline LSCRIPTStateEventType return_first_event(S32 event)
00915 {
00916 S32 count = 1;
00917 while (count < LSTT_EOF)
00918 {
00919 if (event & 0x1)
00920 {
00921 return (LSCRIPTStateEventType) count;
00922 }
00923 else
00924 {
00925 event >>= 1;
00926 count++;
00927 }
00928 }
00929 return LSTT_NULL;
00930 }
00931
00932
00933
00934
00935
00936 inline BOOL safe_instruction_check_address(U8 *stream, S32 offset, S32 size)
00937 {
00938 S32 gfr = get_register(stream, LREG_GFR);
00939 if (offset < gfr)
00940 {
00941 set_fault(stream, LSRF_BOUND_CHECK_ERROR);
00942 return FALSE;
00943 }
00944 else
00945 {
00946 S32 hr = get_register(stream, LREG_HR);
00947 if (offset + size > hr)
00948 {
00949 set_fault(stream, LSRF_BOUND_CHECK_ERROR);
00950 return FALSE;
00951 }
00952 else
00953 {
00954 return TRUE;
00955 }
00956 }
00957 }
00958
00959 inline BOOL safe_heap_check_address(U8 *stream, S32 offset, S32 size)
00960 {
00961 S32 hr = get_register(stream, LREG_HR);
00962 if (offset < hr)
00963 {
00964 set_fault(stream, LSRF_BOUND_CHECK_ERROR);
00965 return FALSE;
00966 }
00967 else
00968 {
00969 S32 hp = get_register(stream, LREG_HP);
00970 if (offset + size > hp)
00971 {
00972 set_fault(stream, LSRF_BOUND_CHECK_ERROR);
00973 return FALSE;
00974 }
00975 else
00976 {
00977 return TRUE;
00978 }
00979 }
00980 }
00981
00982 inline U8 safe_instruction_bytestream2byte(U8 *stream, S32 &offset)
00983 {
00984 if (safe_instruction_check_address(stream, offset, 1))
00985 {
00986 return *(stream + offset++);
00987 }
00988 else
00989 {
00990 return 0;
00991 }
00992 }
00993
00994 inline void safe_instruction_byte2bytestream(U8 *stream, S32 &offset, U8 byte)
00995 {
00996 if (safe_instruction_check_address(stream, offset, 1))
00997 {
00998 *(stream + offset++) = byte;
00999 }
01000 }
01001
01002 inline S32 safe_instruction_bytestream2integer(U8 *stream, S32 &offset)
01003 {
01004 if (safe_instruction_check_address(stream, offset, LSCRIPTDataSize[LST_INTEGER]))
01005 {
01006 return (bytestream2integer(stream, offset));
01007 }
01008 else
01009 {
01010 return 0;
01011 }
01012 }
01013
01014 inline void safe_instruction_integer2bytestream(U8 *stream, S32 &offset, S32 value)
01015 {
01016 if (safe_instruction_check_address(stream, offset, LSCRIPTDataSize[LST_INTEGER]))
01017 {
01018 integer2bytestream(stream, offset, value);
01019 }
01020 }
01021
01022 inline U16 safe_instruction_bytestream2u16(U8 *stream, S32 &offset)
01023 {
01024 if (safe_instruction_check_address(stream, offset, 2))
01025 {
01026 return (bytestream2u16(stream, offset));
01027 }
01028 else
01029 {
01030 return 0;
01031 }
01032 }
01033
01034 inline void safe_instruction_u162bytestream(U8 *stream, S32 &offset, U16 value)
01035 {
01036 if (safe_instruction_check_address(stream, offset, 2))
01037 {
01038 u162bytestream(stream, offset, value);
01039 }
01040 }
01041
01042 inline F32 safe_instruction_bytestream2float(U8 *stream, S32 &offset)
01043 {
01044 if (safe_instruction_check_address(stream, offset, LSCRIPTDataSize[LST_INTEGER]))
01045 {
01046 F32 value = bytestream2float(stream, offset);
01047 if (!llfinite(value))
01048 {
01049 value = 0;
01050 set_fault(stream, LSRF_MATH);
01051 }
01052 return value;
01053 }
01054 else
01055 {
01056 return 0;
01057 }
01058 }
01059
01060 inline void safe_instruction_float2bytestream(U8 *stream, S32 &offset, F32 value)
01061 {
01062 if (safe_instruction_check_address(stream, offset, LSCRIPTDataSize[LST_FLOATINGPOINT]))
01063 {
01064 float2bytestream(stream, offset, value);
01065 }
01066 }
01067
01068 inline void safe_instruction_bytestream2char(char *buffer, U8 *stream, S32 &offset)
01069 {
01070 while ( (safe_instruction_check_address(stream, offset, 1))
01071 &&(*buffer++ = *(stream + offset++)))
01072 ;
01073 }
01074
01075 inline void safe_instruction_bytestream_count_char(U8 *stream, S32 &offset)
01076 {
01077 while ( (safe_instruction_check_address(stream, offset, 1))
01078 &&(*(stream + offset++)))
01079 ;
01080 }
01081
01082 inline void safe_heap_bytestream_count_char(U8 *stream, S32 &offset)
01083 {
01084 while ( (safe_heap_check_address(stream, offset, 1))
01085 &&(*(stream + offset++)))
01086 ;
01087 }
01088
01089 inline void safe_instruction_char2bytestream(U8 *stream, S32 &offset, char *buffer)
01090 {
01091 while ( (safe_instruction_check_address(stream, offset, 1))
01092 &&(*(stream + offset++) = *buffer++))
01093 ;
01094 }
01095
01096 inline void safe_instruction_bytestream2vector(LLVector3 &value, U8 *stream, S32 &offset)
01097 {
01098 if (safe_instruction_check_address(stream, offset, LSCRIPTDataSize[LST_VECTOR]))
01099 {
01100 bytestream2vector(value, stream, offset);
01101 }
01102 }
01103
01104 inline void safe_instruction_vector2bytestream(U8 *stream, S32 &offset, LLVector3 &value)
01105 {
01106 if (safe_instruction_check_address(stream, offset, LSCRIPTDataSize[LST_VECTOR]))
01107 {
01108 vector2bytestream(stream, offset, value);
01109 }
01110 }
01111
01112 inline void safe_instruction_bytestream2quaternion(LLQuaternion &value, U8 *stream, S32 &offset)
01113 {
01114 if (safe_instruction_check_address(stream, offset, LSCRIPTDataSize[LST_QUATERNION]))
01115 {
01116 bytestream2quaternion(value, stream, offset);
01117 }
01118 }
01119
01120 inline void safe_instruction_quaternion2bytestream(U8 *stream, S32 &offset, LLQuaternion &value)
01121 {
01122 if (safe_instruction_check_address(stream, offset, LSCRIPTDataSize[LST_QUATERNION]))
01123 {
01124 quaternion2bytestream(stream, offset, value);
01125 }
01126 }
01127
01128 static inline LSCRIPTType char2type(char type)
01129 {
01130 switch(type)
01131 {
01132 case 'i':
01133 return LST_INTEGER;
01134 case 'f':
01135 return LST_FLOATINGPOINT;
01136 case 's':
01137 return LST_STRING;
01138 case 'k':
01139 return LST_KEY;
01140 case 'v':
01141 return LST_VECTOR;
01142 case 'q':
01143 return LST_QUATERNION;
01144 case 'l':
01145 return LST_LIST;
01146 default:
01147 return LST_NULL;
01148 }
01149 }
01150
01151 #endif