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