[njs] Fixed special getters for objects created using Object.create().
Dmitry Volyntsev
xeioex at nginx.com
Thu Apr 25 12:19:45 UTC 2019
details: https://hg.nginx.org/njs/rev/f5bdddca3252
branches:
changeset: 926:f5bdddca3252
user: Dmitry Volyntsev <xeioex at nginx.com>
date: Thu Apr 25 15:19:37 2019 +0300
description:
Fixed special getters for objects created using Object.create().
This closes #124 issue on Github.
diffstat:
njs/njs_array.c | 15 +++++++++++++--
njs/njs_function.c | 13 ++++++++++++-
njs/njs_object.c | 1 -
njs/njs_string.c | 23 +++++++++++++++++++----
njs/test/njs_unit_test.c | 12 ++++++++++++
5 files changed, 56 insertions(+), 8 deletions(-)
diffs (124 lines):
diff -r e104c8c583c2 -r f5bdddca3252 njs/njs_array.c
--- a/njs/njs_array.c Thu Apr 25 15:19:36 2019 +0300
+++ b/njs/njs_array.c Thu Apr 25 15:19:37 2019 +0300
@@ -420,8 +420,19 @@ njs_array_length(njs_vm_t *vm, njs_value
njs_ret_t ret;
njs_value_t *val;
njs_array_t *array;
-
- array = value->data.u.array;
+ njs_object_t *proto;
+
+ proto = value->data.u.object;
+
+ do {
+ if (nxt_fast_path(proto->type == NJS_ARRAY)) {
+ break;
+ }
+
+ proto = proto->__proto__;
+ } while (proto != NULL);
+
+ array = (njs_array_t *) proto;
if (setval != NULL) {
if (!njs_is_number(setval)) {
diff -r e104c8c583c2 -r f5bdddca3252 njs/njs_function.c
--- a/njs/njs_function.c Thu Apr 25 15:19:36 2019 +0300
+++ b/njs/njs_function.c Thu Apr 25 15:19:37 2019 +0300
@@ -894,10 +894,21 @@ njs_function_instance_length(njs_vm_t *v
njs_value_t *setval, njs_value_t *retval)
{
nxt_uint_t n;
+ njs_object_t *proto;
njs_function_t *function;
njs_function_lambda_t *lambda;
- function = value->data.u.function;
+ proto = value->data.u.object;
+
+ do {
+ if (nxt_fast_path(proto->type == NJS_FUNCTION)) {
+ break;
+ }
+
+ proto = proto->__proto__;
+ } while (proto != NULL);
+
+ function = (njs_function_t *) proto;
if (function->native) {
for (n = function->args_offset; n < NJS_ARGS_TYPES_MAX; n++) {
diff -r e104c8c583c2 -r f5bdddca3252 njs/njs_object.c
--- a/njs/njs_object.c Thu Apr 25 15:19:36 2019 +0300
+++ b/njs/njs_object.c Thu Apr 25 15:19:37 2019 +0300
@@ -283,7 +283,6 @@ njs_object_property(njs_vm_t *vm, const
* NXT_ERROR exception has been thrown.
*
* TODO:
- * Object.create([1,2]).length
* Object.defineProperty([1,2], '1', {configurable:false})
*/
diff -r e104c8c583c2 -r f5bdddca3252 njs/njs_string.c
--- a/njs/njs_string.c Thu Apr 25 15:19:36 2019 +0300
+++ b/njs/njs_string.c Thu Apr 25 15:19:37 2019 +0300
@@ -626,8 +626,10 @@ static njs_ret_t
njs_string_instance_length(njs_vm_t *vm, njs_value_t *value,
njs_value_t *setval, njs_value_t *retval)
{
- size_t size;
- uintptr_t length;
+ size_t size;
+ uintptr_t length;
+ njs_object_t *proto;
+ njs_object_value_t *ov;
/*
* This getter can be called for string primitive, String object,
@@ -635,8 +637,21 @@ njs_string_instance_length(njs_vm_t *vm,
*/
length = 0;
- if (value->type == NJS_OBJECT_STRING) {
- value = &value->data.u.object_value->value;
+ if (nxt_slow_path(njs_is_object(value))) {
+ proto = value->data.u.object;
+
+ do {
+ if (nxt_fast_path(proto->type == NJS_OBJECT_STRING)) {
+ break;
+ }
+
+ proto = proto->__proto__;
+ } while (proto != NULL);
+
+ if (proto != NULL) {
+ ov = (njs_object_value_t *) proto;
+ value = &ov->value;
+ }
}
if (njs_is_string(value)) {
diff -r e104c8c583c2 -r f5bdddca3252 njs/test/njs_unit_test.c
--- a/njs/test/njs_unit_test.c Thu Apr 25 15:19:36 2019 +0300
+++ b/njs/test/njs_unit_test.c Thu Apr 25 15:19:37 2019 +0300
@@ -9110,6 +9110,18 @@ static njs_unit_test_t njs_test[] =
"1..isPrototypeOf(p)"),
nxt_string("false") },
+ { nxt_string("Object.create(new String('asdf')).length"),
+ nxt_string("4") },
+
+ { nxt_string("Object.create(Object('123')).length"),
+ nxt_string("3") },
+
+ { nxt_string("Object.create([1,2]).length"),
+ nxt_string("2") },
+
+ { nxt_string("Object.create(function(a,b,c){}).length"),
+ nxt_string("3") },
+
{ nxt_string("Object.getOwnPropertyDescriptor({a:1}, 'a').value"),
nxt_string("1") },
More information about the nginx-devel
mailing list