[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