/** * Find named data property or named access property in specified object. * * @return pointer to the property, if it is found, * NULL - otherwise. */ ecma_property_t * ecma_find_named_property (ecma_object_t *obj_p, /**< object to find property in */ ecma_string_t *name_p) /**< property's name */ { JERRY_ASSERT (obj_p != NULL); JERRY_ASSERT (name_p != NULL); ecma_property_t *property_p; if (ecma_lcache_lookup (obj_p, name_p, &property_p)) { return property_p; } property_p = NULL; ecma_property_header_t *prop_iter_p = ecma_get_property_list (obj_p); while (prop_iter_p != NULL) { JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (prop_iter_p)); ecma_property_pair_t *prop_pair_p = (ecma_property_pair_t *) prop_iter_p; JERRY_ASSERT (ECMA_PROPERTY_PAIR_ITEM_COUNT == 2); if (prop_pair_p->names_cp[0] != ECMA_NULL_POINTER) { ecma_string_t *property_name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t, prop_pair_p->names_cp[0]); if (ecma_compare_ecma_strings (name_p, property_name_p)) { property_p = prop_iter_p->types + 0; break; } } if (prop_pair_p->names_cp[1] != ECMA_NULL_POINTER) { ecma_string_t *property_name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t, prop_pair_p->names_cp[1]); if (ecma_compare_ecma_strings (name_p, property_name_p)) { property_p = prop_iter_p->types + 1; break; } } prop_iter_p = ECMA_GET_POINTER (ecma_property_header_t, prop_iter_p->next_property_cp); } ecma_lcache_insert (obj_p, name_p, property_p); return property_p; } /* ecma_find_named_property */
/** * [[GetOwnProperty]] ecma object's operation * * See also: * ECMA-262 v5, 8.6.2; ECMA-262 v5, Table 8 * * @return pointer to a property - if it exists, * NULL (i.e. ecma-undefined) - otherwise. */ ecma_property_t* ecma_op_object_get_own_property (ecma_object_t *obj_p, /**< the object */ ecma_string_t *property_name_p) /**< property name */ { JERRY_ASSERT (obj_p != NULL && !ecma_is_lexical_environment (obj_p)); JERRY_ASSERT (property_name_p != NULL); ecma_property_t *prop_p = NULL; if (likely (ecma_lcache_lookup (obj_p, property_name_p, &prop_p))) { return prop_p; } else { return ecma_op_object_get_own_property_longpath (obj_p, property_name_p); } } /* ecma_op_object_get_own_property */
/** * Resolve value corresponding to reference. * * @return value of the reference */ ecma_value_t ecma_op_resolve_reference_value (ecma_object_t *lex_env_p, /**< starting lexical environment */ ecma_string_t *name_p) /**< identifier's name */ { JERRY_ASSERT (lex_env_p != NULL); while (lex_env_p != NULL) { ecma_lexical_environment_type_t lex_env_type = ecma_get_lex_env_type (lex_env_p); if (lex_env_type == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE) { ecma_property_t *property_p = ecma_find_named_property (lex_env_p, name_p); if (property_p != NULL) { return ecma_fast_copy_value (ECMA_PROPERTY_VALUE_PTR (property_p)->value); } } else if (lex_env_type == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND) { ecma_object_t *binding_obj_p = ecma_get_lex_env_binding_object (lex_env_p); #ifndef CONFIG_ECMA_LCACHE_DISABLE ecma_property_t *property_p = ecma_lcache_lookup (binding_obj_p, name_p); if (property_p != NULL) { ecma_property_value_t *prop_value_p = ECMA_PROPERTY_VALUE_PTR (property_p); if (ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDDATA) { return ecma_fast_copy_value (prop_value_p->value); } JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR); ecma_object_t *getter_p = ecma_get_named_accessor_property_getter (prop_value_p); if (getter_p == NULL) { return ECMA_VALUE_UNDEFINED; } ecma_value_t base_value = ecma_make_object_value (binding_obj_p); return ecma_op_function_call (getter_p, base_value, NULL, 0); } #endif /* !CONFIG_ECMA_LCACHE_DISABLE */ ecma_value_t prop_value = ecma_op_object_find (binding_obj_p, name_p); if (ecma_is_value_found (prop_value)) { return prop_value; } } else { #if ENABLED (JERRY_ES2015_CLASS) JERRY_ASSERT (lex_env_type == ECMA_LEXICAL_ENVIRONMENT_SUPER_OBJECT_BOUND); #else /* !ENABLED (JERRY_ES2015_CLASS) */ JERRY_UNREACHABLE (); #endif /* ENABLED (JERRY_ES2015_CLASS) */ } lex_env_p = ecma_get_lex_env_outer_reference (lex_env_p); } #ifdef JERRY_ENABLE_ERROR_MESSAGES ecma_value_t name_val = ecma_make_string_value (name_p); ecma_value_t error_value = ecma_raise_standard_error_with_format (ECMA_ERROR_REFERENCE, "% is not defined", name_val); #else /* !JERRY_ENABLE_ERROR_MESSAGES */ ecma_value_t error_value = ecma_raise_reference_error (NULL); #endif /* JERRY_ENABLE_ERROR_MESSAGES */ return error_value; } /* ecma_op_resolve_reference_value */
/** * Find named data property or named access property in specified object. * * @return pointer to the property, if it is found, * NULL - otherwise. */ ecma_property_t * ecma_find_named_property (ecma_object_t *obj_p, /**< object to find property in */ ecma_string_t *name_p) /**< property's name */ { JERRY_ASSERT (obj_p != NULL); JERRY_ASSERT (name_p != NULL); ecma_property_t *property_p = ecma_lcache_lookup (obj_p, name_p); if (property_p != NULL) { return property_p; } ecma_property_header_t *prop_iter_p = ecma_get_property_list (obj_p); #ifndef CONFIG_ECMA_PROPERTY_HASHMAP_DISABLE if (prop_iter_p != NULL && ECMA_PROPERTY_GET_TYPE (prop_iter_p->types + 0) == ECMA_PROPERTY_TYPE_HASHMAP) { ecma_string_t *property_real_name_p; property_p = ecma_property_hashmap_find ((ecma_property_hashmap_t *) prop_iter_p, name_p, &property_real_name_p); if (property_p != NULL && !ecma_is_property_lcached (property_p)) { ecma_lcache_insert (obj_p, property_real_name_p, property_p); } return property_p; } #endif /* !CONFIG_ECMA_PROPERTY_HASHMAP_DISABLE */ property_p = NULL; ecma_string_t *property_name_p = NULL; uint32_t steps = 0; while (prop_iter_p != NULL) { JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (prop_iter_p)); ecma_property_pair_t *prop_pair_p = (ecma_property_pair_t *) prop_iter_p; JERRY_ASSERT (ECMA_PROPERTY_PAIR_ITEM_COUNT == 2); if (prop_pair_p->names_cp[0] != ECMA_NULL_POINTER) { property_name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t, prop_pair_p->names_cp[0]); if (ecma_compare_ecma_strings (name_p, property_name_p)) { property_p = prop_iter_p->types + 0; break; } } if (prop_pair_p->names_cp[1] != ECMA_NULL_POINTER) { property_name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t, prop_pair_p->names_cp[1]); if (ecma_compare_ecma_strings (name_p, property_name_p)) { property_p = prop_iter_p->types + 1; break; } } steps++; prop_iter_p = ECMA_GET_POINTER (ecma_property_header_t, prop_iter_p->next_property_cp); } if (steps > (ECMA_PROPERTY_HASMAP_MINIMUM_SIZE / 4)) { ecma_property_hashmap_create (obj_p); } if (property_p != NULL && !ecma_is_property_lcached (property_p)) { ecma_lcache_insert (obj_p, property_name_p, property_p); } return property_p; } /* ecma_find_named_property */