[njs] Refactoring Error value types.
Dmitry Volyntsev
xeioex at nginx.com
Thu Oct 24 13:24:27 UTC 2019
details: https://hg.nginx.org/njs/rev/a908c2ef62ca
branches:
changeset: 1199:a908c2ef62ca
user: Dmitry Volyntsev <xeioex at nginx.com>
date: Thu Oct 24 16:17:16 2019 +0300
description:
Refactoring Error value types.
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.
diffstat:
src/njs_builtin.c | 16 ++++++++--------
src/njs_error.c | 38 ++++++++++++++++++++------------------
src/njs_error.h | 22 +++++++++++-----------
src/njs_fs.c | 4 ++--
src/njs_generator.c | 3 ++-
src/njs_json.c | 11 ++---------
src/njs_module.c | 1 +
src/njs_object.c | 15 ++++++---------
src/njs_parser.c | 6 +++---
src/njs_parser.h | 9 +++++----
src/njs_value.c | 32 --------------------------------
src/njs_value.h | 29 ++++++++++++++---------------
src/njs_vm.c | 10 +++++++---
src/njs_vm.h | 6 +++---
src/njs_vmcode.c | 10 +---------
src/test/njs_unit_test.c | 12 ++++++++++++
16 files changed, 97 insertions(+), 127 deletions(-)
diffs (663 lines):
diff -r b02b79e30d4a -r a908c2ef62ca src/njs_builtin.c
--- a/src/njs_builtin.c Thu Oct 24 16:15:01 2019 +0300
+++ b/src/njs_builtin.c Thu Oct 24 16:17:16 2019 +0300
@@ -152,14 +152,14 @@ const njs_object_prototype_t njs_protot
{ .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 } },
};
diff -r b02b79e30d4a -r a908c2ef62ca src/njs_error.c
--- a/src/njs_error.c Thu Oct 24 16:15:01 2019 +0300
+++ b/src/njs_error.c Thu Oct 24 16:17:16 2019 +0300
@@ -13,7 +13,7 @@ static const njs_value_t njs_error_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
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_valu
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_
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
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_v
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_v
* 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);
}
diff -r b02b79e30d4a -r a908c2ef62ca src/njs_error.h
--- a/src/njs_error.h Thu Oct 24 16:15:01 2019 +0300
+++ b/src/njs_error.h Thu Oct 24 16:17:16 2019 +0300
@@ -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);
diff -r b02b79e30d4a -r a908c2ef62ca src/njs_fs.c
--- a/src/njs_fs.c Thu Oct 24 16:15:01 2019 +0300
+++ b/src/njs_fs.c Thu Oct 24 16:17:16 2019 +0300
@@ -1028,7 +1028,7 @@ njs_fs_error(njs_vm_t *vm, const char *s
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 *s
}
}
- njs_set_type_object(retval, error, NJS_OBJECT_ERROR);
+ njs_set_object(retval, error);
return NJS_ERROR;
}
diff -r b02b79e30d4a -r a908c2ef62ca src/njs_generator.c
--- a/src/njs_generator.c Thu Oct 24 16:15:01 2019 +0300
+++ b/src/njs_generator.c Thu Oct 24 16:17:16 2019 +0300
@@ -249,7 +249,8 @@ static njs_int_t njs_generate_function_d
#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("");
diff -r b02b79e30d4a -r a908c2ef62ca src/njs_json.c
--- a/src/njs_json.c Thu Oct 24 16:15:01 2019 +0300
+++ b/src/njs_json.c Thu Oct 24 16:17:16 2019 +0300
@@ -2312,16 +2312,9 @@ njs_dump_value(njs_json_stringify_t *str
/* 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 \
diff -r b02b79e30d4a -r a908c2ef62ca src/njs_module.c
--- a/src/njs_module.c Thu Oct 24 16:15:01 2019 +0300
+++ b/src/njs_module.c Thu Oct 24 16:17:16 2019 +0300
@@ -539,6 +539,7 @@ njs_module_require(njs_vm_t *vm, njs_val
*object = module->object;
object->__proto__ = &vm->prototypes[NJS_PROTOTYPE_OBJECT].object;
object->shared = 0;
+ object->error_data = 0;
njs_set_object(&vm->retval, object);
diff -r b02b79e30d4a -r a908c2ef62ca src/njs_object.c
--- a/src/njs_object.c Thu Oct 24 16:15:01 2019 +0300
+++ b/src/njs_object.c Thu Oct 24 16:17:16 2019 +0300
@@ -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
{
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
&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;
diff -r b02b79e30d4a -r a908c2ef62ca src/njs_parser.c
--- a/src/njs_parser.c Thu Oct 24 16:15:01 2019 +0300
+++ b/src/njs_parser.c Thu Oct 24 16:17:16 2019 +0300
@@ -2300,7 +2300,7 @@ njs_parser_trace_handler(njs_trace_t *tr
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
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
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;
diff -r b02b79e30d4a -r a908c2ef62ca src/njs_parser.h
--- a/src/njs_parser.h Thu Oct 24 16:15:01 2019 +0300
+++ b/src/njs_parser.h Thu Oct 24 16:17:16 2019 +0300
@@ -109,9 +109,9 @@ njs_token_t njs_parser_unexpected_token(
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,
#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
diff -r b02b79e30d4a -r a908c2ef62ca src/njs_value.c
--- a/src/njs_value.c Thu Oct 24 16:15:01 2019 +0300
+++ b/src/njs_value.c Thu Oct 24 16:17:16 2019 +0300
@@ -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_pro
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;
diff -r b02b79e30d4a -r a908c2ef62ca src/njs_value.h
--- a/src/njs_value.h Thu Oct 24 16:15:01 2019 +0300
+++ b/src/njs_value.h Thu Oct 24 16:17:16 2019 +0300
@@ -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)
diff -r b02b79e30d4a -r a908c2ef62ca src/njs_vm.c
--- a/src/njs_vm.c Thu Oct 24 16:15:01 2019 +0300
+++ b/src/njs_vm.c Thu Oct 24 16:17:16 2019 +0300
@@ -675,7 +675,7 @@ njs_vm_value_error_set(njs_vm_t *vm, njs
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
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;
}
diff -r b02b79e30d4a -r a908c2ef62ca src/njs_vm.h
--- a/src/njs_vm.h Thu Oct 24 16:15:01 2019 +0300
+++ b/src/njs_vm.h Thu Oct 24 16:17:16 2019 +0300
@@ -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;
diff -r b02b79e30d4a -r a908c2ef62ca src/njs_vmcode.c
--- a/src/njs_vmcode.c Thu Oct 24 16:15:01 2019 +0300
+++ b/src/njs_vmcode.c Thu Oct 24 16:17:16 2019 +0300
@@ -1384,7 +1384,7 @@ njs_vmcode_typeof(njs_vm_t *vm, njs_valu
{
/* 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_valu
&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];
diff -r b02b79e30d4a -r a908c2ef62ca src/test/njs_unit_test.c
--- a/src/test/njs_unit_test.c Thu Oct 24 16:15:01 2019 +0300
+++ b/src/test/njs_unit_test.c Thu Oct 24 16:17:16 2019 +0300
@@ -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']") },
More information about the nginx-devel
mailing list