[njs] Making native getters into universal property handlers.
Dmitry Volyntsev
xeioex at nginx.com
Fri Apr 20 13:42:37 UTC 2018
details: http://hg.nginx.org/njs/rev/a65deb4c2e03
branches:
changeset: 501:a65deb4c2e03
user: Dmitry Volyntsev <xeioex at nginx.com>
date: Fri Apr 20 16:42:10 2018 +0300
description:
Making native getters into universal property handlers.
diffstat:
njs/njs_array.c | 10 ++++----
njs/njs_boolean.c | 8 +++---
njs/njs_builtin.c | 4 +-
njs/njs_date.c | 8 +++---
njs/njs_error.c | 38 ++++++++++++++++----------------
njs/njs_function.c | 6 ++--
njs/njs_function.h | 2 +-
njs/njs_math.c | 4 +-
njs/njs_number.c | 8 +++---
njs/njs_object.c | 22 +++++++++---------
njs/njs_object.h | 9 +++----
njs/njs_regexp.c | 34 +++++++++++++++---------------
njs/njs_string.c | 14 ++++++------
njs/njs_vm.c | 54 +++++++++++++++++++++++++++++++++++++++++++++--
njs/njs_vm.h | 15 ++++++++----
njs/test/njs_unit_test.c | 6 +++++
16 files changed, 150 insertions(+), 92 deletions(-)
diffs (720 lines):
diff -r 28d75187de15 -r a65deb4c2e03 njs/njs_array.c
--- a/njs/njs_array.c Fri Apr 20 16:42:10 2018 +0300
+++ b/njs/njs_array.c Fri Apr 20 16:42:10 2018 +0300
@@ -351,9 +351,9 @@ static const njs_object_prop_t njs_arra
/* Array.prototype. */
{
- .type = NJS_NATIVE_GETTER,
+ .type = NJS_PROPERTY_HANDLER,
.name = njs_string("prototype"),
- .value = njs_native_getter(njs_object_prototype_create),
+ .value = njs_prop_handler(njs_object_prototype_create),
},
/* Array.isArray(). */
@@ -382,7 +382,7 @@ const njs_object_init_t njs_array_const
static njs_ret_t
njs_array_prototype_length(njs_vm_t *vm, njs_value_t *array,
- njs_value_t *retval)
+ njs_value_t *setval, njs_value_t *retval)
{
njs_value_number_set(retval, array->data.u.array->length);
@@ -2057,9 +2057,9 @@ njs_array_prototype_sort_continuation(nj
static const njs_object_prop_t njs_array_prototype_properties[] =
{
{
- .type = NJS_NATIVE_GETTER,
+ .type = NJS_PROPERTY_HANDLER,
.name = njs_string("length"),
- .value = njs_native_getter(njs_array_prototype_length),
+ .value = njs_prop_handler(njs_array_prototype_length),
},
{
diff -r 28d75187de15 -r a65deb4c2e03 njs/njs_boolean.c
--- a/njs/njs_boolean.c Fri Apr 20 16:42:10 2018 +0300
+++ b/njs/njs_boolean.c Fri Apr 20 16:42:10 2018 +0300
@@ -71,9 +71,9 @@ static const njs_object_prop_t njs_bool
/* Boolean.prototype. */
{
- .type = NJS_NATIVE_GETTER,
+ .type = NJS_PROPERTY_HANDLER,
.name = njs_string("prototype"),
- .value = njs_native_getter(njs_object_prototype_create),
+ .value = njs_prop_handler(njs_object_prototype_create),
},
};
@@ -140,9 +140,9 @@ njs_boolean_prototype_to_string(njs_vm_t
static const njs_object_prop_t njs_boolean_prototype_properties[] =
{
{
- .type = NJS_NATIVE_GETTER,
+ .type = NJS_PROPERTY_HANDLER,
.name = njs_string("__proto__"),
- .value = njs_native_getter(njs_primitive_prototype_get_proto),
+ .value = njs_prop_handler(njs_primitive_prototype_get_proto),
},
{
diff -r 28d75187de15 -r a65deb4c2e03 njs/njs_builtin.c
--- a/njs/njs_builtin.c Fri Apr 20 16:42:10 2018 +0300
+++ b/njs/njs_builtin.c Fri Apr 20 16:42:10 2018 +0300
@@ -246,9 +246,9 @@ njs_builtin_objects_create(njs_vm_t *vm)
};
static const njs_object_prop_t function_prototype_property = {
- .type = NJS_NATIVE_GETTER,
+ .type = NJS_PROPERTY_HANDLER,
.name = njs_string("prototype"),
- .value = njs_native_getter(njs_function_prototype_create),
+ .value = njs_prop_handler(njs_function_prototype_create),
};
ret = njs_object_hash_create(vm, &vm->shared->function_prototype_hash,
diff -r 28d75187de15 -r a65deb4c2e03 njs/njs_date.c
--- a/njs/njs_date.c Fri Apr 20 16:42:10 2018 +0300
+++ b/njs/njs_date.c Fri Apr 20 16:42:10 2018 +0300
@@ -905,9 +905,9 @@ static const njs_object_prop_t njs_date
/* Date.prototype. */
{
- .type = NJS_NATIVE_GETTER,
+ .type = NJS_PROPERTY_HANDLER,
.name = njs_string("prototype"),
- .value = njs_native_getter(njs_object_prototype_create),
+ .value = njs_prop_handler(njs_object_prototype_create),
},
{
@@ -1931,9 +1931,9 @@ njs_date_prototype_to_json_continuation(
static const njs_object_prop_t njs_date_prototype_properties[] =
{
{
- .type = NJS_NATIVE_GETTER,
+ .type = NJS_PROPERTY_HANDLER,
.name = njs_string("__proto__"),
- .value = njs_native_getter(njs_primitive_prototype_get_proto),
+ .value = njs_prop_handler(njs_primitive_prototype_get_proto),
},
{
diff -r 28d75187de15 -r a65deb4c2e03 njs/njs_error.c
--- a/njs/njs_error.c Fri Apr 20 16:42:10 2018 +0300
+++ b/njs/njs_error.c Fri Apr 20 16:42:10 2018 +0300
@@ -192,9 +192,9 @@ static const njs_object_prop_t njs_erro
/* Error.prototype. */
{
- .type = NJS_NATIVE_GETTER,
+ .type = NJS_PROPERTY_HANDLER,
.name = njs_string("prototype"),
- .value = njs_native_getter(njs_object_prototype_create),
+ .value = njs_prop_handler(njs_object_prototype_create),
},
};
@@ -232,9 +232,9 @@ static const njs_object_prop_t njs_eval
/* EvalError.prototype. */
{
- .type = NJS_NATIVE_GETTER,
+ .type = NJS_PROPERTY_HANDLER,
.name = njs_string("prototype"),
- .value = njs_native_getter(njs_object_prototype_create),
+ .value = njs_prop_handler(njs_object_prototype_create),
},
};
@@ -272,9 +272,9 @@ static const njs_object_prop_t njs_inte
/* InternalError.prototype. */
{
- .type = NJS_NATIVE_GETTER,
+ .type = NJS_PROPERTY_HANDLER,
.name = njs_string("prototype"),
- .value = njs_native_getter(njs_object_prototype_create),
+ .value = njs_prop_handler(njs_object_prototype_create),
},
};
@@ -312,9 +312,9 @@ static const njs_object_prop_t njs_rang
/* RangeError.prototype. */
{
- .type = NJS_NATIVE_GETTER,
+ .type = NJS_PROPERTY_HANDLER,
.name = njs_string("prototype"),
- .value = njs_native_getter(njs_object_prototype_create),
+ .value = njs_prop_handler(njs_object_prototype_create),
},
};
@@ -352,9 +352,9 @@ static const njs_object_prop_t njs_refe
/* ReferenceError.prototype. */
{
- .type = NJS_NATIVE_GETTER,
+ .type = NJS_PROPERTY_HANDLER,
.name = njs_string("prototype"),
- .value = njs_native_getter(njs_object_prototype_create),
+ .value = njs_prop_handler(njs_object_prototype_create),
},
};
@@ -392,9 +392,9 @@ static const njs_object_prop_t njs_synt
/* SyntaxError.prototype. */
{
- .type = NJS_NATIVE_GETTER,
+ .type = NJS_PROPERTY_HANDLER,
.name = njs_string("prototype"),
- .value = njs_native_getter(njs_object_prototype_create),
+ .value = njs_prop_handler(njs_object_prototype_create),
},
};
@@ -432,9 +432,9 @@ static const njs_object_prop_t njs_type
/* TypeError.prototype. */
{
- .type = NJS_NATIVE_GETTER,
+ .type = NJS_PROPERTY_HANDLER,
.name = njs_string("prototype"),
- .value = njs_native_getter(njs_object_prototype_create),
+ .value = njs_prop_handler(njs_object_prototype_create),
},
};
@@ -472,9 +472,9 @@ static const njs_object_prop_t njs_uri_
/* URIError.prototype. */
{
- .type = NJS_NATIVE_GETTER,
+ .type = NJS_PROPERTY_HANDLER,
.name = njs_string("prototype"),
- .value = njs_native_getter(njs_object_prototype_create),
+ .value = njs_prop_handler(njs_object_prototype_create),
},
};
@@ -533,7 +533,7 @@ njs_memory_error_constructor(njs_vm_t *v
static njs_ret_t
njs_memory_error_prototype_create(njs_vm_t *vm, njs_value_t *value,
- njs_value_t *retval)
+ njs_value_t *setval, njs_value_t *retval)
{
int32_t index;
njs_value_t *proto;
@@ -574,9 +574,9 @@ static const njs_object_prop_t njs_memo
/* MemoryError.prototype. */
{
- .type = NJS_NATIVE_GETTER,
+ .type = NJS_PROPERTY_HANDLER,
.name = njs_string("prototype"),
- .value = njs_native_getter(njs_memory_error_prototype_create),
+ .value = njs_prop_handler(njs_memory_error_prototype_create),
},
};
diff -r 28d75187de15 -r a65deb4c2e03 njs/njs_function.c
--- a/njs/njs_function.c Fri Apr 20 16:42:10 2018 +0300
+++ b/njs/njs_function.c Fri Apr 20 16:42:10 2018 +0300
@@ -419,7 +419,7 @@ njs_function_call(njs_vm_t *vm, njs_inde
njs_ret_t
njs_function_prototype_create(njs_vm_t *vm, njs_value_t *value,
- njs_value_t *retval)
+ njs_value_t *setval, njs_value_t *retval)
{
njs_value_t *proto;
@@ -495,9 +495,9 @@ static const njs_object_prop_t njs_func
/* Function.prototype. */
{
- .type = NJS_NATIVE_GETTER,
+ .type = NJS_PROPERTY_HANDLER,
.name = njs_string("prototype"),
- .value = njs_native_getter(njs_object_prototype_create),
+ .value = njs_prop_handler(njs_object_prototype_create),
},
};
diff -r 28d75187de15 -r a65deb4c2e03 njs/njs_function.h
--- a/njs/njs_function.h Fri Apr 20 16:42:10 2018 +0300
+++ b/njs/njs_function.h Fri Apr 20 16:42:10 2018 +0300
@@ -147,7 +147,7 @@ njs_function_t *njs_function_alloc(njs_v
njs_function_t *njs_function_value_copy(njs_vm_t *vm, njs_value_t *value);
njs_native_frame_t *njs_function_frame_alloc(njs_vm_t *vm, size_t size);
njs_ret_t njs_function_prototype_create(njs_vm_t *vm, njs_value_t *value,
- njs_value_t *retval);
+ njs_value_t *setval, njs_value_t *retval);
njs_value_t *njs_function_property_prototype_create(njs_vm_t *vm,
njs_value_t *value);
njs_ret_t njs_function_constructor(njs_vm_t *vm, njs_value_t *args,
diff -r 28d75187de15 -r a65deb4c2e03 njs/njs_math.c
--- a/njs/njs_math.c Fri Apr 20 16:42:10 2018 +0300
+++ b/njs/njs_math.c Fri Apr 20 16:42:10 2018 +0300
@@ -822,9 +822,9 @@ static const njs_object_prop_t njs_math
},
{
- .type = NJS_NATIVE_GETTER,
+ .type = NJS_PROPERTY_HANDLER,
.name = njs_string("__proto__"),
- .value = njs_native_getter(njs_object_prototype_get_proto),
+ .value = njs_prop_handler(njs_object_prototype_get_proto),
},
{
diff -r 28d75187de15 -r a65deb4c2e03 njs/njs_number.c
--- a/njs/njs_number.c Fri Apr 20 16:42:10 2018 +0300
+++ b/njs/njs_number.c Fri Apr 20 16:42:10 2018 +0300
@@ -463,9 +463,9 @@ static const njs_object_prop_t njs_numb
/* Number.prototype. */
{
- .type = NJS_NATIVE_GETTER,
+ .type = NJS_PROPERTY_HANDLER,
.name = njs_string("prototype"),
- .value = njs_native_getter(njs_object_prototype_create),
+ .value = njs_prop_handler(njs_object_prototype_create),
},
/* ES6. */
@@ -707,9 +707,9 @@ njs_number_to_string_radix(njs_vm_t *vm,
static const njs_object_prop_t njs_number_prototype_properties[] =
{
{
- .type = NJS_NATIVE_GETTER,
+ .type = NJS_PROPERTY_HANDLER,
.name = njs_string("__proto__"),
- .value = njs_native_getter(njs_primitive_prototype_get_proto),
+ .value = njs_prop_handler(njs_primitive_prototype_get_proto),
},
{
diff -r 28d75187de15 -r a65deb4c2e03 njs/njs_object.c
--- a/njs/njs_object.c Fri Apr 20 16:42:10 2018 +0300
+++ b/njs/njs_object.c Fri Apr 20 16:42:10 2018 +0300
@@ -740,7 +740,7 @@ njs_object_get_prototype_of(njs_vm_t *vm
njs_index_t unused)
{
if (nargs > 1 && njs_is_object(&args[1])) {
- njs_object_prototype_get_proto(vm, &args[1], &vm->retval);
+ njs_object_prototype_get_proto(vm, &args[1], NULL, &vm->retval);
return NXT_OK;
}
@@ -971,7 +971,7 @@ njs_object_is_extensible(njs_vm_t *vm, n
njs_ret_t
njs_primitive_prototype_get_proto(njs_vm_t *vm, njs_value_t *value,
- njs_value_t *retval)
+ njs_value_t *setval, njs_value_t *retval)
{
nxt_uint_t index;
njs_object_t *proto;
@@ -1004,7 +1004,7 @@ njs_primitive_prototype_get_proto(njs_vm
njs_ret_t
njs_object_prototype_create(njs_vm_t *vm, njs_value_t *value,
- njs_value_t *retval)
+ njs_value_t *setval, njs_value_t *retval)
{
int32_t index;
njs_value_t *proto;
@@ -1088,9 +1088,9 @@ static const njs_object_prop_t njs_obje
/* Object.prototype. */
{
- .type = NJS_NATIVE_GETTER,
+ .type = NJS_PROPERTY_HANDLER,
.name = njs_string("prototype"),
- .value = njs_native_getter(njs_object_prototype_create),
+ .value = njs_prop_handler(njs_object_prototype_create),
},
/* Object.create(). */
@@ -1202,7 +1202,7 @@ const njs_object_init_t njs_object_cons
njs_ret_t
njs_object_prototype_get_proto(njs_vm_t *vm, njs_value_t *value,
- njs_value_t *retval)
+ njs_value_t *setval, njs_value_t *retval)
{
njs_object_t *proto;
@@ -1229,7 +1229,7 @@ njs_object_prototype_get_proto(njs_vm_t
static njs_ret_t
njs_object_prototype_create_constructor(njs_vm_t *vm, njs_value_t *value,
- njs_value_t *retval)
+ njs_value_t *setval, njs_value_t *retval)
{
int32_t index;
njs_value_t *cons;
@@ -1521,15 +1521,15 @@ njs_object_prototype_is_prototype_of(njs
static const njs_object_prop_t njs_object_prototype_properties[] =
{
{
- .type = NJS_NATIVE_GETTER,
+ .type = NJS_PROPERTY_HANDLER,
.name = njs_string("__proto__"),
- .value = njs_native_getter(njs_object_prototype_get_proto),
+ .value = njs_prop_handler(njs_object_prototype_get_proto),
},
{
- .type = NJS_NATIVE_GETTER,
+ .type = NJS_PROPERTY_HANDLER,
.name = njs_string("constructor"),
- .value = njs_native_getter(njs_object_prototype_create_constructor),
+ .value = njs_prop_handler(njs_object_prototype_create_constructor),
},
{
diff -r 28d75187de15 -r a65deb4c2e03 njs/njs_object.h
--- a/njs/njs_object.h Fri Apr 20 16:42:10 2018 +0300
+++ b/njs/njs_object.h Fri Apr 20 16:42:10 2018 +0300
@@ -13,8 +13,7 @@ typedef enum {
NJS_GETTER,
NJS_SETTER,
NJS_METHOD,
- NJS_NATIVE_GETTER,
- NJS_NATIVE_SETTER,
+ NJS_PROPERTY_HANDLER,
NJS_WHITEOUT,
} njs_object_property_type_t;
@@ -52,13 +51,13 @@ njs_ret_t njs_object_constructor(njs_vm_
njs_object_prop_t *njs_object_prop_alloc(njs_vm_t *vm, const njs_value_t *name,
const njs_value_t *value, uint8_t attributes);
njs_ret_t njs_primitive_prototype_get_proto(njs_vm_t *vm, njs_value_t *value,
- njs_value_t *retval);
+ njs_value_t *setval, njs_value_t *retval);
njs_ret_t njs_object_prototype_create(njs_vm_t *vm, njs_value_t *value,
- njs_value_t *retval);
+ njs_value_t *setval, njs_value_t *retval);
njs_value_t *njs_property_prototype_create(njs_vm_t *vm, nxt_lvlhsh_t *hash,
njs_object_t *prototype);
njs_ret_t njs_object_prototype_get_proto(njs_vm_t *vm, njs_value_t *value,
- njs_value_t *retval);
+ njs_value_t *setval, njs_value_t *retval);
njs_value_t *njs_property_constructor_create(njs_vm_t *vm, nxt_lvlhsh_t *hash,
njs_value_t *constructor);
njs_ret_t njs_object_prototype_to_string(njs_vm_t *vm, njs_value_t *args,
diff -r 28d75187de15 -r a65deb4c2e03 njs/njs_regexp.c
--- a/njs/njs_regexp.c Fri Apr 20 16:42:10 2018 +0300
+++ b/njs/njs_regexp.c Fri Apr 20 16:42:10 2018 +0300
@@ -464,7 +464,7 @@ njs_regexp_alloc(njs_vm_t *vm, njs_regex
static njs_ret_t
njs_regexp_prototype_last_index(njs_vm_t *vm, njs_value_t *value,
- njs_value_t *retval)
+ njs_value_t *setval, njs_value_t *retval)
{
uint32_t index;
njs_regexp_t *regexp;
@@ -485,7 +485,7 @@ njs_regexp_prototype_last_index(njs_vm_t
static njs_ret_t
njs_regexp_prototype_global(njs_vm_t *vm, njs_value_t *value,
- njs_value_t *retval)
+ njs_value_t *setval, njs_value_t *retval)
{
njs_regexp_pattern_t *pattern;
@@ -499,7 +499,7 @@ njs_regexp_prototype_global(njs_vm_t *vm
static njs_ret_t
njs_regexp_prototype_ignore_case(njs_vm_t *vm, njs_value_t *value,
- njs_value_t *retval)
+ njs_value_t *setval, njs_value_t *retval)
{
njs_regexp_pattern_t *pattern;
@@ -513,7 +513,7 @@ njs_regexp_prototype_ignore_case(njs_vm_
static njs_ret_t
njs_regexp_prototype_multiline(njs_vm_t *vm, njs_value_t *value,
- njs_value_t *retval)
+ njs_value_t *setval, njs_value_t *retval)
{
njs_regexp_pattern_t *pattern;
@@ -527,7 +527,7 @@ njs_regexp_prototype_multiline(njs_vm_t
static njs_ret_t
njs_regexp_prototype_source(njs_vm_t *vm, njs_value_t *value,
- njs_value_t *retval)
+ njs_value_t *setval, njs_value_t *retval)
{
u_char *source;
int32_t length;
@@ -824,9 +824,9 @@ static const njs_object_prop_t njs_rege
/* RegExp.prototype. */
{
- .type = NJS_NATIVE_GETTER,
+ .type = NJS_PROPERTY_HANDLER,
.name = njs_string("prototype"),
- .value = njs_native_getter(njs_object_prototype_create),
+ .value = njs_prop_handler(njs_object_prototype_create),
},
};
@@ -841,33 +841,33 @@ const njs_object_init_t njs_regexp_cons
static const njs_object_prop_t njs_regexp_prototype_properties[] =
{
{
- .type = NJS_NATIVE_GETTER,
+ .type = NJS_PROPERTY_HANDLER,
.name = njs_string("lastIndex"),
- .value = njs_native_getter(njs_regexp_prototype_last_index),
+ .value = njs_prop_handler(njs_regexp_prototype_last_index),
},
{
- .type = NJS_NATIVE_GETTER,
+ .type = NJS_PROPERTY_HANDLER,
.name = njs_string("global"),
- .value = njs_native_getter(njs_regexp_prototype_global),
+ .value = njs_prop_handler(njs_regexp_prototype_global),
},
{
- .type = NJS_NATIVE_GETTER,
+ .type = NJS_PROPERTY_HANDLER,
.name = njs_string("ignoreCase"),
- .value = njs_native_getter(njs_regexp_prototype_ignore_case),
+ .value = njs_prop_handler(njs_regexp_prototype_ignore_case),
},
{
- .type = NJS_NATIVE_GETTER,
+ .type = NJS_PROPERTY_HANDLER,
.name = njs_string("multiline"),
- .value = njs_native_getter(njs_regexp_prototype_multiline),
+ .value = njs_prop_handler(njs_regexp_prototype_multiline),
},
{
- .type = NJS_NATIVE_GETTER,
+ .type = NJS_PROPERTY_HANDLER,
.name = njs_string("source"),
- .value = njs_native_getter(njs_regexp_prototype_source),
+ .value = njs_prop_handler(njs_regexp_prototype_source),
},
{
diff -r 28d75187de15 -r a65deb4c2e03 njs/njs_string.c
--- a/njs/njs_string.c Fri Apr 20 16:42:10 2018 +0300
+++ b/njs/njs_string.c Fri Apr 20 16:42:10 2018 +0300
@@ -570,9 +570,9 @@ static const njs_object_prop_t njs_stri
/* String.prototype. */
{
- .type = NJS_NATIVE_GETTER,
+ .type = NJS_PROPERTY_HANDLER,
.name = njs_string("prototype"),
- .value = njs_native_getter(njs_object_prototype_create),
+ .value = njs_prop_handler(njs_object_prototype_create),
},
/* String.fromCharCode(). */
@@ -600,7 +600,7 @@ const njs_object_init_t njs_string_cons
static njs_ret_t
njs_string_prototype_length(njs_vm_t *vm, njs_value_t *value,
- njs_value_t *retval)
+ njs_value_t *setval, njs_value_t *retval)
{
size_t size;
uintptr_t length;
@@ -3348,15 +3348,15 @@ njs_string_to_c_string(njs_vm_t *vm, njs
static const njs_object_prop_t njs_string_prototype_properties[] =
{
{
- .type = NJS_NATIVE_GETTER,
+ .type = NJS_PROPERTY_HANDLER,
.name = njs_string("__proto__"),
- .value = njs_native_getter(njs_primitive_prototype_get_proto),
+ .value = njs_prop_handler(njs_primitive_prototype_get_proto),
},
{
- .type = NJS_NATIVE_GETTER,
+ .type = NJS_PROPERTY_HANDLER,
.name = njs_string("length"),
- .value = njs_native_getter(njs_string_prototype_length),
+ .value = njs_prop_handler(njs_string_prototype_length),
},
{
diff -r 28d75187de15 -r a65deb4c2e03 njs/njs_vm.c
--- a/njs/njs_vm.c Fri Apr 20 16:42:10 2018 +0300
+++ b/njs/njs_vm.c Fri Apr 20 16:42:10 2018 +0300
@@ -54,7 +54,7 @@
typedef struct {
nxt_lvlhsh_query_t lhq;
- /* scratch is used to get the value of an NJS_NATIVE_GETTER property. */
+ /* scratch is used to get the value of an NJS_PROPERTY_HANDLER property. */
njs_object_prop_t scratch;
njs_value_t value;
@@ -82,6 +82,8 @@ static njs_ret_t njs_array_property_quer
njs_property_query_t *pq, njs_value_t *object, uint32_t index);
static njs_ret_t njs_object_property_query(njs_vm_t *vm,
njs_property_query_t *pq, njs_value_t *value, njs_object_t *object);
+static njs_ret_t njs_object_query_prop_handler(njs_property_query_t *pq,
+ njs_object_t *object);
static njs_ret_t njs_method_private_copy(njs_vm_t *vm,
njs_property_query_t *pq);
static nxt_noinline njs_ret_t njs_values_equal(const njs_value_t *val1,
@@ -695,6 +697,17 @@ njs_vmcode_property_set(njs_vm_t *vm, nj
case NXT_OK:
prop = pq.lhq.value;
+
+ if (prop->type == NJS_PROPERTY_HANDLER) {
+ ret = prop->value.data.u.prop_handler(vm, object, value,
+ &vm->retval);
+ if (nxt_slow_path(ret != NXT_OK)) {
+ return ret;
+ }
+
+ return sizeof(njs_vmcode_prop_set_t);
+ }
+
break;
case NXT_DECLINED:
@@ -1153,6 +1166,13 @@ njs_object_property_query(njs_vm_t *vm,
pq->lhq.proto = &njs_object_hash_proto;
+ if (pq->query == NJS_PROPERTY_QUERY_SET) {
+ ret = njs_object_query_prop_handler(pq, object);
+ if (ret == NXT_OK) {
+ return ret;
+ }
+ }
+
do {
pq->prototype = object;
@@ -1183,10 +1203,11 @@ njs_object_property_query(njs_vm_t *vm,
if (pq->query == NJS_PROPERTY_QUERY_GET) {
prop = pq->lhq.value;
- if (prop->type == NJS_NATIVE_GETTER) {
+ if (prop->type == NJS_PROPERTY_HANDLER) {
pq->scratch = *prop;
prop = &pq->scratch;
- ret = prop->value.data.u.getter(vm, value, &prop->value);
+ ret = prop->value.data.u.prop_handler(vm, value, NULL,
+ &prop->value);
if (nxt_fast_path(ret == NXT_OK)) {
prop->type = NJS_PROPERTY;
@@ -1220,6 +1241,33 @@ njs_object_property_query(njs_vm_t *vm,
static njs_ret_t
+njs_object_query_prop_handler(njs_property_query_t *pq, njs_object_t *object)
+{
+ njs_ret_t ret;
+ njs_object_prop_t *prop;
+
+ do {
+ pq->prototype = object;
+
+ ret = nxt_lvlhsh_find(&object->shared_hash, &pq->lhq);
+
+ if (ret == NXT_OK) {
+ prop = pq->lhq.value;
+
+ if (prop->type == NJS_PROPERTY_HANDLER) {
+ return NXT_OK;
+ }
+ }
+
+ object = object->__proto__;
+
+ } while (object != NULL);
+
+ return NXT_DECLINED;
+}
+
+
+static njs_ret_t
njs_method_private_copy(njs_vm_t *vm, njs_property_query_t *pq)
{
njs_function_t *function;
diff -r 28d75187de15 -r a65deb4c2e03 njs/njs_vm.h
--- a/njs/njs_vm.h Fri Apr 20 16:42:10 2018 +0300
+++ b/njs/njs_vm.h Fri Apr 20 16:42:10 2018 +0300
@@ -118,8 +118,13 @@ typedef enum {
typedef struct njs_parser_s njs_parser_t;
-typedef njs_ret_t (*njs_getter_t) (njs_vm_t *vm, njs_value_t *obj,
- njs_value_t *retval);
+/*
+ * njs_prop_handler_t operates as a property getter and/or setter.
+ * The handler receives NULL setval if it is invoked in GET context and
+ * non-null otherwise.
+ */
+typedef njs_ret_t (*njs_prop_handler_t) (njs_vm_t *vm, njs_value_t *value,
+ njs_value_t *setval, njs_value_t *retval);
typedef njs_ret_t (*njs_function_native_t) (njs_vm_t *vm, njs_value_t *args,
nxt_uint_t nargs, njs_index_t retval);
@@ -177,7 +182,7 @@ union njs_value_s {
njs_function_lambda_t *lambda;
njs_regexp_t *regexp;
njs_date_t *date;
- njs_getter_t getter;
+ njs_prop_handler_t prop_handler;
njs_value_t *value;
njs_property_next_t *next;
void *data;
@@ -374,11 +379,11 @@ typedef union {
}
-#define njs_native_getter(_getter) { \
+#define njs_prop_handler(_handler) { \
.data = { \
.type = NJS_INVALID, \
.truth = 1, \
- .u = { .getter = _getter } \
+ .u = { .prop_handler = _handler } \
} \
}
diff -r 28d75187de15 -r a65deb4c2e03 njs/test/njs_unit_test.c
--- a/njs/test/njs_unit_test.c Fri Apr 20 16:42:10 2018 +0300
+++ b/njs/test/njs_unit_test.c Fri Apr 20 16:42:10 2018 +0300
@@ -5792,6 +5792,12 @@ static njs_unit_test_t njs_test[] =
{ nxt_string("({}).__proto__ === Object.prototype"),
nxt_string("true") },
+ { nxt_string("({}).__proto__ = 1"),
+ nxt_string("1") },
+
+ { nxt_string("var o = {}; o.__proto__ = 1; o.__proto__"),
+ nxt_string("[object Object]") },
+
{ nxt_string("({}).__proto__.constructor === Object"),
nxt_string("true") },
More information about the nginx-devel
mailing list