]> git.kaiwu.me - njs.git/commitdiff
Refactoring Error value types.
authorDmitry Volyntsev <xeioex@nginx.com>
Thu, 24 Oct 2019 13:17:16 +0000 (16:17 +0300)
committerDmitry Volyntsev <xeioex@nginx.com>
Thu, 24 Oct 2019 13:17:16 +0000 (16:17 +0300)
Eliminating special value types (njs_value_type_t) for error instance
objects.  According to the spec error instance objects are ordinary
objects which have an [[ErrorData]] internal slot.

16 files changed:
src/njs_builtin.c
src/njs_error.c
src/njs_error.h
src/njs_fs.c
src/njs_generator.c
src/njs_json.c
src/njs_module.c
src/njs_object.c
src/njs_parser.c
src/njs_parser.h
src/njs_value.c
src/njs_value.h
src/njs_vm.c
src/njs_vm.h
src/njs_vmcode.c
src/test/njs_unit_test.c

index 6d3438c687409858e255513fca6ab9f8008b8bc3..acdf8fec8b86070360fc515780b83ef233f9ef5a 100644 (file)
@@ -152,14 +152,14 @@ const njs_object_prototype_t  njs_prototype_values[] = {
     { .object_value = { .value = njs_value(NJS_DATA, 0, 0.0),
                         .object = { .type = NJS_OBJECT } } },
 
-    { .object =       { .type = NJS_OBJECT_ERROR } },
-    { .object =       { .type = NJS_OBJECT_EVAL_ERROR } },
-    { .object =       { .type = NJS_OBJECT_INTERNAL_ERROR } },
-    { .object =       { .type = NJS_OBJECT_RANGE_ERROR } },
-    { .object =       { .type = NJS_OBJECT_REF_ERROR } },
-    { .object =       { .type = NJS_OBJECT_SYNTAX_ERROR } },
-    { .object =       { .type = NJS_OBJECT_TYPE_ERROR } },
-    { .object =       { .type = NJS_OBJECT_URI_ERROR } },
+    { .object =       { .type = NJS_OBJECT } },
+    { .object =       { .type = NJS_OBJECT } },
+    { .object =       { .type = NJS_OBJECT } },
+    { .object =       { .type = NJS_OBJECT } },
+    { .object =       { .type = NJS_OBJECT } },
+    { .object =       { .type = NJS_OBJECT } },
+    { .object =       { .type = NJS_OBJECT } },
+    { .object =       { .type = NJS_OBJECT } },
 };
 
 
index 682be0414fb693145e3bfd3f5d78b4a086ab04ac..9baa9b83a878badb7bb3f31b82010942026606a0 100644 (file)
@@ -13,7 +13,7 @@ static const njs_value_t  njs_error_name_string = njs_string("name");
 
 
 void
