aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/lscript/lscript_execute/lscript_execute.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/lscript/lscript_execute/lscript_execute.cpp')
-rw-r--r--linden/indra/lscript/lscript_execute/lscript_execute.cpp120
1 files changed, 71 insertions, 49 deletions
diff --git a/linden/indra/lscript/lscript_execute/lscript_execute.cpp b/linden/indra/lscript/lscript_execute/lscript_execute.cpp
index cc2c141..4d8389a 100644
--- a/linden/indra/lscript/lscript_execute/lscript_execute.cpp
+++ b/linden/indra/lscript/lscript_execute/lscript_execute.cpp
@@ -1,4 +1,4 @@
1/** 1/**
2 * @file lscript_execute.cpp 2 * @file lscript_execute.cpp
3 * @brief classes to execute bytecode 3 * @brief classes to execute bytecode
4 * 4 *
@@ -75,7 +75,7 @@ LLScriptExecute::LLScriptExecute(FILE *fp)
75 75
76LLScriptExecute::LLScriptExecute(U8 *buffer) 76LLScriptExecute::LLScriptExecute(U8 *buffer)
77{ 77{
78 mBuffer = buffer; 78 mBuffer = buffer;
79 79
80 init(); 80 init();
81} 81}
@@ -1001,7 +1001,7 @@ BOOL run_loadgsp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1001 S32 address = lscript_global_get(buffer, arg); 1001 S32 address = lscript_global_get(buffer, arg);
1002 if (address) 1002 if (address)
1003 lsa_decrease_ref_count(buffer, address); 1003 lsa_decrease_ref_count(buffer, address);
1004 1004
1005 lscript_global_store(buffer, arg, value); 1005 lscript_global_store(buffer, arg, value);
1006 return FALSE; 1006 return FALSE;
1007} 1007}
@@ -1019,7 +1019,7 @@ BOOL run_loadglp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
1019 S32 address = lscript_global_get(buffer, arg); 1019 S32 address = lscript_global_get(buffer, arg);
1020 if (address) 1020 if (address)
1021 lsa_decrease_ref_count(buffer, address); 1021 lsa_decrease_ref_count(buffer, address);
1022 1022
1023 lscript_global_store(buffer, arg, value); 1023 lscript_global_store(buffer, arg, value);
1024 return FALSE; 1024 return FALSE;
1025} 1025}
@@ -1386,14 +1386,31 @@ void integer_integer_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode)
1386 result = lside * rside; 1386 result = lside * rside;
1387 break; 1387 break;
1388 case LOPC_DIV: 1388 case LOPC_DIV:
1389 if (rside) 1389 if (rside){
1390 result = lside / rside; 1390 if( ( rside == -1 ) || ( rside == 0xffffffff ) )// division by -1 can have funny results: multiplication is OK: SL-31252
1391 {
1392 result = -1 * lside;
1393 }
1394 else
1395 {
1396 result = lside / rside;
1397 }
1398 }
1391 else 1399 else
1392 set_fault(buffer, LSRF_MATH); 1400 set_fault(buffer, LSRF_MATH);
1393 break; 1401 break;
1394 case LOPC_MOD: 1402 case LOPC_MOD:
1395 if (rside) 1403 if (rside)
1396 result = lside % rside; 1404 {
1405 if (rside == -1 || rside == 1 ) // mod(1) = mod(-1) = 0: SL-31252
1406 {
1407 result = 0;
1408 }
1409 else
1410 {
1411 result = lside % rside;
1412 }
1413 }
1397 else 1414 else
1398 set_fault(buffer, LSRF_MATH); 1415 set_fault(buffer, LSRF_MATH);
1399 break; 1416 break;
@@ -2945,14 +2962,14 @@ BOOL run_return(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
2945 return FALSE; 2962 return FALSE;
2946} 2963}
2947 2964
2948S32 axtoi(char *hexStg) 2965S32 axtoi(char *hexStg)
2949{ 2966{
2950 S32 n = 0; // position in string 2967 S32 n = 0; // position in string
2951 S32 m = 0; // position in digit[] to shift 2968 S32 m = 0; // position in digit[] to shift
2952 S32 count; // loop index 2969 S32 count; // loop index
2953 S32 intValue = 0; // integer value of hex string 2970 S32 intValue = 0; // integer value of hex string
2954 S32 digit[9]; // hold values to convert 2971 S32 digit[9]; // hold values to convert
2955 while (n < 8) 2972 while (n < 8)
2956 { 2973 {
2957 if (hexStg[n]=='\0') 2974 if (hexStg[n]=='\0')
2958 break; 2975 break;
@@ -2968,7 +2985,7 @@ S32 axtoi(char *hexStg)
2968 count = n; 2985 count = n;
2969 m = n - 1; 2986 m = n - 1;
2970 n = 0; 2987 n = 0;
2971 while(n < count) 2988 while(n < count)
2972 { 2989 {
2973 // digit[n] is value of hex digit at position n 2990 // digit[n] is value of hex digit at position n
2974 // (m << 2) is the number of positions to shift 2991 // (m << 2) is the number of positions to shift
@@ -3140,7 +3157,7 @@ BOOL run_cast(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
3140 bytestream2char(arg, buffer, string); 3157 bytestream2char(arg, buffer, string);
3141 F32 dest = (F32)atof(arg); 3158 F32 dest = (F32)atof(arg);
3142 3159
3143 3160
3144 lscript_push(buffer, dest); 3161 lscript_push(buffer, dest);
3145 delete [] arg; 3162 delete [] arg;
3146 } 3163 }
@@ -3338,7 +3355,7 @@ BOOL run_cast(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
3338 delete list_root; 3355 delete list_root;
3339 char *tmp = strdup(dest.str().c_str()); 3356 char *tmp = strdup(dest.str().c_str());
3340 LLScriptLibData *string = new LLScriptLibData(tmp); 3357 LLScriptLibData *string = new LLScriptLibData(tmp);
3341 free(tmp); 3358 free(tmp);
3342 tmp = NULL; 3359 tmp = NULL;
3343 S32 destaddress = lsa_heap_add_data(buffer, string, get_max_heap_size(buffer), TRUE); 3360 S32 destaddress = lsa_heap_add_data(buffer, string, get_max_heap_size(buffer), TRUE);
3344 lscript_push(buffer, destaddress); 3361 lscript_push(buffer, destaddress);
@@ -3393,7 +3410,7 @@ void lscript_stacktol_pop_variable(LLScriptLibData *data, U8 *buffer, char type)
3393 break; 3410 break;
3394 case LST_KEY: 3411 case LST_KEY:
3395 data->mType = LST_KEY; 3412 data->mType = LST_KEY;
3396 3413
3397 base_address = lscript_pop_int(buffer); 3414 base_address = lscript_pop_int(buffer);
3398 // this bit of nastiness is to get around that code paths to local variables can result in lack of initialization 3415 // this bit of nastiness is to get around that code paths to local variables can result in lack of initialization
3399 // and function clean up of ref counts isn't based on scope (a mistake, I know) 3416 // and function clean up of ref counts isn't based on scope (a mistake, I know)
@@ -3617,48 +3634,53 @@ BOOL run_print(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
3617void lscript_run(char *filename, BOOL b_debug) 3634void lscript_run(char *filename, BOOL b_debug)
3618{ 3635{
3619 LLTimer timer; 3636 LLTimer timer;
3620 char *error;
3621 BOOL b_state;
3622 LLScriptExecute *execute = NULL;
3623 if (filename == NULL) 3637 if (filename == NULL)
3624 { 3638 {
3625 llerrs << "filename is empty" << llendl; 3639 llerrs << "filename is NULL" << llendl;
3626 // Just reporting error is likely not enough. Need 3640 // Just reporting error is likely not enough. Need
3627 // to check how to abort or error out gracefully 3641 // to check how to abort or error out gracefully
3628 // from this function. XXXTBD 3642 // from this function. XXXTBD
3629 } 3643 }
3630 FILE* file = LLFile::fopen(filename, "r"); /* Flawfinder: ignore */ 3644 else
3631 if (file)
3632 {
3633 execute = new LLScriptExecute(file);
3634 fclose(file);
3635 }
3636 file = LLFile::fopen(filename, "r"); /* Flawfinder: ignore */
3637 if (file)
3638 {
3639 FILE* fp = LLFile::fopen("lscript.parse", "w"); /*Flawfinder: ignore*/
3640 LLScriptLSOParse *parse = new LLScriptLSOParse(file);
3641 parse->printData(fp);
3642 fclose(file);
3643 fclose(fp);
3644 }
3645 file = LLFile::fopen(filename, "r"); /*Flawfinder: ignore*/
3646 if (file && execute)
3647 { 3645 {
3648 timer.reset(); 3646 char *error;
3649 while (!execute->run(b_debug, LLUUID::null, &error, b_state)) 3647 BOOL b_state;
3650 ; 3648 LLScriptExecute *execute = NULL;
3651 F32 time = timer.getElapsedTimeF32(); 3649
3652 F32 ips = execute->mInstructionCount / time; 3650 FILE* file = LLFile::fopen(filename, "r");
3653 llinfos << execute->mInstructionCount << " instructions in " << time << " seconds" << llendl; 3651 if (file)
3654 llinfos << ips/1000 << "K instructions per second" << llendl; 3652 {
3655 printf("ip: 0x%X\n", get_register(execute->mBuffer, LREG_IP)); 3653 execute = new LLScriptExecute(file);
3656 printf("sp: 0x%X\n", get_register(execute->mBuffer, LREG_SP)); 3654 // note: LLScriptExecute() closes file for us
3657 printf("bp: 0x%X\n", get_register(execute->mBuffer, LREG_BP)); 3655 }
3658 printf("hr: 0x%X\n", get_register(execute->mBuffer, LREG_HR)); 3656 file = LLFile::fopen(filename, "r");
3659 printf("hp: 0x%X\n", get_register(execute->mBuffer, LREG_HP)); 3657 if (file)
3660 delete execute; 3658 {
3661 fclose(file); 3659 FILE* fp = LLFile::fopen("lscript.parse", "w"); /*Flawfinder: ignore*/
3660 LLScriptLSOParse *parse = new LLScriptLSOParse(file);
3661 parse->printData(fp);
3662 delete parse;
3663 fclose(file);
3664 fclose(fp);
3665 }
3666 file = LLFile::fopen(filename, "r");
3667 if (file && execute)
3668 {
3669 timer.reset();
3670 while (!execute->run(b_debug, LLUUID::null, &error, b_state))
3671 ;
3672 F32 time = timer.getElapsedTimeF32();
3673 F32 ips = execute->mInstructionCount / time;
3674 llinfos << execute->mInstructionCount << " instructions in " << time << " seconds" << llendl;
3675 llinfos << ips/1000 << "K instructions per second" << llendl;
3676 printf("ip: 0x%X\n", get_register(execute->mBuffer, LREG_IP));
3677 printf("sp: 0x%X\n", get_register(execute->mBuffer, LREG_SP));
3678 printf("bp: 0x%X\n", get_register(execute->mBuffer, LREG_BP));
3679 printf("hr: 0x%X\n", get_register(execute->mBuffer, LREG_HR));
3680 printf("hp: 0x%X\n", get_register(execute->mBuffer, LREG_HP));
3681 delete execute;
3682 fclose(file);
3683 }
3662 } 3684 }
3663} 3685}
3664 3686
@@ -3679,7 +3701,7 @@ void lscript_pop_variable(LLScriptLibData *data, U8 *buffer, char type)
3679 break; 3701 break;
3680 case 'k': 3702 case 'k':
3681 data->mType = LST_KEY; 3703 data->mType = LST_KEY;
3682 3704
3683 base_address = lscript_pop_int(buffer); 3705 base_address = lscript_pop_int(buffer);
3684 // this bit of nastiness is to get around that code paths to local variables can result in lack of initialization 3706 // this bit of nastiness is to get around that code paths to local variables can result in lack of initialization
3685 // and function clean up of ref counts isn't based on scope (a mistake, I know) 3707 // and function clean up of ref counts isn't based on scope (a mistake, I know)