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 // Returns true on success, return false and clip copy on buffer overflow
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         // strncpy without \0 padding overhead
00176         memcpy( buffer, stream+offset, copy_len );
00177         buffer[copy_len] = 0;
00178 
00179         offset += source_len + 1; // advance past source string, include terminating '\0'
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 // vectors and quaternions and encoded in backwards order to match the way in which they are stored on the stack
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    // record the first error
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 //                  lsa_print_heap((U8 *)stream);
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         // Verify that the Instruction Pointer is in a valid
00426         // code area (between the Global Function Register
00427         // and Heap Register).
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         // Verify that the Base Pointer is in a valid
00452         // data area (between the Heap Pointer and
00453         // the Top of Memory, and below the
00454         // Stack Pointer).
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         // Verify that the Stack Pointer is in a valid
00480         // data area (between the Heap Pointer and
00481         // the Top of Memory).
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         // Possibility of overwriting registers?  -- DK 09/07/04
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         // get the start of the state table
00783         S32 sr = get_register(stream, LREG_SR);
00784 
00785         // get the position of the jump to the desired state
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         // get the actual position in memory of the desired state
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         // save that value
00813         S32 state_offset_base = state_offset;
00814 
00815         // jump past the state name
00816         S32 event_jump_offset = state_offset_base + bytestream2integer(stream, state_offset);
00817 
00818         // get the location of the event offset
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         // now, jump to the event
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         // now skip past the parameters
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         // get the start of the state table
00850         S32 sr = get_register(stream, LREG_SR);
00851 
00852         // get the position of the jump to the desired state
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         // get the handled events
00867         return retvalue;
00868 }
00869 
00870 // Returns -1 on error
00871 inline S32 get_event_stack_size(U8 *stream, S32 state, LSCRIPTStateEventType event)
00872 {
00873         // get the start of the state table
00874         S32 sr = get_register(stream, LREG_SR);
00875 
00876         // get state offset
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         // skip to jump table
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         // get the position of the jump to the desired state
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         // get the handled events
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 // the safe instruction versions of these commands will only work if offset is between
00947 // GFR and HR, meaning that it is an instruction (more or less) in global functions or event handlers
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         // This varies from the old method. Previously, we would copy up until we got an error,
01084         // then halt the script via safe_isntruction_check_address. Now we don't bother
01085         // copying a thing if there's an error.
01086 
01087         if( safe_instruction_check_address(stream, offset, strlen( (const char *)stream + offset ) + 1 ) )
01088         {
01089                 // Takes the same parms as this function. Won't overread, per above check.
01090                 bytestream2char( buffer, stream, offset, buffsize );
01091         }
01092         else
01093         {
01094                 // Truncate - no point in copying
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

Generated on Fri May 16 08:33:06 2008 for SecondLife by  doxygen 1.5.5