details: http://hg.nginx.org/njs/rev/69300ba58603 branches: changeset: 570:69300ba58603 user: Igor Sysoev <i...@sysoev.ru> date: Tue Jul 24 19:50:02 2018 +0300 description: Refactored trap infrastructure.
This change allows to introduce virtually unlimited number of traps. diffstat: njs/njs_array.c | 5 +- njs/njs_date.c | 6 +- njs/njs_math.c | 8 +- njs/njs_object.c | 6 +- njs/njs_string.c | 8 +- njs/njs_vm.c | 162 ++++++++++++++++++++++++++++-------------------------- njs/njs_vm.h | 32 +++++++--- 7 files changed, 126 insertions(+), 101 deletions(-) diffs (658 lines): diff -r 8960cef1cd5f -r 69300ba58603 njs/njs_array.c --- a/njs/njs_array.c Tue Jul 24 19:50:02 2018 +0300 +++ b/njs/njs_array.c Tue Jul 24 19:50:02 2018 +0300 @@ -917,7 +917,7 @@ njs_array_prototype_join_continuation(nj if (!njs_is_string(value)) { njs_vm_trap_value(vm, value); - return NJS_TRAP_STRING_ARG; + return njs_trap(vm, NJS_TRAP_STRING_ARG); } } @@ -1952,7 +1952,8 @@ njs_array_string_sort(njs_vm_t *vm, njs_ for (i = 1; i < nargs; i++) { if (!njs_is_string(&args[i])) { njs_vm_trap_value(vm, &args[i]); - return NJS_TRAP_STRING_ARG; + + return njs_trap(vm, NJS_TRAP_STRING_ARG); } } diff -r 8960cef1cd5f -r 69300ba58603 njs/njs_date.c --- a/njs/njs_date.c Tue Jul 24 19:50:02 2018 +0300 +++ b/njs/njs_date.c Tue Jul 24 19:50:02 2018 +0300 @@ -90,7 +90,8 @@ njs_date_constructor(njs_vm_t *vm, njs_v for (i = 1; i < n; i++) { if (!njs_is_numeric(&args[i])) { njs_vm_trap_value(vm, &args[i]); - return NJS_TRAP_NUMBER_ARG; + + return njs_trap(vm, NJS_TRAP_NUMBER_ARG); } num = args[i].data.u.number; @@ -170,7 +171,8 @@ njs_date_utc(njs_vm_t *vm, njs_value_t * for (i = 1; i < n; i++) { if (!njs_is_numeric(&args[i])) { njs_vm_trap_value(vm, &args[i]); - return NJS_TRAP_NUMBER_ARG; + + return njs_trap(vm, NJS_TRAP_NUMBER_ARG); } num = args[i].data.u.number; diff -r 8960cef1cd5f -r 69300ba58603 njs/njs_math.c --- a/njs/njs_math.c Tue Jul 24 19:50:02 2018 +0300 +++ b/njs/njs_math.c Tue Jul 24 19:50:02 2018 +0300 @@ -365,7 +365,7 @@ njs_object_math_hypot(njs_vm_t *vm, njs_ if (!njs_is_numeric(&args[i])) { njs_vm_trap_value(vm, &args[i]); - return NJS_TRAP_NUMBER_ARG; + return njs_trap(vm, NJS_TRAP_NUMBER_ARG); } } @@ -504,7 +504,8 @@ njs_object_math_max(njs_vm_t *vm, njs_va for (i = 1; i < nargs; i++) { if (!njs_is_numeric(&args[i])) { njs_vm_trap_value(vm, &args[i]); - return NJS_TRAP_NUMBER_ARG; + + return njs_trap(vm, NJS_TRAP_NUMBER_ARG); } } @@ -535,7 +536,8 @@ njs_object_math_min(njs_vm_t *vm, njs_va for (i = 1; i < nargs; i++) { if (!njs_is_numeric(&args[i])) { njs_vm_trap_value(vm, &args[i]); - return NJS_TRAP_NUMBER_ARG; + + return njs_trap(vm, NJS_TRAP_NUMBER_ARG); } } diff -r 8960cef1cd5f -r 69300ba58603 njs/njs_object.c --- a/njs/njs_object.c Tue Jul 24 19:50:02 2018 +0300 +++ b/njs/njs_object.c Tue Jul 24 19:50:02 2018 +0300 @@ -227,7 +227,7 @@ njs_object_property(njs_vm_t *vm, const * NJS_STRING_VALUE property operation was applied to a string, * NJS_ARRAY_VALUE object is array, * NJS_EXTERNAL_VALUE object is external entity, - * NJS_TRAP_PROPERTY the property trap must be called, + * NJS_TRAP the property trap must be called, * NXT_ERROR exception has been thrown. */ @@ -275,7 +275,7 @@ njs_property_query(njs_vm_t *vm, njs_pro } } else { - return NJS_TRAP_PROPERTY; + return njs_trap(vm, NJS_TRAP_PROPERTY); } } @@ -359,7 +359,7 @@ njs_property_query(njs_vm_t *vm, njs_pro return ret; } - return NJS_TRAP_PROPERTY; + return njs_trap(vm, NJS_TRAP_PROPERTY); } diff -r 8960cef1cd5f -r 69300ba58603 njs/njs_string.c --- a/njs/njs_string.c Tue Jul 24 19:50:02 2018 +0300 +++ b/njs/njs_string.c Tue Jul 24 19:50:02 2018 +0300 @@ -842,7 +842,7 @@ njs_string_prototype_concat(njs_vm_t *vm if (!njs_is_string(&args[i])) { njs_vm_trap_value(vm, &args[i]); - return NJS_TRAP_STRING_ARG; + return njs_trap(vm, NJS_TRAP_STRING_ARG); } } @@ -1427,7 +1427,8 @@ njs_string_bytes_from_array(njs_vm_t *vm for (i = 0; i < length; i++) { if (!njs_is_numeric(&array->start[i])) { njs_vm_trap_value(vm, &array->start[i]); - return NJS_TRAP_NUMBER_ARG; + + return njs_trap(vm, NJS_TRAP_NUMBER_ARG); } } @@ -1659,7 +1660,8 @@ njs_string_from_char_code(njs_vm_t *vm, for (i = 1; i < nargs; i++) { if (!njs_is_numeric(&args[i])) { njs_vm_trap_value(vm, &args[i]); - return NJS_TRAP_NUMBER_ARG; + + return njs_trap(vm, NJS_TRAP_NUMBER_ARG); } } diff -r 8960cef1cd5f -r 69300ba58603 njs/njs_vm.c --- a/njs/njs_vm.c Tue Jul 24 19:50:02 2018 +0300 +++ b/njs/njs_vm.c Tue Jul 24 19:50:02 2018 +0300 @@ -25,10 +25,10 @@ struct njs_property_next_s { static njs_ret_t njs_method_private_copy(njs_vm_t *vm, njs_property_query_t *pq); -static nxt_noinline njs_ret_t njs_values_equal(const njs_value_t *val1, - const njs_value_t *val2); -static nxt_noinline njs_ret_t njs_values_compare(const njs_value_t *val1, - const njs_value_t *val2); +static nxt_noinline njs_ret_t njs_values_equal(njs_vm_t *vm, + const njs_value_t *val1, const njs_value_t *val2); +static nxt_noinline njs_ret_t njs_values_compare(njs_vm_t *vm, + const njs_value_t *val1, const njs_value_t *val2); static njs_ret_t njs_function_frame_create(njs_vm_t *vm, njs_value_t *value, const njs_value_t *this, uintptr_t nargs, nxt_bool_t ctor); static njs_object_t *njs_function_new_object(njs_vm_t *vm, njs_value_t *value); @@ -41,9 +41,9 @@ static njs_native_frame_t * static njs_ret_t njs_function_frame_free(njs_vm_t *vm, njs_native_frame_t *frame); -static void njs_vm_trap(njs_vm_t *vm, nxt_uint_t trap, njs_value_t *value1, +static void njs_vm_trap(njs_vm_t *vm, njs_trap_t trap, njs_value_t *value1, njs_value_t *value2); -static void njs_vm_trap_argument(njs_vm_t *vm, nxt_uint_t trap); +static void njs_vm_trap_argument(njs_vm_t *vm, njs_trap_t trap); static njs_ret_t njs_vmcode_number_primitive(njs_vm_t *vm, njs_value_t *invld, njs_value_t *narg); static njs_ret_t njs_vmcode_string_primitive(njs_vm_t *vm, njs_value_t *invld, @@ -105,6 +105,7 @@ njs_vmcode_interpreter(njs_vm_t *vm) { u_char *catch; njs_ret_t ret; + njs_trap_t trap; njs_value_t *retval, *value1, *value2; njs_frame_t *frame; njs_native_frame_t *previous; @@ -169,31 +170,36 @@ start: } } - switch (ret) { - - case NJS_TRAP_NUMBER: - value2 = value1; - - /* Fall through. */ - - case NJS_TRAP_NUMBERS: - case NJS_TRAP_STRINGS: - case NJS_TRAP_INCDEC: - case NJS_TRAP_PROPERTY: - - njs_vm_trap(vm, ret - NJS_TRAP_BASE, value1, value2); - - goto start; - - case NJS_TRAP_NUMBER_ARG: - case NJS_TRAP_STRING_ARG: - - njs_vm_trap_argument(vm, ret - NJS_TRAP_BASE); - - goto start; - - default: - break; + if (ret == NJS_TRAP) { + trap = vm->trap; + + switch (trap) { + + case NJS_TRAP_NUMBER: + value2 = value1; + + /* Fall through. */ + + case NJS_TRAP_NUMBERS: + case NJS_TRAP_STRINGS: + case NJS_TRAP_INCDEC: + case NJS_TRAP_PROPERTY: + + njs_vm_trap(vm, trap, value1, value2); + + goto start; + + case NJS_TRAP_NUMBER_ARG: + case NJS_TRAP_STRING_ARG: + + njs_vm_trap_argument(vm, trap); + + goto start; + + default: + ret = NXT_ERROR; + break; + } } if (ret == NXT_ERROR) { @@ -593,7 +599,7 @@ njs_vmcode_property_get(njs_vm_t *vm, nj return sizeof(njs_vmcode_prop_get_t); - case NJS_TRAP_PROPERTY: + case NJS_TRAP: case NXT_ERROR: default: @@ -715,7 +721,7 @@ njs_vmcode_property_set(njs_vm_t *vm, nj return sizeof(njs_vmcode_prop_set_t); - case NJS_TRAP_PROPERTY: + case NJS_TRAP: case NXT_ERROR: default: @@ -799,7 +805,7 @@ njs_vmcode_property_in(njs_vm_t *vm, njs break; - case NJS_TRAP_PROPERTY: + case NJS_TRAP: case NXT_ERROR: default: @@ -901,7 +907,7 @@ njs_vmcode_property_delete(njs_vm_t *vm, break; - case NJS_TRAP_PROPERTY: + case NJS_TRAP: case NXT_ERROR: default: @@ -1130,7 +1136,7 @@ njs_vmcode_increment(njs_vm_t *vm, njs_v return sizeof(njs_vmcode_3addr_t); } - return NJS_TRAP_INCDEC; + return njs_trap(vm, NJS_TRAP_INCDEC); } @@ -1150,7 +1156,7 @@ njs_vmcode_decrement(njs_vm_t *vm, njs_v return sizeof(njs_vmcode_3addr_t); } - return NJS_TRAP_INCDEC; + return njs_trap(vm, NJS_TRAP_INCDEC); } @@ -1171,7 +1177,7 @@ njs_vmcode_post_increment(njs_vm_t *vm, return sizeof(njs_vmcode_3addr_t); } - return NJS_TRAP_INCDEC; + return njs_trap(vm, NJS_TRAP_INCDEC); } @@ -1192,7 +1198,7 @@ njs_vmcode_post_decrement(njs_vm_t *vm, return sizeof(njs_vmcode_3addr_t); } - return NJS_TRAP_INCDEC; + return njs_trap(vm, NJS_TRAP_INCDEC); } @@ -1276,7 +1282,7 @@ njs_vmcode_unary_plus(njs_vm_t *vm, njs_ return sizeof(njs_vmcode_2addr_t); } - return NJS_TRAP_NUMBER; + return njs_trap(vm, NJS_TRAP_NUMBER); } @@ -1288,7 +1294,7 @@ njs_vmcode_unary_negation(njs_vm_t *vm, return sizeof(njs_vmcode_2addr_t); } - return NJS_TRAP_NUMBER; + return njs_trap(vm, NJS_TRAP_NUMBER); } @@ -1336,7 +1342,7 @@ njs_vmcode_addition(njs_vm_t *vm, njs_va return sizeof(njs_vmcode_3addr_t); } - return NJS_TRAP_STRINGS; + return njs_trap(vm, NJS_TRAP_STRINGS); } @@ -1353,7 +1359,7 @@ njs_vmcode_substraction(njs_vm_t *vm, nj return sizeof(njs_vmcode_3addr_t); } - return NJS_TRAP_NUMBERS; + return njs_trap(vm, NJS_TRAP_NUMBERS); } @@ -1370,7 +1376,7 @@ njs_vmcode_multiplication(njs_vm_t *vm, return sizeof(njs_vmcode_3addr_t); } - return NJS_TRAP_NUMBERS; + return njs_trap(vm, NJS_TRAP_NUMBERS); } @@ -1404,7 +1410,7 @@ njs_vmcode_exponentiation(njs_vm_t *vm, return sizeof(njs_vmcode_3addr_t); } - return NJS_TRAP_NUMBERS; + return njs_trap(vm, NJS_TRAP_NUMBERS); } @@ -1421,7 +1427,7 @@ njs_vmcode_division(njs_vm_t *vm, njs_va return sizeof(njs_vmcode_3addr_t); } - return NJS_TRAP_NUMBERS; + return njs_trap(vm, NJS_TRAP_NUMBERS); } @@ -1438,7 +1444,7 @@ njs_vmcode_remainder(njs_vm_t *vm, njs_v return sizeof(njs_vmcode_3addr_t); } - return NJS_TRAP_NUMBERS; + return njs_trap(vm, NJS_TRAP_NUMBERS); } @@ -1457,7 +1463,7 @@ njs_vmcode_left_shift(njs_vm_t *vm, njs_ return sizeof(njs_vmcode_3addr_t); } - return NJS_TRAP_NUMBERS; + return njs_trap(vm, NJS_TRAP_NUMBERS); } @@ -1476,7 +1482,7 @@ njs_vmcode_right_shift(njs_vm_t *vm, njs return sizeof(njs_vmcode_3addr_t); } - return NJS_TRAP_NUMBERS; + return njs_trap(vm, NJS_TRAP_NUMBERS); } @@ -1496,7 +1502,7 @@ njs_vmcode_unsigned_right_shift(njs_vm_t return sizeof(njs_vmcode_3addr_t); } - return NJS_TRAP_NUMBERS; + return njs_trap(vm, NJS_TRAP_NUMBERS); } @@ -1562,7 +1568,7 @@ njs_vmcode_bitwise_not(njs_vm_t *vm, njs return sizeof(njs_vmcode_2addr_t); } - return NJS_TRAP_NUMBER; + return njs_trap(vm, NJS_TRAP_NUMBER); } @@ -1580,7 +1586,7 @@ njs_vmcode_bitwise_and(njs_vm_t *vm, njs return sizeof(njs_vmcode_3addr_t); } - return NJS_TRAP_NUMBERS; + return njs_trap(vm, NJS_TRAP_NUMBERS); } @@ -1598,7 +1604,7 @@ njs_vmcode_bitwise_xor(njs_vm_t *vm, njs return sizeof(njs_vmcode_3addr_t); } - return NJS_TRAP_NUMBERS; + return njs_trap(vm, NJS_TRAP_NUMBERS); } @@ -1616,7 +1622,7 @@ njs_vmcode_bitwise_or(njs_vm_t *vm, njs_ return sizeof(njs_vmcode_3addr_t); } - return NJS_TRAP_NUMBERS; + return njs_trap(vm, NJS_TRAP_NUMBERS); } @@ -1626,7 +1632,7 @@ njs_vmcode_equal(njs_vm_t *vm, njs_value njs_ret_t ret; const njs_value_t *retval; - ret = njs_values_equal(val1, val2); + ret = njs_values_equal(vm, val1, val2); if (nxt_fast_path(ret >= 0)) { @@ -1646,7 +1652,7 @@ njs_vmcode_not_equal(njs_vm_t *vm, njs_v njs_ret_t ret; const njs_value_t *retval; - ret = njs_values_equal(val1, val2); + ret = njs_values_equal(vm, val1, val2); if (nxt_fast_path(ret >= 0)) { @@ -1661,7 +1667,7 @@ njs_vmcode_not_equal(njs_vm_t *vm, njs_v static nxt_noinline njs_ret_t -njs_values_equal(const njs_value_t *val1, const njs_value_t *val2) +njs_values_equal(njs_vm_t *vm, const njs_value_t *val1, const njs_value_t *val2) { /* Void and null are equal and not comparable with anything else. */ if (njs_is_null_or_void(val1)) { @@ -1682,7 +1688,7 @@ njs_values_equal(const njs_value_t *val1 return (val1->data.u.object == val2->data.u.object); } - return NJS_TRAP_NUMBERS; + return njs_trap(vm, NJS_TRAP_NUMBERS); } @@ -1692,7 +1698,7 @@ njs_vmcode_less(njs_vm_t *vm, njs_value_ njs_ret_t ret; const njs_value_t *retval; - ret = njs_values_compare(val1, val2); + ret = njs_values_compare(vm, val1, val2); if (nxt_fast_path(ret >= -1)) { @@ -1726,7 +1732,7 @@ njs_vmcode_greater_or_equal(njs_vm_t *vm njs_ret_t ret; const njs_value_t *retval; - ret = njs_values_compare(val1, val2); + ret = njs_values_compare(vm, val1, val2); if (nxt_fast_path(ret >= -1)) { @@ -1749,7 +1755,8 @@ njs_vmcode_greater_or_equal(njs_vm_t *vm */ static nxt_noinline njs_ret_t -njs_values_compare(const njs_value_t *val1, const njs_value_t *val2) +njs_values_compare(njs_vm_t *vm, const njs_value_t *val1, + const njs_value_t *val2) { if (nxt_fast_path(njs_is_numeric(val1) || njs_is_numeric(val2))) { @@ -1764,14 +1771,14 @@ njs_values_compare(const njs_value_t *va return (val1->data.u.number < val2->data.u.number); } - return NJS_TRAP_NUMBERS; + return njs_trap(vm, NJS_TRAP_NUMBERS); } if (nxt_fast_path(njs_is_string(val1) && njs_is_string(val2))) { return (njs_string_cmp(val1, val2) < 0) ? 1 : 0; } - return NJS_TRAP_STRINGS; + return njs_trap(vm, NJS_TRAP_STRINGS); } @@ -2200,8 +2207,8 @@ njs_ret_t njs_normalize_args(njs_vm_t *vm, njs_value_t *args, uint8_t *args_types, nxt_uint_t nargs) { - njs_ret_t trap; nxt_uint_t n; + njs_trap_t trap; n = nxt_min(nargs, NJS_ARGS_TYPES_MAX); @@ -2319,7 +2326,7 @@ trap: njs_vm_trap_value(vm, args); - return trap; + return njs_trap(vm, trap); type_error: @@ -2830,18 +2837,19 @@ static const njs_vmcode_1addr_t njs_tra static const njs_vm_trap_t njs_vm_traps[] = { - /* NJS_TRAP_STRING_ARG */ { &njs_trap_string_argument, 0 }, - /* NJS_TRAP_INTEGER_ARG */ { &njs_trap_number_argument, 0 }, - /* NJS_TRAP_PROPERTY */ { &njs_trap_strings[1], 0 }, - /* NJS_TRAP_STRINGS */ { &njs_trap_strings[0], 0 }, - /* NJS_TRAP_INCDEC */ { &njs_trap_numbers[1], 1 }, - /* NJS_TRAP_NUMBERS */ { &njs_trap_numbers[0], 0 }, - /* NJS_TRAP_NUMBER */ { &njs_trap_number[0], 0 }, + /* NJS_TRAP_NUMBER */ { .code = &njs_trap_number[0] }, + /* NJS_TRAP_NUMBERS */ { .code = &njs_trap_numbers[0] }, + /* NJS_TRAP_INCDEC */ { .code = &njs_trap_numbers[1], + .reference = 1 }, + /* NJS_TRAP_STRINGS */ { .code = &njs_trap_strings[0] }, + /* NJS_TRAP_PROPERTY */ { .code = &njs_trap_strings[1] }, + /* NJS_TRAP_NUMBER_ARG */ { .code = &njs_trap_number_argument }, + /* NJS_TRAP_STRING_ARG */ { .code = &njs_trap_string_argument }, }; static void -njs_vm_trap(njs_vm_t *vm, nxt_uint_t trap, njs_value_t *value1, +njs_vm_trap(njs_vm_t *vm, njs_trap_t trap, njs_value_t *value1, njs_value_t *value2) { njs_native_frame_t *frame; @@ -2858,9 +2866,9 @@ njs_vm_trap(njs_vm_t *vm, nxt_uint_t tra */ njs_set_invalid(&frame->trap_scratch); frame->trap_values[1] = *value2; - frame->trap_reference = njs_vm_traps[trap].reference_value; - - if (njs_vm_traps[trap].reference_value) { + frame->trap_reference = njs_vm_traps[trap].reference; + + if (njs_vm_traps[trap].reference) { frame->trap_values[0].data.u.value = value1; } else { @@ -2873,7 +2881,7 @@ njs_vm_trap(njs_vm_t *vm, nxt_uint_t tra static void -njs_vm_trap_argument(njs_vm_t *vm, nxt_uint_t trap) +njs_vm_trap_argument(njs_vm_t *vm, njs_trap_t trap) { njs_value_t *value; njs_native_frame_t *frame; diff -r 8960cef1cd5f -r 69300ba58603 njs/njs_vm.h --- a/njs/njs_vm.h Tue Jul 24 19:50:02 2018 +0300 +++ b/njs/njs_vm.h Tue Jul 24 19:50:02 2018 +0300 @@ -27,22 +27,31 @@ * -3: not used; * -4 (NJS_STOP/NXT_DONE): njs_vmcode_stop() has stopped execution, * execution has completed successfully; - * -5 .. -11: traps to convert objects to primitive values. + * -5 (NJS_TRAP) trap to convert objects to primitive values; + * -6 .. -11: not used. */ #define NJS_STOP NXT_DONE +#define NJS_TRAP (-5) + +/* The last return value which preempts execution. */ +#define NJS_PREEMPT (-11) /* Traps events. */ -#define NJS_TRAP_NUMBER (-5) -#define NJS_TRAP_NUMBERS (-6) -#define NJS_TRAP_INCDEC (-7) -#define NJS_TRAP_STRINGS (-8) -#define NJS_TRAP_PROPERTY (-9) -#define NJS_TRAP_NUMBER_ARG (-10) -#define NJS_TRAP_STRING_ARG (-11) -#define NJS_TRAP_BASE NJS_TRAP_STRING_ARG +typedef enum { + NJS_TRAP_NUMBER = 0, + NJS_TRAP_NUMBERS, + NJS_TRAP_INCDEC, + NJS_TRAP_STRINGS, + NJS_TRAP_PROPERTY, + NJS_TRAP_NUMBER_ARG, + NJS_TRAP_STRING_ARG, +} njs_trap_t; -#define NJS_PREEMPT (-11) + +#define njs_trap(vm, code) \ + vm->trap = code, NJS_TRAP; + /* * A user-defined function is prepared to run. This code is never @@ -983,7 +992,7 @@ enum njs_function_e { typedef struct { const njs_vmcode_1addr_t *code; - nxt_bool_t reference_value; + nxt_bool_t reference; } njs_vm_trap_t; @@ -1062,6 +1071,7 @@ struct njs_vm_s { nxt_array_t *debug; nxt_array_t *backtrace; + njs_trap_t trap:8; uint8_t trailer; /* 1 bit */ uint8_t accumulative; /* 1 bit */ }; _______________________________________________ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel