lscript_byteconvert.h

Go to the documentation of this file.
00001 
00032 // data shared between compiler/assembler
00033 // used to convert data between byte stream and outside data types
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 // remember that LScript byte stream is BigEndian
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 // vectors and quaternions and encoded in backwards order to match the way in which they are stored on the stack
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    // record the first error
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 //                  lsa_print_heap((U8 *)stream);
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         // Verify that the Instruction Pointer is in a valid
00413         // code area (between the Global Function Register
00414         // and Heap Register).
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         // Verify that the Base Pointer is in a valid
00439         // data area (between the Heap Pointer and
00440         // the Top of Memory, and below the
00441         // Stack Pointer).
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         // Verify that the Stack Pointer is in a valid
00467         // data area (between the Heap Pointer and
00468         // the Top of Memory).
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         // Possibility of overwriting registers?  -- DK 09/07/04
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         // get the start of the state table
00770         S32 sr = get_register(stream, LREG_SR);
00771 
00772         // get the position of the jump to the desired state
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         // get the actual position in memory of the desired state
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         // save that value
00800         S32 state_offset_base = state_offset;
00801 
00802         // jump past the state name
00803         S32 event_jump_offset = state_offset_base + bytestream2integer(stream, state_offset);
00804 
00805         // get the location of the event offset
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         // now, jump to the event
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         // now skip past the parameters
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         // get the start of the state table
00837         S32 sr = get_register(stream, LREG_SR);
00838 
00839         // get the position of the jump to the desired state
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         // get the handled events
00854         return retvalue;
00855 }
00856 
00857 // Returns -1 on error
00858 inline S32 get_event_stack_size(U8 *stream, S32 state, LSCRIPTStateEventType event)
00859 {
00860         // get the start of the state table
00861         S32 sr = get_register(stream, LREG_SR);
00862 
00863         // get state offset
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         // skip to jump table
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         // get the position of the jump to the desired state
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         // get the handled events
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 // the safe instruction versions of these commands will only work if offset is between
00934 // GFR and HR, meaning that it is an instruction (more or less) in global functions or event handlers
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

Generated on Thu Jul 1 06:09:49 2010 for Second Life Viewer by  doxygen 1.4.7