[njs] Error builtin objects.
Dmitry Volyntsev
xeioex at nginx.com
Fri Nov 17 16:06:04 UTC 2017
details: http://hg.nginx.org/njs/rev/5bc8d7c25e4f
branches:
changeset: 420:5bc8d7c25e4f
user: Dmitry Volyntsev <xeioex at nginx.com>
date: Fri Nov 17 18:55:07 2017 +0300
description:
Error builtin objects.
diffstat:
Makefile | 16 +
njs/njs_array.c | 9 +-
njs/njs_boolean.c | 5 +-
njs/njs_builtin.c | 87 ++++-
njs/njs_date.c | 5 +-
njs/njs_error.c | 865 +++++++++++++++++++++++++++++++++++++++++++
njs/njs_error.h | 77 +++
njs/njs_function.c | 14 +-
njs/njs_generator.c | 14 +-
njs/njs_json.c | 100 +---
njs/njs_lexer_keyword.c | 9 +
njs/njs_number.c | 7 +-
njs/njs_object.c | 71 ++-
njs/njs_object_hash.h | 19 +
njs/njs_parser.c | 36 +
njs/njs_parser.h | 9 +
njs/njs_regexp.c | 9 +-
njs/njs_string.c | 15 +-
njs/njs_vm.c | 57 ++-
njs/njs_vm.h | 131 ++++-
njs/njscript.c | 4 +
njs/test/njs_expect_test.exp | 8 +-
njs/test/njs_unit_test.c | 274 +++++++++++++
nxt/nxt_string.h | 3 +
24 files changed, 1661 insertions(+), 183 deletions(-)
diffs (truncated from 2877 to 1000 lines):
diff -r a6af47aab3f2 -r 5bc8d7c25e4f Makefile
--- a/Makefile Fri Nov 17 18:55:07 2017 +0300
+++ b/Makefile Fri Nov 17 18:55:07 2017 +0300
@@ -20,6 +20,7 @@ NXT_BUILDDIR = build
$(NXT_BUILDDIR)/njs_function.o \
$(NXT_BUILDDIR)/njs_regexp.o \
$(NXT_BUILDDIR)/njs_date.o \
+ $(NXT_BUILDDIR)/njs_error.o \
$(NXT_BUILDDIR)/njs_math.o \
$(NXT_BUILDDIR)/njs_extern.o \
$(NXT_BUILDDIR)/njs_variable.o \
@@ -53,6 +54,7 @@ NXT_BUILDDIR = build
$(NXT_BUILDDIR)/njs_function.o \
$(NXT_BUILDDIR)/njs_regexp.o \
$(NXT_BUILDDIR)/njs_date.o \
+ $(NXT_BUILDDIR)/njs_error.o \
$(NXT_BUILDDIR)/njs_math.o \
$(NXT_BUILDDIR)/njs_extern.o \
$(NXT_BUILDDIR)/njs_variable.o \
@@ -271,6 +273,20 @@ dist:
-I$(NXT_LIB) -Injs $(NXT_PCRE_CFLAGS) \
njs/njs_date.c
+$(NXT_BUILDDIR)/njs_error.o: \
+ $(NXT_BUILDDIR)/libnxt.a \
+ njs/njscript.h \
+ njs/njs_vm.h \
+ njs/njs_string.h \
+ njs/njs_object.h \
+ njs/njs_function.h \
+ njs/njs_error.h \
+ njs/njs_error.c \
+
+ $(NXT_CC) -c -o $(NXT_BUILDDIR)/njs_error.o $(NXT_CFLAGS) \
+ -I$(NXT_LIB) -Injs $(NXT_PCRE_CFLAGS) \
+ njs/njs_error.c
+
$(NXT_BUILDDIR)/njs_math.o: \
$(NXT_BUILDDIR)/libnxt.a \
njs/njscript.h \
diff -r a6af47aab3f2 -r 5bc8d7c25e4f njs/njs_array.c
--- a/njs/njs_array.c Fri Nov 17 18:55:07 2017 +0300
+++ b/njs/njs_array.c Fri Nov 17 18:55:07 2017 +0300
@@ -23,6 +23,7 @@
#include <njs_object_hash.h>
#include <njs_array.h>
#include <njs_function.h>
+#include <njs_error.h>
#include <string.h>
@@ -248,7 +249,7 @@ njs_array_constructor(njs_vm_t *vm, njs_
size = (uint32_t) num;
if ((double) size != num) {
- vm->exception = &njs_exception_range_error;
+ njs_exception_range_error(vm, NULL, NULL);
return NXT_ERROR;
}
@@ -1713,7 +1714,7 @@ njs_array_prototype_reduce(njs_vm_t *vm,
n = njs_array_iterator_index(array, iter);
if (n == NJS_ARRAY_INVALID_INDEX) {
- vm->exception = &njs_exception_type_error;
+ njs_exception_type_error(vm, NULL, NULL);
return NXT_ERROR;
}
@@ -1774,7 +1775,7 @@ njs_array_iterator_args(njs_vm_t *vm, nj
return NXT_OK;
}
- vm->exception = &njs_exception_type_error;
+ njs_exception_type_error(vm, NULL, NULL);
return NXT_ERROR;
}
@@ -1858,7 +1859,7 @@ njs_array_prototype_reduce_right(njs_vm_
unused);
type_error:
- vm->exception = &njs_exception_type_error;
+ njs_exception_type_error(vm, NULL, NULL);
return NXT_ERROR;
}
diff -r a6af47aab3f2 -r 5bc8d7c25e4f njs/njs_boolean.c
--- a/njs/njs_boolean.c Fri Nov 17 18:55:07 2017 +0300
+++ b/njs/njs_boolean.c Fri Nov 17 18:55:07 2017 +0300
@@ -18,6 +18,7 @@
#include <njs_boolean.h>
#include <njs_object.h>
#include <njs_function.h>
+#include <njs_error.h>
njs_ret_t
@@ -98,7 +99,7 @@ njs_boolean_prototype_value_of(njs_vm_t
value = &value->data.u.object_value->value;
} else {
- vm->exception = &njs_exception_type_error;
+ njs_exception_type_error(vm, NULL, NULL);
return NXT_ERROR;
}
}
@@ -123,7 +124,7 @@ njs_boolean_prototype_to_string(njs_vm_t
value = &value->data.u.object_value->value;
} else {
- vm->exception = &njs_exception_type_error;
+ njs_exception_type_error(vm, NULL, NULL);
return NXT_ERROR;
}
}
diff -r a6af47aab3f2 -r 5bc8d7c25e4f njs/njs_builtin.c
--- a/njs/njs_builtin.c Fri Nov 17 18:55:07 2017 +0300
+++ b/njs/njs_builtin.c Fri Nov 17 18:55:07 2017 +0300
@@ -28,6 +28,7 @@
#include <njs_parser.h>
#include <njs_regexp.h>
#include <njs_date.h>
+#include <njs_error.h>
#include <njs_math.h>
#include <string.h>
#include <stdio.h>
@@ -62,6 +63,15 @@ const njs_object_init_t *njs_prototype_
&njs_function_prototype_init,
&njs_regexp_prototype_init,
&njs_date_prototype_init,
+ &njs_error_prototype_init,
+ &njs_eval_error_prototype_init,
+ &njs_internal_error_prototype_init,
+ &njs_range_error_prototype_init,
+ &njs_ref_error_prototype_init,
+ &njs_syntax_error_prototype_init,
+ &njs_type_error_prototype_init,
+ &njs_uri_error_prototype_init,
+ &njs_memory_error_prototype_init,
};
@@ -74,6 +84,15 @@ const njs_object_init_t *njs_construc
&njs_function_constructor_init,
&njs_regexp_constructor_init,
&njs_date_constructor_init,
+ &njs_error_constructor_init,
+ &njs_eval_error_constructor_init,
+ &njs_internal_error_constructor_init,
+ &njs_range_error_constructor_init,
+ &njs_ref_error_constructor_init,
+ &njs_syntax_error_constructor_init,
+ &njs_type_error_constructor_init,
+ &njs_uri_error_constructor_init,
+ &njs_memory_error_constructor_init,
};
@@ -126,6 +145,16 @@ njs_builtin_objects_create(njs_vm_t *vm)
{ .date = { .time = NAN,
.object = { .type = NJS_DATE } } },
+
+ { .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_INTERNAL_ERROR } },
};
static const njs_function_init_t native_constructors[] = {
@@ -139,6 +168,18 @@ njs_builtin_objects_create(njs_vm_t *vm)
{ njs_regexp_constructor,
{ NJS_SKIP_ARG, NJS_STRING_ARG, NJS_STRING_ARG } },
{ njs_date_constructor, { 0 } },
+ { njs_error_constructor, { NJS_SKIP_ARG, NJS_STRING_ARG } },
+ { njs_eval_error_constructor, { NJS_SKIP_ARG, NJS_STRING_ARG } },
+ { njs_internal_error_constructor,
+ { NJS_SKIP_ARG, NJS_STRING_ARG } },
+ { njs_range_error_constructor,
+ { NJS_SKIP_ARG, NJS_STRING_ARG } },
+ { njs_ref_error_constructor, { NJS_SKIP_ARG, NJS_STRING_ARG } },
+ { njs_syntax_error_constructor,
+ { NJS_SKIP_ARG, NJS_STRING_ARG } },
+ { njs_type_error_constructor, { NJS_SKIP_ARG, NJS_STRING_ARG } },
+ { njs_uri_error_constructor, { NJS_SKIP_ARG, NJS_STRING_ARG } },
+ { njs_memory_error_constructor, { NJS_SKIP_ARG, NJS_STRING_ARG } },
};
static const njs_object_init_t *function_init[] = {
@@ -309,6 +350,42 @@ njs_builtin_objects_create(njs_vm_t *vm)
* Date.__proto__ -> Function_Prototype,
* Date_Prototype.__proto__ -> Object_Prototype,
*
+ * Error(),
+ * Error.__proto__ -> Function_Prototype,
+ * Error_Prototype.__proto__ -> Object_Prototype,
+ *
+ * EvalError(),
+ * EvalError.__proto__ -> Function_Prototype,
+ * EvalError_Prototype.__proto__ -> Error_Prototype,
+ *
+ * InternalError(),
+ * InternalError.__proto__ -> Function_Prototype,
+ * InternalError_Prototype.__proto__ -> Error_Prototype,
+ *
+ * RangeError(),
+ * RangeError.__proto__ -> Function_Prototype,
+ * RangeError_Prototype.__proto__ -> Error_Prototype,
+ *
+ * ReferenceError(),
+ * ReferenceError.__proto__ -> Function_Prototype,
+ * ReferenceError_Prototype.__proto__ -> Error_Prototype,
+ *
+ * SyntaxError(),
+ * SyntaxError.__proto__ -> Function_Prototype,
+ * SyntaxError_Prototype.__proto__ -> Error_Prototype,
+ *
+ * TypeError(),
+ * TypeError.__proto__ -> Function_Prototype,
+ * TypeError_Prototype.__proto__ -> Error_Prototype,
+ *
+ * URIError(),
+ * URIError.__proto__ -> Function_Prototype,
+ * URIError_Prototype.__proto__ -> Error_Prototype,
+ *
+ * MemoryError(),
+ * MemoryError.__proto__ -> Function_Prototype,
+ * MemoryError_Prototype.__proto__ -> Error_Prototype,
+ *
* eval(),
* eval.__proto__ -> Function_Prototype.
*/
@@ -319,7 +396,7 @@ njs_builtin_objects_clone(njs_vm_t *vm)
size_t size;
nxt_uint_t i;
njs_value_t *values;
- njs_object_t *object_prototype, *function_prototype;
+ njs_object_t *object_prototype, *function_prototype, *error_prototype;
/*
* Copy both prototypes and constructors arrays by one memcpy()
@@ -332,10 +409,16 @@ njs_builtin_objects_clone(njs_vm_t *vm)
object_prototype = &vm->prototypes[NJS_PROTOTYPE_OBJECT].object;
- for (i = NJS_PROTOTYPE_ARRAY; i < NJS_PROTOTYPE_MAX; i++) {
+ for (i = NJS_PROTOTYPE_ARRAY; i < NJS_PROTOTYPE_EVAL_ERROR; i++) {
vm->prototypes[i].object.__proto__ = object_prototype;
}
+ error_prototype = &vm->prototypes[NJS_PROTOTYPE_ERROR].object;
+
+ for (i = NJS_PROTOTYPE_EVAL_ERROR; i < NJS_PROTOTYPE_MAX; i++) {
+ vm->prototypes[i].object.__proto__ = error_prototype;
+ }
+
function_prototype = &vm->prototypes[NJS_CONSTRUCTOR_FUNCTION].object;
values = vm->scopes[NJS_SCOPE_GLOBAL];
diff -r a6af47aab3f2 -r 5bc8d7c25e4f njs/njs_date.c
--- a/njs/njs_date.c Fri Nov 17 18:55:07 2017 +0300
+++ b/njs/njs_date.c Fri Nov 17 18:55:07 2017 +0300
@@ -25,6 +25,7 @@
#include <njs_object_hash.h>
#include <njs_function.h>
#include <njs_date.h>
+#include <njs_error.h>
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
@@ -1062,7 +1063,7 @@ njs_date_prototype_to_iso_string(njs_vm_
return njs_string_new(vm, &vm->retval, buf, size, size);
}
- vm->exception = &njs_exception_range_error;
+ njs_exception_range_error(vm, NULL, NULL);
return NXT_ERROR;
}
@@ -1910,7 +1911,7 @@ njs_date_prototype_to_json(njs_vm_t *vm,
}
}
- vm->exception = &njs_exception_type_error;
+ njs_exception_type_error(vm, NULL, NULL);
return NXT_ERROR;
}
diff -r a6af47aab3f2 -r 5bc8d7c25e4f njs/njs_error.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/njs/njs_error.c Fri Nov 17 18:55:07 2017 +0300
@@ -0,0 +1,865 @@
+
+/*
+ * Copyright (C) Dmitry Volyntsev
+ * Copyright (C) NGINX, Inc.
+ */
+
+#include <nxt_auto_config.h>
+#include <nxt_types.h>
+#include <nxt_clang.h>
+#include <nxt_string.h>
+#include <nxt_stub.h>
+#include <nxt_djb_hash.h>
+#include <nxt_array.h>
+#include <nxt_lvlhsh.h>
+#include <nxt_random.h>
+#include <nxt_mem_cache_pool.h>
+#include <njscript.h>
+#include <njs_vm.h>
+#include <njs_error.h>
+#include <njs_object.h>
+#include <njs_object_hash.h>
+#include <njs_string.h>
+#include <njs_function.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+
+
+static const njs_value_t njs_error_message_string = njs_string("message");
+static const njs_value_t njs_error_name_string = njs_string("name");
+
+
+void
+njs_exception_error_create(njs_vm_t *vm, njs_value_type_t type,
+ const char* fmt, ...)
+{
+ size_t size;
+ va_list args;
+ nxt_int_t ret;
+ njs_value_t string, *value;
+ njs_object_t *error;
+
+ static char buf[256];
+
+ if (fmt != NULL) {
+ va_start(args, fmt);
+ size = vsnprintf(buf, sizeof(buf), fmt, args);
+ va_end(args);
+
+ } else {
+ size = 0;
+ }
+
+ ret = njs_string_new(vm, &string, (const u_char *) buf, size, size);
+ if (nxt_slow_path(ret != NXT_OK)) {
+ goto memory_error;
+ }
+
+ error = njs_error_alloc(vm, type, NULL, &string);
+ if (nxt_slow_path(error == NULL)) {
+ goto memory_error;
+ }
+
+ value = nxt_mem_cache_alloc(vm->mem_cache_pool, sizeof(njs_value_t));
+ if (nxt_slow_path(value == NULL)) {
+ goto memory_error;
+ }
+
+ value->data.u.object = error;
+ value->type = type;
+ value->data.truth = 1;
+
+ vm->exception = value;
+
+ return;
+
+memory_error:
+
+ njs_exception_memory_error(vm);
+}
+
+
+nxt_noinline njs_object_t *
+njs_error_alloc(njs_vm_t *vm, njs_value_type_t type, const njs_value_t *name,
+ const njs_value_t *message)
+{
+ nxt_int_t ret;
+ njs_object_t *error;
+ njs_object_prop_t *prop;
+ nxt_lvlhsh_query_t lhq;
+
+ error = nxt_mem_cache_alloc(vm->mem_cache_pool, sizeof(njs_object_t));
+ if (nxt_slow_path(error == NULL)) {
+ return NULL;
+ }
+
+ nxt_lvlhsh_init(&error->hash);
+ nxt_lvlhsh_init(&error->shared_hash);
+ error->type = type;
+ error->shared = 0;
+ error->extensible = 1;
+ error->__proto__ = &vm->prototypes[njs_error_prototype_index(type)].object;
+
+ lhq.replace = 0;
+ lhq.pool = vm->mem_cache_pool;
+
+ if (name != NULL) {
+ lhq.key = nxt_string_value("name");
+ lhq.key_hash = NJS_NAME_HASH;
+ lhq.proto = &njs_object_hash_proto;
+
+ prop = njs_object_prop_alloc(vm, &njs_error_name_string, name, 1);
+ if (nxt_slow_path(prop == NULL)) {
+ return NULL;
+ }
+
+ lhq.value = prop;
+
+ ret = nxt_lvlhsh_insert(&error->hash, &lhq);
+ if (nxt_slow_path(ret != NXT_OK)) {
+ return NULL;
+ }
+ }
+
+ if (message!= NULL) {
+ lhq.key = nxt_string_value("message");
+ lhq.key_hash = NJS_MESSAGE_HASH;
+ lhq.proto = &njs_object_hash_proto;
+
+ prop = njs_object_prop_alloc(vm, &njs_error_message_string, message, 1);
+ if (nxt_slow_path(prop == NULL)) {
+ return NULL;
+ }
+
+ prop->enumerable = 0;
+
+ lhq.value = prop;
+
+ ret = nxt_lvlhsh_insert(&error->hash, &lhq);
+ if (nxt_slow_path(ret != NXT_OK)) {
+ return NULL;
+ }
+ }
+
+ return error;
+}
+
+
+static njs_ret_t
+njs_error_create(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs,
+ njs_value_type_t type)
+{
+ njs_object_t *error;
+ const njs_value_t *value;
+
+ if (nargs == 1) {
+ value = &njs_string_empty;
+
+ } else {
+ value = &args[1];
+ }
+
+ error = njs_error_alloc(vm, type, NULL, value);
+ if (nxt_slow_path(error == NULL)) {
+ njs_exception_memory_error(vm);
+ return NXT_ERROR;
+ }
+
+ vm->retval.data.u.object = error;
+ vm->retval.type = type;
+ vm->retval.data.truth = 1;
+
+ return NXT_OK;
+}
+
+
+njs_ret_t
+njs_error_constructor(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs,
+ njs_index_t unused)
+{
+ return njs_error_create(vm, args, nargs, NJS_OBJECT_ERROR);
+}
+
+
+static const njs_object_prop_t njs_error_constructor_properties[] =
+{
+ /* Error.name == "Error". */
+ {
+ .type = NJS_PROPERTY,
+ .name = njs_string("name"),
+ .value = njs_string("Error"),
+ },
+
+ /* Error.length == 1. */
+ {
+ .type = NJS_PROPERTY,
+ .name = njs_string("length"),
+ .value = njs_value(NJS_NUMBER, 1, 1.0),
+ },
+
+ /* Error.prototype. */
+ {
+ .type = NJS_NATIVE_GETTER,
+ .name = njs_string("prototype"),
+ .value = njs_native_getter(njs_object_prototype_create),
+ },
+};
+
+
+const njs_object_init_t njs_error_constructor_init = {
+ nxt_string("Error"),
+ njs_error_constructor_properties,
+ nxt_nitems(njs_error_constructor_properties),
+};
+
+
+njs_ret_t
+njs_eval_error_constructor(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs,
+ njs_index_t unused)
+{
+ return njs_error_create(vm, args, nargs, NJS_OBJECT_EVAL_ERROR);
+}
+
+
+static const njs_object_prop_t njs_eval_error_constructor_properties[] =
+{
+ /* EvalError.name == "EvalError". */
+ {
+ .type = NJS_PROPERTY,
+ .name = njs_string("name"),
+ .value = njs_string("EvalError"),
+ },
+
+ /* EvalError.length == 1. */
+ {
+ .type = NJS_PROPERTY,
+ .name = njs_string("length"),
+ .value = njs_value(NJS_NUMBER, 1, 1.0),
+ },
+
+ /* EvalError.prototype. */
+ {
+ .type = NJS_NATIVE_GETTER,
+ .name = njs_string("prototype"),
+ .value = njs_native_getter(njs_object_prototype_create),
+ },
+};
+
+
+const njs_object_init_t njs_eval_error_constructor_init = {
+ nxt_string("EvalError"),
+ njs_eval_error_constructor_properties,
+ nxt_nitems(njs_eval_error_constructor_properties),
+};
+
+
+njs_ret_t
+njs_internal_error_constructor(njs_vm_t *vm, njs_value_t *args,
+ nxt_uint_t nargs, njs_index_t unused)
+{
+ return njs_error_create(vm, args, nargs, NJS_OBJECT_INTERNAL_ERROR);
+}
+
+
+static const njs_object_prop_t njs_internal_error_constructor_properties[] =
+{
+ /* InternalError.name == "InternalError". */
+ {
+ .type = NJS_PROPERTY,
+ .name = njs_string("name"),
+ .value = njs_string("InternalError"),
+ },
+
+ /* InternalError.length == 1. */
+ {
+ .type = NJS_PROPERTY,
+ .name = njs_string("length"),
+ .value = njs_value(NJS_NUMBER, 1, 1.0),
+ },
+
+ /* InternalError.prototype. */
+ {
+ .type = NJS_NATIVE_GETTER,
+ .name = njs_string("prototype"),
+ .value = njs_native_getter(njs_object_prototype_create),
+ },
+};
+
+
+const njs_object_init_t njs_internal_error_constructor_init = {
+ nxt_string("InternalError"),
+ njs_internal_error_constructor_properties,
+ nxt_nitems(njs_internal_error_constructor_properties),
+};
+
+
+njs_ret_t
+njs_range_error_constructor(njs_vm_t *vm, njs_value_t *args,
+ nxt_uint_t nargs, njs_index_t unused)
+{
+ return njs_error_create(vm, args, nargs, NJS_OBJECT_RANGE_ERROR);
+}
+
+
+static const njs_object_prop_t njs_range_error_constructor_properties[] =
+{
+ /* RangeError.name == "RangeError". */
+ {
+ .type = NJS_PROPERTY,
+ .name = njs_string("name"),
+ .value = njs_string("RangeError"),
+ },
+
+ /* RangeError.length == 1. */
+ {
+ .type = NJS_PROPERTY,
+ .name = njs_string("length"),
+ .value = njs_value(NJS_NUMBER, 1, 1.0),
+ },
+
+ /* RangeError.prototype. */
+ {
+ .type = NJS_NATIVE_GETTER,
+ .name = njs_string("prototype"),
+ .value = njs_native_getter(njs_object_prototype_create),
+ },
+};
+
+
+const njs_object_init_t njs_range_error_constructor_init = {
+ nxt_string("RangeError"),
+ njs_range_error_constructor_properties,
+ nxt_nitems(njs_range_error_constructor_properties),
+};
+
+
+njs_ret_t
+njs_ref_error_constructor(njs_vm_t *vm, njs_value_t *args,
+ nxt_uint_t nargs, njs_index_t unused)
+{
+ return njs_error_create(vm, args, nargs, NJS_OBJECT_REF_ERROR);
+}
+
+
+static const njs_object_prop_t njs_ref_error_constructor_properties[] =
+{
+ /* ReferenceError.name == "ReferenceError". */
+ {
+ .type = NJS_PROPERTY,
+ .name = njs_string("name"),
+ .value = njs_string("ReferenceError"),
+ },
+
+ /* ReferenceError.length == 1. */
+ {
+ .type = NJS_PROPERTY,
+ .name = njs_string("length"),
+ .value = njs_value(NJS_NUMBER, 1, 1.0),
+ },
+
+ /* ReferenceError.prototype. */
+ {
+ .type = NJS_NATIVE_GETTER,
+ .name = njs_string("prototype"),
+ .value = njs_native_getter(njs_object_prototype_create),
+ },
+};
+
+
+const njs_object_init_t njs_ref_error_constructor_init = {
+ nxt_string("ReferenceError"),
+ njs_ref_error_constructor_properties,
+ nxt_nitems(njs_ref_error_constructor_properties),
+};
+
+
+njs_ret_t
+njs_syntax_error_constructor(njs_vm_t *vm, njs_value_t *args,
+ nxt_uint_t nargs, njs_index_t unused)
+{
+ return njs_error_create(vm, args, nargs, NJS_OBJECT_SYNTAX_ERROR);
+}
+
+
+static const njs_object_prop_t njs_syntax_error_constructor_properties[] =
+{
+ /* SyntaxError.name == "SyntaxError". */
+ {
+ .type = NJS_PROPERTY,
+ .name = njs_string("name"),
+ .value = njs_string("SyntaxError"),
+ },
+
+ /* SyntaxError.length == 1. */
+ {
+ .type = NJS_PROPERTY,
+ .name = njs_string("length"),
+ .value = njs_value(NJS_NUMBER, 1, 1.0),
+ },
+
+ /* SyntaxError.prototype. */
+ {
+ .type = NJS_NATIVE_GETTER,
+ .name = njs_string("prototype"),
+ .value = njs_native_getter(njs_object_prototype_create),
+ },
+};
+
+
+const njs_object_init_t njs_syntax_error_constructor_init = {
+ nxt_string("SyntaxError"),
+ njs_syntax_error_constructor_properties,
+ nxt_nitems(njs_syntax_error_constructor_properties),
+};
+
+
+njs_ret_t
+njs_type_error_constructor(njs_vm_t *vm, njs_value_t *args,
+ nxt_uint_t nargs, njs_index_t unused)
+{
+ return njs_error_create(vm, args, nargs, NJS_OBJECT_TYPE_ERROR);
+}
+
+
+static const njs_object_prop_t njs_type_error_constructor_properties[] =
+{
+ /* TypeError.name == "TypeError". */
+ {
+ .type = NJS_PROPERTY,
+ .name = njs_string("name"),
+ .value = njs_string("TypeError"),
+ },
+
+ /* TypeError.length == 1. */
+ {
+ .type = NJS_PROPERTY,
+ .name = njs_string("length"),
+ .value = njs_value(NJS_NUMBER, 1, 1.0),
+ },
+
+ /* TypeError.prototype. */
+ {
+ .type = NJS_NATIVE_GETTER,
+ .name = njs_string("prototype"),
+ .value = njs_native_getter(njs_object_prototype_create),
+ },
+};
+
+
+const njs_object_init_t njs_type_error_constructor_init = {
+ nxt_string("TypeError"),
+ njs_type_error_constructor_properties,
+ nxt_nitems(njs_type_error_constructor_properties),
+};
+
+
+njs_ret_t
+njs_uri_error_constructor(njs_vm_t *vm, njs_value_t *args,
+ nxt_uint_t nargs, njs_index_t unused)
+{
+ return njs_error_create(vm, args, nargs, NJS_OBJECT_URI_ERROR);
+}
+
+
+static const njs_object_prop_t njs_uri_error_constructor_properties[] =
+{
+ /* URIError.name == "URIError". */
+ {
+ .type = NJS_PROPERTY,
+ .name = njs_string("name"),
+ .value = njs_string("URIError"),
+ },
+
+ /* URIError.length == 1. */
+ {
+ .type = NJS_PROPERTY,
+ .name = njs_string("length"),
+ .value = njs_value(NJS_NUMBER, 1, 1.0),
+ },
+
+ /* URIError.prototype. */
+ {
+ .type = NJS_NATIVE_GETTER,
+ .name = njs_string("prototype"),
+ .value = njs_native_getter(njs_object_prototype_create),
+ },
+};
+
+
+const njs_object_init_t njs_uri_error_constructor_init = {
+ nxt_string("URIError"),
+ njs_uri_error_constructor_properties,
+ nxt_nitems(njs_uri_error_constructor_properties),
+};
+
+
+static void
+njs_init_memory_error(njs_vm_t *vm)
+{
+ njs_value_t *value;
+ njs_object_t *object;
+ njs_object_prototype_t *prototypes;
+
+ prototypes = vm->prototypes;
+ object = &vm->memory_error_object;
+
+ nxt_lvlhsh_init(&object->hash);
+ nxt_lvlhsh_init(&object->shared_hash);
+ object->__proto__ = &prototypes[NJS_PROTOTYPE_MEMORY_ERROR].object;
+ object->type = NJS_OBJECT_INTERNAL_ERROR;
+ object->shared = 1;
+
+ /*
+ * Marking it nonextensible to differentiate
+ * it from ordinary internal errors.
+ */
+ object->extensible = 0;
+
+ value = &vm->memory_error;
+
+ value->data.type = NJS_OBJECT_INTERNAL_ERROR;
+ value->data.truth = 1;
+ value->data.u.number = NAN;
+ value->data.u.object = object;
+}
+
+
+void
+njs_exception_memory_error(njs_vm_t *vm)
+{
+ njs_init_memory_error(vm);
+
+ vm->exception = &vm->memory_error;
+}
+
+
+njs_ret_t
+njs_memory_error_constructor(njs_vm_t *vm, njs_value_t *args,
+ nxt_uint_t nargs, njs_index_t unused)
+{
+ njs_init_memory_error(vm);
+
+ vm->retval = vm->memory_error;
+
+ return NXT_OK;
+}
+
+
+static const njs_object_prop_t njs_memory_error_constructor_properties[] =
+{
+ /* MemoryError.name == "MemoryError". */
+ {
+ .type = NJS_PROPERTY,
+ .name = njs_string("name"),
+ .value = njs_string("MemoryError"),
+ },
+
+ /* MemoryError.length == 1. */
+ {
+ .type = NJS_PROPERTY,
+ .name = njs_string("length"),
+ .value = njs_value(NJS_NUMBER, 1, 1.0),
+ },
+
+ /* MemoryError.prototype. */
+ {
+ .type = NJS_NATIVE_GETTER,
+ .name = njs_string("prototype"),
+ .value = njs_native_getter(njs_object_prototype_create),
+ },
+};
+
+
+const njs_object_init_t njs_memory_error_constructor_init = {
+ nxt_string("MemoryError"),
+ njs_memory_error_constructor_properties,
+ nxt_nitems(njs_memory_error_constructor_properties),
+};
+
+
+static njs_ret_t
+njs_error_prototype_value_of(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs,
+ njs_index_t unused)
+{
+ vm->retval = args[0];
+
+ return NXT_OK;
+}
+
+
+static njs_ret_t
+njs_error_prototype_to_string(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs,
+ njs_index_t unused)
+{
+ size_t size;
+ u_char *p;
+ nxt_str_t name, message;
+ const njs_value_t *name_value, *message_value;
+ njs_object_prop_t *prop;
+ nxt_lvlhsh_query_t lhq;
+
+ static const njs_value_t default_name = njs_string("Error");
+
+ if (nargs < 1 || !njs_is_object(&args[0])) {
+ njs_exception_type_error(vm, NULL, NULL);
+ return NXT_ERROR;
+ }
+
+ lhq.key_hash = NJS_NAME_HASH;
+ lhq.key = nxt_string_value("name");
+ lhq.proto = &njs_object_hash_proto;
+
+ prop = njs_object_property(vm, args[0].data.u.object, &lhq);
+
+ if (prop != NULL) {
+ name_value = &prop->value;
+
+ } else {
+ name_value = &default_name;
+ }
+
+ njs_string_get(name_value, &name);
+
+ lhq.key_hash = NJS_MESSAGE_HASH;
+ lhq.key = nxt_string_value("message");
+
+ prop = njs_object_property(vm, args[0].data.u.object, &lhq);
+
+ if (prop != NULL) {
+ message_value = &prop->value;
+
+ } else {
+ message_value = &njs_string_empty;
+ }
+
+ njs_string_get(message_value, &message);
+
+ if (name.length == 0) {
+ vm->retval = *message_value;
+ return NJS_OK;
+ }
+
+ if (message.length == 0) {
+ vm->retval = *name_value;
+ return NJS_OK;
+ }
+
+ size = name.length + message.length + 2;
+
+ p = njs_string_alloc(vm, &vm->retval, size, size);
+
+ if (nxt_fast_path(p != NULL)) {
+ p = nxt_cpymem(p, name.start, name.length);
+ *p++ = ':';
+ *p++ = ' ';
+ memcpy(p, message.start, message.length);
+
+ return NJS_OK;
+ }
+
+ njs_exception_memory_error(vm);
+ return NJS_ERROR;
+}
+
+
+static const njs_object_prop_t njs_error_prototype_properties[] =
+{
+ {
+ .type = NJS_PROPERTY,
+ .name = njs_string("name"),
+ .value = njs_string("Error"),
+ },
+
+ {
+ .type = NJS_PROPERTY,
+ .name = njs_string("message"),
+ .value = njs_string(""),
+ },
+
+ {
+ .type = NJS_METHOD,
+ .name = njs_string("valueOf"),
+ .value = njs_native_function(njs_error_prototype_value_of, 0, 0),
+ },
+
+ {
+ .type = NJS_METHOD,
+ .name = njs_string("toString"),
+ .value = njs_native_function(njs_error_prototype_to_string, 0, 0),
+ },
+};
+
+
+const njs_object_init_t njs_error_prototype_init = {
+ nxt_string("Error"),
+ njs_error_prototype_properties,
+ nxt_nitems(njs_error_prototype_properties),
+};
+
+
+static const njs_object_prop_t njs_eval_error_prototype_properties[] =
+{
More information about the nginx-devel
mailing list