[njs] Added njs_vm_external_constructor().
Dmitry Volyntsev
xeioex at nginx.com
Mon Jul 3 20:34:11 UTC 2023
details: https://hg.nginx.org/njs/rev/167f75576f49
branches:
changeset: 2175:167f75576f49
user: Dmitry Volyntsev <xeioex at nginx.com>
date: Mon Jul 03 12:49:00 2023 -0700
description:
Added njs_vm_external_constructor().
The new API allows to add new constructor/prototype pairs.
diffstat:
external/njs_crypto_module.c | 1 +
external/njs_fs_module.c | 1 +
external/njs_query_string_module.c | 1 +
external/njs_shell.c | 1 +
external/njs_webcrypto_module.c | 1 +
external/njs_xml_module.c | 1 +
external/njs_zlib_module.c | 1 +
nginx/ngx_http_js_module.c | 1 +
nginx/ngx_js.c | 1 +
nginx/ngx_js_fetch.c | 1 +
nginx/ngx_stream_js_module.c | 1 +
src/njs.h | 18 ++-
src/njs_array.c | 2 +-
src/njs_array_buffer.c | 2 +-
src/njs_async.c | 2 +-
src/njs_buffer.c | 13 +-
src/njs_builtin.c | 127 ++++----------------
src/njs_date.c | 2 +-
src/njs_error.c | 16 +-
src/njs_extern.c | 71 +++++++++++
src/njs_function.c | 10 +-
src/njs_json.c | 2 +-
src/njs_object.c | 16 +-
src/njs_parser.c | 6 +-
src/njs_promise.c | 12 +-
src/njs_regexp.c | 8 +-
src/njs_typed_array.c | 6 +-
src/njs_value.c | 2 +-
src/njs_value.h | 5 +-
src/njs_vm.c | 224 ++++++++++++++++++++++++++++++++++--
src/njs_vm.h | 34 ++--
src/njs_vmcode.c | 2 +-
src/test/njs_externals_test.c | 113 ++++++++++++++++++-
src/test/njs_unit_test.c | 44 +++++++-
34 files changed, 561 insertions(+), 187 deletions(-)
diffs (truncated from 1548 to 1000 lines):
diff -r 3386684745b7 -r 167f75576f49 external/njs_crypto_module.c
--- a/external/njs_crypto_module.c Fri Jun 30 21:02:44 2023 -0700
+++ b/external/njs_crypto_module.c Mon Jul 03 12:49:00 2023 -0700
@@ -287,6 +287,7 @@ static njs_int_t njs_crypto_hmac_prot
njs_module_t njs_crypto_module = {
.name = njs_str("crypto"),
+ .preinit = NULL,
.init = njs_crypto_init,
};
diff -r 3386684745b7 -r 167f75576f49 external/njs_fs_module.c
--- a/external/njs_fs_module.c Fri Jun 30 21:02:44 2023 -0700
+++ b/external/njs_fs_module.c Mon Jul 03 12:49:00 2023 -0700
@@ -1407,6 +1407,7 @@ static njs_int_t njs_fs_bytes_written
njs_module_t njs_fs_module = {
.name = njs_str("fs"),
+ .preinit = NULL,
.init = njs_fs_init,
};
diff -r 3386684745b7 -r 167f75576f49 external/njs_query_string_module.c
--- a/external/njs_query_string_module.c Fri Jun 30 21:02:44 2023 -0700
+++ b/external/njs_query_string_module.c Mon Jul 03 12:49:00 2023 -0700
@@ -105,6 +105,7 @@ static njs_external_t njs_ext_query_str
njs_module_t njs_query_string_module = {
.name = njs_str("querystring"),
+ .preinit = NULL,
.init = njs_query_string_init,
};
diff -r 3386684745b7 -r 167f75576f49 external/njs_shell.c
--- a/external/njs_shell.c Fri Jun 30 21:02:44 2023 -0700
+++ b/external/njs_shell.c Mon Jul 03 12:49:00 2023 -0700
@@ -254,6 +254,7 @@ static njs_vm_ops_t njs_console_ops = {
njs_module_t njs_console_module = {
.name = njs_str("console"),
+ .preinit = NULL,
.init = njs_externals_init,
};
diff -r 3386684745b7 -r 167f75576f49 external/njs_webcrypto_module.c
--- a/external/njs_webcrypto_module.c Fri Jun 30 21:02:44 2023 -0700
+++ b/external/njs_webcrypto_module.c Mon Jul 03 12:49:00 2023 -0700
@@ -659,6 +659,7 @@ static njs_external_t njs_ext_webcrypto
njs_module_t njs_webcrypto_module = {
.name = njs_str("webcrypto"),
+ .preinit = NULL,
.init = njs_webcrypto_init,
};
diff -r 3386684745b7 -r 167f75576f49 external/njs_xml_module.c
--- a/external/njs_xml_module.c Fri Jun 30 21:02:44 2023 -0700
+++ b/external/njs_xml_module.c Mon Jul 03 12:49:00 2023 -0700
@@ -402,6 +402,7 @@ static njs_external_t njs_ext_xml_attr[
njs_module_t njs_xml_module = {
.name = njs_str("xml"),
+ .preinit = NULL,
.init = njs_xml_init,
};
diff -r 3386684745b7 -r 167f75576f49 external/njs_zlib_module.c
--- a/external/njs_zlib_module.c Fri Jun 30 21:02:44 2023 -0700
+++ b/external/njs_zlib_module.c Mon Jul 03 12:49:00 2023 -0700
@@ -176,6 +176,7 @@ static njs_external_t njs_ext_zlib[] =
njs_module_t njs_zlib_module = {
.name = njs_str("zlib"),
+ .preinit = NULL,
.init = njs_zlib_init,
};
diff -r 3386684745b7 -r 167f75576f49 nginx/ngx_http_js_module.c
--- a/nginx/ngx_http_js_module.c Fri Jun 30 21:02:44 2023 -0700
+++ b/nginx/ngx_http_js_module.c Mon Jul 03 12:49:00 2023 -0700
@@ -786,6 +786,7 @@ static njs_vm_meta_t ngx_http_js_metas =
njs_module_t ngx_js_http_module = {
.name = njs_str("http"),
+ .preinit = NULL,
.init = ngx_js_http_init,
};
diff -r 3386684745b7 -r 167f75576f49 nginx/ngx_js.c
--- a/nginx/ngx_js.c Fri Jun 30 21:02:44 2023 -0700
+++ b/nginx/ngx_js.c Mon Jul 03 12:49:00 2023 -0700
@@ -165,6 +165,7 @@ static njs_external_t ngx_js_ext_core[]
njs_module_t ngx_js_ngx_module = {
.name = njs_str("ngx"),
+ .preinit = NULL,
.init = ngx_js_core_init,
};
diff -r 3386684745b7 -r 167f75576f49 nginx/ngx_js_fetch.c
--- a/nginx/ngx_js_fetch.c Fri Jun 30 21:02:44 2023 -0700
+++ b/nginx/ngx_js_fetch.c Mon Jul 03 12:49:00 2023 -0700
@@ -656,6 +656,7 @@ static njs_int_t ngx_http_js_fetch_he
njs_module_t ngx_js_fetch_module = {
.name = njs_str("fetch"),
+ .preinit = NULL,
.init = ngx_js_fetch_init,
};
diff -r 3386684745b7 -r 167f75576f49 nginx/ngx_stream_js_module.c
--- a/nginx/ngx_stream_js_module.c Fri Jun 30 21:02:44 2023 -0700
+++ b/nginx/ngx_stream_js_module.c Mon Jul 03 12:49:00 2023 -0700
@@ -568,6 +568,7 @@ static njs_int_t ngx_stream_js_sessio
njs_module_t ngx_js_stream_module = {
.name = njs_str("stream"),
+ .preinit = NULL,
.init = ngx_js_stream_init,
};
diff -r 3386684745b7 -r 167f75576f49 src/njs.h
--- a/src/njs.h Fri Jun 30 21:02:44 2023 -0700
+++ b/src/njs.h Mon Jul 03 12:49:00 2023 -0700
@@ -257,6 +257,7 @@ typedef njs_int_t (*njs_addon_init_pt)(n
typedef struct {
njs_str_t name;
+ njs_addon_init_pt preinit;
njs_addon_init_pt init;
} njs_module_t;
@@ -403,6 +404,10 @@ NJS_EXPORT njs_int_t njs_vm_add_path(njs
NJS_EXPORT njs_int_t njs_vm_external_prototype(njs_vm_t *vm,
const njs_external_t *definition, njs_uint_t n);
+NJS_EXPORT njs_int_t njs_vm_external_constructor(njs_vm_t *vm,
+ const njs_str_t *name, njs_function_native_t native,
+ const njs_external_t *ctor_props, njs_uint_t ctor_nprops,
+ const njs_external_t *proto_props, njs_uint_t proto_nprops);
NJS_EXPORT njs_int_t njs_vm_external_create(njs_vm_t *vm, njs_value_t *value,
njs_int_t proto_id, njs_external_ptr_t external, njs_bool_t shared);
NJS_EXPORT njs_external_ptr_t njs_vm_external(njs_vm_t *vm,
@@ -417,6 +422,15 @@ NJS_EXPORT njs_int_t njs_value_property_
NJS_EXPORT uintptr_t njs_vm_meta(njs_vm_t *vm, njs_uint_t index);
NJS_EXPORT njs_vm_opt_t *njs_vm_options(njs_vm_t *vm);
+NJS_EXPORT njs_int_t njs_error_constructor(njs_vm_t *vm, njs_value_t *args,
+ njs_uint_t nargs, njs_index_t type, njs_value_t *retval);
+NJS_EXPORT njs_int_t njs_object_prototype_create_constructor(njs_vm_t *vm,
+ njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval,
+ njs_value_t *retval);
+NJS_EXPORT njs_int_t njs_object_prototype_create(njs_vm_t *vm,
+ njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval,
+ njs_value_t *retval);
+
NJS_EXPORT njs_function_t *njs_vm_function_alloc(njs_vm_t *vm,
njs_function_native_t native, njs_bool_t shared, njs_bool_t ctor);
@@ -433,7 +447,9 @@ NJS_EXPORT njs_function_t *njs_vm_functi
NJS_EXPORT njs_bool_t njs_vm_constructor(njs_vm_t *vm);
NJS_EXPORT void njs_vm_throw(njs_vm_t *vm, const njs_value_t *value);
-NJS_EXPORT void njs_vm_error2(njs_vm_t *vm, unsigned type, const char *fmt,
+NJS_EXPORT void njs_vm_error2(njs_vm_t *vm, unsigned error_type,
+ const char *fmt, ...);
+NJS_EXPORT void njs_vm_error3(njs_vm_t *vm, unsigned type, const char *fmt,
...);
NJS_EXPORT void njs_vm_exception_get(njs_vm_t *vm, njs_value_t *retval);
NJS_EXPORT njs_mp_t *njs_vm_memory_pool(njs_vm_t *vm);
diff -r 3386684745b7 -r 167f75576f49 src/njs_array.c
--- a/src/njs_array.c Fri Jun 30 21:02:44 2023 -0700
+++ b/src/njs_array.c Mon Jul 03 12:49:00 2023 -0700
@@ -83,7 +83,7 @@ njs_array_alloc(njs_vm_t *vm, njs_bool_t
array->start = array->data;
njs_lvlhsh_init(&array->object.hash);
array->object.shared_hash = vm->shared->array_instance_hash;
- array->object.__proto__ = &vm->prototypes[NJS_OBJ_TYPE_ARRAY].object;
+ array->object.__proto__ = njs_vm_proto(vm, NJS_OBJ_TYPE_ARRAY);
array->object.slots = NULL;
array->object.type = NJS_ARRAY;
array->object.shared = 0;
diff -r 3386684745b7 -r 167f75576f49 src/njs_array_buffer.c
--- a/src/njs_array_buffer.c Fri Jun 30 21:02:44 2023 -0700
+++ b/src/njs_array_buffer.c Mon Jul 03 12:49:00 2023 -0700
@@ -33,7 +33,7 @@ njs_array_buffer_alloc(njs_vm_t *vm, uin
goto memory_error;
}
- proto = &vm->prototypes[NJS_OBJ_TYPE_ARRAY_BUFFER].object;
+ proto = njs_vm_proto(vm, NJS_OBJ_TYPE_ARRAY_BUFFER);
njs_lvlhsh_init(&array->object.hash);
njs_lvlhsh_init(&array->object.shared_hash);
diff -r 3386684745b7 -r 167f75576f49 src/njs_async.c
--- a/src/njs_async.c Fri Jun 30 21:02:44 2023 -0700
+++ b/src/njs_async.c Mon Jul 03 12:49:00 2023 -0700
@@ -18,7 +18,7 @@ njs_async_function_frame_invoke(njs_vm_t
njs_value_t ctor;
njs_promise_capability_t *capability;
- njs_set_function(&ctor, &vm->constructors[NJS_OBJ_TYPE_PROMISE]);
+ njs_set_function(&ctor, &njs_vm_ctor(vm, NJS_OBJ_TYPE_PROMISE));
capability = njs_promise_new_capability(vm, &ctor);
if (njs_slow_path(capability == NULL)) {
diff -r 3386684745b7 -r 167f75576f49 src/njs_buffer.c
--- a/src/njs_buffer.c Fri Jun 30 21:02:44 2023 -0700
+++ b/src/njs_buffer.c Mon Jul 03 12:49:00 2023 -0700
@@ -126,6 +126,7 @@ static njs_external_t njs_ext_buffer[]
njs_module_t njs_buffer_module = {
.name = njs_str("buffer"),
+ .preinit = NULL,
.init = njs_buffer_init,
};
@@ -147,7 +148,7 @@ njs_buffer_set(njs_vm_t *vm, njs_value_t
buffer = (njs_array_buffer_t *) &array[1];
- proto = &vm->prototypes[NJS_OBJ_TYPE_ARRAY_BUFFER].object;
+ proto = njs_vm_proto(vm, NJS_OBJ_TYPE_ARRAY_BUFFER);
njs_lvlhsh_init(&buffer->object.hash);
njs_lvlhsh_init(&buffer->object.shared_hash);
@@ -161,7 +162,7 @@ njs_buffer_set(njs_vm_t *vm, njs_value_t
buffer->u.data = (void *) start;
buffer->size = size;
- proto = &vm->prototypes[NJS_OBJ_TYPE_BUFFER].object;
+ proto = njs_vm_proto(vm, NJS_OBJ_TYPE_BUFFER);
array->type = NJS_OBJ_TYPE_UINT8_ARRAY;
njs_lvlhsh_init(&array->object.hash);
@@ -197,7 +198,7 @@ njs_buffer_alloc(njs_vm_t *vm, size_t si
return NULL;
}
- array->object.__proto__ = &vm->prototypes[NJS_OBJ_TYPE_BUFFER].object;
+ array->object.__proto__ = njs_vm_proto(vm, NJS_OBJ_TYPE_BUFFER);
return array;
}
@@ -462,7 +463,7 @@ njs_buffer_from_array_buffer(njs_vm_t *v
return NJS_ERROR;
}
- buffer->object.__proto__ = &vm->prototypes[NJS_OBJ_TYPE_BUFFER].object;
+ buffer->object.__proto__ = njs_vm_proto(vm, NJS_OBJ_TYPE_BUFFER);
buffer->offset = off;
buffer->byte_length = len;
@@ -943,7 +944,7 @@ njs_buffer_is_buffer(njs_vm_t *vm, njs_v
array = njs_buffer_slot_internal(vm, njs_arg(args, nargs, 1));
if (njs_fast_path(array != NULL && array->object.__proto__
- == &vm->prototypes[NJS_OBJ_TYPE_BUFFER].object))
+ == njs_vm_proto(vm, NJS_OBJ_TYPE_BUFFER)))
{
is = 1;
}
@@ -2184,7 +2185,7 @@ njs_buffer_prototype_slice(njs_vm_t *vm,
}
array = njs_typed_array(retval);
- array->object.__proto__ = &vm->prototypes[NJS_OBJ_TYPE_BUFFER].object;
+ array->object.__proto__ = njs_vm_proto(vm, NJS_OBJ_TYPE_BUFFER);
return NJS_OK;
}
diff -r 3386684745b7 -r 167f75576f49 src/njs_builtin.c
--- a/src/njs_builtin.c Fri Jun 30 21:02:44 2023 -0700
+++ b/src/njs_builtin.c Mon Jul 03 12:49:00 2023 -0700
@@ -115,7 +115,7 @@ njs_object_hash_init(njs_vm_t *vm, njs_l
njs_int_t
njs_builtin_objects_create(njs_vm_t *vm)
{
- njs_int_t ret;
+ njs_int_t ret, index;
njs_uint_t i;
njs_object_t *object, *string_object;
njs_function_t *constructor;
@@ -129,6 +129,8 @@ njs_builtin_objects_create(njs_vm_t *vm)
return NJS_ERROR;
}
+ vm->shared = shared;
+
njs_lvlhsh_init(&shared->keywords_hash);
njs_lvlhsh_init(&shared->values_hash);
@@ -204,34 +206,42 @@ njs_builtin_objects_create(njs_vm_t *vm)
return NJS_ERROR;
}
- prototype = shared->prototypes;
+ for (i = NJS_OBJ_TYPE_OBJECT; i < NJS_OBJ_TYPE_MAX; i++) {
+ index = njs_vm_ctor_push(vm);
+ if (njs_slow_path(index < 0)) {
+ return NJS_ERROR;
+ }
- for (i = NJS_OBJ_TYPE_OBJECT; i < NJS_OBJ_TYPE_MAX; i++) {
- prototype[i] = njs_object_type_init[i]->prototype_value;
+ njs_assert_msg((njs_uint_t) index == i,
+ "ctor index should match object type");
- ret = njs_object_hash_init(vm, &prototype[i].object.shared_hash,
+ prototype = njs_shared_prototype(shared, i);
+ *prototype = njs_object_type_init[i]->prototype_value;
+
+ ret = njs_object_hash_init(vm, &prototype->object.shared_hash,
njs_object_type_init[i]->prototype_props);
if (njs_slow_path(ret != NJS_OK)) {
return NJS_ERROR;
}
- prototype[i].object.extensible = 1;
+ prototype->object.extensible = 1;
}
- shared->prototypes[NJS_OBJ_TYPE_REGEXP].regexp.pattern =
- shared->empty_regexp_pattern;
-
- constructor = shared->constructors;
+ prototype = njs_shared_prototype(shared, NJS_OBJ_TYPE_REGEXP);
+ prototype->regexp.pattern = shared->empty_regexp_pattern;
for (i = NJS_OBJ_TYPE_OBJECT; i < NJS_OBJ_TYPE_MAX; i++) {
+ constructor = njs_shared_ctor(shared, i);
+
if (njs_object_type_init[i]->constructor_props == NULL) {
+ njs_memzero(constructor, sizeof(njs_function_t));
continue;
}
- constructor[i] = njs_object_type_init[i]->constructor;
- constructor[i].object.shared = 0;
+ *constructor = njs_object_type_init[i]->constructor;
+ constructor->object.shared = 0;
- ret = njs_object_hash_init(vm, &constructor[i].object.shared_hash,
+ ret = njs_object_hash_init(vm, &constructor->object.shared_hash,
njs_object_type_init[i]->constructor_props);
if (njs_slow_path(ret != NJS_OK)) {
return NJS_ERROR;
@@ -259,91 +269,6 @@ njs_builtin_objects_create(njs_vm_t *vm)
njs_lvlhsh_init(&shared->modules_hash);
- vm->shared = shared;
-
- return NJS_OK;
-}
-
-
-njs_int_t
-njs_builtin_objects_clone(njs_vm_t *vm, njs_value_t *global)
-{
- size_t size;
- njs_uint_t i;
- njs_object_t *object_prototype, *function_prototype,
- *typed_array_prototype, *error_prototype, *async_prototype,
- *typed_array_ctor, *error_ctor;
-
- /*
- * Copy both prototypes and constructors arrays by one memcpy()
- * because they are stored together.
- */
- size = (sizeof(njs_object_prototype_t) + sizeof(njs_function_t))
- * NJS_OBJ_TYPE_MAX;
-
- memcpy(vm->prototypes, vm->shared->prototypes, size);
-
- object_prototype = &vm->prototypes[NJS_OBJ_TYPE_OBJECT].object;
-
- for (i = NJS_OBJ_TYPE_ARRAY; i < NJS_OBJ_TYPE_NORMAL_MAX; i++) {
- vm->prototypes[i].object.__proto__ = object_prototype;
- }
-
- typed_array_prototype = &vm->prototypes[NJS_OBJ_TYPE_TYPED_ARRAY].object;
-
- for (i = NJS_OBJ_TYPE_TYPED_ARRAY_MIN;
- i < NJS_OBJ_TYPE_TYPED_ARRAY_MAX;
- i++)
- {
- vm->prototypes[i].object.__proto__ = typed_array_prototype;
- }
-
- vm->prototypes[NJS_OBJ_TYPE_ARRAY_ITERATOR].object.__proto__ =
- &vm->prototypes[NJS_OBJ_TYPE_ITERATOR].object;
-
- vm->prototypes[NJS_OBJ_TYPE_BUFFER].object.__proto__ =
- &vm->prototypes[NJS_OBJ_TYPE_UINT8_ARRAY].object;
-
- error_prototype = &vm->prototypes[NJS_OBJ_TYPE_ERROR].object;
- error_prototype->__proto__ = object_prototype;
-
- for (i = NJS_OBJ_TYPE_EVAL_ERROR; i < NJS_OBJ_TYPE_MAX; i++) {
- vm->prototypes[i].object.__proto__ = error_prototype;
- }
-
- function_prototype = &vm->prototypes[NJS_OBJ_TYPE_FUNCTION].object;
-
- async_prototype = &vm->prototypes[NJS_OBJ_TYPE_ASYNC_FUNCTION].object;
- async_prototype->__proto__ = function_prototype;
-
- for (i = NJS_OBJ_TYPE_OBJECT; i < NJS_OBJ_TYPE_NORMAL_MAX; i++) {
- vm->constructors[i].object.__proto__ = function_prototype;
- }
-
- typed_array_ctor = &vm->constructors[NJS_OBJ_TYPE_TYPED_ARRAY].object;
-
- for (i = NJS_OBJ_TYPE_TYPED_ARRAY_MIN;
- i < NJS_OBJ_TYPE_TYPED_ARRAY_MAX;
- i++)
- {
- vm->constructors[i].object.__proto__ = typed_array_ctor;
- }
-
- error_ctor = &vm->constructors[NJS_OBJ_TYPE_ERROR].object;
- error_ctor->__proto__ = function_prototype;
-
- for (i = NJS_OBJ_TYPE_EVAL_ERROR; i < NJS_OBJ_TYPE_MAX; i++) {
- vm->constructors[i].object.__proto__ = error_ctor;
- }
-
- vm->global_object.__proto__ = object_prototype;
-
- njs_set_undefined(global);
- njs_set_object(global, &vm->global_object);
-
- vm->string_object = vm->shared->string_object;
- vm->string_object.__proto__ = &vm->prototypes[NJS_OBJ_TYPE_STRING].object;
-
return NJS_OK;
}
@@ -838,7 +763,7 @@ njs_builtin_match_native_function(njs_vm
/* Constructor from built-in modules (not-mapped to global object). */
for (i = NJS_OBJ_TYPE_HIDDEN_MIN; i < NJS_OBJ_TYPE_HIDDEN_MAX; i++) {
- njs_set_object(&value, &vm->constructors[i].object);
+ njs_set_object(&value, &njs_vm_ctor(vm, i).object);
ret = njs_value_property(vm, &value, njs_value_arg(&njs_string_name),
&tag);
@@ -847,7 +772,7 @@ njs_builtin_match_native_function(njs_vm
njs_string_get(&tag, &ctx.match);
}
- ret = njs_object_traverse(vm, &vm->constructors[i].object, &ctx,
+ ret = njs_object_traverse(vm, njs_object(&value), &ctx,
njs_builtin_traverse);
if (ret == NJS_DONE) {
@@ -1253,7 +1178,7 @@ njs_top_level_constructor(njs_vm_t *vm,
return NJS_DECLINED;
}
- ctor = &vm->constructors[njs_prop_magic16(self)];
+ ctor = &njs_vm_ctor(vm, njs_prop_magic16(self));
njs_set_function(retval, ctor);
}
diff -r 3386684745b7 -r 167f75576f49 src/njs_date.c
--- a/src/njs_date.c Fri Jun 30 21:02:44 2023 -0700
+++ b/src/njs_date.c Mon Jul 03 12:49:00 2023 -0700
@@ -364,7 +364,7 @@ njs_date_alloc(njs_vm_t *vm, double time
date->object.extensible = 1;
date->object.error_data = 0;
date->object.fast_array = 0;
- date->object.__proto__ = &vm->prototypes[NJS_OBJ_TYPE_DATE].object;
+ date->object.__proto__ = njs_vm_proto(vm, NJS_OBJ_TYPE_DATE);
date->object.slots = NULL;
date->time = time;
diff -r 3386684745b7 -r 167f75576f49 src/njs_error.c
--- a/src/njs_error.c Fri Jun 30 21:02:44 2023 -0700
+++ b/src/njs_error.c Mon Jul 03 12:49:00 2023 -0700
@@ -76,7 +76,7 @@ njs_throw_error(njs_vm_t *vm, njs_object
va_list args;
va_start(args, fmt);
- njs_throw_error_va(vm, &vm->prototypes[type].object, fmt, args);
+ njs_throw_error_va(vm, njs_vm_proto(vm, type), fmt, args);
va_end(args);
}
@@ -96,7 +96,7 @@ njs_error_fmt_new(njs_vm_t *vm, njs_valu
va_end(args);
}
- njs_error_new(vm, dst, &vm->prototypes[type].object, buf, p - buf);
+ njs_error_new(vm, dst, njs_vm_proto(vm, type), buf, p - buf);
}
@@ -298,7 +298,7 @@ memory_error:
}
-static njs_int_t
+njs_int_t
njs_error_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
njs_index_t type, njs_value_t *retval)
{
@@ -339,7 +339,7 @@ njs_error_constructor(njs_vm_t *vm, njs_
}
}
- error = njs_error_alloc(vm, &vm->prototypes[type].object, NULL,
+ error = njs_error_alloc(vm, njs_vm_proto(vm, type), NULL,
njs_is_defined(value) ? value : NULL,
njs_is_defined(&list) ? &list : NULL);
if (njs_slow_path(error == NULL)) {
@@ -499,15 +499,13 @@ const njs_object_init_t njs_aggregate_e
void
njs_memory_error_set(njs_vm_t *vm, njs_value_t *value)
{
- njs_object_t *object;
- njs_object_prototype_t *prototypes;
+ njs_object_t *object;
- prototypes = vm->prototypes;
object = &vm->memory_error_object;
njs_lvlhsh_init(&object->hash);
njs_lvlhsh_init(&object->shared_hash);
- object->__proto__ = &prototypes[NJS_OBJ_TYPE_INTERNAL_ERROR].object;
+ object->__proto__ = njs_vm_proto(vm, NJS_OBJ_TYPE_INTERNAL_ERROR);
object->slots = NULL;
object->type = NJS_OBJECT;
object->shared = 1;
@@ -555,7 +553,7 @@ njs_memory_error_prototype_create(njs_vm
function = njs_function(value);
proto = njs_property_prototype_create(vm, &function->object.hash,
- &vm->prototypes[index].object);
+ njs_vm_proto(vm, index));
if (proto == NULL) {
proto = &njs_value_undefined;
}
diff -r 3386684745b7 -r 167f75576f49 src/njs_extern.c
--- a/src/njs_extern.c Fri Jun 30 21:02:44 2023 -0700
+++ b/src/njs_extern.c Mon Jul 03 12:49:00 2023 -0700
@@ -315,6 +315,77 @@ njs_vm_external_prototype(njs_vm_t *vm,
}
+static njs_int_t
+njs_vm_external_constructor_handler(njs_vm_t *vm, njs_object_prop_t *prop,
+ njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
+{
+ njs_set_function(retval, &njs_vm_ctor(vm, njs_prop_magic32(prop)));
+
+ return NJS_OK;
+}
+
+
+njs_int_t
+njs_vm_external_constructor(njs_vm_t *vm, const njs_str_t *name,
+ njs_function_native_t native, const njs_external_t *ctor_props,
+ njs_uint_t ctor_nprops, const njs_external_t *proto_props,
+ njs_uint_t proto_nprops)
+{
+ njs_int_t ret, index, proto_id;
+ njs_arr_t **pprotos;
+ njs_function_t *constructor;
+ njs_exotic_slots_t *slots;
+ njs_object_prototype_t *prototype;
+
+ index = njs_vm_ctor_push(vm);
+ if (njs_slow_path(index < 0)) {
+ njs_internal_error(vm, "njs_vm_ctor_push() failed");
+ return -1;
+ }
+
+ proto_id = njs_vm_external_prototype(vm, proto_props, proto_nprops);
+ if (njs_slow_path(proto_id < 0)) {
+ njs_internal_error(vm, "njs_vm_external_prototype(proto_props) failed");
+ return -1;
+ }
+
+ prototype = njs_shared_prototype(vm->shared, index);
+ njs_memzero(prototype, sizeof(njs_object_prototype_t));
+ prototype->object.type = NJS_OBJECT;
+ prototype->object.extensible = 1;
+
+ pprotos = njs_arr_item(vm->protos, proto_id);
+ slots = (*pprotos)->start;
+ prototype->object.shared_hash = slots->external_shared_hash;
+
+ proto_id = njs_vm_external_prototype(vm, ctor_props, ctor_nprops);
+ if (njs_slow_path(proto_id < 0)) {
+ njs_internal_error(vm, "njs_vm_external_prototype(ctor_props) failed");
+ return -1;
+ }
+
+ constructor = njs_shared_ctor(vm->shared, index);
+ njs_memzero(constructor, sizeof(njs_function_t));
+ constructor->object.type = NJS_FUNCTION;
+ constructor->u.native = native;
+ constructor->magic8 = index;
+ constructor->native = 1;
+ constructor->ctor = 1;
+
+ pprotos = njs_arr_item(vm->protos, proto_id);
+ slots = (*pprotos)->start;
+ constructor->object.shared_hash = slots->external_shared_hash;
+
+ ret = njs_vm_bind_handler(vm, name, njs_vm_external_constructor_handler, 0,
+ index, 1);
+ if (njs_slow_path(ret != NJS_OK)) {
+ return NJS_ERROR;
+ }
+
+ return index;
+}
+
+
njs_int_t
njs_vm_external_create(njs_vm_t *vm, njs_value_t *value, njs_int_t proto_id,
njs_external_ptr_t external, njs_bool_t shared)
diff -r 3386684745b7 -r 167f75576f49 src/njs_function.c
--- a/src/njs_function.c Fri Jun 30 21:02:44 2023 -0700
+++ b/src/njs_function.c Mon Jul 03 12:49:00 2023 -0700
@@ -46,10 +46,10 @@ njs_function_alloc(njs_vm_t *vm, njs_fun
}
if (async) {
- proto = &vm->prototypes[NJS_OBJ_TYPE_ASYNC_FUNCTION].object;
+ proto = njs_vm_proto(vm, NJS_OBJ_TYPE_ASYNC_FUNCTION);
} else {
- proto = &vm->prototypes[NJS_OBJ_TYPE_FUNCTION].object;
+ proto = njs_vm_proto(vm, NJS_OBJ_TYPE_FUNCTION);
}
function->object.__proto__ = proto;
@@ -84,7 +84,7 @@ njs_vm_function_alloc(njs_vm_t *vm, njs_
function->object.shared = shared;
function->u.native = native;
function->object.shared_hash = vm->shared->function_instance_hash;
- function->object.__proto__ = &vm->prototypes[NJS_OBJ_TYPE_FUNCTION].object;
+ function->object.__proto__ = njs_vm_proto(vm, NJS_OBJ_TYPE_FUNCTION);
function->object.type = NJS_FUNCTION;
return function;
@@ -212,7 +212,7 @@ njs_function_copy(njs_vm_t *vm, njs_func
type = njs_function_object_type(vm, function);
- copy->object.__proto__ = &vm->prototypes[type].object;
+ copy->object.__proto__ = njs_vm_proto(vm, type);
copy->object.shared = 0;
if (copy->ctor) {
@@ -1370,7 +1370,7 @@ njs_function_prototype_bind(njs_vm_t *vm
/* Bound functions have no "prototype" property. */
function->object.shared_hash = vm->shared->arrow_instance_hash;
- function->object.__proto__ = &vm->prototypes[NJS_OBJ_TYPE_FUNCTION].object;
+ function->object.__proto__ = njs_vm_proto(vm, NJS_OBJ_TYPE_FUNCTION);
function->object.shared = 0;
function->context = njs_function(&args[0]);
diff -r 3386684745b7 -r 167f75576f49 src/njs_json.c
--- a/src/njs_json.c Fri Jun 30 21:02:44 2023 -0700
+++ b/src/njs_json.c Mon Jul 03 12:49:00 2023 -0700
@@ -1979,7 +1979,7 @@ njs_vm_value_dump(njs_vm_t *vm, njs_str_
if (njs_slow_path(vm->top_frame == NULL)) {
/* An exception was thrown during compilation. */
- njs_vm_init(vm);
+ njs_vm_runtime_init(vm);
}
if (njs_is_valid(&vm->exception)) {
diff -r 3386684745b7 -r 167f75576f49 src/njs_object.c
--- a/src/njs_object.c Fri Jun 30 21:02:44 2023 -0700
+++ b/src/njs_object.c Mon Jul 03 12:49:00 2023 -0700
@@ -45,7 +45,7 @@ njs_object_alloc(njs_vm_t *vm)
if (njs_fast_path(object != NULL)) {
njs_lvlhsh_init(&object->hash);
njs_lvlhsh_init(&object->shared_hash);
- object->__proto__ = &vm->prototypes[NJS_OBJ_TYPE_OBJECT].object;
+ object->__proto__ = njs_vm_proto(vm, NJS_OBJ_TYPE_OBJECT);
object->slots = NULL;
object->type = NJS_OBJECT;
object->shared = 0;
@@ -80,7 +80,7 @@ njs_object_value_copy(njs_vm_t *vm, njs_
if (njs_fast_path(object != NULL)) {
memcpy(object, njs_object(value), size);
- object->__proto__ = &vm->prototypes[NJS_OBJ_TYPE_OBJECT].object;
+ object->__proto__ = njs_vm_proto(vm, NJS_OBJ_TYPE_OBJECT);
object->shared = 0;
value->data.u.object = object;
return object;
@@ -119,7 +119,7 @@ njs_object_value_alloc(njs_vm_t *vm, njs
ov->object.error_data = 0;
ov->object.fast_array = 0;
- ov->object.__proto__ = &vm->prototypes[prototype_index].object;
+ ov->object.__proto__ = njs_vm_proto(vm, prototype_index);
ov->object.slots = NULL;
if (value != NULL) {
@@ -1501,7 +1501,7 @@ njs_object_get_prototype_of(njs_vm_t *vm
index = njs_primitive_prototype_index(value->type);
if (njs_is_symbol(value)) {
- njs_set_object(retval, &vm->prototypes[index].object);
+ njs_set_object(retval, njs_vm_proto(vm, index));
} else {
njs_set_object_value(retval,
@@ -1843,7 +1843,7 @@ njs_primitive_prototype_get_proto(njs_vm
} else {
index = njs_primitive_prototype_index(value->type);
- proto = &vm->prototypes[index].object;
+ proto = njs_vm_proto(vm, index);
}
if (proto != NULL) {
@@ -1875,7 +1875,7 @@ njs_object_prototype_create(njs_vm_t *vm
function = njs_function(value);
index = function - vm->constructors;
- if (index >= 0 && index < NJS_OBJ_TYPE_MAX) {
+ if (index >= 0 && (size_t) index < vm->constructors_size) {
proto = njs_property_prototype_create(vm, &function->object.hash,
&vm->prototypes[index].object);
}
@@ -2111,7 +2111,7 @@ njs_object_prototype_create_constructor(
prototype = (njs_object_prototype_t *) object;
index = prototype - vm->prototypes;
- if (index >= 0 && index < NJS_OBJ_TYPE_MAX) {
+ if (index >= 0 && (size_t) index < vm->constructors_size) {
goto found;
}
@@ -2128,7 +2128,7 @@ njs_object_prototype_create_constructor(
found:
- njs_set_function(&constructor, &vm->constructors[index]);
+ njs_set_function(&constructor, &njs_vm_ctor(vm, index));
setval = &constructor;
cons = njs_property_constructor_set(vm, &prototype->object.hash, setval);
diff -r 3386684745b7 -r 167f75576f49 src/njs_parser.c
--- a/src/njs_parser.c Fri Jun 30 21:02:44 2023 -0700
+++ b/src/njs_parser.c Mon Jul 03 12:49:00 2023 -0700
@@ -9199,6 +9199,10 @@ njs_parser_error(njs_vm_t *vm, njs_objec
static const njs_value_t file_name = njs_string("fileName");
static const njs_value_t line_number = njs_string("lineNumber");
+ if (njs_slow_path(vm->top_frame == NULL)) {
+ njs_vm_runtime_init(vm);
+ }
+
p = msg;
end = msg + NJS_MAX_ERROR_STR;
@@ -9217,7 +9221,7 @@ njs_parser_error(njs_vm_t *vm, njs_objec
p = njs_sprintf(p, end, " in %uD", line);
}
- njs_error_new(vm, &error, &vm->prototypes[type].object, msg, p - msg);
+ njs_error_new(vm, &error, njs_vm_proto(vm, type), msg, p - msg);
njs_set_number(&value, line);
njs_value_property_set(vm, &error, njs_value_arg(&line_number), &value);
diff -r 3386684745b7 -r 167f75576f49 src/njs_promise.c
--- a/src/njs_promise.c Fri Jun 30 21:02:44 2023 -0700
+++ b/src/njs_promise.c Mon Jul 03 12:49:00 2023 -0700
@@ -131,7 +131,7 @@ njs_promise_alloc(njs_vm_t *vm)
promise->object.extensible = 1;
promise->object.error_data = 0;
promise->object.fast_array = 0;
- promise->object.__proto__ = &vm->prototypes[NJS_OBJ_TYPE_PROMISE].object;
+ promise->object.__proto__ = njs_vm_proto(vm, NJS_OBJ_TYPE_PROMISE);
promise->object.slots = NULL;
data = (njs_promise_data_t *) ((uint8_t *) promise + sizeof(njs_promise_t));
@@ -265,7 +265,7 @@ njs_promise_create_function(njs_vm_t *vm
context = NULL;
}
- function->object.__proto__ = &vm->prototypes[NJS_OBJ_TYPE_FUNCTION].object;
+ function->object.__proto__ = njs_vm_proto(vm, NJS_OBJ_TYPE_FUNCTION);
function->object.shared_hash = vm->shared->arrow_instance_hash;
function->object.type = NJS_FUNCTION;
function->object.extensible = 1;
@@ -1352,8 +1352,8 @@ njs_promise_perform_all(njs_vm_t *vm, nj
if (handler == njs_promise_perform_any_handler) {
error = njs_error_alloc(vm,
- &vm->prototypes[NJS_OBJ_TYPE_AGGREGATE_ERROR].object,
- NULL, &string_any_rejected, &argument);
+ njs_vm_proto(vm, NJS_OBJ_TYPE_AGGREGATE_ERROR),
+ NULL, &string_any_rejected, &argument);
if (njs_slow_path(error == NULL)) {
return NJS_ERROR;
}
@@ -1730,8 +1730,8 @@ njs_promise_any_reject_element_functions
njs_mp_free(vm->mem_pool, context->remaining_elements);
error = njs_error_alloc(vm,
- &vm->prototypes[NJS_OBJ_TYPE_AGGREGATE_ERROR].object,
- NULL, &string_any_rejected, &arr_value);
+ njs_vm_proto(vm, NJS_OBJ_TYPE_AGGREGATE_ERROR),
+ NULL, &string_any_rejected, &arr_value);
if (njs_slow_path(error == NULL)) {
return NJS_ERROR;
}
diff -r 3386684745b7 -r 167f75576f49 src/njs_regexp.c
--- a/src/njs_regexp.c Fri Jun 30 21:02:44 2023 -0700
+++ b/src/njs_regexp.c Mon Jul 03 12:49:00 2023 -0700
@@ -503,7 +503,7 @@ njs_regexp_alloc(njs_vm_t *vm, njs_regex
if (njs_fast_path(regexp != NULL)) {
njs_lvlhsh_init(®exp->object.hash);
regexp->object.shared_hash = vm->shared->regexp_instance_hash;
- regexp->object.__proto__ = &vm->prototypes[NJS_OBJ_TYPE_REGEXP].object;
+ regexp->object.__proto__ = njs_vm_proto(vm, NJS_OBJ_TYPE_REGEXP);
regexp->object.slots = NULL;
regexp->object.type = NJS_REGEXP;
regexp->object.shared = 0;
@@ -628,7 +628,7 @@ njs_regexp_prototype_flag(njs_vm_t *vm,
}
if (njs_slow_path(!njs_is_regexp(this))) {
- if (njs_object(this) == &vm->prototypes[NJS_OBJ_TYPE_REGEXP].object) {
+ if (njs_object(this) == njs_vm_proto(vm, NJS_OBJ_TYPE_REGEXP)) {
njs_set_undefined(retval);
return NJS_OK;
}
@@ -679,7 +679,7 @@ njs_regexp_prototype_source(njs_vm_t *vm
}
if (njs_slow_path(!njs_is_regexp(this))) {
- if (njs_object(this) == &vm->prototypes[NJS_OBJ_TYPE_REGEXP].object) {
+ if (njs_object(this) == njs_vm_proto(vm, NJS_OBJ_TYPE_REGEXP)) {
njs_value_assign(retval, &njs_string_empty_regexp);
return NJS_OK;
}
@@ -1553,7 +1553,7 @@ njs_regexp_prototype_symbol_split(njs_vm
return ret;
}
- njs_set_function(&constructor, &vm->constructors[NJS_OBJ_TYPE_REGEXP]);
+ njs_set_function(&constructor, &njs_vm_ctor(vm, NJS_OBJ_TYPE_REGEXP));
ret = njs_value_species_constructor(vm, rx, &constructor, &constructor);
if (njs_slow_path(ret != NJS_OK)) {
diff -r 3386684745b7 -r 167f75576f49 src/njs_typed_array.c
--- a/src/njs_typed_array.c Fri Jun 30 21:02:44 2023 -0700
+++ b/src/njs_typed_array.c Mon Jul 03 12:49:00 2023 -0700
@@ -180,7 +180,7 @@ njs_typed_array_alloc(njs_vm_t *vm, njs_
njs_lvlhsh_init(&array->object.hash);
njs_lvlhsh_init(&array->object.shared_hash);
- array->object.__proto__ = &vm->prototypes[type].object;
+ array->object.__proto__ = njs_vm_proto(vm, type);
array->object.type = NJS_TYPED_ARRAY;
array->object.extensible = 1;
array->object.fast_array = 1;
@@ -264,7 +264,7 @@ njs_typed_array_species_create(njs_vm_t
array = njs_typed_array(exemplar);
- njs_set_function(&constructor, &vm->constructors[array->type]);
+ njs_set_function(&constructor, &njs_vm_ctor(vm, array->type));
ret = njs_value_species_constructor(vm, exemplar, &constructor,
&constructor);
@@ -2413,7 +2413,7 @@ njs_data_view_constructor(njs_vm_t *vm,
njs_lvlhsh_init(&view->object.hash);
njs_lvlhsh_init(&view->object.shared_hash);
- view->object.__proto__ = &vm->prototypes[view->type].object;
+ view->object.__proto__ = njs_vm_proto(vm, view->type);
view->object.type = NJS_DATA_VIEW;
view->object.extensible = 1;
diff -r 3386684745b7 -r 167f75576f49 src/njs_value.c
--- a/src/njs_value.c Fri Jun 30 21:02:44 2023 -0700
+++ b/src/njs_value.c Mon Jul 03 12:49:00 2023 -0700
@@ -638,7 +638,7 @@ njs_property_query(njs_vm_t *vm, njs_pro
case NJS_NUMBER:
case NJS_SYMBOL:
index = njs_primitive_prototype_index(value->type);
- obj = &vm->prototypes[index].object;
+ obj = njs_vm_proto(vm, index);
break;
case NJS_STRING:
diff -r 3386684745b7 -r 167f75576f49 src/njs_value.h
--- a/src/njs_value.h Fri Jun 30 21:02:44 2023 -0700
+++ b/src/njs_value.h Mon Jul 03 12:49:00 2023 -0700
@@ -625,9 +625,8 @@ 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_has_prototype(vm, value, proto_id) \
+ (njs_object(value)->__proto__ == njs_vm_proto(vm, proto_id))
#define njs_is_object_value(value) \
diff -r 3386684745b7 -r 167f75576f49 src/njs_vm.c
--- a/src/njs_vm.c Fri Jun 30 21:02:44 2023 -0700
+++ b/src/njs_vm.c Mon Jul 03 12:49:00 2023 -0700
@@ -9,6 +9,7 @@
static njs_int_t njs_vm_handle_events(njs_vm_t *vm);
+static njs_int_t njs_vm_protos_init(njs_vm_t *vm, njs_value_t *global);
const njs_str_t njs_entry_empty = njs_str("");
@@ -78,13 +79,47 @@ njs_vm_create(njs_vm_opt_t *options)
vm->trace.data = vm;
if (options->init) {
- ret = njs_vm_init(vm);
+ ret = njs_vm_runtime_init(vm);
if (njs_slow_path(ret != NJS_OK)) {
return NULL;
}
}
for (i = 0; njs_modules[i] != NULL; i++) {
+ if (njs_modules[i]->preinit == NULL) {
+ continue;
+ }
+
+ ret = njs_modules[i]->preinit(vm);
+ if (njs_slow_path(ret != NJS_OK)) {
+ return NULL;
+ }
+ }
+
+ if (options->addons != NULL) {
+ addons = options->addons;
+ for (i = 0; addons[i] != NULL; i++) {
+ if (addons[i]->preinit == NULL) {
+ continue;
+ }
+
+ ret = addons[i]->preinit(vm);
+ if (njs_slow_path(ret != NJS_OK)) {
+ return NULL;
+ }
+ }
+ }
+
+ ret = njs_vm_protos_init(vm, &vm->global_value);
+ if (njs_slow_path(ret != NJS_OK)) {
+ return NULL;
+ }
+
+ for (i = 0; njs_modules[i] != NULL; i++) {
+ if (njs_modules[i]->init == NULL) {
+ continue;
+ }
+
ret = njs_modules[i]->init(vm);
if (njs_slow_path(ret != NJS_OK)) {
return NULL;
@@ -94,6 +129,10 @@ njs_vm_create(njs_vm_opt_t *options)
if (options->addons != NULL) {
addons = options->addons;
for (i = 0; addons[i] != NULL; i++) {
+ if (addons[i]->init == NULL) {
+ continue;
+ }
+
ret = addons[i]->init(vm);
if (njs_slow_path(ret != NJS_OK)) {
return NULL;
@@ -111,6 +150,51 @@ njs_vm_create(njs_vm_opt_t *options)
}
+njs_int_t
+njs_vm_ctor_push(njs_vm_t *vm)
+{
+ njs_function_t *ctor;
+ njs_vm_shared_t *shared;
+ njs_object_prototype_t *prototype;
+
+ shared = vm->shared;
More information about the nginx-devel
mailing list