/** * Free property values and change their type to deleted. */ void ecma_free_property (ecma_object_t *object_p, /**< object the property belongs to */ ecma_string_t *name_p, /**< name of the property or NULL */ ecma_property_t *property_p) /**< property */ { JERRY_ASSERT (object_p != NULL && property_p != NULL); switch (ECMA_PROPERTY_GET_TYPE (property_p)) { case ECMA_PROPERTY_TYPE_NAMEDDATA: { ecma_free_named_data_property (object_p, property_p); ecma_lcache_invalidate (object_p, name_p, property_p); break; } case ECMA_PROPERTY_TYPE_NAMEDACCESSOR: { ecma_lcache_invalidate (object_p, name_p, property_p); break; } case ECMA_PROPERTY_TYPE_INTERNAL: { JERRY_ASSERT (name_p == NULL); ecma_free_internal_property (property_p); break; } default: { JERRY_UNREACHABLE (); break; } } property_p->type_and_flags = ECMA_PROPERTY_TYPE_DELETED; } /* ecma_free_property */
/** * Create named data property with given name, attributes and undefined value * in the specified object. * * @return pointer to newly created property */ ecma_property_t * ecma_create_named_data_property (ecma_object_t *object_p, /**< object */ ecma_string_t *name_p, /**< property name */ bool is_writable, /**< 'Writable' attribute */ bool is_enumerable, /**< 'Enumerable' attribute */ bool is_configurable) /**< 'Configurable' attribute */ { JERRY_ASSERT (object_p != NULL && name_p != NULL); JERRY_ASSERT (ecma_find_named_property (object_p, name_p) == NULL); uint8_t type_and_flags = ECMA_PROPERTY_TYPE_NAMEDDATA; if (is_configurable) { type_and_flags = (uint8_t) (type_and_flags | ECMA_PROPERTY_FLAG_CONFIGURABLE); } if (is_enumerable) { type_and_flags = (uint8_t) (type_and_flags | ECMA_PROPERTY_FLAG_ENUMERABLE); } if (is_writable) { type_and_flags = (uint8_t) (type_and_flags | ECMA_PROPERTY_FLAG_WRITABLE); } name_p = ecma_copy_or_ref_ecma_string (name_p); ecma_property_t *property_p = ecma_create_property (object_p, name_p, type_and_flags); ecma_set_named_data_property_value (property_p, ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED)); ecma_lcache_invalidate (object_p, name_p, NULL); return property_p; } /* ecma_create_named_data_property */
/** * Create named accessor property with given name, attributes, getter and setter. * * @return pointer to newly created property */ ecma_property_t * ecma_create_named_accessor_property (ecma_object_t *object_p, /**< object */ ecma_string_t *name_p, /**< property name */ ecma_object_t *get_p, /**< getter */ ecma_object_t *set_p, /**< setter */ bool is_enumerable, /**< 'enumerable' attribute */ bool is_configurable) /**< 'configurable' attribute */ { JERRY_ASSERT (object_p != NULL && name_p != NULL); JERRY_ASSERT (ecma_find_named_property (object_p, name_p) == NULL); uint8_t type_and_flags = ECMA_PROPERTY_TYPE_NAMEDACCESSOR; if (is_configurable) { type_and_flags = (uint8_t) (type_and_flags | ECMA_PROPERTY_FLAG_CONFIGURABLE); } if (is_enumerable) { type_and_flags = (uint8_t) (type_and_flags | ECMA_PROPERTY_FLAG_ENUMERABLE); } name_p = ecma_copy_or_ref_ecma_string (name_p); ecma_property_t *property_p = ecma_create_property (object_p, name_p, type_and_flags); /* * Should be performed after linking the property into object's property list, because the setters assert that. */ ecma_set_named_accessor_property_getter (object_p, property_p, get_p); ecma_set_named_accessor_property_setter (object_p, property_p, set_p); ecma_lcache_invalidate (object_p, name_p, NULL); return property_p; } /* ecma_create_named_accessor_property */
/** * Free property values and change their type to deleted. */ void ecma_free_property (ecma_object_t *object_p, /**< object the property belongs to */ jmem_cpointer_t name_cp, /**< name of the property or ECMA_NULL_POINTER */ ecma_property_t *property_p) /**< property */ { JERRY_ASSERT (object_p != NULL && property_p != NULL); switch (ECMA_PROPERTY_GET_TYPE (*property_p)) { case ECMA_PROPERTY_TYPE_NAMEDDATA: { if (ECMA_PROPERTY_GET_NAME_TYPE (*property_p) == ECMA_STRING_CONTAINER_MAGIC_STRING) { if (name_cp == LIT_INTERNAL_MAGIC_STRING_NATIVE_HANDLE || name_cp == LIT_INTERNAL_MAGIC_STRING_NATIVE_POINTER) { ecma_free_native_pointer (property_p); break; } } ecma_free_value_if_not_object (ECMA_PROPERTY_VALUE_PTR (property_p)->value); break; } case ECMA_PROPERTY_TYPE_NAMEDACCESSOR: { #ifdef JERRY_CPOINTER_32_BIT ecma_getter_setter_pointers_t *getter_setter_pair_p; getter_setter_pair_p = ECMA_GET_POINTER (ecma_getter_setter_pointers_t, ECMA_PROPERTY_VALUE_PTR (property_p)->getter_setter_pair_cp); jmem_pools_free (getter_setter_pair_p, sizeof (ecma_getter_setter_pointers_t)); #endif /* JERRY_CPOINTER_32_BIT */ break; } default: { JERRY_UNREACHABLE (); return; } } if (ecma_is_property_lcached (property_p)) { ecma_lcache_invalidate (object_p, name_cp, property_p); } if (ECMA_PROPERTY_GET_NAME_TYPE (*property_p) == ECMA_PROPERTY_NAME_TYPE_STRING) { ecma_string_t *prop_name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t, name_cp); ecma_deref_ecma_string (prop_name_p); } *property_p = ECMA_PROPERTY_TYPE_DELETED; } /* ecma_free_property */
/** * Get value of function's argument mapped to index of Arguments object. * * Note: * The procedure emulates execution of function described by MakeArgGetter * * @return ecma value * Returned value must be freed with ecma_free_value */ void ecma_arguments_update_mapped_arg_value (ecma_object_t *object_p, /**< the object */ ecma_string_t *property_name_p, /**< property name */ ecma_property_t *property_p) /**< property value */ { ecma_value_t *map_prop_p = ecma_get_internal_property (object_p, ECMA_INTERNAL_PROPERTY_PARAMETERS_MAP); ecma_object_t *map_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t, *map_prop_p); ecma_value_t arg_name = ecma_op_object_find (map_p, property_name_p); if (!ecma_is_value_found (arg_name)) { return; } ecma_value_t *scope_prop_p = ecma_get_internal_property (map_p, ECMA_INTERNAL_PROPERTY_SCOPE); ecma_object_t *lex_env_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t, *scope_prop_p); JERRY_ASSERT (lex_env_p != NULL && ecma_is_lexical_environment (lex_env_p)); ecma_string_t *arg_name_p = ecma_get_string_from_value (arg_name); ecma_value_t value = ecma_op_get_binding_value (lex_env_p, arg_name_p, true); ecma_deref_ecma_string (arg_name_p); JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (value)); ecma_named_data_property_assign_value (object_p, property_p, value); ecma_free_value (value); /* These properties cannot be cached. This is a temporary * workaround until the property management is fully rewritten. */ if (ecma_is_property_lcached (property_p)) { ecma_lcache_invalidate (object_p, property_name_p, property_p); } } /* ecma_arguments_update_mapped_arg_value */