diff options
Diffstat (limited to 'src/njs_value.c')
-rw-r--r-- | src/njs_value.c | 133 |
1 files changed, 56 insertions, 77 deletions
diff --git a/src/njs_value.c b/src/njs_value.c index dcdab5a2..7959c4ed 100644 --- a/src/njs_value.c +++ b/src/njs_value.c @@ -8,8 +8,9 @@ #include <njs_main.h> -static njs_int_t njs_object_property_query(njs_vm_t *vm, - njs_property_query_t *pq, njs_object_t *object, uint32_t atom_id); +njs_inline njs_int_t +njs_object_property_query(njs_vm_t *vm, njs_property_query_t *pq, + njs_object_t *object, uint32_t atom_id); static njs_int_t njs_array_property_query(njs_vm_t *vm, njs_property_query_t *pq, njs_array_t *array, uint32_t index, uint32_t atom_id); @@ -42,7 +43,7 @@ njs_value_to_primitive(njs_vm_t *vm, njs_value_t *dst, njs_value_t *value, njs_int_t ret; njs_uint_t tries; njs_value_t method, retval; - njs_flathsh_query_t lhq; + njs_flathsh_query_t fhq; static const uint32_t atoms[] = { NJS_ATOM_STRING_valueOf, @@ -55,7 +56,7 @@ njs_value_to_primitive(njs_vm_t *vm, njs_value_t *dst, njs_value_t *value, } tries = 0; - lhq.proto = &njs_object_hash_proto; + fhq.proto = &njs_object_hash_proto; for ( ;; ) { ret = NJS_ERROR; @@ -63,9 +64,9 @@ njs_value_to_primitive(njs_vm_t *vm, njs_value_t *dst, njs_value_t *value, if (njs_is_object(value) && tries < 2) { hint ^= tries++; - lhq.key_hash = atoms[hint]; + fhq.key_hash = atoms[hint]; - ret = njs_object_property(vm, njs_object(value), &lhq, &method); + ret = njs_object_property(vm, njs_object(value), &fhq, &method); if (njs_slow_path(ret == NJS_ERROR)) { return ret; @@ -541,7 +542,7 @@ njs_value_is_data_view(const njs_value_t *value) * ES5.1, 8.12.1: [[GetOwnProperty]], [[GetProperty]]. * The njs_property_query() returns values * NJS_OK property has been found in object, - * retval of type njs_object_prop_t * is in pq->lhq.value. + * retval of type njs_object_prop_t * is in pq->fhq.value. * in NJS_PROPERTY_QUERY_GET * prop->type is NJS_PROPERTY or NJS_PROPERTY_HANDLER. * in NJS_PROPERTY_QUERY_SET, NJS_PROPERTY_QUERY_DELETE @@ -549,7 +550,7 @@ njs_value_is_data_view(const njs_value_t *value) * NJS_PROPERTY_TYPED_ARRAY_REF or * NJS_PROPERTY_HANDLER. * NJS_DECLINED property was not found in object, - * if pq->lhq.value != NULL it contains retval of type + * if pq->fhq.value != NULL it contains retval of type * njs_object_prop_t * where prop->type is NJS_WHITEOUT * NJS_ERROR exception has been thrown. */ @@ -560,9 +561,7 @@ njs_property_query(njs_vm_t *vm, njs_property_query_t *pq, njs_value_t *value, { uint32_t index; njs_int_t ret; - njs_value_t key; njs_object_t *obj; - njs_function_t *function; njs_assert(atom_id != NJS_ATOM_STRING_unknown); @@ -585,6 +584,7 @@ njs_property_query(njs_vm_t *vm, njs_property_query_t *pq, njs_value_t *value, case NJS_OBJECT: case NJS_ARRAY: + case NJS_FUNCTION: case NJS_ARRAY_BUFFER: case NJS_DATA_VIEW: case NJS_TYPED_ARRAY: @@ -595,31 +595,12 @@ njs_property_query(njs_vm_t *vm, njs_property_query_t *pq, njs_value_t *value, obj = njs_object(value); break; - case NJS_FUNCTION: - function = njs_function_value_copy(vm, value); - if (njs_slow_path(function == NULL)) { - return NJS_ERROR; - } - - obj = &function->object; - break; - case NJS_UNDEFINED: case NJS_NULL: default: - ret = njs_atom_to_value(vm, &key, atom_id); - - if (njs_fast_path(ret == NJS_OK)) { - njs_string_get(vm, &key, &pq->lhq.key); - njs_type_error(vm, "cannot get property \"%V\" of %s", - &pq->lhq.key, njs_is_null(value) ? "null" - : "undefined"); - return NJS_ERROR; - } - - njs_type_error(vm, "cannot get property \"unknown\" of %s", - njs_is_null(value) ? "null" : "undefined"); - + njs_atom_string_get(vm, atom_id, &pq->fhq.key); + njs_type_error(vm, "cannot get property \"%V\" of %s", &pq->fhq.key, + njs_type_string(value->type)); return NJS_ERROR; } @@ -647,7 +628,7 @@ njs_object_property_query(njs_vm_t *vm, njs_property_query_t *pq, njs_typed_array_t *tarray; njs_object_value_t *ov; - pq->lhq.proto = &njs_object_hash_proto; + pq->fhq.proto = &njs_object_hash_proto; own = pq->own; pq->own = 1; @@ -724,12 +705,12 @@ njs_object_property_query(njs_vm_t *vm, njs_property_query_t *pq, break; } - pq->lhq.key_hash = atom_id; + pq->fhq.key_hash = atom_id; - ret = njs_flathsh_unique_find(&proto->hash, &pq->lhq); + ret = njs_flathsh_unique_find(&proto->hash, &pq->fhq); if (ret == NJS_OK) { - prop = pq->lhq.value; + prop = pq->fhq.value; if (prop->type != NJS_WHITEOUT) { return ret; @@ -740,7 +721,7 @@ njs_object_property_query(njs_vm_t *vm, njs_property_query_t *pq, } } else { - ret = njs_flathsh_unique_find(&proto->shared_hash, &pq->lhq); + ret = njs_flathsh_unique_find(&proto->shared_hash, &pq->fhq); if (ret == NJS_OK) { return njs_prop_private_copy(vm, pq, proto); } @@ -822,11 +803,11 @@ njs_array_property_query(njs_vm_t *vm, njs_property_query_t *pq, } } - pq->lhq.key_hash = atom_id; + pq->fhq.key_hash = atom_id; - ret = njs_flathsh_unique_find(&array->object.hash, &pq->lhq); + ret = njs_flathsh_unique_find(&array->object.hash, &pq->fhq); if (ret == NJS_OK) { - prop = pq->lhq.value; + prop = pq->fhq.value; if (prop->type != NJS_WHITEOUT) { return NJS_OK; @@ -871,7 +852,7 @@ prop: prop->enumerable = 1; prop->configurable = 1; - pq->lhq.value = prop; + pq->fhq.value = prop; return NJS_OK; } @@ -909,7 +890,7 @@ njs_typed_array_property_query(njs_vm_t *vm, njs_property_query_t *pq, prop->enumerable = 1; prop->configurable = 0; - pq->lhq.value = prop; + pq->fhq.value = prop; return NJS_OK; } @@ -941,7 +922,7 @@ njs_string_property_query(njs_vm_t *vm, njs_property_query_t *pq, prop->enumerable = 1; prop->configurable = 0; - pq->lhq.value = prop; + pq->fhq.value = prop; return NJS_OK; } @@ -977,8 +958,9 @@ njs_external_property_query(njs_vm_t *vm, njs_property_query_t *pq, njs_prop_magic32(prop) = slots->magic32; - pq->lhq.value = prop; + pq->fhq.value = prop; + prop->type = NJS_PROPERTY; prop->writable = slots->writable; prop->configurable = slots->configurable; prop->enumerable = slots->enumerable; @@ -986,7 +968,7 @@ njs_external_property_query(njs_vm_t *vm, njs_property_query_t *pq, switch (pq->query) { case NJS_PROPERTY_QUERY_GET: - return slots->prop_handler(vm, prop, pq->lhq.key_hash, value, NULL, + return slots->prop_handler(vm, prop, pq->fhq.key_hash, value, NULL, njs_prop_value(prop)); case NJS_PROPERTY_QUERY_SET: @@ -1029,8 +1011,7 @@ njs_value_property(njs_vm_t *vm, njs_value_t *value, uint32_t atom_id, tarray = njs_typed_array(value); if (njs_slow_path(njs_is_detached_buffer(tarray->buffer))) { - njs_type_error(vm, "detached buffer"); - return NJS_ERROR; + goto not_found; } if (njs_slow_path(index >= njs_typed_array_length(tarray))) { @@ -1072,7 +1053,7 @@ slow_path: switch (ret) { case NJS_OK: - prop = pq.lhq.value; + prop = pq.fhq.value; switch (prop->type) { case NJS_PROPERTY: @@ -1119,6 +1100,7 @@ slow_path: break; case NJS_DECLINED: +not_found: njs_set_undefined(retval); return NJS_DECLINED; @@ -1194,14 +1176,14 @@ slow_path: switch (ret) { case NJS_OK: - prop = pq.lhq.value; + prop = pq.fhq.value; if (njs_is_data_descriptor(prop)) { if (!prop->writable) { - njs_atom_string_get(vm, atom_id, &pq.lhq.key); + njs_atom_string_get(vm, atom_id, &pq.fhq.key); njs_type_error(vm, "Cannot assign to read-only property \"%V\" of %s", - &pq.lhq.key, njs_type_string(value->type)); + &pq.fhq.key, njs_type_string(value->type)); return NJS_ERROR; } @@ -1211,10 +1193,10 @@ slow_path: value, setval, 1, &retval); } - njs_atom_string_get(vm, atom_id, &pq.lhq.key); + njs_atom_string_get(vm, atom_id, &pq.fhq.key); njs_type_error(vm, "Cannot set property \"%V\" of %s which has only a getter", - &pq.lhq.key, njs_type_string(value->type)); + &pq.fhq.key, njs_type_string(value->type)); return NJS_ERROR; } @@ -1275,9 +1257,9 @@ slow_path: goto fail; } - pq.lhq.pool = vm->mem_pool; + pq.fhq.pool = vm->mem_pool; - int rc = njs_flathsh_unique_delete(pq.own_whiteout, &pq.lhq); + int rc = njs_flathsh_unique_delete(pq.own_whiteout, &pq.fhq); if (rc != NJS_OK) { return NJS_ERROR; } @@ -1285,7 +1267,7 @@ slow_path: h = pq.own_whiteout->slot; if (h == NULL) { - h = njs_flathsh_new(&pq.lhq); + h = njs_flathsh_new(&pq.fhq); if (njs_slow_path(h == NULL)) { return NJS_ERROR; } @@ -1293,15 +1275,12 @@ slow_path: pq.own_whiteout->slot = h; } - elt = njs_flathsh_add_elt(pq.own_whiteout, &pq.lhq); + elt = njs_flathsh_add_elt(pq.own_whiteout, &pq.fhq); if (njs_slow_path(elt == NULL)) { return NJS_ERROR; } - elt->value = (&pq.lhq)->value; - - prop = (njs_object_prop_t *) elt->value; - + prop = (njs_object_prop_t *) elt; prop->type = NJS_PROPERTY; prop->enumerable = 1; prop->configurable = 1; @@ -1337,22 +1316,23 @@ slow_path: goto fail; } - prop = njs_object_prop_alloc(vm, &njs_value_undefined, 1); - if (njs_slow_path(prop == NULL)) { - return NJS_ERROR; - } - pq.lhq.replace = 0; - pq.lhq.value = prop; - pq.lhq.key_hash = atom_id; - pq.lhq.pool = vm->mem_pool; + pq.fhq.replace = 0; + pq.fhq.key_hash = atom_id; + pq.fhq.pool = vm->mem_pool; - ret = njs_flathsh_unique_insert(njs_object_hash(value), &pq.lhq); + ret = njs_flathsh_unique_insert(njs_object_hash(value), &pq.fhq); if (njs_slow_path(ret != NJS_OK)) { - njs_internal_error(vm, "lvlhsh insert failed"); + njs_internal_error(vm, "flathsh insert failed"); return NJS_ERROR; } + prop = pq.fhq.value; + prop->type = NJS_PROPERTY; + prop->enumerable = 1; + prop->configurable = 1; + prop->writable = 1; + found: njs_value_assign(njs_prop_value(prop), setval); @@ -1361,9 +1341,9 @@ found: fail: - njs_atom_string_get(vm, atom_id, &pq.lhq.key); + njs_atom_string_get(vm, atom_id, &pq.fhq.key); njs_type_error(vm, "Cannot add property \"%V\", object is not extensible", - &pq.lhq.key); + &pq.fhq.key); return NJS_ERROR; } @@ -1406,13 +1386,13 @@ slow_path: return ret; } - prop = pq.lhq.value; + prop = pq.fhq.value; if (njs_slow_path(!prop->configurable)) { if (thrw) { - njs_atom_string_get(vm, atom_id, &pq.lhq.key); + njs_atom_string_get(vm, atom_id, &pq.fhq.key); njs_type_error(vm, "Cannot delete property \"%V\" of %s", - &pq.lhq.key, njs_type_string(value->type)); + &pq.fhq.key, njs_type_string(value->type)); return NJS_ERROR; } @@ -1471,7 +1451,6 @@ slow_path: } prop->type = NJS_WHITEOUT; - prop->enum_in_object_hash = 1; return NJS_OK; } |