From: Alexander Borisov Date: Thu, 23 May 2019 14:39:22 +0000 (+0300) Subject: Added njs_value_property_set() function. X-Git-Tag: 0.3.3~30 X-Git-Url: http://git.kaiwu.me/postgresql/log/contrib/postgres_fdw/static/gitweb.js?a=commitdiff_plain;h=1301519e99819a25cfb5e75b7641dee81d546146;p=njs.git Added njs_value_property_set() function. --- diff --git a/njs/njs_object.h b/njs/njs_object.h index cb6a2cf3..ad7780fa 100644 --- a/njs/njs_object.h +++ b/njs/njs_object.h @@ -88,6 +88,8 @@ njs_array_t *njs_object_own_enumerate(njs_vm_t *vm, const njs_object_t *object, 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 --git a/njs/njs_vm.c b/njs/njs_vm.c index 4a585947..f7ba55c9 100644 --- a/njs/njs_vm.c +++ b/njs/njs_vm.c @@ -660,134 +660,17 @@ njs_vmcode_property_set(njs_vm_t *vm, njs_value_t *object, { 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 njs_value_t *value, } +/* + * 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)