]> git.kaiwu.me - njs.git/commitdiff
Added njs_value_property_delete().
authorAlexander Borisov <alexander.borisov@nginx.com>
Thu, 19 Sep 2019 07:19:01 +0000 (10:19 +0300)
committerAlexander Borisov <alexander.borisov@nginx.com>
Thu, 19 Sep 2019 07:19:01 +0000 (10:19 +0300)
src/njs_value.c
src/njs_value.h
src/njs_vmcode.c

index 147a12485153f06ff52eed637e24dcb76de3aa11..cbca82f66f07b019be63e18d2e8391ebb221d99a 100644 (file)
@@ -1133,3 +1133,68 @@ found:
 
     return NJS_OK;
 }
+
+
+njs_int_t
+njs_value_property_delete(njs_vm_t *vm, njs_value_t *value, njs_value_t *key,
+    njs_value_t *removed)
+{
+    njs_int_t             ret;
+    njs_object_prop_t     *prop;
+    njs_property_query_t  pq;
+
+    njs_property_query_init(&pq, NJS_PROPERTY_QUERY_DELETE, 1);
+
+    ret = njs_property_query(vm, &pq, value, key);
+    if (njs_slow_path(ret != NJS_OK)) {
+        return ret;
+    }
+
+    prop = pq.lhq.value;
+
+    if (njs_slow_path(!prop->configurable)) {
+        njs_type_error(vm, "Cannot delete property \"%V\" of %s",
+                       &pq.lhq.key, njs_type_string(value->type));
+        return NJS_ERROR;
+    }
+
+    switch (prop->type) {
+    case NJS_PROPERTY_HANDLER:
+        if (njs_is_external(value)) {
+            ret = prop->value.data.u.prop_handler(vm, value, NULL, NULL);
+            if (njs_slow_path(ret != NJS_OK)) {
+                return NJS_ERROR;
+            }
+
+            return NJS_OK;
+        }
+
+        /* Fall through. */
+
+    case NJS_PROPERTY:
+        break;
+
+    case NJS_PROPERTY_REF:
+        if (removed != NULL) {
+            *removed = *prop->value.data.u.value;
+        }
+
+        njs_set_invalid(prop->value.data.u.value);
+        return NJS_OK;
+
+    default:
+        njs_internal_error(vm, "unexpected property type \"%s\" "
+                           "while deleting", njs_prop_type_string(prop->type));
+        return NJS_ERROR;
+    }
+
+    /* GC: release value. */
+    if (removed != NULL) {
+        *removed = prop->value;
+    }
+
+    prop->type = NJS_WHITEOUT;
+    njs_set_invalid(&prop->value);
+
+    return NJS_OK;
+}
index 2144d082055d40950db2dc602a29b2e02ca2b7d1..dd946b215e6efde6d2e8520297a76fff9c0ac4e6 100644 (file)
@@ -840,6 +840,8 @@ njs_int_t njs_value_property(njs_vm_t *vm, njs_value_t *value,
     njs_value_t *key, njs_value_t *retval);
 njs_int_t njs_value_property_set(njs_vm_t *vm, njs_value_t *value,
     njs_value_t *key, njs_value_t *setval);
+njs_int_t njs_value_property_delete(njs_vm_t *vm, njs_value_t *value,
+    njs_value_t *key, njs_value_t *removed);
 
 
 njs_inline njs_int_t
index 5aaf925fafed85ecdb769a4cc46d35626e1fb571..21af6c290556641c3fe6dff0db46a4630302fd1f 100644 (file)
@@ -29,8 +29,6 @@ static njs_jump_off_t njs_vmcode_proto_init(njs_vm_t *vm, njs_value_t *value,
     njs_value_t *key, njs_value_t *retval);
 static njs_jump_off_t njs_vmcode_property_in(njs_vm_t *vm,
     njs_value_t *value, njs_value_t *key);
-static njs_jump_off_t njs_vmcode_property_delete(njs_vm_t *vm,
-    njs_value_t *value, njs_value_t *key);
 static njs_jump_off_t njs_vmcode_property_foreach(njs_vm_t *vm,
     njs_value_t *object, njs_value_t *invld, u_char *pc);
 static njs_jump_off_t njs_vmcode_property_next(njs_vm_t *vm,
@@ -453,7 +451,13 @@ next:
                 break;
 
             case NJS_VMCODE_PROPERTY_DELETE:
-                ret = njs_vmcode_property_delete(vm, value1, value2);
+                ret = njs_value_property_delete(vm, value1, value2, NULL);
+                if (njs_fast_path(ret != NJS_ERROR)) {
+                    vm->retval = njs_value_true;
+
+                    ret = sizeof(njs_vmcode_3addr_t);
+                }
+
                 break;
 
             case NJS_VMCODE_PROPERTY_FOREACH:
@@ -1279,79 +1283,6 @@ njs_vmcode_property_in(njs_vm_t *vm, njs_value_t *value, njs_value_t *key)
 }
 
 
-static njs_jump_off_t
-njs_vmcode_property_delete(njs_vm_t *vm, njs_value_t *value, njs_value_t *key)
-{
-    njs_jump_off_t        ret;
-    njs_object_prop_t     *prop;
-    njs_property_query_t  pq;
-
-    njs_property_query_init(&pq, NJS_PROPERTY_QUERY_DELETE, 1);
-
-    ret = njs_property_query(vm, &pq, value, key);
-
-    switch (ret) {
-
-    case NJS_OK:
-        prop = pq.lhq.value;
-
-        if (njs_slow_path(!prop->configurable)) {
-            njs_type_error(vm, "Cannot delete property \"%V\" of %s",
-                           &pq.lhq.key, njs_type_string(value->type));
-            return NJS_ERROR;
-        }
-
-        switch (prop->type) {
-        case NJS_PROPERTY_HANDLER:
-            if (njs_is_external(value)) {
-                ret = prop->value.data.u.prop_handler(vm, value, NULL, NULL);
-                if (njs_slow_path(ret != NJS_OK)) {
-                    return NJS_ERROR;
-                }
-
-                goto done;
-            }
-
-            /* Fall through. */
-
-        case NJS_PROPERTY:
-            break;
-
-        case NJS_PROPERTY_REF:
-            njs_set_invalid(prop->value.data.u.value);
-            goto done;
-
-        default:
-            njs_internal_error(vm, "unexpected property type \"%s\" "
-                               "while deleting",
-                               njs_prop_type_string(prop->type));
-
-            return NJS_ERROR;
-        }
-
-        /* GC: release value. */
-        prop->type = NJS_WHITEOUT;
-        njs_set_invalid(&prop->value);
-
-        break;
-
-    case NJS_DECLINED:
-        break;
-
-    case NJS_ERROR:
-    default:
-
-        return ret;
-    }
-
-done:
-
-    vm->retval = njs_value_true;
-
-    return sizeof(njs_vmcode_3addr_t);
-}
-
-
 static njs_jump_off_t
 njs_vmcode_property_foreach(njs_vm_t *vm, njs_value_t *object,
     njs_value_t *invld, u_char *pc)