[njs] Added njs_value_property_set() function.
Alexander Borisov
alexander.borisov at nginx.com
Mon May 27 18:09:54 UTC 2019
details: https://hg.nginx.org/njs/rev/4572a6e64bf1
branches:
changeset: 986:4572a6e64bf1
user: Alexander Borisov <alexander.borisov at nginx.com>
date: Thu May 23 17:39:22 2019 +0300
description:
Added njs_value_property_set() function.
diffstat:
njs/njs_object.h | 2 +
njs/njs_vm.c | 254 ++++++++++++++++++++++++++++--------------------------
2 files changed, 135 insertions(+), 121 deletions(-)
diffs (290 lines):
diff -r 7ae4f639fa43 -r 4572a6e64bf1 njs/njs_object.h
--- a/njs/njs_object.h Mon May 27 19:06:34 2019 +0300
+++ b/njs/njs_object.h Thu May 23 17:39:22 2019 +0300
@@ -88,6 +88,8 @@ njs_array_t *njs_object_own_enumerate(nj
njs_object_enum_t kind, nxt_bool_t all);
njs_ret_t njs_value_property(njs_vm_t *vm, const njs_value_t *value,
const njs_value_t *property, njs_value_t *retval);
+njs_ret_t njs_value_property_set(njs_vm_t *vm, njs_value_t *object,
+ const njs_value_t *property, njs_value_t *value);
njs_object_prop_t *njs_object_property(njs_vm_t *vm, const njs_object_t *obj,
nxt_lvlhsh_query_t *lhq);
njs_ret_t njs_property_query(njs_vm_t *vm, njs_property_query_t *pq,
diff -r 7ae4f639fa43 -r 4572a6e64bf1 njs/njs_vm.c
--- a/njs/njs_vm.c Mon May 27 19:06:34 2019 +0300
+++ b/njs/njs_vm.c Thu May 23 17:39:22 2019 +0300
@@ -660,134 +660,17 @@ njs_vmcode_property_set(njs_vm_t *vm, nj
{
njs_ret_t ret;
njs_value_t *value;
- njs_object_prop_t *prop, *shared;
- njs_property_query_t pq;
njs_vmcode_prop_set_t *code;
- if (njs_is_primitive(object)) {
- njs_type_error(vm, "property set on primitive %s type",
- njs_type_string(object->type));
- return NXT_ERROR;
- }
-
code = (njs_vmcode_prop_set_t *) vm->current;
value = njs_vmcode_operand(vm, code->value);
- shared = NULL;
-
- njs_property_query_init(&pq, NJS_PROPERTY_QUERY_SET, 0);
-
- ret = njs_property_query(vm, &pq, object, property);
-
- switch (ret) {
-
- case NXT_OK:
- prop = pq.lhq.value;
-
- if (nxt_slow_path(!prop->writable)) {
- njs_type_error(vm,
- "Cannot assign to read-only property \"%V\" of %s",
- &pq.lhq.key, njs_type_string(object->type));
- return NXT_ERROR;
- }
-
- if (prop->type == NJS_PROPERTY_HANDLER) {
- ret = prop->value.data.u.prop_handler(vm, object, value,
- &vm->retval);
-
- switch (ret) {
- case NXT_OK:
- return sizeof(njs_vmcode_prop_set_t);
-
- case NXT_DECLINED:
- break;
-
- default:
- return ret;
- }
- }
-
- if (pq.own) {
- switch (prop->type) {
- case NJS_PROPERTY:
- case NJS_METHOD:
- if (nxt_slow_path(pq.shared)) {
- shared = prop;
- break;
- }
-
- goto found;
-
- case NJS_PROPERTY_REF:
- *prop->value.data.u.value = *value;
- return sizeof(njs_vmcode_prop_set_t);
-
- default:
- njs_internal_error(vm, "unexpected property type \"%s\" "
- "while setting",
- njs_prop_type_string(prop->type));
-
- return NXT_ERROR;
- }
-
- break;
- }
-
- /* Fall through. */
-
- case NXT_DECLINED:
- if (nxt_slow_path(pq.own_whiteout != NULL)) {
- /* Previously deleted property. */
- prop = pq.own_whiteout;
-
- prop->type = NJS_PROPERTY;
- prop->enumerable = 1;
- prop->configurable = 1;
- prop->writable = 1;
-
- goto found;
- }
-
- break;
-
- case NJS_TRAP:
- case NXT_ERROR:
- default:
-
- return ret;
+ ret = njs_value_property_set(vm, object, property, value);
+ if (ret == NXT_OK) {
+ return sizeof(njs_vmcode_prop_set_t);
}
- if (nxt_slow_path(!object->data.u.object->extensible)) {
- njs_type_error(vm, "Cannot add property \"%V\", "
- "object is not extensible", &pq.lhq.key);
- return NXT_ERROR;
- }
-
- prop = njs_object_prop_alloc(vm, &pq.value, &njs_value_undefined, 1);
- if (nxt_slow_path(prop == NULL)) {
- return NXT_ERROR;
- }
-
- if (nxt_slow_path(shared != NULL)) {
- prop->enumerable = shared->enumerable;
- prop->configurable = shared->configurable;
- }
-
- pq.lhq.replace = 0;
- pq.lhq.value = prop;
- pq.lhq.pool = vm->mem_pool;
-
- ret = nxt_lvlhsh_insert(&object->data.u.object->hash, &pq.lhq);
- if (nxt_slow_path(ret != NXT_OK)) {
- njs_internal_error(vm, "lvlhsh insert failed");
- return NXT_ERROR;
- }
-
-found:
-
- prop->value = *value;
-
- return sizeof(njs_vmcode_prop_set_t);
+ return ret;
}
@@ -3240,6 +3123,135 @@ njs_value_property(njs_vm_t *vm, const n
}
+/*
+ * NXT_OK property has been set successfully
+ * NJS_TRAP the property trap must be called
+ * NXT_ERROR exception has been thrown.
+ */
+njs_ret_t
+njs_value_property_set(njs_vm_t *vm, njs_value_t *object,
+ const njs_value_t *property, njs_value_t *value)
+{
+ njs_ret_t ret;
+ njs_object_prop_t *prop, *shared;
+ njs_property_query_t pq;
+
+ if (njs_is_primitive(object)) {
+ njs_type_error(vm, "property set on primitive %s type",
+ njs_type_string(object->type));
+ return NXT_ERROR;
+ }
+
+ shared = NULL;
+
+ njs_property_query_init(&pq, NJS_PROPERTY_QUERY_SET, 0);
+
+ ret = njs_property_query(vm, &pq, object, property);
+
+ switch (ret) {
+
+ case NXT_OK:
+ prop = pq.lhq.value;
+
+ if (nxt_slow_path(!prop->writable)) {
+ njs_type_error(vm,
+ "Cannot assign to read-only property \"%V\" of %s",
+ &pq.lhq.key, njs_type_string(object->type));
+ return NXT_ERROR;
+ }
+
+ if (prop->type == NJS_PROPERTY_HANDLER) {
+ ret = prop->value.data.u.prop_handler(vm, object, value,
+ &vm->retval);
+ if (ret != NXT_DECLINED) {
+ return ret;
+ }
+ }
+
+ if (pq.own) {
+ switch (prop->type) {
+ case NJS_PROPERTY:
+ case NJS_METHOD:
+ if (nxt_slow_path(pq.shared)) {
+ shared = prop;
+ break;
+ }
+
+ goto found;
+
+ case NJS_PROPERTY_REF:
+ *prop->value.data.u.value = *value;
+ return NXT_OK;
+
+ default:
+ njs_internal_error(vm, "unexpected property type \"%s\" "
+ "while setting",
+ njs_prop_type_string(prop->type));
+
+ return NXT_ERROR;
+ }
+
+ break;
+ }
+
+ /* Fall through. */
+
+ case NXT_DECLINED:
+ if (nxt_slow_path(pq.own_whiteout != NULL)) {
+ /* Previously deleted property. */
+ prop = pq.own_whiteout;
+
+ prop->type = NJS_PROPERTY;
+ prop->enumerable = 1;
+ prop->configurable = 1;
+ prop->writable = 1;
+
+ goto found;
+ }
+
+ break;
+
+ case NJS_TRAP:
+ case NXT_ERROR:
+ default:
+
+ return ret;
+ }
+
+ if (nxt_slow_path(!object->data.u.object->extensible)) {
+ njs_type_error(vm, "Cannot add property \"%V\", "
+ "object is not extensible", &pq.lhq.key);
+ return NXT_ERROR;
+ }
+
+ prop = njs_object_prop_alloc(vm, &pq.value, &njs_value_undefined, 1);
+ if (nxt_slow_path(prop == NULL)) {
+ return NXT_ERROR;
+ }
+
+ if (nxt_slow_path(shared != NULL)) {
+ prop->enumerable = shared->enumerable;
+ prop->configurable = shared->configurable;
+ }
+
+ pq.lhq.replace = 0;
+ pq.lhq.value = prop;
+ pq.lhq.pool = vm->mem_pool;
+
+ ret = nxt_lvlhsh_insert(&object->data.u.object->hash, &pq.lhq);
+ if (nxt_slow_path(ret != NXT_OK)) {
+ njs_internal_error(vm, "lvlhsh insert failed");
+ return NXT_ERROR;
+ }
+
+found:
+
+ prop->value = *value;
+
+ return NXT_OK;
+}
+
+
njs_array_t *
njs_value_enumerate(njs_vm_t *vm, const njs_value_t *value,
njs_object_enum_t kind, nxt_bool_t all)
More information about the nginx-devel
mailing list