[njs] Refactored trap infrastructure.

Igor Sysoev igor at sysoev.ru
Tue Jul 24 17:09:09 UTC 2018


details:   http://hg.nginx.org/njs/rev/69300ba58603
branches:  
changeset: 570:69300ba58603
user:      Igor Sysoev <igor at 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 */
 };


More information about the nginx-devel mailing list