lscript_execute.cpp

Go to the documentation of this file.
00001 
00032 #include "linden_common.h"
00033 
00034 #include <sstream>
00035 
00036 #include "lscript_execute.h"
00037 #include "lltimer.h"
00038 #include "lscript_readlso.h"
00039 #include "lscript_library.h"
00040 #include "lscript_heapruntime.h"
00041 #include "lscript_alloc.h"
00042 
00043 void (*binary_operations[LST_EOF][LST_EOF])(U8 *buffer, LSCRIPTOpCodesEnum opcode);
00044 void (*unary_operations[LST_EOF])(U8 *buffer, LSCRIPTOpCodesEnum opcode);
00045 
00046 char* LSCRIPTRunTimeFaultStrings[LSRF_EOF] =            /*Flawfinder: ignore*/
00047 {
00048         "invalid",                              //      LSRF_INVALID,
00049         "Math Error",                   //      LSRF_MATH,
00050         "Stack-Heap Collision", //      LSRF_STACK_HEAP_COLLISION,
00051         "Bounds Check Error",   //      LSRF_BOUND_CHECK_ERROR,
00052         "Heap Error",                   //      LSRF_HEAP_ERROR,
00053         "Version Mismatch",             //      LSRF_VERSION_MISMATCH,
00054         "Missing Inventory",    //      LSRF_MISSING_INVENTORY,
00055         "Hit Sandbox Limit",    //      LSRF_SANDBOX,
00056         "Chat Overrun",                 //      LSRF_CHAT_OVERRUN,
00057         "Too Many Listens",                       //    LSRF_TOO_MANY_LISTENS,
00058         "Lists may not contain lists" //        LSRF_NESTING_LISTS,
00059 };
00060 
00061 //static
00062 S64 LLScriptExecute::sGlobalInstructionCount = 0;
00063 
00064 LLScriptExecute::LLScriptExecute(FILE *fp)
00065 {
00066         U8  sizearray[4];
00067         S32 filesize;
00068         S32 pos = 0;
00069         if (fread(&sizearray, 1, 4, fp) != 4)
00070         {
00071                 llwarns << "Short read" << llendl;
00072                 filesize = 0;
00073         } else {
00074                 filesize = bytestream2integer(sizearray, pos);
00075         }
00076         mBuffer = new U8[filesize];
00077         fseek(fp, 0, SEEK_SET);
00078         if (fread(mBuffer, 1, filesize, fp) != filesize)
00079         {
00080                 llwarns << "Short read" << llendl;
00081         }
00082         fclose(fp);
00083 
00084         init();
00085 }
00086 
00087 LLScriptExecute::LLScriptExecute(U8 *buffer)
00088 {
00089         mBuffer = buffer;
00090 
00091         init();
00092 }
00093 
00094 LLScriptExecute::~LLScriptExecute()
00095 {
00096         delete [] mBuffer;
00097 }
00098 
00099 void LLScriptExecute::init()
00100 {
00101         S32 i, j;
00102 
00103         mInstructionCount = 0;
00104 
00105         for (i = 0; i < 256; i++)
00106         {
00107                 mExecuteFuncs[i] = run_noop;
00108         }
00109         mExecuteFuncs[LSCRIPTOpCodes[LOPC_NOOP]] = run_noop;
00110 
00111         mExecuteFuncs[LSCRIPTOpCodes[LOPC_POP]] = run_pop;
00112         mExecuteFuncs[LSCRIPTOpCodes[LOPC_POPS]] = run_pops;
00113         mExecuteFuncs[LSCRIPTOpCodes[LOPC_POPL]] = run_popl;
00114         mExecuteFuncs[LSCRIPTOpCodes[LOPC_POPV]] = run_popv;
00115         mExecuteFuncs[LSCRIPTOpCodes[LOPC_POPQ]] = run_popq;
00116         mExecuteFuncs[LSCRIPTOpCodes[LOPC_POPARG]] = run_poparg;
00117         mExecuteFuncs[LSCRIPTOpCodes[LOPC_POPIP]] = run_popip;
00118         mExecuteFuncs[LSCRIPTOpCodes[LOPC_POPBP]] = run_popbp;
00119         mExecuteFuncs[LSCRIPTOpCodes[LOPC_POPSP]] = run_popsp;
00120         mExecuteFuncs[LSCRIPTOpCodes[LOPC_POPSLR]] = run_popslr;
00121 
00122         mExecuteFuncs[LSCRIPTOpCodes[LOPC_DUP]] = run_dup;
00123         mExecuteFuncs[LSCRIPTOpCodes[LOPC_DUPS]] = run_dups;
00124         mExecuteFuncs[LSCRIPTOpCodes[LOPC_DUPL]] = run_dupl;
00125         mExecuteFuncs[LSCRIPTOpCodes[LOPC_DUPV]] = run_dupv;
00126         mExecuteFuncs[LSCRIPTOpCodes[LOPC_DUPQ]] = run_dupq;
00127 
00128         mExecuteFuncs[LSCRIPTOpCodes[LOPC_STORE]] = run_store;
00129         mExecuteFuncs[LSCRIPTOpCodes[LOPC_STORES]] = run_stores;
00130         mExecuteFuncs[LSCRIPTOpCodes[LOPC_STOREL]] = run_storel;
00131         mExecuteFuncs[LSCRIPTOpCodes[LOPC_STOREV]] = run_storev;
00132         mExecuteFuncs[LSCRIPTOpCodes[LOPC_STOREQ]] = run_storeq;
00133         mExecuteFuncs[LSCRIPTOpCodes[LOPC_STOREG]] = run_storeg;
00134         mExecuteFuncs[LSCRIPTOpCodes[LOPC_STOREGL]] = run_storegl;
00135         mExecuteFuncs[LSCRIPTOpCodes[LOPC_STOREGS]] = run_storegs;
00136         mExecuteFuncs[LSCRIPTOpCodes[LOPC_STOREGV]] = run_storegv;
00137         mExecuteFuncs[LSCRIPTOpCodes[LOPC_STOREGQ]] = run_storegq;
00138         mExecuteFuncs[LSCRIPTOpCodes[LOPC_LOADP]] = run_loadp;
00139         mExecuteFuncs[LSCRIPTOpCodes[LOPC_LOADSP]] = run_loadsp;
00140         mExecuteFuncs[LSCRIPTOpCodes[LOPC_LOADLP]] = run_loadlp;
00141         mExecuteFuncs[LSCRIPTOpCodes[LOPC_LOADVP]] = run_loadvp;
00142         mExecuteFuncs[LSCRIPTOpCodes[LOPC_LOADQP]] = run_loadqp;
00143         mExecuteFuncs[LSCRIPTOpCodes[LOPC_LOADGP]] = run_loadgp;
00144         mExecuteFuncs[LSCRIPTOpCodes[LOPC_LOADGSP]] = run_loadgsp;
00145         mExecuteFuncs[LSCRIPTOpCodes[LOPC_LOADGLP]] = run_loadglp;
00146         mExecuteFuncs[LSCRIPTOpCodes[LOPC_LOADGVP]] = run_loadgvp;
00147         mExecuteFuncs[LSCRIPTOpCodes[LOPC_LOADGQP]] = run_loadgqp;
00148 
00149         mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSH]] = run_push;
00150         mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHS]] = run_pushs;
00151         mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHL]] = run_pushl;
00152         mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHV]] = run_pushv;
00153         mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHQ]] = run_pushq;
00154         mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHG]] = run_pushg;
00155         mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHGS]] = run_pushgs;
00156         mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHGL]] = run_pushgl;
00157         mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHGV]] = run_pushgv;
00158         mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHGQ]] = run_pushgq;
00159         mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHIP]] = run_puship;
00160         mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHSP]] = run_pushsp;
00161         mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHBP]] = run_pushbp;
00162         mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHARGB]] = run_pushargb;
00163         mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHARGI]] = run_pushargi;
00164         mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHARGF]] = run_pushargf;
00165         mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHARGS]] = run_pushargs;
00166         mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHARGV]] = run_pushargv;
00167         mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHARGQ]] = run_pushargq;
00168         mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHE]] = run_pushe;
00169         mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHEV]] = run_pushev;
00170         mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHEQ]] = run_pusheq;
00171         mExecuteFuncs[LSCRIPTOpCodes[LOPC_PUSHARGE]] = run_pusharge;
00172 
00173         mExecuteFuncs[LSCRIPTOpCodes[LOPC_ADD]] = run_add;
00174         mExecuteFuncs[LSCRIPTOpCodes[LOPC_SUB]] = run_sub;
00175         mExecuteFuncs[LSCRIPTOpCodes[LOPC_MUL]] = run_mul;
00176         mExecuteFuncs[LSCRIPTOpCodes[LOPC_DIV]] = run_div;
00177         mExecuteFuncs[LSCRIPTOpCodes[LOPC_MOD]] = run_mod;
00178 
00179         mExecuteFuncs[LSCRIPTOpCodes[LOPC_EQ]] = run_eq;
00180         mExecuteFuncs[LSCRIPTOpCodes[LOPC_NEQ]] = run_neq;
00181         mExecuteFuncs[LSCRIPTOpCodes[LOPC_LEQ]] = run_leq;
00182         mExecuteFuncs[LSCRIPTOpCodes[LOPC_GEQ]] = run_geq;
00183         mExecuteFuncs[LSCRIPTOpCodes[LOPC_LESS]] = run_less;
00184         mExecuteFuncs[LSCRIPTOpCodes[LOPC_GREATER]] = run_greater;
00185 
00186         mExecuteFuncs[LSCRIPTOpCodes[LOPC_BITAND]] = run_bitand;
00187         mExecuteFuncs[LSCRIPTOpCodes[LOPC_BITOR]] = run_bitor;
00188         mExecuteFuncs[LSCRIPTOpCodes[LOPC_BITXOR]] = run_bitxor;
00189 
00190         mExecuteFuncs[LSCRIPTOpCodes[LOPC_BOOLAND]] = run_booland;
00191         mExecuteFuncs[LSCRIPTOpCodes[LOPC_BOOLOR]] = run_boolor;
00192 
00193         mExecuteFuncs[LSCRIPTOpCodes[LOPC_SHL]] = run_shl;
00194         mExecuteFuncs[LSCRIPTOpCodes[LOPC_SHR]] = run_shr;
00195 
00196         mExecuteFuncs[LSCRIPTOpCodes[LOPC_NEG]] = run_neg;
00197         mExecuteFuncs[LSCRIPTOpCodes[LOPC_BITNOT]] = run_bitnot;
00198         mExecuteFuncs[LSCRIPTOpCodes[LOPC_BOOLNOT]] = run_boolnot;
00199 
00200         mExecuteFuncs[LSCRIPTOpCodes[LOPC_JUMP]] = run_jump;
00201         mExecuteFuncs[LSCRIPTOpCodes[LOPC_JUMPIF]] = run_jumpif;
00202         mExecuteFuncs[LSCRIPTOpCodes[LOPC_JUMPNIF]] = run_jumpnif;
00203 
00204         mExecuteFuncs[LSCRIPTOpCodes[LOPC_STATE]] = run_state;
00205         mExecuteFuncs[LSCRIPTOpCodes[LOPC_CALL]] = run_call;
00206         mExecuteFuncs[LSCRIPTOpCodes[LOPC_RETURN]] = run_return;
00207         mExecuteFuncs[LSCRIPTOpCodes[LOPC_CAST]] = run_cast;
00208         mExecuteFuncs[LSCRIPTOpCodes[LOPC_STACKTOS]] = run_stacktos;
00209         mExecuteFuncs[LSCRIPTOpCodes[LOPC_STACKTOL]] = run_stacktol;
00210 
00211         mExecuteFuncs[LSCRIPTOpCodes[LOPC_PRINT]] = run_print;
00212 
00213         mExecuteFuncs[LSCRIPTOpCodes[LOPC_CALLLIB]] = run_calllib;
00214         mExecuteFuncs[LSCRIPTOpCodes[LOPC_CALLLIB_TWO_BYTE]] = run_calllib_two_byte;
00215 
00216         for (i = 0; i < LST_EOF; i++)
00217         {
00218                 for (j = 0; j < LST_EOF; j++)
00219                 {
00220                         binary_operations[i][j] = unknown_operation;
00221                 }
00222         }
00223 
00224         binary_operations[LST_INTEGER][LST_INTEGER] = integer_integer_operation;
00225         binary_operations[LST_INTEGER][LST_FLOATINGPOINT] = integer_float_operation;
00226         binary_operations[LST_INTEGER][LST_VECTOR] = integer_vector_operation;
00227 
00228         binary_operations[LST_FLOATINGPOINT][LST_INTEGER] = float_integer_operation;
00229         binary_operations[LST_FLOATINGPOINT][LST_FLOATINGPOINT] = float_float_operation;
00230         binary_operations[LST_FLOATINGPOINT][LST_VECTOR] = float_vector_operation;
00231 
00232         binary_operations[LST_STRING][LST_STRING] = string_string_operation;
00233         binary_operations[LST_STRING][LST_KEY] = string_key_operation;
00234 
00235         binary_operations[LST_KEY][LST_STRING] = key_string_operation;
00236         binary_operations[LST_KEY][LST_KEY] = key_key_operation;
00237 
00238         binary_operations[LST_VECTOR][LST_INTEGER] = vector_integer_operation;
00239         binary_operations[LST_VECTOR][LST_FLOATINGPOINT] = vector_float_operation;
00240         binary_operations[LST_VECTOR][LST_VECTOR] = vector_vector_operation;
00241         binary_operations[LST_VECTOR][LST_QUATERNION] = vector_quaternion_operation;
00242 
00243         binary_operations[LST_QUATERNION][LST_QUATERNION] = quaternion_quaternion_operation;
00244 
00245         binary_operations[LST_INTEGER][LST_LIST] = integer_list_operation;
00246         binary_operations[LST_FLOATINGPOINT][LST_LIST] = float_list_operation;
00247         binary_operations[LST_STRING][LST_LIST] = string_list_operation;
00248         binary_operations[LST_KEY][LST_LIST] = key_list_operation;
00249         binary_operations[LST_VECTOR][LST_LIST] = vector_list_operation;
00250         binary_operations[LST_QUATERNION][LST_LIST] = quaternion_list_operation;
00251         binary_operations[LST_LIST][LST_INTEGER] = list_integer_operation;
00252         binary_operations[LST_LIST][LST_FLOATINGPOINT] = list_float_operation;
00253         binary_operations[LST_LIST][LST_STRING] = list_string_operation;
00254         binary_operations[LST_LIST][LST_KEY] = list_key_operation;
00255         binary_operations[LST_LIST][LST_VECTOR] = list_vector_operation;
00256         binary_operations[LST_LIST][LST_QUATERNION] = list_quaternion_operation;
00257         binary_operations[LST_LIST][LST_LIST] = list_list_operation;
00258 
00259         for (i = 0; i < LST_EOF; i++)
00260         {
00261                 unary_operations[i] = unknown_operation;
00262         }
00263 
00264         unary_operations[LST_INTEGER] = integer_operation;
00265         unary_operations[LST_FLOATINGPOINT] = float_operation;
00266         unary_operations[LST_VECTOR] = vector_operation;
00267         unary_operations[LST_QUATERNION] = quaternion_operation;
00268 
00269 }
00270 
00271 
00272 // Utility routine for when there's a boundary error parsing bytecode
00273 void LLScriptExecute::recordBoundaryError( const LLUUID &id )
00274 {
00275         set_fault(mBuffer, LSRF_BOUND_CHECK_ERROR);
00276         llwarns << "Script boundary error for ID " << id << llendl;
00277 }
00278 
00279 
00280 //      set IP to the event handler with some error checking
00281 void LLScriptExecute::setStateEventOpcoodeStartSafely( S32 state, LSCRIPTStateEventType event, const LLUUID &id )
00282 {
00283         S32                     opcode_start = get_state_event_opcoode_start( mBuffer, state, event );
00284         if ( opcode_start == -1 )
00285         {
00286                 recordBoundaryError( id );
00287         }
00288         else
00289         {
00290                 set_ip( mBuffer, opcode_start );
00291         }
00292 }
00293 
00294 
00295 
00296 
00297 S32 lscript_push_variable(LLScriptLibData *data, U8 *buffer);
00298 
00299 U32 LLScriptExecute::run(BOOL b_print, const LLUUID &id, char **errorstr, BOOL &state_transition)
00300 {
00301         //  is there a fault?
00302         //      if yes, print out message and exit
00303         state_transition = FALSE;
00304         S32 value = get_register(mBuffer, LREG_VN);
00305         S32 major_version = 0;
00306         if (value == LSL2_VERSION1_END_NUMBER)
00307         {
00308                 major_version = 1;
00309         }
00310         else if (value == LSL2_VERSION_NUMBER)
00311         {
00312                 major_version = 2;
00313         }
00314         else
00315         {
00316                 set_fault(mBuffer, LSRF_VERSION_MISMATCH);
00317         }
00318         value = get_register(mBuffer, LREG_FR);
00319         if (value)
00320         {
00321                 if (b_print)
00322                 {
00323                         printf("Error!\n");
00324                 }
00325                 *errorstr = LSCRIPTRunTimeFaultStrings[value];
00326                 return NO_DELETE_FLAG;
00327         }
00328         else
00329         {
00330                 *errorstr = NULL;
00331         }
00332 
00333         //  Get IP
00334         //  is IP nonzero?
00335         value = get_register(mBuffer, LREG_IP);
00336 
00337         if (value)
00338         {
00339         //      if yes, we're in opcodes, execute the next opcode by:
00340         //      call opcode run function pointer with buffer and IP
00341                 mInstructionCount++;
00342                 sGlobalInstructionCount++;
00343                 S32 tvalue = value;
00344                 S32     opcode = safe_instruction_bytestream2byte(mBuffer, tvalue);
00345                 S32 b_ret_val = mExecuteFuncs[opcode](mBuffer, value, b_print, id);
00346                 set_ip(mBuffer, value);
00347                 add_register_fp(mBuffer, LREG_ESR, -0.1f);
00348         //      lsa_print_heap(mBuffer);
00349 
00350                 if (b_print)
00351                 {
00352                         lsa_print_heap(mBuffer);
00353                         printf("ip: 0x%X\n", get_register(mBuffer, LREG_IP));
00354                         printf("sp: 0x%X\n", get_register(mBuffer, LREG_SP));
00355                         printf("bp: 0x%X\n", get_register(mBuffer, LREG_BP));
00356                         printf("hr: 0x%X\n", get_register(mBuffer, LREG_HR));
00357                         printf("hp: 0x%X\n", get_register(mBuffer, LREG_HP));
00358                 }
00359         //                      update IP
00360                 if (b_ret_val)
00361                 {
00362                         return DELETE_FLAG | CREDIT_MONEY_FLAG;
00363                 }
00364                 else
00365                 {
00366                         return NO_DELETE_FLAG;
00367                 }
00368         }
00369         else
00370         {
00371                 // make sure that IE is zero
00372                 set_event_register(mBuffer, LREG_IE, 0, major_version);
00373 
00374         //      if no, we're in a state and waiting for an event
00375                 S32 next_state = get_register(mBuffer, LREG_NS);
00376                 S32 current_state = get_register(mBuffer, LREG_CS);
00377                 U64 current_events = get_event_register(mBuffer, LREG_CE, major_version);
00378                 U64 event_register = get_event_register(mBuffer, LREG_ER, major_version);
00379         //      check NS to see if need to switch states (NS != CS)
00380                 if (next_state != current_state)
00381                 {
00382                         state_transition = TRUE;
00383                         // ok, blow away any pending events
00384                         mEventData.mEventDataList.deleteAllData();
00385 
00386         //              if yes, check state exit flag is set
00387                         if (current_events & LSCRIPTStateBitField[LSTT_STATE_EXIT])
00388                         {
00389         //                      if yes, clear state exit flag
00390                                 set_event_register(mBuffer, LREG_IE, LSCRIPTStateBitField[LSTT_STATE_EXIT], major_version);
00391                                 current_events &= ~LSCRIPTStateBitField[LSTT_STATE_EXIT];
00392                                 set_event_register(mBuffer, LREG_CE, current_events, major_version);
00393         //                      check state exit event handler
00394         //                              if there is a handler, call it
00395                                 if (event_register & LSCRIPTStateBitField[LSTT_STATE_EXIT])
00396                                 {
00397                 //                      push a zero to be popped
00398                                         lscript_push(mBuffer, 0);
00399                 //                      push sp as current bp
00400                                         S32 sp = get_register(mBuffer, LREG_SP);
00401                                         lscript_push(mBuffer, sp);
00402 
00403                 //                      now, push any additional stack space
00404                                         S32 additional_size = get_event_stack_size(mBuffer, current_state, LSTT_STATE_EXIT);
00405                                         if ( additional_size == -1 )
00406                                         {       
00407                                                 recordBoundaryError( id );
00408                                         }
00409                                         else
00410                                         {
00411                                                 lscript_pusharge(mBuffer, additional_size);
00412 
00413                                                 sp = get_register(mBuffer, LREG_SP);
00414                                                 sp += additional_size;
00415                                                 set_bp(mBuffer, sp);
00416                 //                              set IP to the event handler
00417                                                 setStateEventOpcoodeStartSafely( current_state, LSTT_STATE_EXIT, id );
00418                                         }
00419                                         return NO_DELETE_FLAG;
00420                                 }
00421                         }
00422         //              if no handler or no state exit flag switch to new state
00423         //              set state entry flag and clear other CE flags
00424                         current_events = LSCRIPTStateBitField[LSTT_STATE_ENTRY];
00425                         set_event_register(mBuffer, LREG_CE, current_events, major_version);
00426         //              copy NS to CS
00427                         set_register(mBuffer, LREG_CS, next_state);
00428         //              copy new state's handled events into ER (SR + CS*4 + 4)
00429                         U64 handled_events = get_handled_events(mBuffer, next_state);
00430                         set_event_register(mBuffer, LREG_ER, handled_events, major_version);
00431                 }
00432 //              check to see if any current events are covered by events handled by this state (CE & ER != 0)
00433 // now, we want to look like we were called like a function
00434 //              0x0000:         00 00 00 00 (return ip)
00435 //              0x0004:         bp                      (current sp)
00436 //              0x0008:         parameters
00437 //              push sp
00438 //              add parameter size
00439 //              pop bp
00440 //              set ip
00441 
00442                 S32 size = 0;
00443 //                      try to get next event from stack
00444                 BOOL b_done = FALSE;
00445                 LSCRIPTStateEventType event = LSTT_NULL;
00446                 LLScriptDataCollection *eventdata;
00447 
00448                 next_state = get_register(mBuffer, LREG_NS);
00449                 current_state = get_register(mBuffer, LREG_CS);
00450                 current_events = get_event_register(mBuffer, LREG_CE, major_version);
00451                 event_register = get_event_register(mBuffer, LREG_ER, major_version);
00452 
00453                 // first, check to see if state_entry or onrez are raised and handled
00454                 if (  (current_events & LSCRIPTStateBitField[LSTT_STATE_ENTRY])
00455                         &&(current_events & event_register))
00456                 {
00457                         // ok, this is easy since there isn't any data waiting, just set it
00458                         //                      push a zero to be popped
00459                         lscript_push(mBuffer, 0);
00460 //                      push sp as current bp
00461                         S32 sp = get_register(mBuffer, LREG_SP);
00462                         lscript_push(mBuffer, sp);
00463 
00464                         event = return_first_event((S32)LSCRIPTStateBitField[LSTT_STATE_ENTRY]);
00465                         set_event_register(mBuffer, LREG_IE, LSCRIPTStateBitField[event], major_version);
00466                         current_events &= ~LSCRIPTStateBitField[event];
00467                         set_event_register(mBuffer, LREG_CE, current_events, major_version);
00468 //                      now, push any additional stack space
00469                         S32 additional_size = get_event_stack_size(mBuffer, current_state, event);
00470                         if ( additional_size == -1 )
00471                         {       // b_done will be set, so we'll exit the loop at the bottom
00472                                 recordBoundaryError( id );
00473                         }
00474                         else
00475                         {
00476                                 additional_size -= size;
00477                                 lscript_pusharge(mBuffer, additional_size);
00478 
00479 //                      now set the bp correctly
00480                                 sp = get_register(mBuffer, LREG_SP);
00481                                 sp += additional_size + size;
00482                                 set_bp(mBuffer, sp);
00483 //                      set IP to the function
00484                                 setStateEventOpcoodeStartSafely( current_state, event, id );
00485                         }
00486                         b_done = TRUE;
00487                 }
00488                 else if (  (current_events & LSCRIPTStateBitField[LSTT_REZ])
00489                                 &&(current_events & event_register))
00490                 {
00491                         for (eventdata = mEventData.mEventDataList.getFirstData(); eventdata; eventdata = mEventData.mEventDataList.getNextData())
00492                         {
00493                                 if (eventdata->mType & LSCRIPTStateBitField[LSTT_REZ])
00494                                 {
00495                                         //                      push a zero to be popped
00496                                         lscript_push(mBuffer, 0);
00497                 //                      push sp as current bp
00498                                         S32 sp = get_register(mBuffer, LREG_SP);
00499                                         lscript_push(mBuffer, sp);
00500 
00501                                         set_event_register(mBuffer, LREG_IE, LSCRIPTStateBitField[event], major_version);
00502                                         current_events &= ~LSCRIPTStateBitField[event];
00503                                         set_event_register(mBuffer, LREG_CE, current_events, major_version);
00504 
00505         //                              push any arguments that need to be pushed onto the stack
00506                                         // last piece of data will be type LST_NULL
00507                                         LLScriptLibData *data = eventdata->mData;
00508                                         while (data->mType)
00509                                         {
00510                                                 size += lscript_push_variable(data, mBuffer);
00511                                                 data++;
00512                                         }
00513                 //                      now, push any additional stack space
00514                                         S32 additional_size = get_event_stack_size(mBuffer, current_state, event);
00515                                         if ( additional_size == -1 )
00516                                         {       // b_done will be set, so we'll exit the loop at the bottom
00517                                                 recordBoundaryError( id );
00518                                         }
00519                                         else
00520                                         {
00521                                                 additional_size -= size;
00522                                                 lscript_pusharge(mBuffer, additional_size);
00523 
00524                         //                      now set the bp correctly
00525                                                 sp = get_register(mBuffer, LREG_SP);
00526                                                 sp += additional_size + size;
00527                                                 set_bp(mBuffer, sp);
00528                         //                      set IP to the function
00529                                                 setStateEventOpcoodeStartSafely( current_state, event, id );
00530                                                 mEventData.mEventDataList.deleteCurrentData();
00531                                         }
00532                                         b_done = TRUE;
00533                                         break;
00534                                 }
00535                         }
00536                 }
00537 
00538                 while (!b_done)
00539                 {
00540                         eventdata = mEventData.getNextEvent();
00541                         if (eventdata)
00542                         {
00543                                 event = eventdata->mType;
00544 
00545                                 // make sure that we can actually handle this one
00546                                 if (LSCRIPTStateBitField[event] & event_register)
00547                                 {
00548                                         //                      push a zero to be popped
00549                                         lscript_push(mBuffer, 0);
00550                 //                      push sp as current bp
00551                                         S32 sp = get_register(mBuffer, LREG_SP);
00552                                         lscript_push(mBuffer, sp);
00553 
00554                                         set_event_register(mBuffer, LREG_IE, LSCRIPTStateBitField[event], major_version);
00555                                         current_events &= ~LSCRIPTStateBitField[event];
00556                                         set_event_register(mBuffer, LREG_CE, current_events, major_version);
00557 
00558         //                              push any arguments that need to be pushed onto the stack
00559                                         // last piece of data will be type LST_NULL
00560                                         LLScriptLibData *data = eventdata->mData;
00561                                         while (data->mType)
00562                                         {
00563                                                 size += lscript_push_variable(data, mBuffer);
00564                                                 data++;
00565                                         }
00566                                         b_done = TRUE;
00567                 //                      now, push any additional stack space
00568                                         S32 additional_size = get_event_stack_size(mBuffer, current_state, event);
00569                                         if ( additional_size == -1 )
00570                                         {       // b_done was just set, so we'll exit the loop at the bottom
00571                                                 recordBoundaryError( id );
00572                                         }
00573                                         else
00574                                         {
00575                                                 additional_size -= size;
00576                                                 lscript_pusharge(mBuffer, additional_size);
00577 
00578                         //                      now set the bp correctly
00579                                                 sp = get_register(mBuffer, LREG_SP);
00580                                                 sp += additional_size + size;
00581                                                 set_bp(mBuffer, sp);
00582                         //                      set IP to the function
00583                                                 setStateEventOpcoodeStartSafely( current_state, event, id );
00584                                         }
00585                                 }
00586                                 else
00587                                 {
00588                                         llwarns << "Shit, somehow got an event that we're not registered for!" << llendl;
00589                                 }
00590                                 delete eventdata;
00591                         }
00592                         else
00593                         {
00594 //                              if no data waiting, do it the old way:
00595                                 U64 handled_current = current_events & event_register;
00596                                 if (handled_current)
00597                                 {
00598                                         //                      push a zero to be popped
00599                                         lscript_push(mBuffer, 0);
00600                 //                      push sp as current bp
00601                                         S32 sp = get_register(mBuffer, LREG_SP);
00602                                         lscript_push(mBuffer, sp);
00603 
00604                                         event = return_first_event((S32)handled_current);
00605                                         set_event_register(mBuffer, LREG_IE, LSCRIPTStateBitField[event], major_version);
00606                                         current_events &= ~LSCRIPTStateBitField[event];
00607                                         set_event_register(mBuffer, LREG_CE, current_events, major_version);
00608                 //                      now, push any additional stack space
00609                                         S32 additional_size = get_event_stack_size(mBuffer, current_state, event);
00610                                         if ( additional_size == -1 )
00611                                         {       // b_done will be set, so we'll exit the loop at the bottom
00612                                                 recordBoundaryError( id );
00613                                         }
00614                                         else
00615                                         {
00616                                                 additional_size -= size;
00617                                                 lscript_pusharge(mBuffer, additional_size);
00618 
00619                         //                      now set the bp correctly
00620                                                 sp = get_register(mBuffer, LREG_SP);
00621                                                 sp += additional_size + size;
00622                                                 set_bp(mBuffer, sp);
00623                         //                      set IP to the function
00624                                                 setStateEventOpcoodeStartSafely( current_state, event, id );
00625                                         }
00626                                 }
00627                                 b_done = TRUE;
00628                         }
00629                 }       // while (!b_done)
00630         } // end of else ...  in state processing code
00631 
00632         return NO_DELETE_FLAG;
00633 }
00634 
00635 BOOL run_noop(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
00636 {
00637         if (b_print)
00638                 printf("[0x%X]\tNOOP\n", offset);
00639         offset++;
00640         return FALSE;
00641 }
00642 
00643 BOOL run_pop(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
00644 {
00645         if (b_print)
00646                 printf("[0x%X]\tPOP\n", offset);
00647         offset++;
00648         lscript_poparg(buffer, LSCRIPTDataSize[LST_INTEGER]);
00649         return FALSE;
00650 }
00651 
00652 BOOL run_pops(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
00653 {
00654         if (b_print)
00655                 printf("[0x%X]\tPOPS\n", offset);
00656         offset++;
00657         S32 address = lscript_pop_int(buffer);
00658         if (address)
00659                 lsa_decrease_ref_count(buffer, address);
00660         return FALSE;
00661 }
00662 
00663 BOOL run_popl(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
00664 {
00665         if (b_print)
00666                 printf("[0x%X]\tPOPL\n", offset);
00667         offset++;
00668         S32 address = lscript_pop_int(buffer);
00669         if (address)
00670                 lsa_decrease_ref_count(buffer, address);
00671         return FALSE;
00672 }
00673 
00674 BOOL run_popv(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
00675 {
00676         if (b_print)
00677                 printf("[0x%X]\tPOPV\n", offset);
00678         offset++;
00679         lscript_poparg(buffer, LSCRIPTDataSize[LST_VECTOR]);
00680         return FALSE;
00681 }
00682 
00683 BOOL run_popq(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
00684 {
00685         if (b_print)
00686                 printf("[0x%X]\tPOPQ\n", offset);
00687         offset++;
00688         lscript_poparg(buffer, LSCRIPTDataSize[LST_QUATERNION]);
00689         return FALSE;
00690 }
00691 
00692 BOOL run_poparg(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
00693 {
00694         if (b_print)
00695                 printf("[0x%X]\tPOPARG ", offset);
00696         offset++;
00697         S32 arg = safe_instruction_bytestream2integer(buffer, offset);
00698         if (b_print)
00699                 printf("%d\n", arg);
00700         lscript_poparg(buffer, arg);
00701         return FALSE;
00702 }
00703 
00704 BOOL run_popip(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
00705 {
00706         if (b_print)
00707                 printf("[0x%X]\tPOPIP\n", offset);
00708         offset++;
00709         offset = lscript_pop_int(buffer);
00710         return FALSE;
00711 }
00712 
00713 BOOL run_popbp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
00714 {
00715         if (b_print)
00716                 printf("[0x%X]\tPOPBP\n", offset);
00717         offset++;
00718         S32 bp = lscript_pop_int(buffer);
00719         set_bp(buffer, bp);
00720         return FALSE;
00721 }
00722 
00723 BOOL run_popsp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
00724 {
00725         if (b_print)
00726                 printf("[0x%X]\tPOPSP\n", offset);
00727         offset++;
00728         S32 sp = lscript_pop_int(buffer);
00729         set_sp(buffer, sp);
00730         return FALSE;
00731 }
00732 
00733 BOOL run_popslr(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
00734 {
00735         if (b_print)
00736                 printf("[0x%X]\tPOPSLR\n", offset);
00737         offset++;
00738         S32 slr = lscript_pop_int(buffer);
00739         set_register(buffer, LREG_SLR, slr);
00740         return FALSE;
00741 }
00742 
00743 BOOL run_dup(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
00744 {
00745         if (b_print)
00746                 printf("[0x%X]\tDUP\n", offset);
00747         offset++;
00748         S32 sp = get_register(buffer, LREG_SP);
00749         S32 value = bytestream2integer(buffer, sp);
00750         lscript_push(buffer, value);
00751         return FALSE;
00752 }
00753 
00754 BOOL run_dups(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
00755 {
00756         if (b_print)
00757                 printf("[0x%X]\tDUPS\n", offset);
00758         offset++;
00759         S32 sp = get_register(buffer, LREG_SP);
00760         S32 value = bytestream2integer(buffer, sp);
00761         lscript_push(buffer, value);
00762         lsa_increase_ref_count(buffer, value);
00763         return FALSE;
00764 }
00765 
00766 BOOL run_dupl(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
00767 {
00768         if (b_print)
00769                 printf("[0x%X]\tDUPL\n", offset);
00770         offset++;
00771         S32 sp = get_register(buffer, LREG_SP);
00772         S32 value = bytestream2integer(buffer, sp);
00773         lscript_push(buffer, value);
00774         lsa_increase_ref_count(buffer, value);
00775         return FALSE;
00776 }
00777 
00778 BOOL run_dupv(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
00779 {
00780         if (b_print)
00781                 printf("[0x%X]\tDUPV\n", offset);
00782         offset++;
00783         S32 sp = get_register(buffer, LREG_SP);
00784         LLVector3 value;
00785         bytestream2vector(value, buffer, sp);
00786         lscript_push(buffer, value);
00787         return FALSE;
00788 }
00789 
00790 BOOL run_dupq(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
00791 {
00792         if (b_print)
00793                 printf("[0x%X]\tDUPV\n", offset);
00794         offset++;
00795         S32 sp = get_register(buffer, LREG_SP);
00796         LLQuaternion value;
00797         bytestream2quaternion(value, buffer, sp);
00798         lscript_push(buffer, value);
00799         return FALSE;
00800 }
00801 
00802 BOOL run_store(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
00803 {
00804         if (b_print)
00805                 printf("[0x%X]\tSTORE ", offset);
00806         offset++;
00807         S32 arg = safe_instruction_bytestream2integer(buffer, offset);
00808         if (b_print)
00809                 printf("0x%X\n", arg);
00810         S32 sp = get_register(buffer, LREG_SP);
00811         S32 value = bytestream2integer(buffer, sp);
00812         lscript_local_store(buffer, arg, value);
00813         return FALSE;
00814 }
00815 
00816 BOOL run_stores(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
00817 {
00818         if (b_print)
00819                 printf("[0x%X]\tSTORES ", offset);
00820         offset++;
00821         S32 arg = safe_instruction_bytestream2integer(buffer, offset);
00822         if (b_print)
00823                 printf("0x%X\n", arg);
00824         S32 sp = get_register(buffer, LREG_SP);
00825         S32 value = bytestream2integer(buffer, sp);
00826 
00827         S32 address = lscript_local_get(buffer, arg);
00828 
00829         lscript_local_store(buffer, arg, value);
00830         lsa_increase_ref_count(buffer, value);
00831         if (address)
00832                 lsa_decrease_ref_count(buffer, address);
00833         return FALSE;
00834 }
00835 
00836 BOOL run_storel(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
00837 {
00838         if (b_print)
00839                 printf("[0x%X]\tSTOREL ", offset);
00840         offset++;
00841         S32 arg = safe_instruction_bytestream2integer(buffer, offset);
00842         if (b_print)
00843                 printf("0x%X\n", arg);
00844         S32 sp = get_register(buffer, LREG_SP);
00845         S32 value = bytestream2integer(buffer, sp);
00846 
00847         S32 address = lscript_local_get(buffer, arg);
00848 
00849         lscript_local_store(buffer, arg, value);
00850         lsa_increase_ref_count(buffer, value);
00851         if (address)
00852                 lsa_decrease_ref_count(buffer, address);
00853         return FALSE;
00854 }
00855 
00856 BOOL run_storev(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
00857 {
00858         if (b_print)
00859                 printf("[0x%X]\tSTOREV ", offset);
00860         offset++;
00861         S32 arg = safe_instruction_bytestream2integer(buffer, offset);
00862         if (b_print)
00863                 printf("0x%X\n", arg);
00864         LLVector3 value;
00865         S32 sp = get_register(buffer, LREG_SP);
00866         bytestream2vector(value, buffer, sp);
00867         lscript_local_store(buffer, arg, value);
00868         return FALSE;
00869 }
00870 
00871 BOOL run_storeq(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
00872 {
00873         if (b_print)
00874                 printf("[0x%X]\tSTOREQ ", offset);
00875         offset++;
00876         S32 arg = safe_instruction_bytestream2integer(buffer, offset);
00877         if (b_print)
00878                 printf("0x%X\n", arg);
00879         LLQuaternion value;
00880         S32 sp = get_register(buffer, LREG_SP);
00881         bytestream2quaternion(value, buffer, sp);
00882         lscript_local_store(buffer, arg, value);
00883         return FALSE;
00884 }
00885 
00886 BOOL run_storeg(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
00887 {
00888         if (b_print)
00889                 printf("[0x%X]\tSTOREG ", offset);
00890         offset++;
00891         S32 arg = safe_instruction_bytestream2integer(buffer, offset);
00892         if (b_print)
00893                 printf("0x%X\n", arg);
00894         S32 sp = get_register(buffer, LREG_SP);
00895         S32 value = bytestream2integer(buffer, sp);
00896         lscript_global_store(buffer, arg, value);
00897         return FALSE;
00898 }
00899 
00900 BOOL run_storegs(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
00901 {
00902         if (b_print)
00903                 printf("[0x%X]\tSTOREGS ", offset);
00904         offset++;
00905         S32 arg = safe_instruction_bytestream2integer(buffer, offset);
00906         if (b_print)
00907                 printf("0x%X\n", arg);
00908         S32 sp = get_register(buffer, LREG_SP);
00909         S32 value = bytestream2integer(buffer, sp);
00910 
00911         S32 address = lscript_global_get(buffer, arg);
00912 
00913         lscript_global_store(buffer, arg, value);
00914 
00915         lsa_increase_ref_count(buffer, value);
00916         if (address)
00917                 lsa_decrease_ref_count(buffer, address);
00918         return FALSE;
00919 }
00920 
00921 BOOL run_storegl(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
00922 {
00923         if (b_print)
00924                 printf("[0x%X]\tSTOREGL ", offset);
00925         offset++;
00926         S32 arg = safe_instruction_bytestream2integer(buffer, offset);
00927         if (b_print)
00928                 printf("0x%X\n", arg);
00929         S32 sp = get_register(buffer, LREG_SP);
00930         S32 value = bytestream2integer(buffer, sp);
00931 
00932         S32 address = lscript_global_get(buffer, arg);
00933 
00934         lscript_global_store(buffer, arg, value);
00935 
00936         lsa_increase_ref_count(buffer, value);
00937         if (address)
00938                 lsa_decrease_ref_count(buffer, address);
00939         return FALSE;
00940 }
00941 
00942 BOOL run_storegv(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
00943 {
00944         if (b_print)
00945                 printf("[0x%X]\tSTOREGV ", offset);
00946         offset++;
00947         S32 arg = safe_instruction_bytestream2integer(buffer, offset);
00948         if (b_print)
00949                 printf("0x%X\n", arg);
00950         LLVector3 value;
00951         S32 sp = get_register(buffer, LREG_SP);
00952         bytestream2vector(value, buffer, sp);
00953         lscript_global_store(buffer, arg, value);
00954         return FALSE;
00955 }
00956 
00957 BOOL run_storegq(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
00958 {
00959         if (b_print)
00960                 printf("[0x%X]\tSTOREGQ ", offset);
00961         offset++;
00962         S32 arg = safe_instruction_bytestream2integer(buffer, offset);
00963         if (b_print)
00964                 printf("0x%X\n", arg);
00965         LLQuaternion value;
00966         S32 sp = get_register(buffer, LREG_SP);
00967         bytestream2quaternion(value, buffer, sp);
00968         lscript_global_store(buffer, arg, value);
00969         return FALSE;
00970 }
00971 
00972 BOOL run_loadp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
00973 {
00974         if (b_print)
00975                 printf("[0x%X]\tSTOREP ", offset);
00976         offset++;
00977         S32 arg = safe_instruction_bytestream2integer(buffer, offset);
00978         if (b_print)
00979                 printf("0x%X\n", arg);
00980         S32 value = lscript_pop_int(buffer);
00981         lscript_local_store(buffer, arg, value);
00982         return FALSE;
00983 }
00984 
00985 BOOL run_loadsp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
00986 {
00987         if (b_print)
00988                 printf("[0x%X]\tSTORESP ", offset);
00989         offset++;
00990         S32 arg = safe_instruction_bytestream2integer(buffer, offset);
00991         if (b_print)
00992                 printf("0x%X\n", arg);
00993         S32 value = lscript_pop_int(buffer);
00994 
00995         S32 address = lscript_local_get(buffer, arg);
00996         if (address)
00997                 lsa_decrease_ref_count(buffer, address);
00998 
00999         lscript_local_store(buffer, arg, value);
01000         return FALSE;
01001 }
01002 
01003 BOOL run_loadlp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
01004 {
01005         if (b_print)
01006                 printf("[0x%X]\tSTORELP ", offset);
01007         offset++;
01008         S32 arg = safe_instruction_bytestream2integer(buffer, offset);
01009         if (b_print)
01010                 printf("0x%X\n", arg);
01011         S32 value = lscript_pop_int(buffer);
01012 
01013         S32 address = lscript_local_get(buffer, arg);
01014         if (address)
01015                 lsa_decrease_ref_count(buffer, address);
01016 
01017         lscript_local_store(buffer, arg, value);
01018         return FALSE;
01019 }
01020 
01021 BOOL run_loadvp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
01022 {
01023         if (b_print)
01024                 printf("[0x%X]\tSTOREVP ", offset);
01025         offset++;
01026         S32 arg = safe_instruction_bytestream2integer(buffer, offset);
01027         if (b_print)
01028                 printf("0x%X\n", arg);
01029         LLVector3 value;
01030         lscript_pop_vector(buffer, value);
01031         lscript_local_store(buffer, arg, value);
01032         return FALSE;
01033 }
01034 
01035 BOOL run_loadqp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
01036 {
01037         if (b_print)
01038                 printf("[0x%X]\tSTOREQP ", offset);
01039         offset++;
01040         S32 arg = safe_instruction_bytestream2integer(buffer, offset);
01041         if (b_print)
01042                 printf("0x%X\n", arg);
01043         LLQuaternion value;
01044         lscript_pop_quaternion(buffer, value);
01045         lscript_local_store(buffer, arg, value);
01046         return FALSE;
01047 }
01048 
01049 BOOL run_loadgp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
01050 {
01051         if (b_print)
01052                 printf("[0x%X]\tSTOREGP ", offset);
01053         offset++;
01054         S32 arg = safe_instruction_bytestream2integer(buffer, offset);
01055         if (b_print)
01056                 printf("0x%X\n", arg);
01057         S32 value = lscript_pop_int(buffer);
01058         lscript_global_store(buffer, arg, value);
01059         return FALSE;
01060 }
01061 
01062 BOOL run_loadgsp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
01063 {
01064         if (b_print)
01065                 printf("[0x%X]\tSTOREGSP ", offset);
01066         offset++;
01067         S32 arg = safe_instruction_bytestream2integer(buffer, offset);
01068         if (b_print)
01069                 printf("%d\n", arg);
01070         S32 value = lscript_pop_int(buffer);
01071 
01072         S32 address = lscript_global_get(buffer, arg);
01073         if (address)
01074                 lsa_decrease_ref_count(buffer, address);
01075 
01076         lscript_global_store(buffer, arg, value);
01077         return FALSE;
01078 }
01079 
01080 BOOL run_loadglp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
01081 {
01082         if (b_print)
01083                 printf("[0x%X]\tSTOREGLP ", offset);
01084         offset++;
01085         S32 arg = safe_instruction_bytestream2integer(buffer, offset);
01086         if (b_print)
01087                 printf("0x%X\n", arg);
01088         S32 value = lscript_pop_int(buffer);
01089 
01090         S32 address = lscript_global_get(buffer, arg);
01091         if (address)
01092                 lsa_decrease_ref_count(buffer, address);
01093 
01094         lscript_global_store(buffer, arg, value);
01095         return FALSE;
01096 }
01097 
01098 BOOL run_loadgvp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
01099 {
01100         if (b_print)
01101                 printf("[0x%X]\tSTOREGVP ", offset);
01102         offset++;
01103         S32 arg = safe_instruction_bytestream2integer(buffer, offset);
01104         if (b_print)
01105                 printf("0x%X\n", arg);
01106         LLVector3 value;
01107         lscript_pop_vector(buffer, value);
01108         lscript_global_store(buffer, arg, value);
01109         return FALSE;
01110 }
01111 
01112 BOOL run_loadgqp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
01113 {
01114         if (b_print)
01115                 printf("[0x%X]\tSTOREGQP ", offset);
01116         offset++;
01117         S32 arg = safe_instruction_bytestream2integer(buffer, offset);
01118         if (b_print)
01119                 printf("0x%X\n", arg);
01120         LLQuaternion value;
01121         lscript_pop_quaternion(buffer, value);
01122         lscript_global_store(buffer, arg, value);
01123         return FALSE;
01124 }
01125 
01126 BOOL run_push(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
01127 {
01128         if (b_print)
01129                 printf("[0x%X]\tPUSH ", offset);
01130         offset++;
01131         S32 arg = safe_instruction_bytestream2integer(buffer, offset);
01132         if (b_print)
01133                 printf("0x%X\n", arg);
01134         S32 value = lscript_local_get(buffer, arg);
01135         lscript_push(buffer, value);
01136         return FALSE;
01137 }
01138 
01139 BOOL run_pushs(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
01140 {
01141         if (b_print)
01142                 printf("[0x%X]\tPUSHS ", offset);
01143         offset++;
01144         S32 arg = safe_instruction_bytestream2integer(buffer, offset);
01145         if (b_print)
01146                 printf("0x%X\n", arg);
01147         S32 value = lscript_local_get(buffer, arg);
01148         lscript_push(buffer, value);
01149         lsa_increase_ref_count(buffer, value);
01150         return FALSE;
01151 }
01152 
01153 BOOL run_pushl(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
01154 {
01155         if (b_print)
01156                 printf("[0x%X]\tPUSHL ", offset);
01157         offset++;
01158         S32 arg = safe_instruction_bytestream2integer(buffer, offset);
01159         if (b_print)
01160                 printf("0x%X\n", arg);
01161         S32 value = lscript_local_get(buffer, arg);
01162         lscript_push(buffer, value);
01163         lsa_increase_ref_count(buffer, value);
01164         return FALSE;
01165 }
01166 
01167 BOOL run_pushv(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
01168 {
01169         if (b_print)
01170                 printf("[0x%X]\tPUSHV ", offset);
01171         offset++;
01172         S32 arg = safe_instruction_bytestream2integer(buffer, offset);
01173         if (b_print)
01174                 printf("0x%X\n", arg);
01175         LLVector3 value;
01176         lscript_local_get(buffer, arg, value);
01177         lscript_push(buffer, value);
01178         return FALSE;
01179 }
01180 
01181 BOOL run_pushq(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
01182 {
01183         if (b_print)
01184                 printf("[0x%X]\tPUSHQ ", offset);
01185         offset++;
01186         S32 arg = safe_instruction_bytestream2integer(buffer, offset);
01187         if (b_print)
01188                 printf("0x%X\n", arg);
01189         LLQuaternion value;
01190         lscript_local_get(buffer, arg, value);
01191         lscript_push(buffer, value);
01192         return FALSE;
01193 }
01194 
01195 BOOL run_pushg(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
01196 {
01197         if (b_print)
01198                 printf("[0x%X]\tPUSHG ", offset);
01199         offset++;
01200         S32 arg = safe_instruction_bytestream2integer(buffer, offset);
01201         if (b_print)
01202                 printf("0x%X\n", arg);
01203         S32 value = lscript_global_get(buffer, arg);
01204         lscript_push(buffer, value);
01205         return FALSE;
01206 }
01207 
01208 BOOL run_pushgs(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
01209 {
01210         if (b_print)
01211                 printf("[0x%X]\tPUSHGS ", offset);
01212         offset++;
01213         S32 arg = safe_instruction_bytestream2integer(buffer, offset);
01214         if (b_print)
01215                 printf("0x%X\n", arg);
01216         S32 value = lscript_global_get(buffer, arg);
01217         lscript_push(buffer, value);
01218         lsa_increase_ref_count(buffer, value);
01219         return FALSE;
01220 }
01221 
01222 BOOL run_pushgl(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
01223 {
01224         if (b_print)
01225                 printf("[0x%X]\tPUSHGL ", offset);
01226         offset++;
01227         S32 arg = safe_instruction_bytestream2integer(buffer, offset);
01228         if (b_print)
01229                 printf("0x%X\n", arg);
01230         S32 value = lscript_global_get(buffer, arg);
01231         lscript_push(buffer, value);
01232         lsa_increase_ref_count(buffer, value);
01233         return FALSE;
01234 }
01235 
01236 BOOL run_pushgv(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
01237 {
01238         if (b_print)
01239                 printf("[0x%X]\tPUSHGV ", offset);
01240         offset++;
01241         S32 arg = safe_instruction_bytestream2integer(buffer, offset);
01242         if (b_print)
01243                 printf("0x%X\n", arg);
01244         LLVector3 value;
01245         lscript_global_get(buffer, arg, value);
01246         lscript_push(buffer, value);
01247         return FALSE;
01248 }
01249 
01250 BOOL run_pushgq(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
01251 {
01252         if (b_print)
01253                 printf("[0x%X]\tPUSHGQ ", offset);
01254         offset++;
01255         S32 arg = safe_instruction_bytestream2integer(buffer, offset);
01256         if (b_print)
01257                 printf("0x%X\n", arg);
01258         LLQuaternion value;
01259         lscript_global_get(buffer, arg, value);
01260         lscript_push(buffer, value);
01261         return FALSE;
01262 }
01263 
01264 BOOL run_puship(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
01265 {
01266         if (b_print)
01267                 printf("[0x%X]\tPUSHIP\n", offset);
01268         offset++;
01269         lscript_push(buffer, offset);
01270         return FALSE;
01271 }
01272 
01273 BOOL run_pushbp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
01274 {
01275         if (b_print)
01276                 printf("[0x%X]\tPUSHBP\n", offset);
01277         offset++;
01278         lscript_push(buffer, get_register(buffer, LREG_BP));
01279         return FALSE;
01280 }
01281 
01282 BOOL run_pushsp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
01283 {
01284         if (b_print)
01285                 printf("[0x%X]\tPUSHSP\n", offset);
01286         offset++;
01287         lscript_push(buffer, get_register(buffer, LREG_SP));
01288         return FALSE;
01289 }
01290 
01291 BOOL run_pushargb(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
01292 {
01293         if (b_print)
01294                 printf("[0x%X]\tPUSHGARGB ", offset);
01295         offset++;
01296         U8 arg = safe_instruction_bytestream2byte(buffer, offset);
01297         if (b_print)
01298                 printf("%d\n", (U32)arg);
01299         lscript_push(buffer, arg);
01300         return FALSE;
01301 }
01302 
01303 BOOL run_pushargi(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
01304 {
01305         if (b_print)
01306                 printf("[0x%X]\tPUSHARGI ", offset);
01307         offset++;
01308         S32 arg = safe_instruction_bytestream2integer(buffer, offset);
01309         if (b_print)
01310                 printf("%d\n", arg);
01311         lscript_push(buffer, arg);
01312         return FALSE;
01313 }
01314 
01315 BOOL run_pushargf(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
01316 {
01317         if (b_print)
01318                 printf("[0x%X]\tPUSHARGF ", offset);
01319         offset++;
01320         F32 arg = safe_instruction_bytestream2float(buffer, offset);
01321         if (b_print)
01322                 printf("%f\n", arg);
01323         lscript_push(buffer, arg);
01324         return FALSE;
01325 }
01326 
01327 BOOL run_pushargs(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
01328 {
01329         if (b_print)
01330                 printf("[0x%X]\tPUSHARGS ", offset);
01331         S32 toffset = offset;
01332         safe_instruction_bytestream_count_char(buffer, toffset);
01333         S32 size = toffset - offset;
01334         char *arg = new char[size];
01335         offset++;
01336         safe_instruction_bytestream2char(arg, buffer, offset);
01337         if (b_print)
01338                 printf("%s\n", arg);
01339         S32 address = lsa_heap_add_data(buffer, new LLScriptLibData(arg), get_max_heap_size(buffer), TRUE);
01340         lscript_push(buffer, address);
01341         delete [] arg;
01342         return FALSE;
01343 }
01344 
01345 BOOL run_pushargv(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
01346 {
01347         if (b_print)
01348                 printf("[0x%X]\tPUSHARGV ", offset);
01349         offset++;
01350         LLVector3 arg;
01351         safe_instruction_bytestream2vector(arg, buffer, offset);
01352         if (b_print)
01353                 printf("< %f, %f, %f >\n", arg.mV[VX], arg.mV[VY], arg.mV[VZ]);
01354         lscript_push(buffer, arg);
01355         return FALSE;
01356 }
01357 BOOL run_pushargq(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
01358 {
01359         if (b_print)
01360                 printf("[0x%X]\tPUSHARGQ ", offset);
01361         offset++;
01362         LLQuaternion arg;
01363         safe_instruction_bytestream2quaternion(arg, buffer, offset);
01364         if (b_print)
01365                 printf("< %f, %f, %f, %f >\n", arg.mQ[VX], arg.mQ[VY], arg.mQ[VZ], arg.mQ[VS]);
01366         lscript_push(buffer, arg);
01367         return FALSE;
01368 }
01369 BOOL run_pushe(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
01370 {
01371         if (b_print)
01372                 printf("[0x%X]\tPUSHE\n", offset);
01373         offset++;
01374         lscript_pusharge(buffer, LSCRIPTDataSize[LST_INTEGER]);
01375         return FALSE;
01376 }
01377 BOOL run_pushev(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
01378 {
01379         if (b_print)
01380                 printf("[0x%X]\tPUSHEV\n", offset);
01381         offset++;
01382         lscript_pusharge(buffer, LSCRIPTDataSize[LST_VECTOR]);
01383         return FALSE;
01384 }
01385 BOOL run_pusheq(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
01386 {
01387         if (b_print)
01388                 printf("[0x%X]\tPUSHEQ\n", offset);
01389         offset++;
01390         lscript_pusharge(buffer, LSCRIPTDataSize[LST_QUATERNION]);
01391         return FALSE;
01392 }
01393 BOOL run_pusharge(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
01394 {
01395         if (b_print)
01396                 printf("[0x%X]\tPUSHARGE ", offset);
01397         offset++;
01398         S32 arg = safe_instruction_bytestream2integer(buffer, offset);
01399         if (b_print)
01400                 printf("%d\n", arg);
01401         lscript_pusharge(buffer, arg);
01402         return FALSE;
01403 }
01404 
01405 void print_type(U8 type)
01406 {
01407         if (type == LSCRIPTTypeByte[LST_INTEGER])
01408         {
01409                 printf("integer");
01410         }
01411         else if (type == LSCRIPTTypeByte[LST_FLOATINGPOINT])
01412         {
01413                 printf("float");
01414         }
01415         else if (type == LSCRIPTTypeByte[LST_STRING])
01416         {
01417                 printf("string");
01418         }
01419         else if (type == LSCRIPTTypeByte[LST_KEY])
01420         {
01421                 printf("key");
01422         }
01423         else if (type == LSCRIPTTypeByte[LST_VECTOR])
01424         {
01425                 printf("vector");
01426         }
01427         else if (type == LSCRIPTTypeByte[LST_QUATERNION])
01428         {
01429                 printf("quaternion");
01430         }
01431         else if (type == LSCRIPTTypeByte[LST_LIST])
01432         {
01433                 printf("list");
01434         }
01435 }
01436 
01437 void unknown_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
01438 {
01439         printf("Unknown arithmetic operation!\n");
01440 }
01441 
01442 void integer_integer_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
01443 {
01444         S32 lside = lscript_pop_int(buffer);
01445         S32 rside = lscript_pop_int(buffer);
01446         S32 result = 0;
01447 
01448         switch(opcode)
01449         {
01450         case LOPC_ADD:
01451                 result = lside + rside;
01452                 break;
01453         case LOPC_SUB:
01454                 result = lside - rside;
01455                 break;
01456         case LOPC_MUL:
01457                 result = lside * rside;
01458                 break;
01459         case LOPC_DIV:
01460                 if (rside){
01461                         if( ( rside == -1 ) || ( rside == (S32) 0xffffffff ) )//        division by -1 can have funny results: multiplication is OK: SL-31252
01462                         {
01463                                 result = -1 * lside;
01464                         }
01465                         else
01466                         {
01467                                 result = lside / rside;
01468                         }
01469                 }
01470                 else
01471                         set_fault(buffer, LSRF_MATH);
01472                 break;
01473         case LOPC_MOD:
01474                 if (rside)
01475                 {
01476                         if (rside == -1 || rside == 1 )  // mod(1) = mod(-1) = 0: SL-31252
01477                         {
01478                                 result = 0;
01479                         }
01480                         else
01481                         {
01482                                 result = lside % rside;
01483                         }
01484                 }
01485                 else
01486                         set_fault(buffer, LSRF_MATH);
01487                 break;
01488         case LOPC_EQ:
01489                 result = (lside == rside);
01490                 break;
01491         case LOPC_NEQ:
01492                 result = (lside != rside);
01493                 break;
01494         case LOPC_LEQ:
01495                 result = (lside <= rside);
01496                 break;
01497         case LOPC_GEQ:
01498                 result = (lside >= rside);
01499                 break;
01500         case LOPC_LESS:
01501                 result = (lside < rside);
01502                 break;
01503         case LOPC_GREATER:
01504                 result = (lside > rside);
01505                 break;
01506         case LOPC_BITAND:
01507                 result = (lside & rside);
01508                 break;
01509         case LOPC_BITOR:
01510                 result = (lside | rside);
01511                 break;
01512         case LOPC_BITXOR:
01513                 result = (lside ^ rside);
01514                 break;
01515         case LOPC_BOOLAND:
01516                 result = (lside && rside);
01517                 break;
01518         case LOPC_BOOLOR:
01519                 result = (lside || rside);
01520                 break;
01521         case LOPC_SHL:
01522                 result = (lside << rside);
01523                 break;
01524         case LOPC_SHR:
01525                 result = (lside >> rside);
01526                 break;
01527         default:
01528                 break;
01529         }
01530         lscript_push(buffer, result);
01531 }
01532 
01533 void integer_float_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
01534 {
01535         S32 lside = lscript_pop_int(buffer);
01536         F32 rside = lscript_pop_float(buffer);
01537         S32 resulti = 0;
01538         F32 resultf = 0;
01539 
01540         switch(opcode)
01541         {
01542         case LOPC_ADD:
01543                 resultf = lside + rside;
01544                 lscript_push(buffer, resultf);
01545                 break;
01546         case LOPC_SUB:
01547                 resultf = lside - rside;
01548                 lscript_push(buffer, resultf);
01549                 break;
01550         case LOPC_MUL:
01551                 resultf = lside * rside;
01552                 lscript_push(buffer, resultf);
01553                 break;
01554         case LOPC_DIV:
01555                 if (rside)
01556                         resultf = lside / rside;
01557                 else
01558                         set_fault(buffer, LSRF_MATH);
01559                 lscript_push(buffer, resultf);
01560                 break;
01561         case LOPC_EQ:
01562                 resulti = (lside == rside);
01563                 lscript_push(buffer, resulti);
01564                 break;
01565         case LOPC_NEQ:
01566                 resulti = (lside != rside);
01567                 lscript_push(buffer, resulti);
01568                 break;
01569         case LOPC_LEQ:
01570                 resulti = (lside <= rside);
01571                 lscript_push(buffer, resulti);
01572                 break;
01573         case LOPC_GEQ:
01574                 resulti = (lside >= rside);
01575                 lscript_push(buffer, resulti);
01576                 break;
01577         case LOPC_LESS:
01578                 resulti = (lside < rside);
01579                 lscript_push(buffer, resulti);
01580                 break;
01581         case LOPC_GREATER:
01582                 resulti = (lside > rside);
01583                 lscript_push(buffer, resulti);
01584                 break;
01585         default:
01586                 break;
01587         }
01588 }
01589 
01590 void integer_vector_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
01591 {
01592         S32 lside = lscript_pop_int(buffer);
01593         LLVector3 rside;
01594         lscript_pop_vector(buffer, rside);
01595 
01596         switch(opcode)
01597         {
01598         case LOPC_MUL:
01599                 rside *= (F32)lside;
01600                 lscript_push(buffer, rside);
01601                 break;
01602         default:
01603                 break;
01604         }
01605 }
01606 
01607 void float_integer_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
01608 {
01609         F32 lside = lscript_pop_float(buffer);
01610         S32 rside = lscript_pop_int(buffer);
01611         S32 resulti = 0;
01612         F32 resultf = 0;
01613 
01614         switch(opcode)
01615         {
01616         case LOPC_ADD:
01617                 resultf = lside + rside;
01618                 lscript_push(buffer, resultf);
01619                 break;
01620         case LOPC_SUB:
01621                 resultf = lside - rside;
01622                 lscript_push(buffer, resultf);
01623                 break;
01624         case LOPC_MUL:
01625                 resultf = lside * rside;
01626                 lscript_push(buffer, resultf);
01627                 break;
01628         case LOPC_DIV:
01629                 if (rside)
01630                         resultf = lside / rside;
01631                 else
01632                         set_fault(buffer, LSRF_MATH);
01633                 lscript_push(buffer, resultf);
01634                 break;
01635         case LOPC_EQ:
01636                 resulti = (lside == rside);
01637                 lscript_push(buffer, resulti);
01638                 break;
01639         case LOPC_NEQ:
01640                 resulti = (lside != rside);
01641                 lscript_push(buffer, resulti);
01642                 break;
01643         case LOPC_LEQ:
01644                 resulti = (lside <= rside);
01645                 lscript_push(buffer, resulti);
01646                 break;
01647         case LOPC_GEQ:
01648                 resulti = (lside >= rside);
01649                 lscript_push(buffer, resulti);
01650                 break;
01651         case LOPC_LESS:
01652                 resulti = (lside < rside);
01653                 lscript_push(buffer, resulti);
01654                 break;
01655         case LOPC_GREATER:
01656                 resulti = (lside > rside);
01657                 lscript_push(buffer, resulti);
01658                 break;
01659         default:
01660                 break;
01661         }
01662 }
01663 
01664 void float_float_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
01665 {
01666         F32 lside = lscript_pop_float(buffer);
01667         F32 rside = lscript_pop_float(buffer);
01668         F32 resultf = 0;
01669         S32 resulti = 0;
01670 
01671         switch(opcode)
01672         {
01673         case LOPC_ADD:
01674                 resultf = lside + rside;
01675                 lscript_push(buffer, resultf);
01676                 break;
01677         case LOPC_SUB:
01678                 resultf = lside - rside;
01679                 lscript_push(buffer, resultf);
01680                 break;
01681         case LOPC_MUL:
01682                 resultf = lside * rside;
01683                 lscript_push(buffer, resultf);
01684                 break;
01685         case LOPC_DIV:
01686                 if (rside)
01687                         resultf = lside / rside;
01688                 else
01689                         set_fault(buffer, LSRF_MATH);
01690                 lscript_push(buffer, resultf);
01691                 break;
01692         case LOPC_EQ:
01693                 resulti = (lside == rside);
01694                 lscript_push(buffer, resulti);
01695                 break;
01696         case LOPC_NEQ:
01697                 resulti = (lside != rside);
01698                 lscript_push(buffer, resulti);
01699                 break;
01700         case LOPC_LEQ:
01701                 resulti = (lside <= rside);
01702                 lscript_push(buffer, resulti);
01703                 break;
01704         case LOPC_GEQ:
01705                 resulti = (lside >= rside);
01706                 lscript_push(buffer, resulti);
01707                 break;
01708         case LOPC_LESS:
01709                 resulti = (lside < rside);
01710                 lscript_push(buffer, resulti);
01711                 break;
01712         case LOPC_GREATER:
01713                 resulti = (lside > rside);
01714                 lscript_push(buffer, resulti);
01715                 break;
01716         default:
01717                 break;
01718         }
01719 }
01720 
01721 void float_vector_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
01722 {
01723         F32 lside = lscript_pop_float(buffer);
01724         LLVector3 rside;
01725         lscript_pop_vector(buffer, rside);
01726 
01727         switch(opcode)
01728         {
01729         case LOPC_MUL:
01730                 rside *= lside;
01731                 lscript_push(buffer, rside);
01732                 break;
01733         default:
01734                 break;
01735         }
01736 }
01737 
01738 void string_string_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
01739 {
01740         S32 lside = lscript_pop_int(buffer);
01741         S32 rside = lscript_pop_int(buffer);
01742         S32 resulti;
01743         S32 address;
01744 
01745         switch(opcode)
01746         {
01747         case LOPC_ADD:
01748                 address = lsa_cat_strings(buffer, lside, rside, get_max_heap_size(buffer));
01749                 lscript_push(buffer, address);
01750                 break;
01751         case LOPC_EQ:
01752                 resulti = !lsa_cmp_strings(buffer, lside, rside);
01753                 lscript_push(buffer, resulti);
01754                 break;
01755         case LOPC_NEQ:
01756                 resulti = lsa_cmp_strings(buffer, lside, rside);
01757                 lscript_push(buffer, resulti);
01758                 break;
01759         default:
01760                 break;
01761         }
01762 }
01763 
01764 void string_key_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
01765 {
01766         S32 lside = lscript_pop_int(buffer);
01767         S32 rside = lscript_pop_int(buffer);
01768         S32 resulti;
01769 
01770         switch(opcode)
01771         {
01772         case LOPC_NEQ:
01773                 resulti = lsa_cmp_strings(buffer, lside, rside);
01774                 lscript_push(buffer, resulti);
01775                 break;
01776         case LOPC_EQ:
01777                 resulti = !lsa_cmp_strings(buffer, lside, rside);
01778                 lscript_push(buffer, resulti);
01779                 break;
01780         default:
01781                 break;
01782         }
01783 }
01784 
01785 void key_string_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
01786 {
01787         S32 lside = lscript_pop_int(buffer);
01788         S32 rside = lscript_pop_int(buffer);
01789         S32 resulti;
01790 
01791         switch(opcode)
01792         {
01793         case LOPC_NEQ:
01794                 resulti = lsa_cmp_strings(buffer, lside, rside);
01795                 lscript_push(buffer, resulti);
01796                 break;
01797         case LOPC_EQ:
01798                 resulti = !lsa_cmp_strings(buffer, lside, rside);
01799                 lscript_push(buffer, resulti);
01800                 break;
01801         default:
01802                 break;
01803         }
01804 }
01805 
01806 void key_key_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
01807 {
01808         S32 lside = lscript_pop_int(buffer);
01809         S32 rside = lscript_pop_int(buffer);
01810         S32 resulti;
01811 
01812         switch(opcode)
01813         {
01814         case LOPC_EQ:
01815                 resulti = !lsa_cmp_strings(buffer, lside, rside);
01816                 lscript_push(buffer, resulti);
01817                 break;
01818         case LOPC_NEQ:
01819                 resulti = lsa_cmp_strings(buffer, lside, rside);
01820                 lscript_push(buffer, resulti);
01821                 break;
01822         default:
01823                 break;
01824         }
01825 }
01826 
01827 void vector_integer_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
01828 {
01829         LLVector3 lside;
01830         lscript_pop_vector(buffer, lside);
01831         S32 rside = lscript_pop_int(buffer);
01832 
01833         switch(opcode)
01834         {
01835         case LOPC_MUL:
01836                 lside *= (F32)rside;
01837                 lscript_push(buffer, lside);
01838                 break;
01839         case LOPC_DIV:
01840                 if (rside)
01841                         lside *= (1.f/rside);
01842                 else
01843                         set_fault(buffer, LSRF_MATH);
01844                 lscript_push(buffer, lside);
01845                 break;
01846         default:
01847                 break;
01848         }
01849 }
01850 
01851 void vector_float_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
01852 {
01853         LLVector3 lside;
01854         lscript_pop_vector(buffer, lside);
01855         F32 rside = lscript_pop_float(buffer);
01856 
01857         switch(opcode)
01858         {
01859         case LOPC_MUL:
01860                 lside *= rside;
01861                 lscript_push(buffer, lside);
01862                 break;
01863         case LOPC_DIV:
01864                 if (rside)
01865                         lside *= (1.f/rside);
01866                 else
01867                         set_fault(buffer, LSRF_MATH);
01868                 lscript_push(buffer, lside);
01869                 break;
01870         default:
01871                 break;
01872         }
01873 }
01874 
01875 void vector_vector_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
01876 {
01877         LLVector3 lside;
01878         lscript_pop_vector(buffer, lside);
01879         LLVector3 rside;
01880         lscript_pop_vector(buffer, rside);
01881         S32 resulti = 0;
01882         F32 resultf = 0.f;
01883 
01884         switch(opcode)
01885         {
01886         case LOPC_ADD:
01887                 lside += rside;
01888                 lscript_push(buffer, lside);
01889                 break;
01890         case LOPC_SUB:
01891                 lside -= rside;
01892                 lscript_push(buffer, lside);
01893                 break;
01894         case LOPC_MUL:
01895                 resultf = lside * rside;
01896                 lscript_push(buffer, resultf);
01897                 break;
01898         case LOPC_MOD:
01899                 lside = lside % rside;
01900                 lscript_push(buffer, lside);
01901                 break;
01902         case LOPC_EQ:
01903                 resulti = (lside == rside);
01904                 lscript_push(buffer, resulti);
01905                 break;
01906         case LOPC_NEQ:
01907                 resulti = (lside != rside);
01908                 lscript_push(buffer, resulti);
01909                 break;
01910         default:
01911                 break;
01912         }
01913 }
01914 
01915 void vector_quaternion_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
01916 {
01917         LLVector3 lside;
01918         lscript_pop_vector(buffer, lside);
01919         LLQuaternion rside;
01920         lscript_pop_quaternion(buffer, rside);
01921 
01922         switch(opcode)
01923         {
01924         case LOPC_MUL:
01925                 lside = lside * rside;
01926                 lscript_push(buffer, lside);
01927                 break;
01928         case LOPC_DIV:
01929                 lside = lside * rside.conjQuat();
01930                 lscript_push(buffer, lside);
01931                 break;
01932         default:
01933                 break;
01934         }
01935 }
01936 
01937 void quaternion_quaternion_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
01938 {
01939         LLQuaternion lside;
01940         lscript_pop_quaternion(buffer, lside);
01941         LLQuaternion rside;
01942         lscript_pop_quaternion(buffer, rside);
01943         S32 resulti = 0;
01944 
01945         switch(opcode)
01946         {
01947         case LOPC_ADD:
01948                 lside = lside + rside;
01949                 lscript_push(buffer, lside);
01950                 break;
01951         case LOPC_SUB:
01952                 lside = lside - rside;
01953                 lscript_push(buffer, lside);
01954                 break;
01955         case LOPC_MUL:
01956                 lside *= rside;
01957                 lscript_push(buffer, lside);
01958                 break;
01959         case LOPC_DIV:
01960                 lside = lside * rside.conjQuat();
01961                 lscript_push(buffer, lside);
01962                 break;
01963         case LOPC_EQ:
01964                 resulti = (lside == rside);
01965                 lscript_push(buffer, resulti);
01966                 break;
01967         case LOPC_NEQ:
01968                 resulti = (lside != rside);
01969                 lscript_push(buffer, resulti);
01970                 break;
01971         default:
01972                 break;
01973         }
01974 }
01975 
01976 void integer_list_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
01977 {
01978         S32 lside = lscript_pop_int(buffer);
01979         S32 rside = lscript_pop_int(buffer);
01980         S32 address;
01981 
01982         switch(opcode)
01983         {
01984         case LOPC_ADD:
01985                 {
01986                         LLScriptLibData *list = new LLScriptLibData;
01987                         list->mType = LST_LIST;
01988                         list->mListp = new LLScriptLibData(lside);
01989                         address = lsa_preadd_lists(buffer, list, rside, get_max_heap_size(buffer));
01990                         lscript_push(buffer, address);
01991                         list->mListp = NULL;
01992                         delete list;
01993                 }
01994                 break;
01995         default:
01996                 break;
01997         }
01998 }
01999 
02000 void float_list_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
02001 {
02002         F32 lside = lscript_pop_float(buffer);
02003         S32 rside = lscript_pop_int(buffer);
02004         S32 address;
02005 
02006         switch(opcode)
02007         {
02008         case LOPC_ADD:
02009                 {
02010                         LLScriptLibData *list = new LLScriptLibData;
02011                         list->mType = LST_LIST;
02012                         list->mListp = new LLScriptLibData(lside);
02013                         address = lsa_preadd_lists(buffer, list, rside, get_max_heap_size(buffer));
02014                         lscript_push(buffer, address);
02015                         list->mListp = NULL;
02016                         delete list;
02017                 }
02018                 break;
02019         default:
02020                 break;
02021         }
02022 }
02023 
02024 void string_list_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
02025 {
02026         S32 lside = lscript_pop_int(buffer);
02027         S32 rside = lscript_pop_int(buffer);
02028         S32 address;
02029 
02030         switch(opcode)
02031         {
02032         case LOPC_ADD:
02033                 {
02034                         LLScriptLibData *string = lsa_get_data(buffer, lside, TRUE);
02035                         LLScriptLibData *list = new LLScriptLibData;
02036                         list->mType = LST_LIST;
02037                         list->mListp = string;
02038                         address = lsa_preadd_lists(buffer, list, rside, get_max_heap_size(buffer));
02039                         lscript_push(buffer, address);
02040                         list->mListp = NULL;
02041                         delete list;
02042                 }
02043                 break;
02044         default:
02045                 break;
02046         }
02047 }
02048 
02049 void key_list_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
02050 {
02051         S32 lside = lscript_pop_int(buffer);
02052         S32 rside = lscript_pop_int(buffer);
02053         S32 address;
02054 
02055         switch(opcode)
02056         {
02057         case LOPC_ADD:
02058                 {
02059                         LLScriptLibData *key = lsa_get_data(buffer, lside, TRUE);
02060                         // need to convert key to key, since it comes out like a string
02061                         if (key->mType == LST_STRING)
02062                         {
02063                                 key->mKey = key->mString;
02064                                 key->mString = NULL;
02065                                 key->mType = LST_KEY;
02066                         }
02067                         LLScriptLibData *list = new LLScriptLibData;
02068                         list->mType = LST_LIST;
02069                         list->mListp = key;
02070                         address = lsa_preadd_lists(buffer, list, rside, get_max_heap_size(buffer));
02071                         lscript_push(buffer, address);
02072                         list->mListp = NULL;
02073                         delete list;
02074                 }
02075                 break;
02076         default:
02077                 break;
02078         }
02079 }
02080 
02081 void vector_list_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
02082 {
02083         LLVector3 lside;
02084         lscript_pop_vector(buffer, lside);
02085         S32 rside = lscript_pop_int(buffer);
02086         S32 address;
02087 
02088         switch(opcode)
02089         {
02090         case LOPC_ADD:
02091                 {
02092                         LLScriptLibData *list = new LLScriptLibData;
02093                         list->mType = LST_LIST;
02094                         list->mListp = new LLScriptLibData(lside);
02095                         address = lsa_preadd_lists(buffer, list, rside, get_max_heap_size(buffer));
02096                         lscript_push(buffer, address);
02097                         list->mListp = NULL;
02098                         delete list;
02099                 }
02100                 break;
02101         default:
02102                 break;
02103         }
02104 }
02105 
02106 void quaternion_list_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
02107 {
02108         LLQuaternion lside;
02109         lscript_pop_quaternion(buffer, lside);
02110         S32 rside = lscript_pop_int(buffer);
02111         S32 address;
02112 
02113         switch(opcode)
02114         {
02115         case LOPC_ADD:
02116                 {
02117                         LLScriptLibData *list = new LLScriptLibData;
02118                         list->mType = LST_LIST;
02119                         list->mListp = new LLScriptLibData(lside);
02120                         address = lsa_preadd_lists(buffer, list, rside, get_max_heap_size(buffer));
02121                         lscript_push(buffer, address);
02122                         list->mListp = NULL;
02123                         delete list;
02124                 }
02125                 break;
02126         default:
02127                 break;
02128         }
02129 }
02130 
02131 void list_integer_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
02132 {
02133         S32 lside = lscript_pop_int(buffer);
02134         S32 rside = lscript_pop_int(buffer);
02135         S32 address;
02136 
02137         switch(opcode)
02138         {
02139         case LOPC_ADD:
02140                 {
02141                         LLScriptLibData *list = new LLScriptLibData;
02142                         list->mType = LST_LIST;
02143                         list->mListp = new LLScriptLibData(rside);
02144                         address = lsa_postadd_lists(buffer, lside, list, get_max_heap_size(buffer));
02145                         list->mListp = NULL;
02146                         delete list;
02147                         lscript_push(buffer, address);
02148                 }
02149                 break;
02150         default:
02151                 break;
02152         }
02153 }
02154 
02155 void list_float_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
02156 {
02157         S32 lside = lscript_pop_int(buffer);
02158         F32 rside = lscript_pop_float(buffer);
02159         S32 address;
02160 
02161         switch(opcode)
02162         {
02163         case LOPC_ADD:
02164                 {
02165                         LLScriptLibData *list = new LLScriptLibData;
02166                         list->mType = LST_LIST;
02167                         list->mListp = new LLScriptLibData(rside);
02168                         address = lsa_postadd_lists(buffer, lside, list, get_max_heap_size(buffer));
02169                         list->mListp = NULL;
02170                         delete list;
02171                         lscript_push(buffer, address);
02172                 }
02173                 break;
02174         default:
02175                 break;
02176         }
02177 }
02178 
02179 void list_string_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
02180 {
02181         S32 lside = lscript_pop_int(buffer);
02182         S32 rside = lscript_pop_int(buffer);
02183         S32 address;
02184 
02185         switch(opcode)
02186         {
02187         case LOPC_ADD:
02188                 {
02189                         LLScriptLibData *string = lsa_get_data(buffer, rside, TRUE);
02190                         LLScriptLibData *list = new LLScriptLibData;
02191                         list->mType = LST_LIST;
02192                         list->mListp = string;
02193                         address = lsa_postadd_lists(buffer, lside, list, get_max_heap_size(buffer));
02194                         list->mListp = NULL;
02195                         delete list;
02196                         lscript_push(buffer, address);
02197                 }
02198                 break;
02199         default:
02200                 break;
02201         }
02202 }
02203 
02204 void list_key_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
02205 {
02206         S32 lside = lscript_pop_int(buffer);
02207         S32 rside = lscript_pop_int(buffer);
02208         S32 address;
02209 
02210         switch(opcode)
02211         {
02212         case LOPC_ADD:
02213                 {
02214                         LLScriptLibData *key = lsa_get_data(buffer, rside, TRUE);
02215                         // need to convert key to key, since it comes out like a string
02216                         if (key->mType == LST_STRING)
02217                         {
02218                                 key->mKey = key->mString;
02219                                 key->mString = NULL;
02220                                 key->mType = LST_KEY;
02221                         }
02222                         LLScriptLibData *list = new LLScriptLibData;
02223                         list->mType = LST_LIST;
02224                         list->mListp = key;
02225                         address = lsa_postadd_lists(buffer, lside, list, get_max_heap_size(buffer));
02226                         list->mListp = NULL;
02227                         delete list;
02228                         lscript_push(buffer, address);
02229                 }
02230                 break;
02231         default:
02232                 break;
02233         }
02234 }
02235 
02236 void list_vector_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
02237 {
02238         S32 lside = lscript_pop_int(buffer);
02239         LLVector3 rside;
02240         lscript_pop_vector(buffer, rside);
02241         S32 address;
02242 
02243         switch(opcode)
02244         {
02245         case LOPC_ADD:
02246                 {
02247                         LLScriptLibData *list = new LLScriptLibData;
02248                         list->mType = LST_LIST;
02249                         list->mListp = new LLScriptLibData(rside);
02250                         address = lsa_postadd_lists(buffer, lside, list, get_max_heap_size(buffer));
02251                         list->mListp = NULL;
02252                         delete list;
02253                         lscript_push(buffer, address);
02254                 }
02255                 break;
02256         default:
02257                 break;
02258         }
02259 }
02260 
02261 void list_quaternion_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
02262 {
02263         S32 lside = lscript_pop_int(buffer);
02264         LLQuaternion rside;
02265         lscript_pop_quaternion(buffer, rside);
02266         S32 address;
02267 
02268         switch(opcode)
02269         {
02270         case LOPC_ADD:
02271                 {
02272                         LLScriptLibData *list = new LLScriptLibData;
02273                         list->mType = LST_LIST;
02274                         list->mListp = new LLScriptLibData(rside);
02275                         address = lsa_postadd_lists(buffer, lside, list, get_max_heap_size(buffer));
02276                         list->mListp = NULL;
02277                         delete list;
02278                         lscript_push(buffer, address);
02279                 }
02280                 break;
02281         default:
02282                 break;
02283         }
02284 }
02285 
02286 void list_list_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
02287 {
02288         S32 lside = lscript_pop_int(buffer);
02289         S32 rside = lscript_pop_int(buffer);
02290         S32 resulti;
02291         S32 address;
02292 
02293         switch(opcode)
02294         {
02295         case LOPC_ADD:
02296                 address = lsa_cat_lists(buffer, lside, rside, get_max_heap_size(buffer));
02297                 lscript_push(buffer, address);
02298                 break;
02299         case LOPC_EQ:
02300                 resulti = !lsa_cmp_lists(buffer, lside, rside);
02301                 lscript_push(buffer, resulti);
02302                 break;
02303         case LOPC_NEQ:
02304                 resulti = lsa_cmp_lists(buffer, lside, rside);
02305                 lscript_push(buffer, resulti);
02306                 break;
02307         default:
02308                 break;
02309         }
02310 }
02311 
02312 BOOL run_add(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
02313 {
02314         if (b_print)
02315                 printf("[0x%X]\tADD ", offset);
02316         offset++;
02317         U8 arg = safe_instruction_bytestream2byte(buffer, offset);
02318         U8 arg1 = arg >> 4;
02319         U8 arg2 = arg & 0xf;
02320         if (b_print)
02321         {
02322                 print_type(arg1);
02323                 printf(", ");
02324                 print_type(arg2);
02325                 printf("\n");
02326         }
02327         binary_operations[arg1][arg2](buffer, LOPC_ADD);
02328         return FALSE;
02329 }
02330 
02331 BOOL run_sub(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
02332 {
02333         if (b_print)
02334                 printf("[0x%X]\tSUB ", offset);
02335         offset++;
02336         U8 arg = safe_instruction_bytestream2byte(buffer, offset);
02337         U8 arg1 = arg >> 4;
02338         U8 arg2 = arg & 0xf;
02339         if (b_print)
02340         {
02341                 print_type(arg1);
02342                 printf(", ");
02343                 print_type(arg2);
02344                 printf("\n");
02345         }
02346         binary_operations[arg1][arg2](buffer, LOPC_SUB);
02347         return FALSE;
02348 }
02349 BOOL run_mul(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
02350 {
02351         if (b_print)
02352                 printf("[0x%X]\tMUL ", offset);
02353         offset++;
02354         U8 arg = safe_instruction_bytestream2byte(buffer, offset);
02355         U8 arg1 = arg >> 4;
02356         U8 arg2 = arg & 0xf;
02357         if (b_print)
02358         {
02359                 print_type(arg1);
02360                 printf(", ");
02361                 print_type(arg2);
02362                 printf("\n");
02363         }
02364         binary_operations[arg1][arg2](buffer, LOPC_MUL);
02365         return FALSE;
02366 }
02367 BOOL run_div(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
02368 {
02369         if (b_print)
02370                 printf("[0x%X]\tDIV ", offset);
02371         offset++;
02372         U8 arg = safe_instruction_bytestream2byte(buffer, offset);
02373         U8 arg1 = arg >> 4;
02374         U8 arg2 = arg & 0xf;
02375         if (b_print)
02376         {
02377                 print_type(arg1);
02378                 printf(", ");
02379                 print_type(arg2);
02380                 printf("\n");
02381         }
02382         binary_operations[arg1][arg2](buffer, LOPC_DIV);
02383         return FALSE;
02384 }
02385 BOOL run_mod(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
02386 {
02387         if (b_print)
02388                 printf("[0x%X]\tMOD ", offset);
02389         offset++;
02390         U8 arg = safe_instruction_bytestream2byte(buffer, offset);
02391         U8 arg1 = arg >> 4;
02392         U8 arg2 = arg & 0xf;
02393         if (b_print)
02394         {
02395                 print_type(arg1);
02396                 printf(", ");
02397                 print_type(arg2);
02398                 printf("\n");
02399         }
02400         binary_operations[arg1][arg2](buffer, LOPC_MOD);
02401         return FALSE;
02402 }
02403 
02404 BOOL run_eq(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
02405 {
02406         if (b_print)
02407                 printf("[0x%X]\tEQ ", offset);
02408         offset++;
02409         U8 arg = safe_instruction_bytestream2byte(buffer, offset);
02410         U8 arg1 = arg >> 4;
02411         U8 arg2 = arg & 0xf;
02412         if (b_print)
02413         {
02414                 print_type(arg1);
02415                 printf(", ");
02416                 print_type(arg2);
02417                 printf("\n");
02418         }
02419         binary_operations[arg1][arg2](buffer, LOPC_EQ);
02420         return FALSE;
02421 }
02422 BOOL run_neq(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
02423 {
02424         if (b_print)
02425                 printf("[0x%X]\tNEQ ", offset);
02426         offset++;
02427         U8 arg = safe_instruction_bytestream2byte(buffer, offset);
02428         U8 arg1 = arg >> 4;
02429         U8 arg2 = arg & 0xf;
02430         if (b_print)
02431         {
02432                 print_type(arg1);
02433                 printf(", ");
02434                 print_type(arg2);
02435                 printf("\n");
02436         }
02437         binary_operations[arg1][arg2](buffer, LOPC_NEQ);
02438         return FALSE;
02439 }
02440 BOOL run_leq(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
02441 {
02442         if (b_print)
02443                 printf("[0x%X]\tLEQ ", offset);
02444         offset++;
02445         U8 arg = safe_instruction_bytestream2byte(buffer, offset);
02446         U8 arg1 = arg >> 4;
02447         U8 arg2 = arg & 0xf;
02448         if (b_print)
02449         {
02450                 print_type(arg1);
02451                 printf(", ");
02452                 print_type(arg2);
02453                 printf("\n");
02454         }
02455         binary_operations[arg1][arg2](buffer, LOPC_LEQ);
02456         return FALSE;
02457 }
02458 BOOL run_geq(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
02459 {
02460         if (b_print)
02461                 printf("[0x%X]\tGEQ ", offset);
02462         offset++;
02463         U8 arg = safe_instruction_bytestream2byte(buffer, offset);
02464         U8 arg1 = arg >> 4;
02465         U8 arg2 = arg & 0xf;
02466         if (b_print)
02467         {
02468                 print_type(arg1);
02469                 printf(", ");
02470                 print_type(arg2);
02471                 printf("\n");
02472         }
02473         binary_operations[arg1][arg2](buffer, LOPC_GEQ);
02474         return FALSE;
02475 }
02476 BOOL run_less(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
02477 {
02478         if (b_print)
02479                 printf("[0x%X]\tLESS ", offset);
02480         offset++;
02481         U8 arg = safe_instruction_bytestream2byte(buffer, offset);
02482         U8 arg1 = arg >> 4;
02483         U8 arg2 = arg & 0xf;
02484         if (b_print)
02485         {
02486                 print_type(arg1);
02487                 printf(", ");
02488                 print_type(arg2);
02489                 printf("\n");
02490         }
02491         binary_operations[arg1][arg2](buffer, LOPC_LESS);
02492         return FALSE;
02493 }
02494 BOOL run_greater(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
02495 {
02496         if (b_print)
02497                 printf("[0x%X]\tGREATER ", offset);
02498         offset++;
02499         U8 arg = safe_instruction_bytestream2byte(buffer, offset);
02500         U8 arg1 = arg >> 4;
02501         U8 arg2 = arg & 0xf;
02502         if (b_print)
02503         {
02504                 print_type(arg1);
02505                 printf(", ");
02506                 print_type(arg2);
02507                 printf("\n");
02508         }
02509         binary_operations[arg1][arg2](buffer, LOPC_GREATER);
02510         return FALSE;
02511 }
02512 
02513 BOOL run_bitand(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
02514 {
02515         if (b_print)
02516                 printf("[0x%X]\tBITAND\n", offset);
02517         offset++;
02518         binary_operations[LST_INTEGER][LST_INTEGER](buffer, LOPC_BITAND);
02519         return FALSE;
02520 }
02521 BOOL run_bitor(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
02522 {
02523         if (b_print)
02524                 printf("[0x%X]\tBITOR\n", offset);
02525         offset++;
02526         binary_operations[LST_INTEGER][LST_INTEGER](buffer, LOPC_BITOR);
02527         return FALSE;
02528 }
02529 BOOL run_bitxor(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
02530 {
02531         if (b_print)
02532                 printf("[0x%X]\tBITXOR\n", offset);
02533         offset++;
02534         binary_operations[LST_INTEGER][LST_INTEGER](buffer, LOPC_BITXOR);
02535         return FALSE;
02536 }
02537 BOOL run_booland(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
02538 {
02539         if (b_print)
02540                 printf("[0x%X]\tBOOLAND\n", offset);
02541         offset++;
02542         binary_operations[LST_INTEGER][LST_INTEGER](buffer, LOPC_BOOLAND);
02543         return FALSE;
02544 }
02545 BOOL run_boolor(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
02546 {
02547         if (b_print)
02548                 printf("[0x%X]\tBOOLOR\n", offset);
02549         offset++;
02550         binary_operations[LST_INTEGER][LST_INTEGER](buffer, LOPC_BOOLOR);
02551         return FALSE;
02552 }
02553 
02554 BOOL run_shl(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
02555 {
02556         if (b_print)
02557                 printf("[0x%X]\tSHL\n", offset);
02558         offset++;
02559         binary_operations[LST_INTEGER][LST_INTEGER](buffer, LOPC_SHL);
02560         return FALSE;
02561 }
02562 BOOL run_shr(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
02563 {
02564         if (b_print)
02565                 printf("[0x%X]\tSHR\n", offset);
02566         offset++;
02567         binary_operations[LST_INTEGER][LST_INTEGER](buffer, LOPC_SHR);
02568         return FALSE;
02569 }
02570 
02571 void integer_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
02572 {
02573         S32 lside = lscript_pop_int(buffer);
02574         S32 result = 0;
02575 
02576         switch(opcode)
02577         {
02578         case LOPC_NEG:
02579                 result = -lside;
02580                 break;
02581         case LOPC_BITNOT:
02582                 result = ~lside;
02583                 break;
02584         case LOPC_BOOLNOT:
02585                 result = !lside;
02586                 break;
02587         default:
02588                 break;
02589         }
02590         lscript_push(buffer, result);
02591 }
02592 
02593 void float_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
02594 {
02595         F32 lside = lscript_pop_float(buffer);
02596         F32 result = 0;
02597 
02598         switch(opcode)
02599         {
02600         case LOPC_NEG:
02601                 result = -lside;
02602                 lscript_push(buffer, result);
02603                 break;
02604         default:
02605                 break;
02606         }
02607 }
02608 
02609 void vector_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
02610 {
02611         LLVector3 lside;
02612         lscript_pop_vector(buffer, lside);
02613         LLVector3 result;
02614 
02615         switch(opcode)
02616         {
02617         case LOPC_NEG:
02618                 result = -lside;
02619                 lscript_push(buffer, result);
02620                 break;
02621         default:
02622                 break;
02623         }
02624 }
02625 
02626 void quaternion_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
02627 {
02628         LLQuaternion lside;
02629         lscript_pop_quaternion(buffer, lside);
02630         LLQuaternion result;
02631 
02632         switch(opcode)
02633         {
02634         case LOPC_NEG:
02635                 result = -lside;
02636                 lscript_push(buffer, result);
02637                 break;
02638         default:
02639                 break;
02640         }
02641 }
02642 
02643 
02644 BOOL run_neg(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
02645 {
02646         if (b_print)
02647                 printf("[0x%X]\tNEG ", offset);
02648         offset++;
02649         U8 arg = safe_instruction_bytestream2byte(buffer, offset);
02650         if (b_print)
02651         {
02652                 print_type(arg);
02653                 printf("\n");
02654         }
02655         unary_operations[arg](buffer, LOPC_NEG);
02656         return FALSE;
02657 }
02658 
02659 BOOL run_bitnot(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
02660 {
02661         if (b_print)
02662                 printf("[0x%X]\tBITNOT\n", offset);
02663         offset++;
02664         unary_operations[LST_INTEGER](buffer, LOPC_BITNOT);
02665         return FALSE;
02666 }
02667 
02668 BOOL run_boolnot(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
02669 {
02670         if (b_print)
02671                 printf("[0x%X]\tBOOLNOT\n", offset);
02672         offset++;
02673         unary_operations[LST_INTEGER](buffer, LOPC_BOOLNOT);
02674         return FALSE;
02675 }
02676 
02677 BOOL run_jump(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
02678 {
02679         if (b_print)
02680                 printf("[0x%X]\tJUMP ", offset);
02681         offset++;
02682         S32 arg = safe_instruction_bytestream2integer(buffer, offset);
02683         if (b_print)
02684                 printf("%d\n", arg);
02685         offset += arg;
02686         return FALSE;
02687 }
02688 
02689 BOOL run_jumpif(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
02690 {
02691         if (b_print)
02692                 printf("[0x%X]\tJUMPIF ", offset);
02693         offset++;
02694         U8 type = safe_instruction_bytestream2byte(buffer, offset);
02695         if (b_print)
02696         {
02697                 print_type(type);
02698                 printf(", ");
02699         }
02700         S32 arg = safe_instruction_bytestream2integer(buffer, offset);
02701         if (b_print)
02702                 printf("%d\n", arg);
02703 
02704         if (type == LST_INTEGER)
02705         {
02706                 S32 test = lscript_pop_int(buffer);
02707                 if (test)
02708                 {
02709                         offset += arg;
02710                 }
02711         }
02712         else if (type == LST_FLOATINGPOINT)
02713         {
02714                 F32 test = lscript_pop_float(buffer);
02715                 if (test)
02716                 {
02717                         offset += arg;
02718                 }
02719         }
02720         else if (type == LST_VECTOR)
02721         {
02722                 LLVector3 test;
02723                 lscript_pop_vector(buffer, test);
02724                 if (!test.isExactlyZero())
02725                 {
02726                         offset += arg;
02727                 }
02728         }
02729         else if (type == LST_QUATERNION)
02730         {
02731                 LLQuaternion test;
02732                 lscript_pop_quaternion(buffer, test);
02733                 if (!test.isIdentity())
02734                 {
02735                         offset += arg;
02736                 }
02737         }
02738         else if (type == LST_STRING)
02739         {
02740                 S32 base_address = lscript_pop_int(buffer);
02741                 // this bit of nastiness is to get around that code paths to
02742                 // local variables can result in lack of initialization and
02743                 // function clean up of ref counts isn't based on scope (a
02744                 // mistake, I know)
02745                 S32 address = base_address + get_register(buffer, LREG_HR) - 1;
02746                 if (address)
02747                 {
02748                         S32 string = address;
02749                         string += SIZEOF_SCRIPT_ALLOC_ENTRY;
02750                         if (safe_heap_check_address(buffer, string, 1))
02751                         {
02752                                 S32 toffset = string;
02753                                 safe_heap_bytestream_count_char(buffer, toffset);
02754                                 S32 size = toffset - string;
02755                                 char *sdata = new char[size];
02756                                 bytestream2char(sdata, buffer, string);
02757                                 if (strlen(sdata))              /*Flawfinder: ignore*/
02758                                 {
02759                                         offset += arg;
02760                                 }
02761                                 delete [] sdata;
02762                         }
02763                         lsa_decrease_ref_count(buffer, base_address);
02764                 }
02765         }
02766         else if (type == LST_KEY)
02767         {
02768                 S32 base_address = lscript_pop_int(buffer);
02769                 // this bit of nastiness is to get around that code paths to
02770                 // local variables can result in lack of initialization and
02771                 // function clean up of ref counts isn't based on scope (a
02772                 // mistake, I know)
02773                 S32 address = base_address + get_register(buffer, LREG_HR) - 1;
02774                 if (address)
02775                 {
02776                         S32 string = address;
02777                         string += SIZEOF_SCRIPT_ALLOC_ENTRY;
02778                         if (safe_heap_check_address(buffer, string, 1))
02779                         {
02780                                 S32 toffset = string;
02781                                 safe_heap_bytestream_count_char(buffer, toffset);
02782                                 S32 size = toffset - string;
02783                                 char *sdata = new char[size];
02784                                 bytestream2char(sdata, buffer, string);
02785                                 if (strlen(sdata))              /*Flawfinder: ignore*/
02786                                 {
02787                                         LLUUID id;
02788                                         if (id.set(sdata) && id.notNull())
02789                                                 offset += arg;
02790                                 }
02791                                 delete [] sdata;
02792                         }
02793                         lsa_decrease_ref_count(buffer, base_address);
02794                 }
02795         }
02796         else if (type == LST_LIST)
02797         {
02798                 S32 base_address = lscript_pop_int(buffer);
02799                 S32 address = base_address + get_register(buffer, LREG_HR) - 1;
02800                 if (address)
02801                 {
02802                         if (safe_heap_check_address(buffer, address + SIZEOF_SCRIPT_ALLOC_ENTRY, 1))
02803                         {
02804                                 LLScriptLibData *list = lsa_get_list_ptr(buffer, base_address, TRUE);
02805                                 if (list && list->getListLength())
02806                                 {
02807                                         offset += arg;
02808                                 }
02809                                 delete list;
02810                         }
02811                 }
02812         }
02813         return FALSE;
02814 }
02815 
02816 BOOL run_jumpnif(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
02817 {
02818         if (b_print)
02819                 printf("[0x%X]\tJUMPNIF ", offset);
02820         offset++;
02821         U8 type = safe_instruction_bytestream2byte(buffer, offset);
02822         if (b_print)
02823         {
02824                 print_type(type);
02825                 printf(", ");
02826         }
02827         S32 arg = safe_instruction_bytestream2integer(buffer, offset);
02828         if (b_print)
02829                 printf("%d\n", arg);
02830 
02831         if (type == LST_INTEGER)
02832         {
02833                 S32 test = lscript_pop_int(buffer);
02834                 if (!test)
02835                 {
02836                         offset += arg;
02837                 }
02838         }
02839         else if (type == LST_FLOATINGPOINT)
02840         {
02841                 F32 test = lscript_pop_float(buffer);
02842                 if (!test)
02843                 {
02844                         offset += arg;
02845                 }
02846         }
02847         else if (type == LST_VECTOR)
02848         {
02849                 LLVector3 test;
02850                 lscript_pop_vector(buffer, test);
02851                 if (test.isExactlyZero())
02852                 {
02853                         offset += arg;
02854                 }
02855         }
02856         else if (type == LST_QUATERNION)
02857         {
02858                 LLQuaternion test;
02859                 lscript_pop_quaternion(buffer, test);
02860                 if (test.isIdentity())
02861                 {
02862                         offset += arg;
02863                 }
02864         }
02865         else if (type == LST_STRING)
02866         {
02867                 S32 base_address = lscript_pop_int(buffer);
02868                 // this bit of nastiness is to get around that code paths to
02869                 // local variables can result in lack of initialization and
02870                 // function clean up of ref counts isn't based on scope (a
02871                 // mistake, I know)
02872                 S32 address = base_address + get_register(buffer, LREG_HR) - 1;
02873                 if (address)
02874                 {
02875                         S32 string = address;
02876                         string += SIZEOF_SCRIPT_ALLOC_ENTRY;
02877                         if (safe_heap_check_address(buffer, string, 1))
02878                         {
02879                                 S32 toffset = string;
02880                                 safe_heap_bytestream_count_char(buffer, toffset);
02881                                 S32 size = toffset - string;
02882                                 char *sdata = new char[size];
02883                                 bytestream2char(sdata, buffer, string);
02884                                 if (!strlen(sdata))             /*Flawfinder: ignore*/
02885                                 {
02886                                         offset += arg;
02887                                 }
02888                                 delete [] sdata;
02889                         }
02890                         lsa_decrease_ref_count(buffer, base_address);
02891                 }
02892         }
02893         else if (type == LST_KEY)
02894         {
02895                 S32 base_address = lscript_pop_int(buffer);
02896                 // this bit of nastiness is to get around that code paths to
02897                 // local variables can result in lack of initialization and
02898                 // function clean up of ref counts isn't based on scope (a
02899                 // mistake, I know)
02900                 S32 address = base_address + get_register(buffer, LREG_HR) - 1;
02901                 if (address)
02902                 {
02903                         S32 string = address;
02904                         string += SIZEOF_SCRIPT_ALLOC_ENTRY;
02905                         if (safe_heap_check_address(buffer, string, 1))
02906                         {
02907                                 S32 toffset = string;
02908                                 safe_heap_bytestream_count_char(buffer, toffset);
02909                                 S32 size = toffset - string;
02910                                 char *sdata = new char[size];
02911                                 bytestream2char(sdata, buffer, string);
02912                                 if (strlen(sdata))              /*Flawfinder: ignore*/
02913                                 {
02914                                         LLUUID id;
02915                                         if (!id.set(sdata) || id.isNull())
02916                                                 offset += arg;
02917                                 }
02918                                 else
02919                                 {
02920                                         offset += arg;
02921                                 }
02922                                 delete [] sdata;
02923                         }
02924                         lsa_decrease_ref_count(buffer, base_address);
02925                 }
02926         }
02927         else if (type == LST_LIST)
02928         {
02929                 S32 base_address = lscript_pop_int(buffer);
02930                 // this bit of nastiness is to get around that code paths to
02931                 // local variables can result in lack of initialization and
02932                 // function clean up of ref counts isn't based on scope (a
02933                 // mistake, I know)
02934                 S32 address = base_address + get_register(buffer, LREG_HR) - 1;
02935                 if (address)
02936                 {
02937                         if (safe_heap_check_address(buffer, address + SIZEOF_SCRIPT_ALLOC_ENTRY, 1))
02938                         {
02939                                 LLScriptLibData *list = lsa_get_list_ptr(buffer, base_address, TRUE);
02940                                 if (!list || !list->getListLength())
02941                                 {
02942                                         offset += arg;
02943                                 }
02944                                 delete list;
02945                         }
02946                 }
02947         }
02948         return FALSE;
02949 }
02950 
02951 BOOL run_state(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
02952 {
02953         if (b_print)
02954                 printf("[0x%X]\tSTATE ", offset);
02955         offset++;
02956         S32 state = safe_instruction_bytestream2integer(buffer, offset);
02957         if (b_print)
02958                 printf("%d\n", state);
02959 
02960         S32 bp = lscript_pop_int(buffer);
02961         set_bp(buffer, bp);
02962 
02963         offset = lscript_pop_int(buffer);
02964 
02965         S32 major_version = 0;
02966         S32 value = get_register(buffer, LREG_VN);
02967         if (value == LSL2_VERSION1_END_NUMBER)
02968         {
02969                 major_version = 1;
02970         }
02971         else if (value == LSL2_VERSION_NUMBER)
02972         {
02973                 major_version = 2;
02974         }
02975 
02976         S32 current_state = get_register(buffer, LREG_CS);
02977         if (state != current_state)
02978         {
02979                 U64 ce = get_event_register(buffer, LREG_CE, major_version);
02980                 ce |= LSCRIPTStateBitField[LSTT_STATE_EXIT];
02981                 set_event_register(buffer, LREG_CE, ce, major_version);
02982         }
02983         set_register(buffer, LREG_NS, state);
02984         return FALSE;
02985 }
02986 
02987 BOOL run_call(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
02988 {
02989         if (b_print)
02990                 printf("[0x%X]\tCALL ", offset);
02991         offset++;
02992         S32 func = safe_instruction_bytestream2integer(buffer, offset);
02993         if (b_print)
02994                 printf("%d\n", func);
02995 
02996         lscript_local_store(buffer, -8, offset);
02997 
02998         S32 minimum = get_register(buffer, LREG_GFR);
02999         S32 maximum = get_register(buffer, LREG_SR);
03000         S32 lookup = minimum + func*4 + 4;
03001         S32 function;
03002 
03003         if (  (lookup >= minimum)
03004                 &&(lookup < maximum))
03005         {
03006                 function = bytestream2integer(buffer, lookup) + minimum;
03007                 if (  (lookup >= minimum)
03008                         &&(lookup < maximum))
03009                 {
03010                         offset = function;
03011                         offset += bytestream2integer(buffer, function);
03012                 }
03013                 else
03014                 {
03015                         set_fault(buffer, LSRF_BOUND_CHECK_ERROR);
03016                 }
03017         }
03018         else
03019         {
03020                 set_fault(buffer, LSRF_BOUND_CHECK_ERROR);
03021         }
03022         return FALSE;
03023 }
03024 
03025 BOOL run_return(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
03026 {
03027         if (b_print)
03028                 printf("[0x%X]\tRETURN\n", offset);
03029         offset++;
03030         S32 bp = lscript_pop_int(buffer);
03031         set_bp(buffer, bp);
03032         offset = lscript_pop_int(buffer);
03033         return FALSE;
03034 }
03035 
03036 S32 axtoi(char *hexStg)
03037 {
03038   S32 n = 0;         // position in string
03039   S32 m = 0;         // position in digit[] to shift
03040   S32 count;         // loop index
03041   S32 intValue = 0;  // integer value of hex string
03042   S32 digit[9];      // hold values to convert
03043   while (n < 8)
03044   {
03045      if (hexStg[n]=='\0')
03046         break;
03047      if (hexStg[n] > 0x29 && hexStg[n] < 0x40 ) //if 0 to 9
03048         digit[n] = hexStg[n] & 0x0f;            //convert to int
03049      else if (hexStg[n] >='a' && hexStg[n] <= 'f') //if a to f
03050         digit[n] = (hexStg[n] & 0x0f) + 9;      //convert to int
03051      else if (hexStg[n] >='A' && hexStg[n] <= 'F') //if A to F
03052         digit[n] = (hexStg[n] & 0x0f) + 9;      //convert to int
03053      else break;
03054     n++;
03055   }
03056   count = n;
03057   m = n - 1;
03058   n = 0;
03059   while(n < count)
03060   {
03061      // digit[n] is value of hex digit at position n
03062      // (m << 2) is the number of positions to shift
03063      // OR the bits into return value
03064      intValue = intValue | (digit[n] << (m << 2));
03065      m--;   // adjust the position to set
03066      n++;   // next digit to process
03067   }
03068   return (intValue);
03069 }
03070 
03071 
03072 BOOL run_cast(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
03073 {
03074         char caststr[1024];             /*Flawfinder: ignore*/
03075         if (b_print)
03076                 printf("[0x%X]\tCAST ", offset);
03077         offset++;
03078         U8 arg = safe_instruction_bytestream2byte(buffer, offset);
03079         U8 from = arg >> 4;
03080         U8 to = arg & 0xf;
03081         if (b_print)
03082         {
03083                 print_type(from);
03084                 printf(", ");
03085                 print_type(to);
03086                 printf("\n");
03087         }
03088 
03089         switch(from)
03090         {
03091         case LST_INTEGER:
03092                 {
03093                         switch(to)
03094                         {
03095                         case LST_INTEGER:
03096                                 break;
03097                         case LST_FLOATINGPOINT:
03098                                 {
03099                                         S32 source = lscript_pop_int(buffer);
03100                                         F32 dest = (F32)source;
03101                                         lscript_push(buffer, dest);
03102                                 }
03103                                 break;
03104                         case LST_STRING:
03105                                 {
03106                                         S32 address, source = lscript_pop_int(buffer);
03107                                         snprintf(caststr, sizeof(caststr), "%d", source);               /* Flawfinder: ignore */
03108                                         address = lsa_heap_add_data(buffer, new LLScriptLibData(caststr), get_max_heap_size(buffer), TRUE);
03109                                         lscript_push(buffer, address);
03110                                 }
03111                                 break;
03112                         case LST_LIST:
03113                                 {
03114                                         S32 address, source = lscript_pop_int(buffer);
03115                                         LLScriptLibData *list = new LLScriptLibData;
03116                                         list->mType = LST_LIST;
03117                                         list->mListp = new LLScriptLibData(source);
03118                                         address = lsa_heap_add_data(buffer, list, get_max_heap_size(buffer), TRUE);
03119                                         lscript_push(buffer, address);
03120                                 }
03121                                 break;
03122                         default:
03123                                 break;
03124                         }
03125                 }
03126                 break;
03127         case LST_FLOATINGPOINT:
03128                 {
03129                         switch(to)
03130                         {
03131                         case LST_INTEGER:
03132                                 {
03133                                         F32 source = lscript_pop_float(buffer);
03134                                         S32 dest = (S32)source;
03135                                         lscript_push(buffer, dest);
03136                                 }
03137                                 break;
03138                         case LST_FLOATINGPOINT:
03139                                 break;
03140                         case LST_STRING:
03141                                 {
03142                                         S32 address;
03143                                         F32 source = lscript_pop_float(buffer);
03144                                         snprintf(caststr, sizeof(caststr), "%f", source);               /* Flawfinder: ignore */
03145                                         address = lsa_heap_add_data(buffer, new LLScriptLibData(caststr), get_max_heap_size(buffer), TRUE);
03146                                         lscript_push(buffer, address);
03147                                 }
03148                                 break;
03149                         case LST_LIST:
03150                                 {
03151                                         S32 address;
03152                                         F32 source = lscript_pop_float(buffer);
03153                                         LLScriptLibData *list = new LLScriptLibData;
03154                                         list->mType = LST_LIST;
03155                                         list->mListp = new LLScriptLibData(source);
03156                                         address = lsa_heap_add_data(buffer, list, get_max_heap_size(buffer), TRUE);
03157                                         lscript_push(buffer, address);
03158                                 }
03159                                 break;
03160                         default:
03161                                 break;
03162                         }
03163                 }
03164                 break;
03165         case LST_STRING:
03166                 {
03167                         switch(to)
03168                         {
03169                         case LST_INTEGER:
03170                                 {
03171                                         S32 base_address = lscript_pop_int(buffer);
03172         // this bit of nastiness is to get around that code paths to local variables can result in lack of initialization
03173         // and function clean up of ref counts isn't based on scope (a mistake, I know)
03174                                         S32 address = base_address + get_register(buffer, LREG_HR) - 1;
03175                                         if (address)
03176                                         {
03177                                                 S32 string = address;
03178                                                 string += SIZEOF_SCRIPT_ALLOC_ENTRY;
03179                                                 if (safe_heap_check_address(buffer, string, 1))
03180                                                 {
03181                                                         S32 toffset = string;
03182                                                         safe_heap_bytestream_count_char(buffer, toffset);
03183                                                         S32 size = toffset - string;
03184                                                         char *arg = new char[size];
03185                                                         bytestream2char(arg, buffer, string);
03186                                                         // S32 length = strlen(arg);
03187                                                         S32 dest;
03188                                                         S32 base;
03189 
03190                                                         // Check to see if this is a hexidecimal number.
03191                                                         if (  (arg[0] == '0') &&
03192                                                                   (arg[1] == 'x' || arg[1] == 'X') )
03193                                                         {
03194                                                                 // Let strtoul do a hex conversion.
03195                                                                 base = 16;
03196                                                         }
03197                                                         else
03198                                                         {
03199                                                                 // Force base-10, so octal is never used.
03200                                                                 base = 10;
03201                                                         }
03202 
03203                                                         dest = strtoul(arg, NULL, base);
03204 
03205                                                         lscript_push(buffer, dest);
03206                                                         delete [] arg;
03207                                                 }
03208                                                 lsa_decrease_ref_count(buffer, base_address);
03209                                         }
03210                                 }
03211                                 break;
03212                         case LST_FLOATINGPOINT:
03213                                 {
03214                                         S32 base_address = lscript_pop_int(buffer);
03215         // this bit of nastiness is to get around that code paths to local variables can result in lack of initialization
03216         // and function clean up of ref counts isn't based on scope (a mistake, I know)
03217                                         S32 address = base_address + get_register(buffer, LREG_HR) - 1;
03218                                         if (address)
03219                                         {
03220                                                 S32 string = address;
03221                                                 string += SIZEOF_SCRIPT_ALLOC_ENTRY;
03222                                                 if (safe_heap_check_address(buffer, string, 1))
03223                                                 {
03224                                                         S32 toffset = string;
03225                                                         safe_heap_bytestream_count_char(buffer, toffset);
03226                                                         S32 size = toffset - string;
03227                                                         char *arg = new char[size];
03228                                                         bytestream2char(arg, buffer, string);
03229                                                         F32 dest = (F32)atof(arg);
03230 
03231 
03232                                                         lscript_push(buffer, dest);
03233                                                         delete [] arg;
03234                                                 }
03235                                                 lsa_decrease_ref_count(buffer, base_address);
03236                                         }
03237                                 }
03238                                 break;
03239                         case LST_STRING:
03240                                 break;
03241                         case LST_LIST:
03242                                 {
03243                                         S32 saddress = lscript_pop_int(buffer);
03244                                         LLScriptLibData *string = lsa_get_data(buffer, saddress, TRUE);
03245                                         LLScriptLibData *list = new LLScriptLibData;
03246                                         list->mType = LST_LIST;
03247                                         list->mListp = string;
03248                                         S32 address = lsa_heap_add_data(buffer, list, get_max_heap_size(buffer), TRUE);
03249                                         lscript_push(buffer, address);
03250                                 }
03251                                 break;
03252                         case LST_VECTOR:
03253                                 {
03254                                         S32 base_address = lscript_pop_int(buffer);
03255         // this bit of nastiness is to get around that code paths to local variables can result in lack of initialization
03256         // and function clean up of ref counts isn't based on scope (a mistake, I know)
03257                                         S32 address = base_address + get_register(buffer, LREG_HR) - 1;
03258                                         if (address)
03259                                         {
03260                                                 S32 string = address;
03261                                                 string += SIZEOF_SCRIPT_ALLOC_ENTRY;
03262                                                 if (safe_heap_check_address(buffer, string, 1))
03263                                                 {
03264                                                         S32 toffset = string;
03265                                                         safe_heap_bytestream_count_char(buffer, toffset);
03266                                                         S32 size = toffset - string;
03267                                                         char *arg = new char[size];
03268                                                         bytestream2char(arg, buffer, string);
03269                                                         LLVector3 vec;
03270                                                         S32 num = sscanf(arg, "<%f, %f, %f>", &vec.mV[VX], &vec.mV[VY], &vec.mV[VZ]);
03271                                                         if (num != 3)
03272                                                         {
03273                                                                 vec = LLVector3::zero;
03274                                                         }
03275                                                         lscript_push(buffer, vec);
03276                                                         delete [] arg;
03277                                                 }
03278                                                 lsa_decrease_ref_count(buffer, base_address);
03279                                         }
03280                                 }
03281                                 break;
03282                         case LST_QUATERNION:
03283                                 {
03284                                         S32 base_address = lscript_pop_int(buffer);
03285         // this bit of nastiness is to get around that code paths to local variables can result in lack of initialization
03286         // and function clean up of ref counts isn't based on scope (a mistake, I know)
03287                                         S32 address = base_address + get_register(buffer, LREG_HR) - 1;
03288                                         if (address)
03289                                         {
03290                                                 S32 string = address;
03291                                                 string += SIZEOF_SCRIPT_ALLOC_ENTRY;
03292                                                 if (safe_heap_check_address(buffer, string, 1))
03293                                                 {
03294                                                         S32 toffset = string;
03295                                                         safe_heap_bytestream_count_char(buffer, toffset);
03296                                                         S32 size = toffset - string;
03297                                                         char *arg = new char[size];
03298                                                         bytestream2char(arg, buffer, string);
03299                                                         LLQuaternion quat;
03300                                                         S32 num = sscanf(arg, "<%f, %f, %f, %f>", &quat.mQ[VX], &quat.mQ[VY], &quat.mQ[VZ], &quat.mQ[VW]);
03301                                                         if (num != 4)
03302                                                         {
03303                                                                 quat = LLQuaternion::DEFAULT;
03304 
03305                                                         }
03306                                                         lscript_push(buffer, quat);
03307                                                         delete [] arg;
03308                                                 }
03309                                                 lsa_decrease_ref_count(buffer, base_address);
03310                                         }
03311                                 }
03312                                 break;
03313                         default:
03314                                 break;
03315                         }
03316                 }
03317                 break;
03318         case LST_KEY:
03319                 {
03320                         switch(to)
03321                         {
03322                         case LST_KEY:
03323                                 break;
03324                         case LST_STRING:
03325                                 break;
03326                         case LST_LIST:
03327                                 {
03328                                         S32 saddress = lscript_pop_int(buffer);
03329                                         LLScriptLibData *string = lsa_get_data(buffer, saddress, TRUE);
03330                                         LLScriptLibData *list = new LLScriptLibData;
03331                                         list->mType = LST_LIST;
03332                                         list->mListp = string;
03333                                         S32 address = lsa_heap_add_data(buffer, list, get_max_heap_size(buffer), TRUE);
03334                                         lscript_push(buffer, address);
03335                                 }
03336                                 break;
03337                         default:
03338                                 break;
03339                         }
03340                 }
03341                 break;
03342         case LST_VECTOR:
03343                 {
03344                         switch(to)
03345                         {
03346                         case LST_VECTOR:
03347                                 break;
03348                         case LST_STRING:
03349                                 {
03350                                         S32 address;
03351                                         LLVector3 source;
03352                                         lscript_pop_vector(buffer, source);
03353                                         snprintf(caststr, sizeof(caststr), "<%5.5f, %5.5f, %5.5f>", source.mV[VX], source.mV[VY], source.mV[VZ]);               /* Flawfinder: ignore */
03354                                         address = lsa_heap_add_data(buffer, new LLScriptLibData(caststr), get_max_heap_size(buffer), TRUE);
03355                                         lscript_push(buffer, address);
03356                                 }
03357                                 break;
03358                         case LST_LIST:
03359                                 {
03360                                         S32 address;
03361                                         LLVector3 source;
03362                                         lscript_pop_vector(buffer, source);
03363                                         LLScriptLibData *list = new LLScriptLibData;
03364                                         list->mType = LST_LIST;
03365                                         list->mListp = new LLScriptLibData(source);
03366                                         address = lsa_heap_add_data(buffer, list, get_max_heap_size(buffer), TRUE);
03367                                         lscript_push(buffer, address);
03368                                 }
03369                                 break;
03370                         default:
03371                                 break;
03372                         }
03373                 }
03374                 break;
03375         case LST_QUATERNION:
03376                 {
03377                         switch(to)
03378                         {
03379                         case LST_QUATERNION:
03380                                 break;
03381                         case LST_STRING:
03382                                 {
03383                                         S32 address;
03384                                         LLQuaternion source;
03385                                         lscript_pop_quaternion(buffer, source);
03386                                         snprintf(caststr, sizeof(caststr), "<%5.5f, %5.5f, %5.5f, %5.5f>", source.mQ[VX], source.mQ[VY], source.mQ[VZ], source.mQ[VS]);         /* Flawfinder: ignore */
03387                                         address = lsa_heap_add_data(buffer, new LLScriptLibData(caststr), get_max_heap_size(buffer), TRUE);
03388                                         lscript_push(buffer, address);
03389                                 }
03390                                 break;
03391                         case LST_LIST:
03392                                 {
03393                                         S32 address;
03394                                         LLQuaternion source;
03395                                         lscript_pop_quaternion(buffer, source);
03396                                         LLScriptLibData *list = new LLScriptLibData;
03397                                         list->mType = LST_LIST;
03398                                         list->mListp = new LLScriptLibData(source);
03399                                         address = lsa_heap_add_data(buffer, list, get_max_heap_size(buffer), TRUE);
03400                                         lscript_push(buffer, address);
03401                                 }
03402                                 break;
03403                         default:
03404                                 break;
03405                         }
03406                 }
03407                 break;
03408         case LST_LIST:
03409                 {
03410                         switch(to)
03411                         {
03412                         case LST_LIST:
03413                                 break;
03414                         case LST_STRING:
03415                                 {
03416                                         S32 address = lscript_pop_int(buffer);
03417                                         LLScriptLibData *list = lsa_get_data(buffer, address, TRUE);
03418                                         LLScriptLibData *list_root = list;
03419 
03420                                         std::ostringstream dest;
03421                                         while (list)
03422                                         {
03423                                                 list->print(dest, FALSE);
03424                                                 list = list->mListp;
03425                                         }
03426                                         delete list_root;
03427                                         char *tmp = strdup(dest.str().c_str());
03428                                         LLScriptLibData *string = new LLScriptLibData(tmp);
03429                                         free(tmp);
03430                                         tmp = NULL;
03431                                         S32 destaddress = lsa_heap_add_data(buffer, string, get_max_heap_size(buffer), TRUE);
03432                                         lscript_push(buffer, destaddress);
03433                                 }
03434                                 break;
03435                         default:
03436                                 break;
03437                         }
03438                 }
03439                 break;
03440                 default:
03441                         break;
03442         }
03443         return FALSE;
03444 }
03445 
03446 BOOL run_stacktos(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
03447 {
03448         offset++;
03449         S32 length = lscript_pop_int(buffer);
03450         S32 i;
03451         char *arg = new char[length];
03452         S32 fault;
03453         for (i = 0; i < length; i++)
03454         {
03455                 fault = get_register(buffer, LREG_FR);
03456                 if (fault)
03457                         break;
03458 
03459                 arg[length - i - 1] = lscript_pop_char(buffer);
03460         }
03461         S32 address = lsa_heap_add_data(buffer, new LLScriptLibData(arg), get_max_heap_size(buffer), TRUE);
03462         lscript_push(buffer, address);
03463         delete [] arg;
03464         return FALSE;
03465 }
03466 
03467 void lscript_stacktol_pop_variable(LLScriptLibData *data, U8 *buffer, char type)
03468 {
03469         S32 address, string;
03470         S32 base_address;
03471 
03472         switch(type)
03473         {
03474         case LST_INTEGER:
03475                 data->mType = LST_INTEGER;
03476                 data->mInteger = lscript_pop_int(buffer);
03477                 break;
03478         case LST_FLOATINGPOINT:
03479                 data->mType = LST_FLOATINGPOINT;
03480                 data->mFP = lscript_pop_float(buffer);
03481                 break;
03482         case LST_KEY:
03483                 data->mType = LST_KEY;
03484 
03485                 base_address = lscript_pop_int(buffer);
03486         // this bit of nastiness is to get around that code paths to local variables can result in lack of initialization
03487         // and function clean up of ref counts isn't based on scope (a mistake, I know)
03488                 address = base_address + get_register(buffer, LREG_HR) - 1;
03489 
03490                 if (address)
03491                 {
03492                         string = address + SIZEOF_SCRIPT_ALLOC_ENTRY;
03493                         if (safe_heap_check_address(buffer, string, 1))
03494                         {
03495                                 S32 toffset = string;
03496                                 safe_heap_bytestream_count_char(buffer, toffset);
03497                                 S32 size = toffset - string;
03498                                 data->mKey = new char[size];
03499                                 bytestream2char(data->mKey, buffer, string);
03500                         }
03501                         lsa_decrease_ref_count(buffer, base_address);
03502                 }
03503                 else
03504                 {
03505                         data->mKey = new char[1];
03506                         data->mKey[0] = 0;
03507                 }
03508                 break;
03509         case LST_STRING:
03510                 data->mType = LST_STRING;
03511 
03512                 base_address = lscript_pop_int(buffer);
03513         // this bit of nastiness is to get around that code paths to local variables can result in lack of initialization
03514         // and function clean up of ref counts isn't based on scope (a mistake, I know)
03515                 address = base_address + get_register(buffer, LREG_HR) - 1;
03516 
03517                 if (address)
03518                 {
03519                         string = address + SIZEOF_SCRIPT_ALLOC_ENTRY;
03520                         if (safe_heap_check_address(buffer, string, 1))
03521                         {
03522                                 S32 toffset = string;
03523                                 safe_heap_bytestream_count_char(buffer, toffset);
03524                                 S32 size = toffset - string;
03525                                 data->mString = new char[size];
03526                                 bytestream2char(data->mString, buffer, string);
03527                         }
03528                         lsa_decrease_ref_count(buffer, base_address);
03529                 }
03530                 else
03531                 {
03532                         data->mString = new char[1];
03533                         data->mString[0] = 0;
03534                 }
03535                 break;
03536         case LST_VECTOR:
03537                 data->mType = LST_VECTOR;
03538                 lscript_pop_vector(buffer, data->mVec);
03539                 break;
03540         case LST_QUATERNION:
03541                 data->mType = LST_QUATERNION;
03542                 lscript_pop_quaternion(buffer, data->mQuat);
03543                 break;
03544         case LST_LIST:
03545                 data->mType = LST_LIST;
03546                 address = lscript_pop_int(buffer);
03547                 data->mListp = lsa_get_data(buffer, address, TRUE);
03548                 break;
03549         }
03550 }
03551 
03552 BOOL run_stacktol(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
03553 {
03554         offset++;
03555         S32 length = safe_instruction_bytestream2integer(buffer, offset);
03556         S32 i;
03557         S32 fault;
03558 
03559         S8 type;
03560 
03561         LLScriptLibData *data = new LLScriptLibData, *tail;
03562         data->mType = LST_LIST;
03563 
03564         for (i = 0; i < length; i++)
03565         {
03566                 fault = get_register(buffer, LREG_FR);
03567                 if (fault)
03568                         break;
03569 
03570                 type = lscript_pop_char(buffer);
03571 
03572                 tail = new LLScriptLibData;
03573 
03574                 lscript_stacktol_pop_variable(tail, buffer, type);
03575 
03576                 tail->mListp = data->mListp;
03577                 data->mListp = tail;
03578         }
03579         S32 address = lsa_heap_add_data(buffer,data, get_max_heap_size(buffer), TRUE);
03580         lscript_push(buffer, address);
03581         return FALSE;
03582 }
03583 
03584 BOOL run_print(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
03585 {
03586         if (b_print)
03587                 printf("[0x%X]\tPRINT ", offset);
03588         offset++;
03589         U8 type = safe_instruction_bytestream2byte(buffer, offset);
03590         if (b_print)
03591         {
03592                 print_type(type);
03593                 printf("\n");
03594         }
03595         switch(type)
03596         {
03597         case LST_INTEGER:
03598                 {
03599                         S32 source = lscript_pop_int(buffer);
03600                         printf("%d\n", source);
03601                 }
03602                 break;
03603         case LST_FLOATINGPOINT:
03604                 {
03605                         F32 source = lscript_pop_float(buffer);
03606                         printf("%f\n", source);
03607                 }
03608                 break;
03609         case LST_STRING:
03610                 {
03611                         S32 base_address = lscript_pop_int(buffer);
03612         // this bit of nastiness is to get around that code paths to local variables can result in lack of initialization
03613         // and function clean up of ref counts isn't based on scope (a mistake, I know)
03614                         S32     address = base_address + get_register(buffer, LREG_HR) - 1;
03615 
03616                         if (address)
03617                         {
03618                                 S32 string = address;
03619                                 string += SIZEOF_SCRIPT_ALLOC_ENTRY;
03620                                 if (safe_heap_check_address(buffer, string, 1))
03621                                 {
03622                                         S32 toffset = string;
03623                                         safe_heap_bytestream_count_char(buffer, toffset);
03624                                         S32 size = toffset - string;
03625                                         char *arg = new char[size];
03626                                         bytestream2char(arg, buffer, string);
03627                                         printf("%s\n", arg);
03628                                         delete [] arg;
03629                                 }
03630                                 lsa_decrease_ref_count(buffer, base_address);
03631                         }
03632                 }
03633                 break;
03634         case LST_VECTOR:
03635                 {
03636                         LLVector3 source;
03637                         lscript_pop_vector(buffer, source);
03638                         printf("< %f, %f, %f >\n", source.mV[VX], source.mV[VY], source.mV[VZ]);
03639                 }
03640                 break;
03641         case LST_QUATERNION:
03642                 {
03643                         LLQuaternion source;
03644                         lscript_pop_quaternion(buffer, source);
03645                         printf("< %f, %f, %f, %f >\n", source.mQ[VX], source.mQ[VY], source.mQ[VZ], source.mQ[VS]);
03646                 }
03647                 break;
03648         case LST_LIST:
03649                 {
03650                         S32 base_address = lscript_pop_int(buffer);
03651                         LLScriptLibData *data = lsa_get_data(buffer, base_address, TRUE);
03652                         LLScriptLibData *print = data;
03653 
03654                         printf("list\n");
03655 
03656                         while (print)
03657                         {
03658                                 switch(print->mType)
03659                                 {
03660                                 case LST_INTEGER:
03661                                         {
03662                                                 printf("%d\n", print->mInteger);
03663                                         }
03664                                         break;
03665                                 case LST_FLOATINGPOINT:
03666                                         {
03667                                                 printf("%f\n", print->mFP);
03668                                         }
03669                                         break;
03670                                 case LST_STRING:
03671                                         {
03672                                                 printf("%s\n", print->mString);
03673                                         }
03674                                         break;
03675                                 case LST_KEY:
03676                                         {
03677                                                 printf("%s\n", print->mKey);
03678                                         }
03679                                         break;
03680                                 case LST_VECTOR:
03681                                         {
03682                                                 printf("< %f, %f, %f >\n", print->mVec.mV[VX], print->mVec.mV[VY], print->mVec.mV[VZ]);
03683                                         }
03684                                         break;
03685                                 case LST_QUATERNION:
03686                                         {
03687                                                 printf("< %f, %f, %f, %f >\n", print->mQuat.mQ[VX], print->mQuat.mQ[VY], print->mQuat.mQ[VZ], print->mQuat.mQ[VS]);
03688                                         }
03689                                         break;
03690                                 default:
03691                                         break;
03692                                 }
03693                                 print = print->mListp;
03694                         }
03695                         delete data;
03696                 }
03697                 break;
03698         default:
03699                 break;
03700         }
03701         return FALSE;
03702 }
03703 
03704 
03705 void lscript_run(char *filename, BOOL b_debug)
03706 {
03707         LLTimer timer;
03708         if (filename == NULL)
03709         {
03710                 llerrs << "filename is NULL" << llendl;
03711                 // Just reporting error is likely not enough. Need
03712                 // to check how to abort or error out gracefully
03713                 // from this function. XXXTBD
03714         }
03715         else
03716         {
03717                 char *error;
03718                 BOOL b_state;
03719                 LLScriptExecute *execute = NULL;
03720 
03721                 FILE* file = LLFile::fopen(filename, "r");
03722                 if (file)
03723                 {
03724                         execute = new LLScriptExecute(file);
03725                         // note: LLScriptExecute() closes file for us
03726                 }
03727                 file = LLFile::fopen(filename, "r");
03728                 if (file)
03729                 {
03730                         FILE* fp = LLFile::fopen("lscript.parse", "w");         /*Flawfinder: ignore*/
03731                         LLScriptLSOParse *parse = new LLScriptLSOParse(file);
03732                         parse->printData(fp);
03733                         delete parse;
03734                         fclose(file);
03735                         fclose(fp);
03736                 }
03737                 file = LLFile::fopen(filename, "r");
03738                 if (file && execute)
03739                 {
03740                         timer.reset();
03741                         while (!execute->run(b_debug, LLUUID::null, &error, b_state))
03742                                 ;
03743                         F32 time = timer.getElapsedTimeF32();
03744                         F32 ips = execute->mInstructionCount / time;
03745                         llinfos << execute->mInstructionCount << " instructions in " << time << " seconds" << llendl;
03746                         llinfos << ips/1000 << "K instructions per second" << llendl;
03747                         printf("ip: 0x%X\n", get_register(execute->mBuffer, LREG_IP));
03748                         printf("sp: 0x%X\n", get_register(execute->mBuffer, LREG_SP));
03749                         printf("bp: 0x%X\n", get_register(execute->mBuffer, LREG_BP));
03750                         printf("hr: 0x%X\n", get_register(execute->mBuffer, LREG_HR));
03751                         printf("hp: 0x%X\n", get_register(execute->mBuffer, LREG_HP));
03752                         delete execute;
03753                         fclose(file);
03754                 }
03755         }
03756 }
03757 
03758 void lscript_pop_variable(LLScriptLibData *data, U8 *buffer, char type)
03759 {
03760         S32 address, string;
03761         S32 base_address;
03762 
03763         switch(type)
03764         {
03765         case 'i':
03766                 data->mType = LST_INTEGER;
03767                 data->mInteger = lscript_pop_int(buffer);
03768                 break;
03769         case 'f':
03770                 data->mType = LST_FLOATINGPOINT;
03771                 data->mFP = lscript_pop_float(buffer);
03772                 break;
03773         case 'k':
03774                 data->mType = LST_KEY;
03775 
03776                 base_address = lscript_pop_int(buffer);
03777         // this bit of nastiness is to get around that code paths to local variables can result in lack of initialization
03778         // and function clean up of ref counts isn't based on scope (a mistake, I know)
03779                 address = base_address + get_register(buffer, LREG_HR) - 1;
03780 
03781                 if (address)
03782                 {
03783                         string = address + SIZEOF_SCRIPT_ALLOC_ENTRY;
03784                         if (safe_heap_check_address(buffer, string, 1))
03785                         {
03786                                 S32 toffset = string;
03787                                 safe_heap_bytestream_count_char(buffer, toffset);
03788                                 S32 size = toffset - string;
03789                                 data->mKey = new char[size];
03790                                 bytestream2char(data->mKey, buffer, string);
03791                         }
03792                         lsa_decrease_ref_count(buffer, base_address);
03793                 }
03794                 else
03795                 {
03796                         data->mKey = new char[1];
03797                         data->mKey[0] = 0;
03798                 }
03799                 break;
03800         case 's':
03801                 data->mType = LST_STRING;
03802 
03803                 base_address = lscript_pop_int(buffer);
03804         // this bit of nastiness is to get around that code paths to local variables can result in lack of initialization
03805         // and function clean up of ref counts isn't based on scope (a mistake, I know)
03806                 address = base_address + get_register(buffer, LREG_HR) - 1;
03807 
03808                 if (address)
03809                 {
03810                         string = address + SIZEOF_SCRIPT_ALLOC_ENTRY;
03811                         if (safe_heap_check_address(buffer, string, 1))
03812                         {
03813                                 S32 toffset = string;
03814                                 safe_heap_bytestream_count_char(buffer, toffset);
03815                                 S32 size = toffset - string;
03816                                 data->mString = new char[size];
03817                                 bytestream2char(data->mString, buffer, string);
03818                         }
03819                         lsa_decrease_ref_count(buffer, base_address);
03820                 }
03821                 else
03822                 {
03823                         data->mString = new char[1];
03824                         data->mString[0] = 0;
03825                 }
03826                 break;
03827         case 'l':
03828                 {
03829                         S32 base_address = lscript_pop_int(buffer);
03830                         data->mType = LST_LIST;
03831                         data->mListp = lsa_get_list_ptr(buffer, base_address, TRUE);
03832                 }
03833                 break;
03834         case 'v':
03835                 data->mType = LST_VECTOR;
03836                 lscript_pop_vector(buffer, data->mVec);
03837                 break;
03838         case 'q':
03839                 data->mType = LST_QUATERNION;
03840                 lscript_pop_quaternion(buffer, data->mQuat);
03841                 break;
03842         }
03843 }
03844 
03845 void lscript_push_return_variable(LLScriptLibData *data, U8 *buffer)
03846 {
03847         S32 address;
03848         switch(data->mType)
03849         {
03850         case LST_INTEGER:
03851                 lscript_local_store(buffer, -12, data->mInteger);
03852                 break;
03853         case LST_FLOATINGPOINT:
03854                 lscript_local_store(buffer, -12, data->mFP);
03855                 break;
03856         case LST_KEY:
03857                 address = lsa_heap_add_data(buffer, data, get_max_heap_size(buffer), FALSE);
03858                 lscript_local_store(buffer, -12, address);
03859                 break;
03860         case LST_STRING:
03861                 address = lsa_heap_add_data(buffer, data, get_max_heap_size(buffer), FALSE);
03862                 lscript_local_store(buffer, -12, address);
03863                 break;
03864         case LST_LIST:
03865                 address = lsa_heap_add_data(buffer, data, get_max_heap_size(buffer), FALSE);
03866                 lscript_local_store(buffer, -12, address);
03867                 break;
03868         case LST_VECTOR:
03869                 lscript_local_store(buffer, -20, data->mVec);
03870                 break;
03871         case LST_QUATERNION:
03872                 lscript_local_store(buffer, -24, data->mQuat);
03873                 break;
03874         default:
03875                 break;
03876         }
03877 }
03878 
03879 S32 lscript_push_variable(LLScriptLibData *data, U8 *buffer)
03880 {
03881         S32 address;
03882         switch(data->mType)
03883         {
03884         case LST_INTEGER:
03885                 lscript_push(buffer, data->mInteger);
03886                 break;
03887         case LST_FLOATINGPOINT:
03888                 lscript_push(buffer, data->mFP);
03889                 return 4;
03890                 break;
03891         case LST_KEY:
03892                 address = lsa_heap_add_data(buffer, data, get_max_heap_size(buffer), FALSE);
03893                 lscript_push(buffer, address);
03894                 return 4;
03895                 break;
03896         case LST_STRING:
03897                 address = lsa_heap_add_data(buffer, data, get_max_heap_size(buffer), FALSE);
03898                 lscript_push(buffer, address);
03899                 return 4;
03900                 break;
03901         case LST_LIST:
03902                 address = lsa_heap_add_data(buffer, data, get_max_heap_size(buffer), FALSE);
03903                 lscript_push(buffer, address);
03904                 return 4;
03905                 break;
03906         case LST_VECTOR:
03907                 lscript_push(buffer, data->mVec);
03908                 return 12;
03909                 break;
03910         case LST_QUATERNION:
03911                 lscript_push(buffer, data->mQuat);
03912                 return 16;
03913                 break;
03914         default:
03915                 break;
03916         }
03917         return 4;
03918 }
03919 
03920 BOOL run_calllib(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
03921 {
03922         if (b_print)
03923                 printf("[0x%X]\tCALLLIB ", offset);
03924         offset++;
03925         U8 arg = safe_instruction_bytestream2byte(buffer, offset);
03926         if (arg >= gScriptLibrary.mNextNumber)
03927         {
03928                 set_fault(buffer, LSRF_BOUND_CHECK_ERROR);
03929                 return FALSE;
03930         }
03931         if (b_print)
03932                 printf("%d (%s)\n", (U32)arg, gScriptLibrary.mFunctions[arg]->mName);
03933 
03934         // pull out the arguments and the return values
03935         LLScriptLibData *arguments = NULL;
03936         LLScriptLibData *returnvalue = NULL;
03937 
03938         S32 i, number;
03939 
03940         if (gScriptLibrary.mFunctions[arg]->mReturnType)
03941         {
03942                 returnvalue = new LLScriptLibData;
03943         }
03944 
03945         if (gScriptLibrary.mFunctions[arg]->mArgs)
03946         {
03947                 number = (S32)strlen(gScriptLibrary.mFunctions[arg]->mArgs);            /*Flawfinder: ignore*/
03948                 arguments = new LLScriptLibData[number];
03949         }
03950         else
03951         {
03952                 number = 0;
03953         }
03954 
03955         for (i = number - 1; i >= 0; i--)
03956         {
03957                 lscript_pop_variable(&arguments[i], buffer, gScriptLibrary.mFunctions[arg]->mArgs[i]);
03958         }
03959 
03960         if (b_print)
03961         {
03962                 printf("%s\n", gScriptLibrary.mFunctions[arg]->mDesc);
03963         }
03964 
03965         {
03966                 // LLFastTimer time_in_libraries1(LLFastTimer::FTM_TEMP7);
03967                 gScriptLibrary.mFunctions[arg]->mExecFunc(returnvalue, arguments, id);
03968         }
03969         add_register_fp(buffer, LREG_ESR, -gScriptLibrary.mFunctions[arg]->mEnergyUse);
03970         add_register_fp(buffer, LREG_SLR, gScriptLibrary.mFunctions[arg]->mSleepTime);
03971 
03972         if (returnvalue)
03973         {
03974                 returnvalue->mType = char2type(*gScriptLibrary.mFunctions[arg]->mReturnType);
03975                 lscript_push_return_variable(returnvalue, buffer);
03976         }
03977 
03978         delete [] arguments;
03979         delete returnvalue;
03980 
03981         // reset the BP after calling the library files
03982         S32 bp = lscript_pop_int(buffer);
03983         set_bp(buffer, bp);
03984 
03985         // pop off the spot for the instruction pointer
03986         lscript_poparg(buffer, 4);
03987         return FALSE;
03988 }
03989 
03990 
03991 BOOL run_calllib_two_byte(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
03992 {
03993         if (b_print)
03994                 printf("[0x%X]\tCALLLIB ", offset);
03995         offset++;
03996         U16 arg = safe_instruction_bytestream2u16(buffer, offset);
03997         if (arg >= gScriptLibrary.mNextNumber)
03998         {
03999                 set_fault(buffer, LSRF_BOUND_CHECK_ERROR);
04000                 return FALSE;
04001         }
04002         if (b_print)
04003                 printf("%d (%s)\n", (U32)arg, gScriptLibrary.mFunctions[arg]->mName);
04004 
04005         // pull out the arguments and the return values
04006         LLScriptLibData *arguments = NULL;
04007         LLScriptLibData *returnvalue = NULL;
04008 
04009         S32 i, number;
04010 
04011         if (gScriptLibrary.mFunctions[arg]->mReturnType)
04012         {
04013                 returnvalue = new LLScriptLibData;
04014         }
04015 
04016         if (gScriptLibrary.mFunctions[arg]->mArgs)
04017         {
04018                 number = (S32)strlen(gScriptLibrary.mFunctions[arg]->mArgs);            /*Flawfinder: ignore*/
04019                 arguments = new LLScriptLibData[number];
04020         }
04021         else
04022         {
04023                 number = 0;
04024         }
04025 
04026         for (i = number - 1; i >= 0; i--)
04027         {
04028                 lscript_pop_variable(&arguments[i], buffer, gScriptLibrary.mFunctions[arg]->mArgs[i]);
04029         }
04030 
04031         if (b_print)
04032         {
04033                 printf("%s\n", gScriptLibrary.mFunctions[arg]->mDesc);
04034         }
04035 
04036         {
04037                 // LLFastTimer time_in_libraries2(LLFastTimer::FTM_TEMP8);
04038                 gScriptLibrary.mFunctions[arg]->mExecFunc(returnvalue, arguments, id);
04039         }
04040         add_register_fp(buffer, LREG_ESR, -gScriptLibrary.mFunctions[arg]->mEnergyUse);
04041         add_register_fp(buffer, LREG_SLR, gScriptLibrary.mFunctions[arg]->mSleepTime);
04042 
04043         if (returnvalue)
04044         {
04045                 returnvalue->mType = char2type(*gScriptLibrary.mFunctions[arg]->mReturnType);
04046                 lscript_push_return_variable(returnvalue, buffer);
04047         }
04048 
04049         delete [] arguments;
04050         delete returnvalue;
04051 
04052         // reset the BP after calling the library files
04053         S32 bp = lscript_pop_int(buffer);
04054         set_bp(buffer, bp);
04055 
04056         // pop off the spot for the instruction pointer
04057         lscript_poparg(buffer, 4);
04058         return FALSE;
04059 }

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