diff options
Diffstat (limited to 'linden/indra/lscript/lscript_execute/lscript_execute.cpp')
-rw-r--r-- | linden/indra/lscript/lscript_execute/lscript_execute.cpp | 120 |
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 | ||
76 | LLScriptExecute::LLScriptExecute(U8 *buffer) | 76 | LLScriptExecute::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 | ||
2948 | S32 axtoi(char *hexStg) | 2965 | S32 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) | |||
3617 | void lscript_run(char *filename, BOOL b_debug) | 3634 | void 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) |