[njs] Simplified element access in Array.prototype.shift().
Dmitry Volyntsev
xeioex at nginx.com
Fri Jan 14 14:57:27 UTC 2022
details: https://hg.nginx.org/njs/rev/dfbde7620ced
branches:
changeset: 1806:dfbde7620ced
user: Dmitry Volyntsev <xeioex at nginx.com>
date: Thu Jan 13 18:30:31 2022 +0000
description:
Simplified element access in Array.prototype.shift().
Previously, array structure may be left in inconsistent state
when a custom getter in a proto array changes array size.
The change is similar to the previous commits.
diffstat:
src/njs_array.c | 89 ++++++++++++++++++++++++--------------------------------
1 files changed, 39 insertions(+), 50 deletions(-)
diffs (121 lines):
diff -r 762774041f05 -r dfbde7620ced src/njs_array.c
--- a/src/njs_array.c Thu Jan 13 18:30:31 2022 +0000
+++ b/src/njs_array.c Thu Jan 13 18:30:31 2022 +0000
@@ -1135,78 +1135,67 @@ njs_array_prototype_shift(njs_vm_t *vm,
int64_t i, length;
njs_int_t ret;
njs_array_t *array;
- njs_value_t *this, *item, entry;
+ njs_value_t *this, entry;
this = njs_argument(args, 0);
- length = 0;
ret = njs_value_to_object(vm, this);
if (njs_slow_path(ret != NJS_OK)) {
return ret;
}
- njs_set_undefined(&vm->retval);
-
- if (njs_is_fast_array(this)) {
- array = njs_array(this);
-
- if (array->length != 0) {
- array->length--;
- item = &array->start[0];
-
- if (njs_is_valid(item)) {
- vm->retval = *item;
-
- } else {
- /* src value may be in Array.prototype object. */
-
- ret = njs_value_property_i64(vm, this, 0, &vm->retval);
- if (njs_slow_path(ret == NJS_ERROR)) {
- return NJS_ERROR;
- }
- }
-
- array->start++;
- }
-
- return NJS_OK;
- }
-
ret = njs_object_length(vm, this, &length);
if (njs_slow_path(ret == NJS_ERROR)) {
return ret;
}
if (length == 0) {
- goto done;
- }
-
- ret = njs_value_property_i64_delete(vm, this, 0, &vm->retval);
- if (njs_slow_path(ret == NJS_ERROR)) {
- return ret;
- }
-
- for (i = 1; i < length; i++) {
- ret = njs_value_property_i64_delete(vm, this, i, &entry);
+ ret = njs_object_length_set(vm, this, length);
if (njs_slow_path(ret == NJS_ERROR)) {
return ret;
}
- if (ret == NJS_OK) {
- ret = njs_value_property_i64_set(vm, this, i - 1, &entry);
+ njs_set_undefined(&vm->retval);
+
+ return NJS_OK;
+ }
+
+ ret = njs_value_property_i64(vm, this, 0, &vm->retval);
+ if (njs_slow_path(ret == NJS_ERROR)) {
+ return NJS_ERROR;
+ }
+
+ if (njs_is_fast_array(this)) {
+ array = njs_array(this);
+
+ array->start++;
+ array->length--;
+
+ } else {
+
+ ret = njs_value_property_i64_delete(vm, this, 0, &vm->retval);
+ if (njs_slow_path(ret == NJS_ERROR)) {
+ return ret;
+ }
+
+ for (i = 1; i < length; i++) {
+ ret = njs_value_property_i64_delete(vm, this, i, &entry);
if (njs_slow_path(ret == NJS_ERROR)) {
return ret;
}
+
+ if (ret == NJS_OK) {
+ ret = njs_value_property_i64_set(vm, this, i - 1, &entry);
+ if (njs_slow_path(ret == NJS_ERROR)) {
+ return ret;
+ }
+ }
}
- }
-
- length--;
-
-done:
-
- ret = njs_object_length_set(vm, this, length);
- if (njs_slow_path(ret == NJS_ERROR)) {
- return ret;
+
+ ret = njs_object_length_set(vm, this, length - 1);
+ if (njs_slow_path(ret == NJS_ERROR)) {
+ return ret;
+ }
}
return NJS_OK;
More information about the nginx-devel
mailing list