-njs_error_new(njs_vm_t *vm, njs_value_t *dst, njs_value_type_t type,
+njs_error_new(njs_vm_t *vm, njs_value_t *dst, njs_prototype_t type,
     u_char *start, size_t size)
 {
     ssize_t        length;
@@ -36,12 +36,12 @@ njs_error_new(njs_vm_t *vm, njs_value_t *dst, njs_value_type_t type,
         return;
     }
 
-    njs_set_type_object(dst, error, type);
+    njs_set_object(dst, error);
 }
 
 
 void
-njs_error_fmt_new(njs_vm_t *vm, njs_value_t *dst, njs_value_type_t type,
+njs_error_fmt_new(njs_vm_t *vm, njs_value_t *dst, njs_prototype_t type,
     const char *fmt, ...)
 {
     va_list  args;
@@ -60,7 +60,7 @@ njs_error_fmt_new(njs_vm_t *vm, njs_value_t *dst, njs_value_type_t type,
 
 
 njs_object_t *
-njs_error_alloc(njs_vm_t *vm, njs_value_type_t type, const njs_value_t *name,
+njs_error_alloc(njs_vm_t *vm, njs_prototype_t type, const njs_value_t *name,
     const njs_value_t *message)
 {
     njs_int_t           ret;
@@ -75,10 +75,11 @@ njs_error_alloc(njs_vm_t *vm, njs_value_type_t type, const njs_value_t *name,
 
     njs_lvlhsh_init(&error->hash);
     njs_lvlhsh_init(&error->shared_hash);
-    error->type = type;
+    error->type = NJS_OBJECT;
     error->shared = 0;
     error->extensible = 1;
-    error->__proto__ = &vm->prototypes[njs_error_prototype_index(type)].object;
+    error->error_data = 1;
+    error->__proto__ = &vm->prototypes[type].object;
 
     lhq.replace = 0;
     lhq.pool = vm->mem_pool;
@@ -135,7 +136,7 @@ memory_error:
 
 static njs_int_t
 njs_error_create(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_value_type_t type)
+    njs_prototype_t type)
 {
     njs_int_t     ret;
     njs_value_t   *value;
@@ -158,7 +159,7 @@ njs_error_create(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return NJS_ERROR;
     }
 
-    njs_set_type_object(&vm->retval, error, type);
+    njs_set_object(&vm->retval, error);
 
     return NJS_OK;
 }
@@ -168,7 +169,7 @@ njs_int_t
 njs_error_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused)
 {
-    return njs_error_create(vm, args, nargs, NJS_OBJECT_ERROR);
+    return njs_error_create(vm, args, nargs, NJS_PROTOTYPE_ERROR);
 }
 
 
@@ -210,7 +211,7 @@ njs_int_t
 njs_eval_error_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused)
 {
-    return njs_error_create(vm, args, nargs, NJS_OBJECT_EVAL_ERROR);
+    return njs_error_create(vm, args, nargs, NJS_PROTOTYPE_EVAL_ERROR);
 }
 
 
@@ -252,7 +253,7 @@ njs_int_t
 njs_internal_error_constructor(njs_vm_t *vm, njs_value_t *args,
     njs_uint_t nargs, njs_index_t unused)
 {
-    return njs_error_create(vm, args, nargs, NJS_OBJECT_INTERNAL_ERROR);
+    return njs_error_create(vm, args, nargs, NJS_PROTOTYPE_INTERNAL_ERROR);
 }
 
 
@@ -294,7 +295,7 @@ njs_int_t
 njs_range_error_constructor(njs_vm_t *vm, njs_value_t *args,
     njs_uint_t nargs, njs_index_t unused)
 {
-    return njs_error_create(vm, args, nargs, NJS_OBJECT_RANGE_ERROR);
+    return njs_error_create(vm, args, nargs, NJS_PROTOTYPE_RANGE_ERROR);
 }
 
 
@@ -336,7 +337,7 @@ njs_int_t
 njs_reference_error_constructor(njs_vm_t *vm, njs_value_t *args,
     njs_uint_t nargs, njs_index_t unused)
 {
-    return njs_error_create(vm, args, nargs, NJS_OBJECT_REF_ERROR);
+    return njs_error_create(vm, args, nargs, NJS_PROTOTYPE_REF_ERROR);
 }
 
 
@@ -378,7 +379,7 @@ njs_int_t
 njs_syntax_error_constructor(njs_vm_t *vm, njs_value_t *args,
     njs_uint_t nargs, njs_index_t unused)
 {
-    return njs_error_create(vm, args, nargs, NJS_OBJECT_SYNTAX_ERROR);
+    return njs_error_create(vm, args, nargs, NJS_PROTOTYPE_SYNTAX_ERROR);
 }
 
 
@@ -420,7 +421,7 @@ njs_int_t
 njs_type_error_constructor(njs_vm_t *vm, njs_value_t *args,
     njs_uint_t nargs, njs_index_t unused)
 {
-    return njs_error_create(vm, args, nargs, NJS_OBJECT_TYPE_ERROR);
+    return njs_error_create(vm, args, nargs, NJS_PROTOTYPE_TYPE_ERROR);
 }
 
 
@@ -462,7 +463,7 @@ njs_int_t
 njs_uri_error_constructor(njs_vm_t *vm, njs_value_t *args,
     njs_uint_t nargs, njs_index_t unused)
 {
-    return njs_error_create(vm, args, nargs, NJS_OBJECT_URI_ERROR);
+    return njs_error_create(vm, args, nargs, NJS_PROTOTYPE_URI_ERROR);
 }
 
 
@@ -512,7 +513,7 @@ njs_memory_error_set(njs_vm_t *vm, njs_value_t *value)
     njs_lvlhsh_init(&object->hash);
     njs_lvlhsh_init(&object->shared_hash);
     object->__proto__ = &prototypes[NJS_PROTOTYPE_INTERNAL_ERROR].object;
-    object->type = NJS_OBJECT_INTERNAL_ERROR;
+    object->type = NJS_OBJECT;
     object->shared = 1;
 
     /*
@@ -520,8 +521,9 @@ njs_memory_error_set(njs_vm_t *vm, njs_value_t *value)
      * it from ordinary internal errors.
      */
     object->extensible = 0;
+    object->error_data = 1;
 
-    njs_set_type_object(value, object, NJS_OBJECT_INTERNAL_ERROR);
+    njs_set_object(value, object);
 }
 
 
index ac94d8d02c9cdf4c31209e22e835ce06ecf9a4d8..efc580c00c9cf1e02893f5feb4f7edc54d8d4132 100644 (file)
@@ -9,38 +9,38 @@
 
 
 #define njs_error(vm, fmt, ...)                                               \
-    njs_error_fmt_new(vm, &vm->retval, NJS_OBJECT_ERROR, fmt, ##__VA_ARGS__)
+    njs_error_fmt_new(vm, &vm->retval, NJS_PROTOTYPE_ERROR, fmt, ##__VA_ARGS__)
 #define njs_eval_error(vm, fmt, ...)                                          \
-    njs_error_fmt_new(vm, &vm->retval, NJS_OBJECT_EVAL_ERROR, fmt,            \
+    njs_error_fmt_new(vm, &vm->retval, NJS_PROTOTYPE_EVAL_ERROR, fmt,         \
                       ##__VA_ARGS__)
 #define njs_internal_error(vm, fmt, ...)                                      \
-    njs_error_fmt_new(vm, &vm->retval, NJS_OBJECT_INTERNAL_ERROR, fmt,        \
+    njs_error_fmt_new(vm, &vm->retval, NJS_PROTOTYPE_INTERNAL_ERROR, fmt,     \
                       ##__VA_ARGS__)
 #define njs_range_error(vm, fmt, ...)                                         \
-    njs_error_fmt_new(vm, &vm->retval, NJS_OBJECT_RANGE_ERROR, fmt,           \
+    njs_error_fmt_new(vm, &vm->retval, NJS_PROTOTYPE_RANGE_ERROR, fmt,        \
                       ##__VA_ARGS__)
 #define njs_reference_error(vm, fmt, ...)                                     \
-    njs_error_fmt_new(vm, &vm->retval, NJS_OBJECT_REF_ERROR, fmt,             \
+    njs_error_fmt_new(vm, &vm->retval, NJS_PROTOTYPE_REF_ERROR, fmt,          \
                       ##__VA_ARGS__)
 #define njs_syntax_error(vm, fmt, ...)                                        \
-    njs_error_fmt_new(vm, &vm->retval, NJS_OBJECT_SYNTAX_ERROR, fmt,          \
+    njs_error_fmt_new(vm, &vm->retval, NJS_PROTOTYPE_SYNTAX_ERROR, fmt,       \
                       ##__VA_ARGS__)
 #define njs_type_error(vm, fmt, ...)                                          \
-    njs_error_fmt_new(vm, &vm->retval, NJS_OBJECT_TYPE_ERROR, fmt,            \
+    njs_error_fmt_new(vm, &vm->retval, NJS_PROTOTYPE_TYPE_ERROR, fmt,         \
                       ##__VA_ARGS__)
 #define njs_uri_error(vm, fmt, ...)                                           \
-    njs_error_fmt_new(vm, &vm->retval, NJS_OBJECT_URI_ERROR, fmt,             \
+    njs_error_fmt_new(vm, &vm->retval, NJS_PROTOTYPE_URI_ERROR, fmt,          \
                       ##__VA_ARGS__)
 
-void njs_error_new(njs_vm_t *vm, njs_value_t *dst, njs_value_type_t type,
+void njs_error_new(njs_vm_t *vm, njs_value_t *dst, njs_prototype_t type,
     u_char *start, size_t size);
 void njs_noinline njs_error_fmt_new(njs_vm_t *vm, njs_value_t *dst,
-    njs_value_type_t type, const char *fmt, ...);
+    njs_prototype_t type, const char *fmt, ...);
 
 void njs_memory_error(njs_vm_t *vm);
 void njs_memory_error_set(njs_vm_t *vm, njs_value_t *value);
 
-njs_object_t *njs_error_alloc(njs_vm_t *vm, njs_value_type_t type,
+njs_object_t *njs_error_alloc(njs_vm_t *vm, njs_prototype_t type,
     const njs_value_t *name, const njs_value_t *message);
 njs_int_t njs_error_constructor(njs_vm_t *vm, njs_value_t *args,
     njs_uint_t nargs, njs_index_t unused);
index 9d89df32a143f544260865bb026e8031a20555c9..f2a053b86cd8850d22afd06ef393cb99a5430f84 100644 (file)
@@ -1028,7 +1028,7 @@ njs_fs_error(njs_vm_t *vm, const char *syscall, const char *description,
         return NJS_ERROR;
     }
 
-    error = njs_error_alloc(vm, NJS_OBJECT_ERROR, NULL, &string);
+    error = njs_error_alloc(vm, NJS_PROTOTYPE_ERROR, NULL, &string);
     if (njs_slow_path(error == NULL)) {
         return NJS_ERROR;
     }
@@ -1101,7 +1101,7 @@ njs_fs_error(njs_vm_t *vm, const char *syscall, const char *description,
         }
     }
 
-    njs_set_type_object(retval, error, NJS_OBJECT_ERROR);
+    njs_set_object(retval, error);
 
     return NJS_ERROR;
 }
index a4b43ce4fed7dcf0f540a3e1430623053c8eb5df..41a19c5647e7f0d21b9ae63985d93ebb3c924e23 100644 (file)
@@ -249,7 +249,8 @@ static njs_int_t njs_generate_function_debug(njs_vm_t *vm,
 
 
 #define njs_generate_syntax_error(vm, node, fmt, ...)                         \
-    njs_parser_node_error(vm, node, NJS_OBJECT_SYNTAX_ERROR, fmt, ##__VA_ARGS__)
+    njs_parser_node_error(vm, node, NJS_PROTOTYPE_SYNTAX_ERROR, fmt,          \
+                          ##__VA_ARGS__)
 
 
 static const njs_str_t  no_label     = njs_str("");
index 9dff714820708af8fae89901df23ba9d7665c279..7867ffc67051231a30a7a77a4a9197aa40561a7f 100644 (file)
@@ -2312,16 +2312,9 @@ njs_dump_value(njs_json_stringify_t *stringify, const njs_value_t *value,
 
         /* Fall through. */
 
+    case NJS_OBJECT:
     case NJS_REGEXP:
     case NJS_DATE:
-    case NJS_OBJECT_ERROR:
-    case NJS_OBJECT_EVAL_ERROR:
-    case NJS_OBJECT_INTERNAL_ERROR:
-    case NJS_OBJECT_RANGE_ERROR:
-    case NJS_OBJECT_REF_ERROR:
-    case NJS_OBJECT_SYNTAX_ERROR:
-    case NJS_OBJECT_TYPE_ERROR:
-    case NJS_OBJECT_URI_ERROR:
 
         switch (value->type) {
         case NJS_NUMBER:
@@ -2366,7 +2359,7 @@ memory_error:
 
 
 #define njs_dump_is_object(value)                                             \
-    (((value)->type == NJS_OBJECT)                                            \
+    (((value)->type == NJS_OBJECT && !njs_object(value)->error_data)          \
      || ((value)->type == NJS_ARRAY)                                          \
      || ((value)->type == NJS_OBJECT_VALUE)                                   \
      || ((value)->type == NJS_EXTERNAL                                        \
index 1f3d508cfec6e93429b92da62ade4776abed539c..ecad60f9faa1c2aeb47d4f8976aff4d8c88360c9 100644 (file)
@@ -539,6 +539,7 @@ njs_module_require(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         *object = module->object;
         object->__proto__ = &vm->prototypes[NJS_PROTOTYPE_OBJECT].object;
         object->shared = 0;
+        object->error_data = 0;
 
         njs_set_object(&vm->retval, object);
 
index cb17691ea1687498688b67b21dd19becc26d28d2..fb9d747a683d090b126fe1e3c56797b35afde0a6 100644 (file)
@@ -43,6 +43,7 @@ njs_object_alloc(njs_vm_t *vm)
         object->type = NJS_OBJECT;
         object->shared = 0;
         object->extensible = 1;
+        object->error_data = 0;
         return object;
     }
 
@@ -2057,7 +2058,7 @@ njs_object_prototype_to_string(njs_vm_t *vm, njs_value_t *args,
 {
     const njs_value_t  *name;
 
-    static const njs_value_t  *class_name[NJS_TYPE_MAX] = {
+    static const njs_value_t  *class_name[NJS_VALUE_TYPE_MAX] = {
         /* Primitives. */
         &njs_object_null_string,
         &njs_object_undefined_string,
@@ -2086,19 +2087,15 @@ njs_object_prototype_to_string(njs_vm_t *vm, njs_value_t *args,
         &njs_object_function_string,
         &njs_object_regexp_string,
         &njs_object_date_string,
-        &njs_object_error_string,
-        &njs_object_error_string,
-        &njs_object_error_string,
-        &njs_object_error_string,
-        &njs_object_error_string,
-        &njs_object_error_string,
-        &njs_object_error_string,
-        &njs_object_error_string,
         &njs_object_object_string,
     };
 
     name = class_name[args[0].type];
 
+    if (njs_is_error(&args[0])) {
+        name = &njs_object_error_string;
+    }
+
     if (njs_fast_path(name != NULL)) {
         vm->retval = *name;
 
index c1620b7d15cc582b13a997d8d13ae45abf9295f8..01a0f6466f127daddb8d534ec7253a71477bedad 100644 (file)
@@ -2300,7 +2300,7 @@ njs_parser_trace_handler(njs_trace_t *trace, njs_trace_data_t *td,
 
 static void
 njs_parser_scope_error(njs_vm_t *vm, njs_parser_scope_t *scope,
-    njs_value_type_t type, uint32_t line, const char *fmt, va_list args)
+    njs_prototype_t type, uint32_t line, const char *fmt, va_list args)
 {
     size_t     width;
     u_char     msg[NJS_MAX_ERROR_STR];
@@ -2333,7 +2333,7 @@ njs_parser_scope_error(njs_vm_t *vm, njs_parser_scope_t *scope,
 
 void
 njs_parser_lexer_error(njs_vm_t *vm, njs_parser_t *parser,
-    njs_value_type_t type, const char *fmt, ...)
+    njs_prototype_t type, const char *fmt, ...)
 {
     va_list  args;
 
@@ -2350,7 +2350,7 @@ njs_parser_lexer_error(njs_vm_t *vm, njs_parser_t *parser,
 
 void
 njs_parser_node_error(njs_vm_t *vm, njs_parser_node_t *node,
-    njs_value_type_t type, const char *fmt, ...)
+    njs_prototype_t type, const char *fmt, ...)
 {
     va_list  args;
 
index 066f96ad5034b9a61e656c7c6acd1531559149b1..7d0d46e37552dc4ddebdda2a3269d945aedda35f 100644 (file)
@@ -109,9 +109,9 @@ njs_token_t njs_parser_unexpected_token(njs_vm_t *vm, njs_parser_t *parser,
 u_char *njs_parser_trace_handler(njs_trace_t *trace, njs_trace_data_t *td,
     u_char *start);
 void njs_parser_lexer_error(njs_vm_t *vm, njs_parser_t *parser,
-    njs_value_type_t type, const char *fmt, ...);
+    njs_prototype_t type, const char *fmt, ...);
 void njs_parser_node_error(njs_vm_t *vm, njs_parser_node_t *node,
-    njs_value_type_t type, const char *fmt, ...);
+    njs_prototype_t type, const char *fmt, ...);
 
 
 #define njs_parser_enter(vm, parser)                                          \
@@ -155,12 +155,13 @@ void njs_parser_node_error(njs_vm_t *vm, njs_parser_node_t *node,
 
 
 #define njs_parser_syntax_error(vm, parser, fmt, ...)                         \
-    njs_parser_lexer_error(vm, parser, NJS_OBJECT_SYNTAX_ERROR, fmt,          \
+    njs_parser_lexer_error(vm, parser, NJS_PROTOTYPE_SYNTAX_ERROR, fmt,       \
                            ##__VA_ARGS__)
 
 
 #define njs_parser_ref_error(vm, parser, fmt, ...)                            \
-    njs_parser_lexer_error(vm, parser, NJS_OBJECT_REF_ERROR, fmt, ##__VA_ARGS__)
+    njs_parser_lexer_error(vm, parser, NJS_PROTOTYPE_REF_ERROR, fmt,          \
+                           ##__VA_ARGS__)
 
 
 njs_inline njs_token_t
index 4d0cf7e80921937d4216cb636fc5eaf3bb5dca93..95713486ef649b5aa2eb966f82fa2dd389dab666 100644 (file)
@@ -342,30 +342,6 @@ njs_type_string(njs_value_type_t type)
     case NJS_DATE:
         return "date";
 
-    case NJS_OBJECT_ERROR:
-        return "error";
-
-    case NJS_OBJECT_EVAL_ERROR:
-        return "eval error";
-
-    case NJS_OBJECT_INTERNAL_ERROR:
-        return "internal error";
-
-    case NJS_OBJECT_RANGE_ERROR:
-        return "range error";
-
-    case NJS_OBJECT_REF_ERROR:
-        return "reference error";
-
-    case NJS_OBJECT_SYNTAX_ERROR:
-        return "syntax error";
-
-    case NJS_OBJECT_TYPE_ERROR:
-        return "type error";
-
-    case NJS_OBJECT_URI_ERROR:
-        return "uri error";
-
     default:
         return NULL;
     }
@@ -558,14 +534,6 @@ njs_property_query(njs_vm_t *vm, njs_property_query_t *pq, njs_value_t *value,
     case NJS_OBJECT_STRING:
     case NJS_REGEXP:
     case NJS_DATE:
-    case NJS_OBJECT_ERROR:
-    case NJS_OBJECT_EVAL_ERROR:
-    case NJS_OBJECT_INTERNAL_ERROR:
-    case NJS_OBJECT_RANGE_ERROR:
-    case NJS_OBJECT_REF_ERROR:
-    case NJS_OBJECT_SYNTAX_ERROR:
-    case NJS_OBJECT_TYPE_ERROR:
-    case NJS_OBJECT_URI_ERROR:
     case NJS_OBJECT_VALUE:
         obj = njs_object(value);
         break;
index 2a713618db395b695e562e7d5efa9a6d6aa6cf11..08046fdcbbedb804a04094ef40626fe8b982bc9f 100644 (file)
@@ -64,16 +64,8 @@ typedef enum {
     NJS_FUNCTION              = 0x15,
     NJS_REGEXP                = 0x16,
     NJS_DATE                  = 0x17,
-    NJS_OBJECT_ERROR          = 0x18,
-    NJS_OBJECT_EVAL_ERROR     = 0x19,
-    NJS_OBJECT_INTERNAL_ERROR = 0x1a,
-    NJS_OBJECT_RANGE_ERROR    = 0x1b,
-    NJS_OBJECT_REF_ERROR      = 0x1c,
-    NJS_OBJECT_SYNTAX_ERROR   = 0x1d,
-    NJS_OBJECT_TYPE_ERROR     = 0x1e,
-    NJS_OBJECT_URI_ERROR      = 0x1f,
-    NJS_OBJECT_VALUE          = 0x20,
-#define NJS_TYPE_MAX         (NJS_OBJECT_VALUE + 1)
+    NJS_OBJECT_VALUE          = 0x18,
+#define NJS_VALUE_TYPE_MAX    (NJS_OBJECT_VALUE + 1)
 } njs_value_type_t;
 
 
@@ -205,7 +197,9 @@ struct njs_object_s {
     /* The type is used in constructor prototypes. */
     njs_value_type_t                  type:8;
     uint8_t                           shared;     /* 1 bit */
-    uint8_t                           extensible; /* 1 bit */
+
+    uint8_t                           extensible:1;
+    uint8_t                           error_data:1;
 };
 
 
@@ -459,10 +453,6 @@ typedef struct {
 #define njs_is_string(value)                                                  \
     ((value)->type == NJS_STRING)
 
-#define njs_is_error(value)                                                   \
-    ((value)->type >= NJS_OBJECT_ERROR                                        \
-     && (value)->type <= NJS_OBJECT_URI_ERROR)
-
 
 /*
  * The truth field coincides with short_string.size and short_string.length
@@ -520,6 +510,11 @@ typedef struct {
     ((value)->type >= NJS_OBJECT)
 
 
+#define njs_has_prototype(vm, value, proto)                                   \
+    (((njs_object_prototype_t *)                                              \
+        njs_object(value)->__proto__ - (vm)->prototypes) == proto)
+
+
 #define njs_is_object_value(value)                                            \
     ((value)->type == NJS_OBJECT_VALUE)
 
@@ -552,6 +547,10 @@ typedef struct {
     ((value)->type == NJS_DATE)
 
 
+#define njs_is_error(value)                                                   \
+    ((value)->type == NJS_OBJECT && njs_object(value)->error_data)
+
+
 #define njs_is_external(value)                                                \
     ((value)->type == NJS_EXTERNAL)
 
index 8564e2f339ed5f39b7d7fdc1951e5c2ab3c66fc5..422847d11cfbca833fc3686fa0c0774212d4f6fd 100644 (file)
@@ -675,7 +675,7 @@ njs_vm_value_error_set(njs_vm_t *vm, njs_value_t *value, const char *fmt, ...)
         va_end(args);
     }
 
-    njs_error_new(vm, value, NJS_OBJECT_ERROR, buf, p - buf);
+    njs_error_new(vm, value, NJS_PROTOTYPE_ERROR, buf, p - buf);
 }
 
 
@@ -1015,9 +1015,13 @@ njs_vm_value_to_string(njs_vm_t *vm, njs_str_t *dst, const njs_value_t *src)
         return NJS_ERROR;
     }
 
-    if (njs_slow_path(src->type == NJS_OBJECT_INTERNAL_ERROR)) {
+    if (njs_slow_path(njs_is_error(src))) {
+
         /* MemoryError is a nonextensible internal error. */
-        if (!njs_object(src)->extensible) {
+
+        if (njs_has_prototype(vm, src, NJS_PROTOTYPE_INTERNAL_ERROR)
+            && !njs_object(src)->extensible)
+        {
             njs_string_get(&njs_string_memory_error, dst);
             return NJS_OK;
         }
index a0e098387d9fe255666cdb79d2904f5f0311453d..86f9758bc47ee8db6a937e5c237aec1f2bf999d0 100644 (file)
@@ -81,7 +81,7 @@ typedef enum {
     (((index) & NJS_SCOPE_CALLEE_ARGUMENTS) == NJS_SCOPE_CALLEE_ARGUMENTS)
 
 
-enum njs_prototypes_e {
+typedef enum {
     NJS_PROTOTYPE_OBJECT = 0,
     NJS_PROTOTYPE_ARRAY,
     NJS_PROTOTYPE_BOOLEAN,
@@ -101,7 +101,7 @@ enum njs_prototypes_e {
     NJS_PROTOTYPE_TYPE_ERROR,
     NJS_PROTOTYPE_URI_ERROR,
 #define NJS_PROTOTYPE_MAX      (NJS_PROTOTYPE_URI_ERROR + 1)
-};
+} njs_prototype_t;
 
 
 #define njs_primitive_prototype_index(type)                                   \
@@ -266,7 +266,7 @@ struct njs_vm_s {
 
     /*
      * MemoryError is statically allocated immutable Error object
-     * with the generic type NJS_OBJECT_INTERNAL_ERROR.
+     * with the InternalError prototype.
      */
     njs_object_t             memory_error_object;
 
index 68d5a372e8ce3c8eb645bf54acd6d8ebda693b0f..0527a9cd7fee9324112fe7a0ae71a7f0a57f470f 100644 (file)
@@ -1384,7 +1384,7 @@ njs_vmcode_typeof(njs_vm_t *vm, njs_value_t *value, njs_value_t *invld)
 {
     /* ECMAScript 5.1: null, array and regexp are objects. */
 
-    static const njs_value_t  *types[NJS_TYPE_MAX] = {
+    static const njs_value_t  *types[NJS_VALUE_TYPE_MAX] = {
         &njs_string_object,
         &njs_string_undefined,
         &njs_string_boolean,
@@ -1411,14 +1411,6 @@ njs_vmcode_typeof(njs_vm_t *vm, njs_value_t *value, njs_value_t *invld)
         &njs_string_object,
         &njs_string_object,
         &njs_string_object,
-        &njs_string_object,
-        &njs_string_object,
-        &njs_string_object,
-        &njs_string_object,
-        &njs_string_object,
-        &njs_string_object,
-        &njs_string_object,
-        &njs_string_object,
     };
 
     vm->retval = *types[value->type];
index 67d3503296af69be873cdf29f8f456f7e87bb6fe..9e29ee4f666a7d590b97aa1b5f586f9cbb3acafc 100644 (file)
@@ -8670,6 +8670,9 @@ static njs_unit_test_t  njs_test[] =
     { njs_str("RangeError('e')"),
       njs_str("RangeError: e") },
 
+    { njs_str("var e = RangeError('e'); Object.preventExtensions(e);e"),
+      njs_str("RangeError: e") },
+
     { njs_str("ReferenceError('e')"),
       njs_str("ReferenceError: e") },
 
@@ -9532,6 +9535,9 @@ static njs_unit_test_t  njs_test[] =
     { njs_str("Object.prototype.toString.call(new URIError)"),
       njs_str("[object Error]") },
 
+    { njs_str("Object.prototype.toString.call(URIError.prototype)"),
+      njs_str("[object Object]") },
+
     { njs_str("Object.prototype"),
       njs_str("[object Object]") },
 
@@ -10264,6 +10270,9 @@ static njs_unit_test_t  njs_test[] =
     { njs_str("var fn = (function() { return new Function('return this'); }).call({}), o = {}; fn.call(o) == o && fn.bind(o).call(this) == o"),
       njs_str("true") },
 
+    { njs_str("this.NN = {}; var f = Function('eval = 42;'); f()"),
+      njs_str("SyntaxError: Identifier \"eval\" is forbidden as left-hand in assignment in runtime:1") },
+
     { njs_str("RegExp()"),
       njs_str("/(?:)/") },
 
@@ -14029,6 +14038,9 @@ static njs_unit_test_t  njs_test[] =
     { njs_str("njs.dump({a:1, b:[1,,2,{c:new Boolean(1)}]})"),
       njs_str("{a:1,b:[1,<empty>,2,{c:[Boolean: true]}]}") },
 
+    { njs_str("njs.dump([InternalError(),TypeError('msg'), new RegExp(), /^undef$/m, new Date(0)])"),
+      njs_str("[InternalError,TypeError: msg,/(?:)/,/^undef$/m,1970-01-01T00:00:00.000Z]") },
+
     { njs_str("njs.dump(Array.prototype.slice.call({'1':'b', length:2}))"),
       njs_str("[<empty>,'b']") },