Major property rework: introducing virtual properties.

Properties are changed to a type and value pair instead of a pointer to an internal
representation. Functions such as ecma_op_object_get_[own_]property do not
return with property pointers anymore.

JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
Zoltan Herczeg 2016-09-19 00:32:38 -07:00
parent ea96430e77
commit dcaec22c0c
32 changed files with 852 additions and 931 deletions

View File

@ -166,11 +166,11 @@ ecma_deref_object (ecma_object_t *object_p) /**< object */
static void
ecma_gc_mark_property (ecma_property_t *property_p) /**< property */
{
switch (ECMA_PROPERTY_GET_TYPE (property_p))
switch (ECMA_PROPERTY_GET_TYPE (*property_p))
{
case ECMA_PROPERTY_TYPE_NAMEDDATA:
{
ecma_value_t value = ecma_get_named_data_property_value (property_p);
ecma_value_t value = ECMA_PROPERTY_VALUE_PTR (property_p)->value;
if (ecma_is_value_object (value))
{
@ -182,8 +182,9 @@ ecma_gc_mark_property (ecma_property_t *property_p) /**< property */
}
case ECMA_PROPERTY_TYPE_NAMEDACCESSOR:
{
ecma_object_t *getter_obj_p = ecma_get_named_accessor_property_getter (property_p);
ecma_object_t *setter_obj_p = ecma_get_named_accessor_property_setter (property_p);
ecma_property_value_t *prop_value_p = ECMA_PROPERTY_VALUE_PTR (property_p);
ecma_object_t *getter_obj_p = ecma_get_named_accessor_property_getter (prop_value_p);
ecma_object_t *setter_obj_p = ecma_get_named_accessor_property_setter (prop_value_p);
if (getter_obj_p != NULL)
{
@ -328,7 +329,7 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */
ecma_property_header_t *prop_iter_p = ecma_get_property_list (object_p);
if (prop_iter_p != NULL
&& ECMA_PROPERTY_GET_TYPE (prop_iter_p->types + 0) == ECMA_PROPERTY_TYPE_HASHMAP)
&& ECMA_PROPERTY_GET_TYPE (prop_iter_p->types[0]) == ECMA_PROPERTY_TYPE_HASHMAP)
{
prop_iter_p = ECMA_GET_POINTER (ecma_property_header_t,
prop_iter_p->next_property_cp);
@ -338,12 +339,12 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */
{
JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (prop_iter_p));
if (prop_iter_p->types[0].type_and_flags != ECMA_PROPERTY_TYPE_DELETED)
if (prop_iter_p->types[0] != ECMA_PROPERTY_TYPE_DELETED)
{
ecma_gc_mark_property (prop_iter_p->types + 0);
}
if (prop_iter_p->types[1].type_and_flags != ECMA_PROPERTY_TYPE_DELETED)
if (prop_iter_p->types[1] != ECMA_PROPERTY_TYPE_DELETED)
{
ecma_gc_mark_property (prop_iter_p->types + 1);
}
@ -392,7 +393,7 @@ ecma_gc_sweep (ecma_object_t *object_p) /**< object to free */
ecma_property_header_t *prop_iter_p = ecma_get_property_list (object_p);
if (prop_iter_p != NULL
&& ECMA_PROPERTY_GET_TYPE (prop_iter_p->types + 0) == ECMA_PROPERTY_TYPE_HASHMAP)
&& ECMA_PROPERTY_GET_TYPE (prop_iter_p->types[0]) == ECMA_PROPERTY_TYPE_HASHMAP)
{
ecma_property_hashmap_free (object_p);
prop_iter_p = ecma_get_property_list (object_p);
@ -403,14 +404,14 @@ ecma_gc_sweep (ecma_object_t *object_p) /**< object to free */
JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (prop_iter_p));
/* Both cannot be deleted. */
JERRY_ASSERT (prop_iter_p->types[0].type_and_flags != ECMA_PROPERTY_TYPE_DELETED
|| prop_iter_p->types[1].type_and_flags != ECMA_PROPERTY_TYPE_DELETED);
JERRY_ASSERT (prop_iter_p->types[0] != ECMA_PROPERTY_TYPE_DELETED
|| prop_iter_p->types[1] != ECMA_PROPERTY_TYPE_DELETED);
ecma_property_pair_t *prop_pair_p = (ecma_property_pair_t *) prop_iter_p;
for (int i = 0; i < ECMA_PROPERTY_PAIR_ITEM_COUNT; i++)
{
if (prop_iter_p->types[i].type_and_flags != ECMA_PROPERTY_TYPE_DELETED)
if (prop_iter_p->types[i] != ECMA_PROPERTY_TYPE_DELETED)
{
ecma_string_t *name_p = ECMA_GET_POINTER (ecma_string_t, prop_pair_p->names_cp[i]);
@ -424,8 +425,8 @@ ecma_gc_sweep (ecma_object_t *object_p) /**< object to free */
}
/* Both must be deleted. */
JERRY_ASSERT (prop_iter_p->types[0].type_and_flags == ECMA_PROPERTY_TYPE_DELETED
&& prop_iter_p->types[1].type_and_flags == ECMA_PROPERTY_TYPE_DELETED);
JERRY_ASSERT (prop_iter_p->types[0] == ECMA_PROPERTY_TYPE_DELETED
&& prop_iter_p->types[1] == ECMA_PROPERTY_TYPE_DELETED);
prop_iter_p = ECMA_GET_POINTER (ecma_property_header_t,
prop_iter_p->next_property_cp);
@ -555,7 +556,7 @@ ecma_gc_run (jmem_free_unused_memory_severity_t severity) /**< gc severity */
{
ecma_property_header_t *prop_iter_p = ecma_get_property_list (obj_iter_p);
if (prop_iter_p != NULL
&& ECMA_PROPERTY_GET_TYPE (prop_iter_p->types + 0) == ECMA_PROPERTY_TYPE_HASHMAP)
&& ECMA_PROPERTY_GET_TYPE (prop_iter_p->types[0]) == ECMA_PROPERTY_TYPE_HASHMAP)
{
ecma_property_hashmap_free (obj_iter_p);
}

View File

@ -273,6 +273,10 @@ typedef enum
ECMA_PROPERTY_TYPE_HASHMAP, /**< hash map for fast property access */
ECMA_PROPERTY_TYPE__MAX = ECMA_PROPERTY_TYPE_HASHMAP, /**< highest value for property types. */
/* Property type aliases. */
ECMA_PROPERTY_TYPE_NOT_FOUND = ECMA_PROPERTY_TYPE_DELETED, /**< property is not found */
ECMA_PROPERTY_TYPE_VIRTUAL = ECMA_PROPERTY_TYPE_HASHMAP, /**< property is virtual */
} ecma_property_types_t;
/**
@ -347,10 +351,7 @@ typedef enum
* from the property address. However, property pointers cannot be compressed
* anymore.
*/
typedef struct
{
uint8_t type_and_flags; /**< ecma_property_types_t (3 bit) and ecma_property_flags_t */
} ecma_property_t;
typedef uint8_t ecma_property_t; /**< ecma_property_types_t (3 bit) and ecma_property_flags_t */
/**
* Number of items in a property pair.
@ -409,20 +410,20 @@ typedef struct
/**
* Get property type.
*/
#define ECMA_PROPERTY_GET_TYPE(property_p) \
((ecma_property_types_t) ((property_p)->type_and_flags & ECMA_PROPERTY_TYPE_MASK))
#define ECMA_PROPERTY_GET_TYPE(property) \
((ecma_property_types_t) ((property) & ECMA_PROPERTY_TYPE_MASK))
/**
* Returns true if the property pointer is a property pair.
*/
#define ECMA_PROPERTY_IS_PROPERTY_PAIR(property_header_p) \
(ECMA_PROPERTY_GET_TYPE ((property_header_p)->types + 0) <= ECMA_PROPERTY_TYPE_PROPERTY_PAIR__MAX)
(ECMA_PROPERTY_GET_TYPE ((property_header_p)->types[0]) <= ECMA_PROPERTY_TYPE_PROPERTY_PAIR__MAX)
/**
* Returns the internal property type
*/
#define ECMA_PROPERTY_GET_INTERNAL_PROPERTY_TYPE(property_p) \
((ecma_internal_property_id_t) ((property_p)->type_and_flags >> ECMA_PROPERTY_FLAG_SHIFT))
((ecma_internal_property_id_t) (*(property_p) >> ECMA_PROPERTY_FLAG_SHIFT))
/**
* Computing the data offset of a property.
@ -442,13 +443,31 @@ typedef struct
#define ECMA_PROPERTY_VALUE_PTR(property_p) \
(ECMA_PROPERTY_VALUE_BASE_PTR (property_p) + ECMA_PROPERTY_VALUE_OFFSET (property_p))
/**
* Property reference.
*/
typedef union
{
ecma_property_value_t *value_p; /**< direct pointer to property value */
ecma_value_t virtual_value; /**< property value */
} ecma_property_ref_t;
/**
* Option flags for ecma_op_object_get_property
*/
typedef enum
{
ECMA_PROPERTY_GET_NO_OPTIONS = 0, /**< no option flags for ecma_op_object_get_property */
ECMA_PROPERTY_GET_VALUE = 1u << 0, /**< fill virtual_value field for virtual properties */
} ecma_property_get_option_bits_t;
/**
* Internal object types
*/
typedef enum
{
ECMA_OBJECT_TYPE_GENERAL = 0, /**< all objects that are not String (15.5), Function (15.3),
Arguments (10.6), Array (15.4) specification-defined objects */
ECMA_OBJECT_TYPE_GENERAL = 0, /**< all objects that are not String (15.5),
* Function (15.3), Arguments (10.6), Array (15.4) objects */
ECMA_OBJECT_TYPE_FUNCTION = 1, /**< Function objects (15.3), created through 13.2 routine */
ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION = 2, /**< External (host) function object */
ECMA_OBJECT_TYPE_ARRAY = 3, /**< Array object (15.4) */

View File

@ -913,6 +913,8 @@ ecma_string_is_empty (const ecma_string_t *str_p) /**< ecma-string */
inline bool __attr_always_inline___
ecma_string_is_length (const ecma_string_t *string_p) /**< property name */
{
static const char length_str_p[] = "length";
ecma_string_container_t container = ECMA_STRING_GET_CONTAINER (string_p);
if (container == ECMA_STRING_CONTAINER_MAGIC_STRING)
@ -921,13 +923,13 @@ ecma_string_is_length (const ecma_string_t *string_p) /**< property name */
}
if (container != ECMA_STRING_CONTAINER_HEAP_UTF8_STRING
|| string_p->u.utf8_string.size != 6
|| string_p->u.utf8_string.size != (sizeof (length_str_p) - 1)
|| string_p->hash != LIT_STRING_LENGTH_HASH)
{
return false;
}
return !strncmp ((char *) (string_p + 1), "length", 6);
return !strncmp ((char *) (string_p + 1), length_str_p, (sizeof (length_str_p) - 1));
} /* ecma_string_is_length */
/**

View File

@ -373,13 +373,15 @@ ecma_get_lex_env_binding_object (const ecma_object_t *object_p) /**< object-boun
* Create a property in an object and link it into
* the object's properties' linked-list (at start of the list).
*
* @return pointer to newly created property
* @return pointer to the newly created property value
*/
static ecma_property_t *
static ecma_property_value_t *
ecma_create_property (ecma_object_t *object_p, /**< the object */
ecma_string_t *name_p, /**< property name */
uint8_t type_and_flags, /**< type and flags, see ecma_property_info_t */
ecma_property_value_t value) /**< property value */
ecma_property_value_t value, /**< property value */
ecma_property_t **out_prop_p) /**< [out] the property is also returned
* if this field is non-NULL */
{
JERRY_ASSERT (ECMA_PROPERTY_PAIR_ITEM_COUNT == 2);
@ -392,7 +394,7 @@ ecma_create_property (ecma_object_t *object_p, /**< the object */
*property_list_head_p);
bool has_hashmap = false;
if (ECMA_PROPERTY_GET_TYPE (first_property_p->types + 0) == ECMA_PROPERTY_TYPE_HASHMAP)
if (ECMA_PROPERTY_GET_TYPE (first_property_p->types[0]) == ECMA_PROPERTY_TYPE_HASHMAP)
{
property_list_head_p = &first_property_p->next_property_cp;
first_property_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t,
@ -402,9 +404,9 @@ ecma_create_property (ecma_object_t *object_p, /**< the object */
JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (first_property_p));
if (first_property_p->types[0].type_and_flags == ECMA_PROPERTY_TYPE_DELETED)
if (first_property_p->types[0] == ECMA_PROPERTY_TYPE_DELETED)
{
first_property_p->types[0].type_and_flags = type_and_flags;
first_property_p->types[0] = type_and_flags;
ecma_property_pair_t *first_property_pair_p = (ecma_property_pair_t *) first_property_p;
ECMA_SET_POINTER (first_property_pair_p->names_cp[0], name_p);
@ -413,6 +415,11 @@ ecma_create_property (ecma_object_t *object_p, /**< the object */
JERRY_ASSERT (ECMA_PROPERTY_VALUE_PTR (property_p) == first_property_pair_p->values + 0);
if (out_prop_p != NULL)
{
*out_prop_p = property_p;
}
first_property_pair_p->values[0] = value;
/* The property must be fully initialized before ecma_property_hashmap_insert
@ -428,7 +435,7 @@ ecma_create_property (ecma_object_t *object_p, /**< the object */
0);
}
return property_p;
return first_property_pair_p->values + 0;
}
}
@ -445,7 +452,7 @@ ecma_create_property (ecma_object_t *object_p, /**< the object */
ecma_property_header_t *first_property_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t,
*property_list_head_p);
if (ECMA_PROPERTY_GET_TYPE (first_property_p->types + 0) == ECMA_PROPERTY_TYPE_HASHMAP)
if (ECMA_PROPERTY_GET_TYPE (first_property_p->types[0]) == ECMA_PROPERTY_TYPE_HASHMAP)
{
property_list_head_p = &first_property_p->next_property_cp;
has_hashmap = true;
@ -454,8 +461,8 @@ ecma_create_property (ecma_object_t *object_p, /**< the object */
/* Just copy the previous value (no need to decompress, compress). */
first_property_pair_p->header.next_property_cp = *property_list_head_p;
first_property_pair_p->header.types[0].type_and_flags = ECMA_PROPERTY_TYPE_DELETED;
first_property_pair_p->header.types[1].type_and_flags = type_and_flags;
first_property_pair_p->header.types[0] = ECMA_PROPERTY_TYPE_DELETED;
first_property_pair_p->header.types[1] = type_and_flags;
first_property_pair_p->names_cp[0] = ECMA_NULL_POINTER;
ECMA_SET_POINTER (first_property_pair_p->names_cp[1], name_p);
@ -465,6 +472,11 @@ ecma_create_property (ecma_object_t *object_p, /**< the object */
JERRY_ASSERT (ECMA_PROPERTY_VALUE_PTR (property_p) == first_property_pair_p->values + 1);
if (out_prop_p != NULL)
{
*out_prop_p = property_p;
}
first_property_pair_p->values[1] = value;
/* See the comment before the other ecma_property_hashmap_insert above. */
@ -477,14 +489,14 @@ ecma_create_property (ecma_object_t *object_p, /**< the object */
1);
}
return property_p;
return first_property_pair_p->values + 1;
} /* ecma_create_property */
/**
* Create internal property in an object and link it into
* the object's properties' linked-list (at start of the list).
*
* @return pointer to newly created property
* @return pointer to the newly created property value
*/
ecma_value_t *
ecma_create_internal_property (ecma_object_t *object_p, /**< the object */
@ -498,8 +510,8 @@ ecma_create_internal_property (ecma_object_t *object_p, /**< the object */
ecma_property_value_t value;
value.value = ECMA_NULL_POINTER;
ecma_property_t *property_p = ecma_create_property (object_p, NULL, type_and_flags, value);
return &ECMA_PROPERTY_VALUE_PTR (property_p)->value;
ecma_property_value_t *prop_value_p = ecma_create_property (object_p, NULL, type_and_flags, value, NULL);
return &prop_value_p->value;
} /* ecma_create_internal_property */
/**
@ -517,7 +529,7 @@ ecma_find_internal_property (ecma_object_t *object_p, /**< object descriptor */
ecma_property_header_t *prop_iter_p = ecma_get_property_list (object_p);
if (prop_iter_p != NULL
&& ECMA_PROPERTY_GET_TYPE (prop_iter_p->types + 0) == ECMA_PROPERTY_TYPE_HASHMAP)
&& ECMA_PROPERTY_GET_TYPE (prop_iter_p->types[0]) == ECMA_PROPERTY_TYPE_HASHMAP)
{
prop_iter_p = ECMA_GET_POINTER (ecma_property_header_t,
prop_iter_p->next_property_cp);
@ -527,14 +539,14 @@ ecma_find_internal_property (ecma_object_t *object_p, /**< object descriptor */
{
JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (prop_iter_p));
if (ECMA_PROPERTY_GET_TYPE (&prop_iter_p->types[0]) == ECMA_PROPERTY_TYPE_INTERNAL
if (ECMA_PROPERTY_GET_TYPE (prop_iter_p->types[0]) == ECMA_PROPERTY_TYPE_INTERNAL
&& ECMA_PROPERTY_GET_INTERNAL_PROPERTY_TYPE (prop_iter_p->types + 0) == property_id)
{
ecma_property_pair_t *prop_pair_p = (ecma_property_pair_t *) prop_iter_p;
return &prop_pair_p->values[0].value;
}
if (ECMA_PROPERTY_GET_TYPE (&prop_iter_p->types[1]) == ECMA_PROPERTY_TYPE_INTERNAL
if (ECMA_PROPERTY_GET_TYPE (prop_iter_p->types[1]) == ECMA_PROPERTY_TYPE_INTERNAL
&& ECMA_PROPERTY_GET_INTERNAL_PROPERTY_TYPE (prop_iter_p->types + 1) == property_id)
{
ecma_property_pair_t *prop_pair_p = (ecma_property_pair_t *) prop_iter_p;
@ -571,12 +583,14 @@ ecma_get_internal_property (ecma_object_t *object_p, /**< object descriptor */
* Create named data property with given name, attributes and undefined value
* in the specified object.
*
* @return pointer to newly created property
* @return pointer to the newly created property value
*/
ecma_property_t *
ecma_property_value_t *
ecma_create_named_data_property (ecma_object_t *object_p, /**< object */
ecma_string_t *name_p, /**< property name */
uint8_t prop_attributes) /**< property attributes (See: ecma_property_flags_t) */
uint8_t prop_attributes, /**< property attributes (See: ecma_property_flags_t) */
ecma_property_t **out_prop_p) /**< [out] the property is also returned
* if this field is non-NULL */
{
JERRY_ASSERT (object_p != NULL && name_p != NULL);
JERRY_ASSERT (ecma_find_named_property (object_p, name_p) == NULL);
@ -589,15 +603,15 @@ ecma_create_named_data_property (ecma_object_t *object_p, /**< object */
ecma_property_value_t value;
value.value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
return ecma_create_property (object_p, name_p, type_and_flags, value);
return ecma_create_property (object_p, name_p, type_and_flags, value, out_prop_p);
} /* ecma_create_named_data_property */
/**
* Create named accessor property with given name, attributes, getter and setter.
*
* @return pointer to newly created property
* @return pointer to the newly created property value
*/
ecma_property_t *
ecma_property_value_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 */
@ -624,7 +638,7 @@ ecma_create_named_accessor_property (ecma_object_t *object_p, /**< object */
ECMA_SET_POINTER (value.getter_setter_pair.setter_p, set_p);
#endif /* JERRY_CPOINTER_32_BIT */
return ecma_create_property (object_p, name_p, type_and_flags, value);
return ecma_create_property (object_p, name_p, type_and_flags, value, NULL);
} /* ecma_create_named_accessor_property */
/**
@ -651,7 +665,7 @@ ecma_find_named_property (ecma_object_t *obj_p, /**< object to find property in
#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_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,
@ -734,30 +748,7 @@ ecma_find_named_property (ecma_object_t *obj_p, /**< object to find property in
* @return pointer to the property, if it is found,
* NULL - otherwise.
*/
ecma_property_t *
ecma_get_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_find_named_property (obj_p, name_p);
JERRY_ASSERT (property_p != NULL);
return property_p;
} /* ecma_get_named_property */
/**
* Get named data property in specified object.
*
* Warning:
* the property must exist and be named data property
*
* @return pointer to the property, if it is found,
* NULL - otherwise.
*/
ecma_property_t *
ecma_property_value_t *
ecma_get_named_data_property (ecma_object_t *obj_p, /**< object to find property in */
ecma_string_t *name_p) /**< property's name */
{
@ -766,9 +757,10 @@ ecma_get_named_data_property (ecma_object_t *obj_p, /**< object to find property
ecma_property_t *property_p = ecma_find_named_property (obj_p, name_p);
JERRY_ASSERT (property_p != NULL && ECMA_PROPERTY_GET_TYPE (property_p) == ECMA_PROPERTY_TYPE_NAMEDDATA);
JERRY_ASSERT (property_p != NULL
&& ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDDATA);
return property_p;
return ECMA_PROPERTY_VALUE_PTR (property_p);
} /* ecma_get_named_data_property */
/**
@ -777,7 +769,7 @@ ecma_get_named_data_property (ecma_object_t *obj_p, /**< object to find property
static void
ecma_free_internal_property (ecma_property_t *property_p) /**< the property */
{
JERRY_ASSERT (property_p != NULL && ECMA_PROPERTY_GET_TYPE (property_p) == ECMA_PROPERTY_TYPE_INTERNAL);
JERRY_ASSERT (property_p != NULL && ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_INTERNAL);
uint32_t property_value = ECMA_PROPERTY_VALUE_PTR (property_p)->value;
@ -863,11 +855,11 @@ ecma_free_property (ecma_object_t *object_p, /**< object the property belongs to
{
JERRY_ASSERT (object_p != NULL && property_p != NULL);
switch (ECMA_PROPERTY_GET_TYPE (property_p))
switch (ECMA_PROPERTY_GET_TYPE (*property_p))
{
case ECMA_PROPERTY_TYPE_NAMEDDATA:
{
ecma_free_value_if_not_object (ecma_get_named_data_property_value (property_p));
ecma_free_value_if_not_object (ECMA_PROPERTY_VALUE_PTR (property_p)->value);
if (ecma_is_property_lcached (property_p))
{
@ -903,24 +895,24 @@ ecma_free_property (ecma_object_t *object_p, /**< object the property belongs to
}
}
property_p->type_and_flags = ECMA_PROPERTY_TYPE_DELETED;
*property_p = ECMA_PROPERTY_TYPE_DELETED;
} /* ecma_free_property */
/**
* Delete the object's property.
* Delete the object's property referenced by its value pointer.
*
* Warning: specified property must be owned by specified object.
* Note: specified property must be owned by specified object.
*/
void
ecma_delete_property (ecma_object_t *object_p, /**< object */
ecma_property_t *prop_p) /**< property */
ecma_property_value_t *prop_value_p) /**< property value reference */
{
ecma_property_header_t *cur_prop_p = ecma_get_property_list (object_p);
ecma_property_header_t *prev_prop_p = NULL;
bool has_hashmap = false;
if (cur_prop_p != NULL
&& ECMA_PROPERTY_GET_TYPE (cur_prop_p->types + 0) == ECMA_PROPERTY_TYPE_HASHMAP)
&& ECMA_PROPERTY_GET_TYPE (cur_prop_p->types[0]) == ECMA_PROPERTY_TYPE_HASHMAP)
{
prev_prop_p = cur_prop_p;
cur_prop_p = ECMA_GET_POINTER (ecma_property_header_t,
@ -937,7 +929,7 @@ ecma_delete_property (ecma_object_t *object_p, /**< object */
for (int i = 0; i < ECMA_PROPERTY_PAIR_ITEM_COUNT; i++)
{
if ((cur_prop_p->types + i) == prop_p)
if ((prop_pair_p->values + i) == prop_value_p)
{
ecma_string_t *name_p = ECMA_GET_POINTER (ecma_string_t, prop_pair_p->names_cp[i]);
@ -949,7 +941,7 @@ ecma_delete_property (ecma_object_t *object_p, /**< object */
{
ecma_property_hashmap_delete (object_p,
name_p,
prop_p);
cur_prop_p->types + i);
}
ecma_deref_ecma_string (name_p);
@ -959,13 +951,13 @@ ecma_delete_property (ecma_object_t *object_p, /**< object */
JERRY_ASSERT (ECMA_PROPERTY_PAIR_ITEM_COUNT == 2);
if (cur_prop_p->types[1 - i].type_and_flags != ECMA_PROPERTY_TYPE_DELETED)
if (cur_prop_p->types[1 - i] != ECMA_PROPERTY_TYPE_DELETED)
{
/* The other property is still valid. */
return;
}
JERRY_ASSERT (cur_prop_p->types[i].type_and_flags == ECMA_PROPERTY_TYPE_DELETED);
JERRY_ASSERT (cur_prop_p->types[i] == ECMA_PROPERTY_TYPE_DELETED);
if (prev_prop_p == NULL)
{
@ -992,14 +984,15 @@ ecma_delete_property (ecma_object_t *object_p, /**< object */
*/
static void
ecma_assert_object_contains_the_property (const ecma_object_t *object_p, /**< ecma-object */
const ecma_property_t *prop_p) /**< ecma-property */
const ecma_property_value_t *prop_value_p, /**< property value */
ecma_property_types_t type) /**< expected property type */
{
#ifndef JERRY_NDEBUG
ecma_property_header_t *prop_iter_p = ecma_get_property_list (object_p);
JERRY_ASSERT (prop_iter_p != NULL);
if (ECMA_PROPERTY_GET_TYPE (prop_iter_p->types + 0) == ECMA_PROPERTY_TYPE_HASHMAP)
if (ECMA_PROPERTY_GET_TYPE (prop_iter_p->types[0]) == ECMA_PROPERTY_TYPE_HASHMAP)
{
prop_iter_p = ECMA_GET_POINTER (ecma_property_header_t,
prop_iter_p->next_property_cp);
@ -1013,8 +1006,9 @@ ecma_assert_object_contains_the_property (const ecma_object_t *object_p, /**< ec
for (int i = 0; i < ECMA_PROPERTY_PAIR_ITEM_COUNT; i++)
{
if ((prop_pair_p->header.types + i) == prop_p)
if ((prop_pair_p->values + i) == prop_value_p)
{
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (prop_pair_p->header.types[i]) == type);
return;
}
}
@ -1027,50 +1021,23 @@ ecma_assert_object_contains_the_property (const ecma_object_t *object_p, /**< ec
#else /* JERRY_NDEBUG */
JERRY_UNUSED (object_p);
JERRY_UNUSED (prop_p);
JERRY_UNUSED (prop_value_p);
JERRY_UNUSED (type);
#endif /* !JERRY_NDEBUG */
} /* ecma_assert_object_contains_the_property */
/**
* Get value field of named data property
*
* @return ecma value
*/
inline ecma_value_t __attr_always_inline___
ecma_get_named_data_property_value (const ecma_property_t *prop_p) /**< property */
{
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA);
return ECMA_PROPERTY_VALUE_PTR (prop_p)->value;
} /* ecma_get_named_data_property_value */
/**
* Set value field of named data property
*/
inline void __attr_always_inline___
ecma_set_named_data_property_value (ecma_property_t *prop_p, /**< property */
ecma_value_t value) /**< value to set */
{
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA);
ECMA_PROPERTY_VALUE_PTR (prop_p)->value = value;
} /* ecma_set_named_data_property_value */
/**
* Assign value to named data property
*
* Note:
* value previously stored in the property is freed
*/
void
inline void __attr_always_inline___
ecma_named_data_property_assign_value (ecma_object_t *obj_p, /**< object */
ecma_property_t *prop_p, /**< property */
ecma_property_value_t *prop_value_p, /**< property value reference */
ecma_value_t value) /**< value to assign */
{
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA);
ecma_assert_object_contains_the_property (obj_p, prop_p);
ecma_property_value_t *prop_value_p = ECMA_PROPERTY_VALUE_PTR (prop_p);
ecma_assert_object_contains_the_property (obj_p, prop_value_p, ECMA_PROPERTY_TYPE_NAMEDDATA);
ecma_value_assign_value (&prop_value_p->value, value);
} /* ecma_named_data_property_assign_value */
@ -1081,17 +1048,15 @@ ecma_named_data_property_assign_value (ecma_object_t *obj_p, /**< object */
* @return pointer to object - getter of the property
*/
ecma_object_t *
ecma_get_named_accessor_property_getter (const ecma_property_t *prop_p) /**< named accessor property */
ecma_get_named_accessor_property_getter (const ecma_property_value_t *prop_value_p) /**< property value reference */
{
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (prop_p) == 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 (prop_p)->getter_setter_pair_cp);
prop_value_p->getter_setter_pair_cp);
return ECMA_GET_POINTER (ecma_object_t, getter_setter_pair_p->getter_p);
#else /* !JERRY_CPOINTER_32_BIT */
return ECMA_GET_POINTER (ecma_object_t, ECMA_PROPERTY_VALUE_PTR (prop_p)->getter_setter_pair.getter_p);
return ECMA_GET_POINTER (ecma_object_t, prop_value_p->getter_setter_pair.getter_p);
#endif /* JERRY_CPOINTER_32_BIT */
} /* ecma_get_named_accessor_property_getter */
@ -1101,17 +1066,15 @@ ecma_get_named_accessor_property_getter (const ecma_property_t *prop_p) /**< nam
* @return pointer to object - setter of the property
*/
ecma_object_t *
ecma_get_named_accessor_property_setter (const ecma_property_t *prop_p) /**< named accessor property */
ecma_get_named_accessor_property_setter (const ecma_property_value_t *prop_value_p) /**< property value reference */
{
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (prop_p) == 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 (prop_p)->getter_setter_pair_cp);
prop_value_p->getter_setter_pair_cp);
return ECMA_GET_POINTER (ecma_object_t, getter_setter_pair_p->setter_p);
#else /* !JERRY_CPOINTER_32_BIT */
return ECMA_GET_POINTER (ecma_object_t, ECMA_PROPERTY_VALUE_PTR (prop_p)->getter_setter_pair.setter_p);
return ECMA_GET_POINTER (ecma_object_t, prop_value_p->getter_setter_pair.setter_p);
#endif /* JERRY_CPOINTER_32_BIT */
} /* ecma_get_named_accessor_property_setter */
@ -1120,19 +1083,18 @@ ecma_get_named_accessor_property_setter (const ecma_property_t *prop_p) /**< nam
*/
void
ecma_set_named_accessor_property_getter (ecma_object_t *object_p, /**< the property's container */
ecma_property_t *prop_p, /**< named accessor property */
ecma_property_value_t *prop_value_p, /**< property value reference */
ecma_object_t *getter_p) /**< getter object */
{
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR);
ecma_assert_object_contains_the_property (object_p, prop_p);
ecma_assert_object_contains_the_property (object_p, prop_value_p, 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 (prop_p)->getter_setter_pair_cp);
prop_value_p->getter_setter_pair_cp);
ECMA_SET_POINTER (getter_setter_pair_p->getter_p, getter_p);
#else /* !JERRY_CPOINTER_32_BIT */
ECMA_SET_POINTER (ECMA_PROPERTY_VALUE_PTR (prop_p)->getter_setter_pair.getter_p, getter_p);
ECMA_SET_POINTER (prop_value_p->getter_setter_pair.getter_p, getter_p);
#endif /* JERRY_CPOINTER_32_BIT */
} /* ecma_set_named_accessor_property_getter */
@ -1141,19 +1103,18 @@ ecma_set_named_accessor_property_getter (ecma_object_t *object_p, /**< the prope
*/
void
ecma_set_named_accessor_property_setter (ecma_object_t *object_p, /**< the property's container */
ecma_property_t *prop_p, /**< named accessor property */
ecma_property_value_t *prop_value_p, /**< property value reference */
ecma_object_t *setter_p) /**< setter object */
{
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR);
ecma_assert_object_contains_the_property (object_p, prop_p);
ecma_assert_object_contains_the_property (object_p, prop_value_p, 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 (prop_p)->getter_setter_pair_cp);
prop_value_p->getter_setter_pair_cp);
ECMA_SET_POINTER (getter_setter_pair_p->setter_p, setter_p);
#else /* !JERRY_CPOINTER_32_BIT */
ECMA_SET_POINTER (ECMA_PROPERTY_VALUE_PTR (prop_p)->getter_setter_pair.setter_p, setter_p);
ECMA_SET_POINTER (prop_value_p->getter_setter_pair.setter_p, setter_p);
#endif /* JERRY_CPOINTER_32_BIT */
} /* ecma_set_named_accessor_property_setter */
@ -1164,30 +1125,30 @@ ecma_set_named_accessor_property_setter (ecma_object_t *object_p, /**< the prope
* false - otherwise.
*/
inline bool __attr_always_inline___
ecma_is_property_writable (ecma_property_t *prop_p) /**< property */
ecma_is_property_writable (ecma_property_t property) /**< property */
{
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA);
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (property) == ECMA_PROPERTY_TYPE_NAMEDDATA
|| ECMA_PROPERTY_GET_TYPE (property) == ECMA_PROPERTY_TYPE_VIRTUAL);
return (prop_p->type_and_flags & ECMA_PROPERTY_FLAG_WRITABLE) != 0;
return (property & ECMA_PROPERTY_FLAG_WRITABLE) != 0;
} /* ecma_is_property_writable */
/**
* Set property's 'Writable' attribute value
*/
void
ecma_set_property_writable_attr (ecma_property_t *prop_p, /**< property */
bool is_writable) /**< should the property
* be writable? */
ecma_set_property_writable_attr (ecma_property_t *property_p, /**< [in,out] property */
bool is_writable) /**< new value for writable flag */
{
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA);
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDDATA);
if (is_writable)
{
prop_p->type_and_flags = (uint8_t) (prop_p->type_and_flags | ECMA_PROPERTY_FLAG_WRITABLE);
*property_p = (uint8_t) (*property_p | ECMA_PROPERTY_FLAG_WRITABLE);
}
else
{
prop_p->type_and_flags = (uint8_t) (prop_p->type_and_flags & ~ECMA_PROPERTY_FLAG_WRITABLE);
*property_p = (uint8_t) (*property_p & ~ECMA_PROPERTY_FLAG_WRITABLE);
}
} /* ecma_set_property_writable_attr */
@ -1198,32 +1159,32 @@ ecma_set_property_writable_attr (ecma_property_t *prop_p, /**< property */
* false - otherwise.
*/
inline bool __attr_always_inline___
ecma_is_property_enumerable (ecma_property_t *prop_p) /**< property */
ecma_is_property_enumerable (ecma_property_t property) /**< property */
{
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA
|| ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR);
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (property) == ECMA_PROPERTY_TYPE_NAMEDDATA
|| ECMA_PROPERTY_GET_TYPE (property) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR
|| ECMA_PROPERTY_GET_TYPE (property) == ECMA_PROPERTY_TYPE_VIRTUAL);
return (prop_p->type_and_flags & ECMA_PROPERTY_FLAG_ENUMERABLE) != 0;
return (property & ECMA_PROPERTY_FLAG_ENUMERABLE) != 0;
} /* ecma_is_property_enumerable */
/**
* Set property's 'Enumerable' attribute value
*/
void
ecma_set_property_enumerable_attr (ecma_property_t *prop_p, /**< property */
bool is_enumerable) /**< should the property
* be enumerable? */
ecma_set_property_enumerable_attr (ecma_property_t *property_p, /**< [in,out] property */
bool is_enumerable) /**< new value for enumerable flag */
{
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA
|| ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR);
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDDATA
|| ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR);
if (is_enumerable)
{
prop_p->type_and_flags = (uint8_t) (prop_p->type_and_flags | ECMA_PROPERTY_FLAG_ENUMERABLE);
*property_p = (uint8_t) (*property_p | ECMA_PROPERTY_FLAG_ENUMERABLE);
}
else
{
prop_p->type_and_flags = (uint8_t) (prop_p->type_and_flags & ~ECMA_PROPERTY_FLAG_ENUMERABLE);
*property_p = (uint8_t) (*property_p & ~ECMA_PROPERTY_FLAG_ENUMERABLE);
}
} /* ecma_set_property_enumerable_attr */
@ -1234,32 +1195,32 @@ ecma_set_property_enumerable_attr (ecma_property_t *prop_p, /**< property */
* false - otherwise.
*/
inline bool __attr_always_inline___
ecma_is_property_configurable (ecma_property_t *prop_p) /**< property */
ecma_is_property_configurable (ecma_property_t property) /**< property */
{
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA
|| ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR);
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (property) == ECMA_PROPERTY_TYPE_NAMEDDATA
|| ECMA_PROPERTY_GET_TYPE (property) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR
|| ECMA_PROPERTY_GET_TYPE (property) == ECMA_PROPERTY_TYPE_VIRTUAL);
return (prop_p->type_and_flags & ECMA_PROPERTY_FLAG_CONFIGURABLE) != 0;
return (property & ECMA_PROPERTY_FLAG_CONFIGURABLE) != 0;
} /* ecma_is_property_configurable */
/**
* Set property's 'Configurable' attribute value
*/
void
ecma_set_property_configurable_attr (ecma_property_t *prop_p, /**< property */
bool is_configurable) /**< should the property
* be configurable? */
ecma_set_property_configurable_attr (ecma_property_t *property_p, /**< [in,out] property */
bool is_configurable) /**< new value for configurable flag */
{
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA
|| ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR);
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDDATA
|| ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR);
if (is_configurable)
{
prop_p->type_and_flags = (uint8_t) (prop_p->type_and_flags | ECMA_PROPERTY_FLAG_CONFIGURABLE);
*property_p = (uint8_t) (*property_p | ECMA_PROPERTY_FLAG_CONFIGURABLE);
}
else
{
prop_p->type_and_flags = (uint8_t) (prop_p->type_and_flags & ~ECMA_PROPERTY_FLAG_CONFIGURABLE);
*property_p = (uint8_t) (*property_p & ~ECMA_PROPERTY_FLAG_CONFIGURABLE);
}
} /* ecma_set_property_configurable_attr */
@ -1269,31 +1230,31 @@ ecma_set_property_configurable_attr (ecma_property_t *prop_p, /**< property */
* @return true / false
*/
inline bool __attr_always_inline___
ecma_is_property_lcached (ecma_property_t *prop_p) /**< property */
ecma_is_property_lcached (ecma_property_t *property_p) /**< property */
{
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA
|| ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR);
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDDATA
|| ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR);
return (prop_p->type_and_flags & ECMA_PROPERTY_FLAG_LCACHED) != 0;
return (*property_p & ECMA_PROPERTY_FLAG_LCACHED) != 0;
} /* ecma_is_property_lcached */
/**
* Set value of flag indicating whether the property is registered in LCache
*/
inline void __attr_always_inline___
ecma_set_property_lcached (ecma_property_t *prop_p, /**< property */
bool is_lcached) /**< contained (true) or not (false) */
ecma_set_property_lcached (ecma_property_t *property_p, /**< property */
bool is_lcached) /**< new value for lcached flag */
{
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA
|| ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR);
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDDATA
|| ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR);
if (is_lcached)
{
prop_p->type_and_flags = (uint8_t) (prop_p->type_and_flags | ECMA_PROPERTY_FLAG_LCACHED);
*property_p = (uint8_t) (*property_p | ECMA_PROPERTY_FLAG_LCACHED);
}
else
{
prop_p->type_and_flags = (uint8_t) (prop_p->type_and_flags & ~ECMA_PROPERTY_FLAG_LCACHED);
*property_p = (uint8_t) (*property_p & ~ECMA_PROPERTY_FLAG_LCACHED);
}
} /* ecma_set_property_lcached */
@ -1349,54 +1310,6 @@ ecma_free_property_descriptor (ecma_property_descriptor_t *prop_desc_p) /**< pro
*prop_desc_p = ecma_make_empty_property_descriptor ();
} /* ecma_free_property_descriptor */
/**
* Construct property descriptor from specified property
*
* @return property descriptor, corresponding to type and content of the specified property, i.e.:
* - for named data properties: { [Value], [Writable], [Enumerable], [Configurable] };
* - for named accessor properties: { [Get] - if defined,
* [Set] - if defined,
* [Enumerable], [Configurable]
* }.
*/
ecma_property_descriptor_t
ecma_get_property_descriptor_from_property (ecma_property_t *prop_p) /**< property */
{
ecma_property_descriptor_t prop_desc = ecma_make_empty_property_descriptor ();
prop_desc.is_enumerable = ecma_is_property_enumerable (prop_p);
prop_desc.is_enumerable_defined = true;
prop_desc.is_configurable = ecma_is_property_configurable (prop_p);
prop_desc.is_configurable_defined = true;
if (ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA)
{
prop_desc.value = ecma_copy_value (ecma_get_named_data_property_value (prop_p));
prop_desc.is_value_defined = true;
prop_desc.is_writable = ecma_is_property_writable (prop_p);
prop_desc.is_writable_defined = true;
}
else
{
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR);
prop_desc.get_p = ecma_get_named_accessor_property_getter (prop_p);
prop_desc.is_get_defined = true;
if (prop_desc.get_p != NULL)
{
ecma_ref_object (prop_desc.get_p);
}
prop_desc.set_p = ecma_get_named_accessor_property_setter (prop_p);
prop_desc.is_set_defined = true;
if (prop_desc.set_p != NULL)
{
ecma_ref_object (prop_desc.set_p);
}
}
return prop_desc;
} /* ecma_get_property_descriptor_from_property */
/**
* Increase reference counter of Compact
* Byte Code or regexp byte code.

View File

@ -271,34 +271,30 @@ extern ecma_value_t *ecma_create_internal_property (ecma_object_t *, ecma_intern
extern ecma_value_t *ecma_find_internal_property (ecma_object_t *, ecma_internal_property_id_t);
extern ecma_value_t *ecma_get_internal_property (ecma_object_t *, ecma_internal_property_id_t);
extern ecma_property_t *
ecma_create_named_data_property (ecma_object_t *, ecma_string_t *, uint8_t);
extern ecma_property_t *
extern ecma_property_value_t *
ecma_create_named_data_property (ecma_object_t *, ecma_string_t *, uint8_t, ecma_property_t **);
extern ecma_property_value_t *
ecma_create_named_accessor_property (ecma_object_t *, ecma_string_t *, ecma_object_t *, ecma_object_t *, uint8_t);
extern ecma_property_t *
ecma_find_named_property (ecma_object_t *, ecma_string_t *);
extern ecma_property_t *
ecma_get_named_property (ecma_object_t *, ecma_string_t *);
extern ecma_property_t *
extern ecma_property_value_t *
ecma_get_named_data_property (ecma_object_t *, ecma_string_t *);
extern void ecma_free_property (ecma_object_t *, ecma_string_t *, ecma_property_t *);
extern void ecma_delete_property (ecma_object_t *, ecma_property_t *);
extern void ecma_delete_property (ecma_object_t *, ecma_property_value_t *);
extern ecma_value_t ecma_get_named_data_property_value (const ecma_property_t *);
extern void ecma_set_named_data_property_value (ecma_property_t *, ecma_value_t);
extern void ecma_named_data_property_assign_value (ecma_object_t *, ecma_property_t *, ecma_value_t);
extern void ecma_named_data_property_assign_value (ecma_object_t *, ecma_property_value_t *, ecma_value_t);
extern ecma_object_t *ecma_get_named_accessor_property_getter (const ecma_property_t *);
extern ecma_object_t *ecma_get_named_accessor_property_setter (const ecma_property_t *);
extern void ecma_set_named_accessor_property_getter (ecma_object_t *, ecma_property_t *, ecma_object_t *);
extern void ecma_set_named_accessor_property_setter (ecma_object_t *, ecma_property_t *, ecma_object_t *);
extern bool ecma_is_property_writable (ecma_property_t *);
extern ecma_object_t *ecma_get_named_accessor_property_getter (const ecma_property_value_t *);
extern ecma_object_t *ecma_get_named_accessor_property_setter (const ecma_property_value_t *);
extern void ecma_set_named_accessor_property_getter (ecma_object_t *, ecma_property_value_t *, ecma_object_t *);
extern void ecma_set_named_accessor_property_setter (ecma_object_t *, ecma_property_value_t *, ecma_object_t *);
extern bool ecma_is_property_writable (ecma_property_t);
extern void ecma_set_property_writable_attr (ecma_property_t *, bool);
extern bool ecma_is_property_enumerable (ecma_property_t *);
extern bool ecma_is_property_enumerable (ecma_property_t);
extern void ecma_set_property_enumerable_attr (ecma_property_t *, bool);
extern bool ecma_is_property_configurable (ecma_property_t *);
extern bool ecma_is_property_configurable (ecma_property_t);
extern void ecma_set_property_configurable_attr (ecma_property_t *, bool);
extern bool ecma_is_property_lcached (ecma_property_t *);
@ -306,7 +302,6 @@ extern void ecma_set_property_lcached (ecma_property_t *, bool);
extern ecma_property_descriptor_t ecma_make_empty_property_descriptor (void);
extern void ecma_free_property_descriptor (ecma_property_descriptor_t *);
extern ecma_property_descriptor_t ecma_get_property_descriptor_from_property (ecma_property_t *);
extern ecma_property_t *ecma_get_next_property_pair (ecma_property_pair_t *);

View File

@ -89,8 +89,8 @@ ecma_lcache_insert (ecma_object_t *object_p, /**< object */
JERRY_ASSERT (object_p != NULL);
JERRY_ASSERT (prop_name_p != NULL);
JERRY_ASSERT (prop_p != NULL && !ecma_is_property_lcached (prop_p));
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA
|| ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR);
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (*prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA
|| ECMA_PROPERTY_GET_TYPE (*prop_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR);
#ifndef CONFIG_ECMA_LCACHE_DISABLE
jmem_cpointer_t object_cp;
@ -196,8 +196,8 @@ ecma_lcache_invalidate (ecma_object_t *object_p, /**< object */
JERRY_ASSERT (object_p != NULL);
JERRY_ASSERT (prop_name_p != NULL);
JERRY_ASSERT (prop_p != NULL && ecma_is_property_lcached (prop_p));
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA
|| ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR);
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (*prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA
|| ECMA_PROPERTY_GET_TYPE (*prop_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR);
#ifndef CONFIG_ECMA_LCACHE_DISABLE
jmem_cpointer_t object_cp;

View File

@ -88,7 +88,7 @@ ecma_property_hashmap_create (ecma_object_t *object_p) /**< object */
for (int i = 0; i < ECMA_PROPERTY_PAIR_ITEM_COUNT; i++)
{
ecma_property_types_t type = ECMA_PROPERTY_GET_TYPE (prop_iter_p->types + i);
ecma_property_types_t type = ECMA_PROPERTY_GET_TYPE (prop_iter_p->types[i]);
if (type == ECMA_PROPERTY_TYPE_NAMEDDATA || type == ECMA_PROPERTY_TYPE_NAMEDACCESSOR)
{
@ -119,7 +119,7 @@ ecma_property_hashmap_create (ecma_object_t *object_p) /**< object */
memset (hashmap_p, 0, total_size);
hashmap_p->header.types[0].type_and_flags = ECMA_PROPERTY_TYPE_HASHMAP;
hashmap_p->header.types[0] = ECMA_PROPERTY_TYPE_HASHMAP;
hashmap_p->header.next_property_cp = object_p->property_list_or_bound_object_cp;
hashmap_p->max_property_count = max_property_count;
hashmap_p->null_count = max_property_count - named_property_count;
@ -132,7 +132,7 @@ ecma_property_hashmap_create (ecma_object_t *object_p) /**< object */
if (max_property_count <= LIT_STRING_HASH_LIMIT)
{
hashmap_p->header.types[1].type_and_flags = 0;
hashmap_p->header.types[1] = 0;
}
else
{
@ -143,7 +143,7 @@ ecma_property_hashmap_create (ecma_object_t *object_p) /**< object */
}
}
hashmap_p->header.types[1].type_and_flags = shift_counter;
hashmap_p->header.types[1] = shift_counter;
prop_iter_p = ecma_get_property_list (object_p);
ECMA_SET_POINTER (object_p->property_list_or_bound_object_cp, hashmap_p);
@ -154,7 +154,7 @@ ecma_property_hashmap_create (ecma_object_t *object_p) /**< object */
for (int i = 0; i < ECMA_PROPERTY_PAIR_ITEM_COUNT; i++)
{
ecma_property_types_t type = ECMA_PROPERTY_GET_TYPE (prop_iter_p->types + i);
ecma_property_types_t type = ECMA_PROPERTY_GET_TYPE (prop_iter_p->types[i]);
if (!(type == ECMA_PROPERTY_TYPE_NAMEDDATA || type == ECMA_PROPERTY_TYPE_NAMEDACCESSOR))
{
@ -225,7 +225,7 @@ ecma_property_hashmap_free (ecma_object_t *object_p) /**< object */
ecma_property_header_t *property_p = ecma_get_property_list (object_p);
JERRY_ASSERT (property_p != NULL
&& ECMA_PROPERTY_GET_TYPE (property_p->types + 0) == ECMA_PROPERTY_TYPE_HASHMAP);
&& ECMA_PROPERTY_GET_TYPE (property_p->types[0]) == ECMA_PROPERTY_TYPE_HASHMAP);
ecma_property_hashmap_t *hashmap_p = (ecma_property_hashmap_t *) property_p;
@ -251,7 +251,7 @@ ecma_property_hashmap_insert (ecma_object_t *object_p, /**< object */
ecma_property_hashmap_t *hashmap_p = ECMA_GET_NON_NULL_POINTER (ecma_property_hashmap_t,
object_p->property_list_or_bound_object_cp);
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (hashmap_p->header.types + 0) == ECMA_PROPERTY_TYPE_HASHMAP);
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (hashmap_p->header.types[0]) == ECMA_PROPERTY_TYPE_HASHMAP);
/* The NULLs are reduced below 1/8 of the hashmap. */
if (hashmap_p->null_count < (hashmap_p->max_property_count >> 3))
@ -273,7 +273,7 @@ ecma_property_hashmap_insert (ecma_object_t *object_p, /**< object */
}
else
{
entry_index <<= hashmap_p->header.types[1].type_and_flags;
entry_index <<= hashmap_p->header.types[1];
}
#ifndef JERRY_NDEBUG
@ -334,7 +334,7 @@ ecma_property_hashmap_delete (ecma_object_t *object_p, /**< object */
ecma_property_hashmap_t *hashmap_p = ECMA_GET_NON_NULL_POINTER (ecma_property_hashmap_t,
object_p->property_list_or_bound_object_cp);
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (hashmap_p->header.types + 0) == ECMA_PROPERTY_TYPE_HASHMAP);
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (hashmap_p->header.types[0]) == ECMA_PROPERTY_TYPE_HASHMAP);
uint32_t entry_index = name_p->hash;
uint32_t step = ecma_property_hashmap_steps[entry_index & (ECMA_PROPERTY_HASHMAP_NUMBER_OF_STEPS - 1)];
@ -348,7 +348,7 @@ ecma_property_hashmap_delete (ecma_object_t *object_p, /**< object */
}
else
{
entry_index <<= hashmap_p->header.types[1].type_and_flags;
entry_index <<= hashmap_p->header.types[1];
JERRY_ASSERT (entry_index <= mask);
}
@ -458,7 +458,7 @@ ecma_property_hashmap_find (ecma_property_hashmap_t *hashmap_p, /**< hashmap */
}
else
{
entry_index <<= hashmap_p->header.types[1].type_and_flags;
entry_index <<= hashmap_p->header.types[1];
JERRY_ASSERT (entry_index <= mask);
}

View File

@ -668,9 +668,9 @@ ecma_builtin_json_walk (ecma_object_t *reviver_p, /**< reviver function */
arguments_list[0] = ecma_make_string_value (name_p);
arguments_list[1] = value_get;
/*
* The completion value can be anything including exceptions.
*/
/*
* The completion value can be anything including exceptions.
*/
ret_value = ecma_op_function_call (reviver_p,
ecma_make_object_value (holder_p),
arguments_list,
@ -746,12 +746,13 @@ ecma_builtin_json_parse (ecma_value_t this_arg, /**< 'this' argument */
ecma_object_t *object_p = ecma_op_create_object_object_noarg ();
ecma_string_t *name_p = ecma_get_magic_string (LIT_MAGIC_STRING__EMPTY);
ecma_property_t *property_p;
property_p = ecma_create_named_data_property (object_p,
name_p,
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE);
ecma_property_value_t *prop_value_p;
prop_value_p = ecma_create_named_data_property (object_p,
name_p,
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE,
NULL);
ecma_named_data_property_assign_value (object_p, property_p, final_result);
ecma_named_data_property_assign_value (object_p, prop_value_p, final_result);
ecma_free_value (final_result);
ret_value = ecma_builtin_json_walk (ecma_get_object_from_value (arg2),
@ -1445,11 +1446,15 @@ ecma_builtin_json_object (ecma_object_t *obj_p, /**< the object*/
while (ecma_collection_iterator_next (&iter))
{
ecma_string_t *property_name_p = ecma_get_string_from_value (*iter.current_value_p);
ecma_property_t *property_p = ecma_op_object_get_own_property (obj_p, property_name_p);
JERRY_ASSERT (ecma_is_property_enumerable (property_p));
ecma_property_t property = ecma_op_object_get_own_property (obj_p,
property_name_p,
NULL,
ECMA_PROPERTY_GET_NO_OPTIONS);
if (ECMA_PROPERTY_GET_TYPE (property_p) == ECMA_PROPERTY_TYPE_NAMEDDATA)
JERRY_ASSERT (ecma_is_property_enumerable (property));
if (ECMA_PROPERTY_GET_TYPE (property) == ECMA_PROPERTY_TYPE_NAMEDDATA)
{
ecma_append_to_values_collection (property_keys_p, *iter.current_value_p, true);
}

View File

@ -242,15 +242,17 @@ ecma_builtin_object_prototype_object_property_is_enumerable (ecma_value_t this_a
ecma_object_t *obj_p = ecma_get_object_from_value (obj_val);
/* 3. */
ecma_property_t *property_p = ecma_op_object_get_own_property (obj_p, property_name_string_p);
ecma_property_t property = ecma_op_object_get_own_property (obj_p,
property_name_string_p,
NULL,
ECMA_PROPERTY_GET_NO_OPTIONS);
/* 4. */
if (property_p != NULL)
if (property != ECMA_PROPERTY_TYPE_NOT_FOUND)
{
bool is_enumerable = ecma_is_property_enumerable (property_p);
bool is_enumerable = ecma_is_property_enumerable (property);
return_value = ecma_make_simple_value (is_enumerable ? ECMA_SIMPLE_VALUE_TRUE
: ECMA_SIMPLE_VALUE_FALSE);
return_value = ecma_make_boolean_value (is_enumerable);
}
else
{

View File

@ -202,16 +202,17 @@ ecma_builtin_object_object_seal (ecma_value_t this_arg, /**< 'this' argument */
&& ecma_is_value_empty (ret_value))
{
ecma_string_t *property_name_p = ecma_get_string_from_value (*iter.current_value_p);
ecma_property_t *property_p = ecma_op_object_get_own_property (obj_p, property_name_p);
// 2.a
ecma_property_descriptor_t prop_desc = ecma_get_property_descriptor_from_property (property_p);
ecma_property_descriptor_t prop_desc;
if (!ecma_op_object_get_own_property_descriptor (obj_p, property_name_p, &prop_desc))
{
continue;
}
// 2.b
if (ecma_is_property_configurable (property_p))
{
prop_desc.is_configurable = false;
}
prop_desc.is_configurable = false;
// 2.c
ECMA_TRY_CATCH (define_own_prop_ret,
@ -276,23 +277,23 @@ ecma_builtin_object_object_freeze (ecma_value_t this_arg, /**< 'this' argument *
&& ecma_is_value_empty (ret_value))
{
ecma_string_t *property_name_p = ecma_get_string_from_value (*iter.current_value_p);
ecma_property_t *property_p = ecma_op_object_get_own_property (obj_p, property_name_p);
// 2.a
ecma_property_descriptor_t prop_desc = ecma_get_property_descriptor_from_property (property_p);
ecma_property_descriptor_t prop_desc;
if (!ecma_op_object_get_own_property_descriptor (obj_p, property_name_p, &prop_desc))
{
continue;
}
// 2.b
if (ECMA_PROPERTY_GET_TYPE (property_p) == ECMA_PROPERTY_TYPE_NAMEDDATA
&& ecma_is_property_writable (property_p))
if (prop_desc.is_writable_defined && prop_desc.is_writable)
{
prop_desc.is_writable = false;
}
// 2.c
if (ecma_is_property_configurable (property_p))
{
prop_desc.is_configurable = false;
}
prop_desc.is_configurable = false;
// 2.d
ECMA_TRY_CATCH (define_own_prop_ret,
@ -400,10 +401,13 @@ ecma_builtin_object_object_is_sealed (ecma_value_t this_arg, /**< 'this' argumen
ecma_string_t *property_name_p = ecma_get_string_from_value (*iter.current_value_p);
// 2.a
ecma_property_t *property_p = ecma_op_object_get_own_property (obj_p, property_name_p);
ecma_property_t property = ecma_op_object_get_own_property (obj_p,
property_name_p,
NULL,
ECMA_PROPERTY_GET_NO_OPTIONS);
// 2.b
if (ecma_is_property_configurable (property_p))
if (ecma_is_property_configurable (property))
{
is_sealed = false;
break;
@ -468,21 +472,21 @@ ecma_builtin_object_object_is_frozen (ecma_value_t this_arg, /**< 'this' argumen
ecma_string_t *property_name_p = ecma_get_string_from_value (*iter.current_value_p);
// 2.a
ecma_property_t *property_p = ecma_op_object_get_own_property (obj_p, property_name_p);
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (property_p) == ECMA_PROPERTY_TYPE_NAMEDDATA
|| ECMA_PROPERTY_GET_TYPE (property_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR);
ecma_property_t property = ecma_op_object_get_own_property (obj_p,
property_name_p,
NULL,
ECMA_PROPERTY_GET_NO_OPTIONS);
// 2.b
if (ECMA_PROPERTY_GET_TYPE (property_p) == ECMA_PROPERTY_TYPE_NAMEDDATA
&& ecma_is_property_writable (property_p))
if (ECMA_PROPERTY_GET_TYPE (property) != ECMA_PROPERTY_TYPE_NAMEDACCESSOR
&& ecma_is_property_writable (property))
{
is_frozen = false;
break;
}
// 2.c
if (ecma_is_property_configurable (property_p))
if (ecma_is_property_configurable (property))
{
is_frozen = false;
break;
@ -598,12 +602,10 @@ ecma_builtin_object_object_get_own_property_descriptor (ecma_value_t this_arg, /
ecma_string_t *name_str_p = ecma_get_string_from_value (name_str_value);
// 3.
ecma_property_t *prop_p = ecma_op_object_get_own_property (obj_p, name_str_p);
ecma_property_descriptor_t prop_desc;
if (prop_p != NULL)
if (ecma_op_object_get_own_property_descriptor (obj_p, name_str_p, &prop_desc))
{
ecma_property_descriptor_t prop_desc = ecma_get_property_descriptor_from_property (prop_p);
// 4.
ecma_object_t *desc_obj_p = ecma_op_from_property_descriptor (&prop_desc);

View File

@ -1517,10 +1517,10 @@ ecma_builtin_helper_split_match (ecma_value_t input_string, /**< first argument
{
ecma_object_t *obj_p = ecma_get_object_from_value (ret_value);
ecma_string_t *magic_index_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_INDEX);
ecma_property_t *index_prop_p = ecma_get_named_property (obj_p, magic_index_str_p);
ecma_property_value_t *index_prop_value_p = ecma_get_named_data_property (obj_p, magic_index_str_p);
ecma_number_t index_num = ecma_get_number_from_value (ecma_get_named_data_property_value (index_prop_p));
ecma_value_assign_number (&ECMA_PROPERTY_VALUE_PTR (index_prop_p)->value, index_num + start_idx);
ecma_number_t index_num = ecma_get_number_from_value (index_prop_value_p->value);
ecma_value_assign_number (&index_prop_value_p->value, index_num + start_idx);
ecma_deref_ecma_string (magic_index_str_p);
}
@ -1578,13 +1578,15 @@ ecma_builtin_helper_split_match (ecma_value_t input_string, /**< first argument
JERRY_ASSERT (ecma_is_value_true (put_comp));
ecma_string_t *magic_index_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_INDEX);
ecma_property_t *index_prop_p = ecma_create_named_data_property (match_array_p,
magic_index_str_p,
ECMA_PROPERTY_FLAG_WRITABLE);
ecma_property_value_t *index_prop_value_p;
index_prop_value_p = ecma_create_named_data_property (match_array_p,
magic_index_str_p,
ECMA_PROPERTY_FLAG_WRITABLE,
NULL);
ecma_deref_ecma_string (magic_index_str_p);
ecma_named_data_property_assign_value (match_array_p,
index_prop_p,
index_prop_value_p,
ecma_make_uint32_value (start_idx));
ret_value = match_array;
@ -1787,10 +1789,10 @@ ecma_builtin_string_prototype_object_split (ecma_value_t this_arg, /**< this arg
ecma_deref_ecma_string (zero_str_p);
ecma_string_t *magic_index_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_INDEX);
ecma_property_t *index_prop_p = ecma_get_named_property (match_array_obj_p, magic_index_str_p);
ecma_property_value_t *index_prop_value_p = ecma_get_named_data_property (match_array_obj_p,
magic_index_str_p);
ecma_value_t index_value = ecma_get_named_data_property_value (index_prop_p);
ecma_number_t index_num = ecma_get_number_from_value (index_value);
ecma_number_t index_num = ecma_get_number_from_value (index_prop_value_p->value);
JERRY_ASSERT (index_num >= 0);
uint32_t end_pos = ecma_number_to_uint32 (index_num);

View File

@ -127,11 +127,13 @@ ecma_builtin_init_object (ecma_builtin_id_t obj_builtin_id, /**< built-in ID */
{
ecma_string_t *length_str_p = ecma_new_ecma_length_string ();
ecma_property_t *length_prop_p = ecma_create_named_data_property (obj_p,
length_str_p,
ECMA_PROPERTY_FLAG_WRITABLE);
ecma_property_value_t *length_prop_value_p;
length_prop_value_p = ecma_create_named_data_property (obj_p,
length_str_p,
ECMA_PROPERTY_FLAG_WRITABLE,
NULL);
ecma_set_named_data_property_value (length_prop_p, ecma_make_integer_value (0));
length_prop_value_p->value = ecma_make_integer_value (0);
ecma_deref_ecma_string (length_str_p);
break;
@ -346,14 +348,14 @@ ecma_builtin_try_to_instantiate_property (ecma_object_t *object_p, /**< object *
* as it is non-configurable and so can't be deleted
*/
ecma_property_t *len_prop_p = ecma_create_named_data_property (object_p,
string_p,
ECMA_PROPERTY_FIXED);
ecma_property_t *len_prop_p;
ecma_property_value_t *len_prop_value_p = ecma_create_named_data_property (object_p,
string_p,
ECMA_PROPERTY_FIXED,
&len_prop_p);
ecma_set_named_data_property_value (len_prop_p,
ecma_make_integer_value (ext_obj_p->u.built_in.length));
len_prop_value_p->value = ecma_make_integer_value (ext_obj_p->u.built_in.length);
JERRY_ASSERT (!ecma_is_property_configurable (len_prop_p));
return len_prop_p;
}
@ -519,11 +521,13 @@ ecma_builtin_try_to_instantiate_property (ecma_object_t *object_p, /**< object *
}
}
ecma_property_t *prop_p = ecma_create_named_data_property (object_p,
string_p,
curr_property_p->attributes);
ecma_property_t *prop_p;
ecma_property_value_t *prop_value_p = ecma_create_named_data_property (object_p,
string_p,
curr_property_p->attributes,
&prop_p);
ecma_set_named_data_property_value (prop_p, value);
prop_value_p->value = value;
/* Reference count of objects must be decreased. */
if (ecma_is_value_object (value))

View File

@ -105,11 +105,13 @@ ecma_op_create_array_object (const ecma_value_t *arguments_list_p, /**< list of
ecma_string_t *length_magic_string_p = ecma_new_ecma_length_string ();
ecma_property_t *length_prop_p = ecma_create_named_data_property (obj_p,
length_magic_string_p,
ECMA_PROPERTY_FLAG_WRITABLE);
ecma_property_value_t *length_prop_value_p;
length_prop_value_p = ecma_create_named_data_property (obj_p,
length_magic_string_p,
ECMA_PROPERTY_FLAG_WRITABLE,
NULL);
ecma_set_named_data_property_value (length_prop_p, ecma_make_number_value ((ecma_number_t) length));
length_prop_value_p->value = ecma_make_number_value ((ecma_number_t) length);
ecma_deref_ecma_string (length_magic_string_p);
@ -158,11 +160,13 @@ ecma_op_array_object_define_own_property (ecma_object_t *obj_p, /**< the array o
// 1.
ecma_string_t *magic_string_length_p = ecma_new_ecma_length_string ();
ecma_property_t *len_prop_p = ecma_op_object_get_own_property (obj_p, magic_string_length_p);
JERRY_ASSERT (len_prop_p != NULL && ECMA_PROPERTY_GET_TYPE (len_prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA);
ecma_property_t *len_prop_p = ecma_find_named_property (obj_p, magic_string_length_p);
JERRY_ASSERT (len_prop_p != NULL
&& ECMA_PROPERTY_GET_TYPE (*len_prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA);
// 2.
ecma_value_t old_len_value = ecma_get_named_data_property_value (len_prop_p);
ecma_value_t old_len_value = ECMA_PROPERTY_VALUE_PTR (len_prop_p)->value;
uint32_t old_len_uint32 = ecma_get_uint32_from_value (old_len_value);
@ -231,7 +235,7 @@ ecma_op_array_object_define_own_property (ecma_object_t *obj_p, /**< the array o
else
{
// g.
if (!ecma_is_property_writable (len_prop_p))
if (!ecma_is_property_writable (*len_prop_p))
{
ret_value = ecma_reject (is_throw);
}
@ -410,7 +414,7 @@ ecma_op_array_object_define_own_property (ecma_object_t *obj_p, /**< the array o
// b.
if (index >= old_len_uint32
&& !ecma_is_property_writable (len_prop_p))
&& !ecma_is_property_writable (*len_prop_p))
{
return ecma_reject (is_throw);
}

View File

@ -118,14 +118,16 @@ ecma_new_standard_error_with_message (ecma_standard_error_t error_type, /**< nat
ecma_object_t *new_error_obj_p = ecma_new_standard_error (error_type);
ecma_string_t *message_magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_MESSAGE);
ecma_property_t *prop_p = ecma_create_named_data_property (new_error_obj_p,
message_magic_string_p,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE);
ecma_property_value_t *prop_value_p;
prop_value_p = ecma_create_named_data_property (new_error_obj_p,
message_magic_string_p,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE,
NULL);
ecma_deref_ecma_string (message_magic_string_p);
ecma_ref_ecma_string (message_string_p);
ecma_set_named_data_property_value (prop_p,
ecma_make_string_value (message_string_p));
ecma_deref_ecma_string (message_magic_string_p);
prop_value_p->value = ecma_make_string_value (message_string_p);
return new_error_obj_p;
} /* ecma_new_standard_error_with_message */

View File

@ -184,8 +184,7 @@ ecma_op_create_function_object (ecma_object_t *scope_p, /**< function's scope */
/*
* 'length' and 'prototype' properties are instantiated lazily
*
* See also: ecma_op_function_object_get_own_property
* ecma_op_function_try_lazy_instantiate_property
* See also: ecma_op_function_try_lazy_instantiate_property
*/
// 19.
@ -278,124 +277,69 @@ ecma_op_function_list_lazy_property_names (bool separate_enumerable, /**< true -
* NULL - otherwise
*/
ecma_property_t *
ecma_op_function_try_lazy_instantiate_property (ecma_object_t *obj_p, /**< the function object */
ecma_op_function_try_lazy_instantiate_property (ecma_object_t *object_p, /**< the function object */
ecma_string_t *property_name_p) /**< property name */
{
JERRY_ASSERT (!ecma_get_object_is_builtin (obj_p));
static const char prototype_str_p[] = "prototype";
if (ecma_string_is_length (property_name_p))
JERRY_ASSERT (!ecma_get_object_is_builtin (object_p));
ecma_string_container_t container = ECMA_STRING_GET_CONTAINER (property_name_p);
/* Check whether the property_name_p is prototype */
if (container == ECMA_STRING_CONTAINER_MAGIC_STRING)
{
/* ECMA-262 v5, 13.2, 14-15 */
ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) obj_p;
const ecma_compiled_code_t *bytecode_data_p;
bytecode_data_p = ECMA_GET_INTERNAL_VALUE_POINTER (const ecma_compiled_code_t,
ext_func_p->u.function.bytecode_cp);
// 14
uint32_t len;
if (bytecode_data_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS)
if (property_name_p->u.magic_string_id != LIT_MAGIC_STRING_PROTOTYPE)
{
cbc_uint16_arguments_t *args_p = (cbc_uint16_arguments_t *) bytecode_data_p;
len = args_p->argument_end;
return NULL;
}
else
}
else if (container != ECMA_STRING_CONTAINER_HEAP_UTF8_STRING
|| property_name_p->u.utf8_string.size != (sizeof (prototype_str_p) - 1))
{
return NULL;
}
else
{
if (strncmp ((char *) (property_name_p + 1), prototype_str_p, (sizeof (prototype_str_p) - 1)) != 0)
{
cbc_uint8_arguments_t *args_p = (cbc_uint8_arguments_t *) bytecode_data_p;
len = args_p->argument_end;
return NULL;
}
// 15
ecma_property_t *length_prop_p = ecma_create_named_data_property (obj_p,
property_name_p,
ECMA_PROPERTY_FIXED);
ecma_named_data_property_assign_value (obj_p, length_prop_p, ecma_make_uint32_value (len));
JERRY_ASSERT (!ecma_is_property_configurable (length_prop_p));
return length_prop_p;
}
ecma_string_t *magic_string_prototype_p = ecma_get_magic_string (LIT_MAGIC_STRING_PROTOTYPE);
/* ECMA-262 v5, 13.2, 16-18 */
bool is_prototype_property = ecma_compare_ecma_strings (magic_string_prototype_p, property_name_p);
/* 16. */
ecma_object_t *proto_object_p = ecma_op_create_object_object_noarg ();
ecma_deref_ecma_string (magic_string_prototype_p);
/* 17. */
ecma_string_t *magic_string_constructor_p = ecma_get_magic_string (LIT_MAGIC_STRING_CONSTRUCTOR);
if (is_prototype_property)
{
/* ECMA-262 v5, 13.2, 16-18 */
ecma_property_value_t *constructor_prop_value_p;
constructor_prop_value_p = ecma_create_named_data_property (proto_object_p,
magic_string_constructor_p,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE,
NULL);
// 16.
ecma_object_t *proto_p = ecma_op_create_object_object_noarg ();
constructor_prop_value_p->value = ecma_make_object_value (object_p);
// 17.
ecma_string_t *magic_string_constructor_p = ecma_get_magic_string (LIT_MAGIC_STRING_CONSTRUCTOR);
ecma_builtin_helper_def_prop (proto_p,
magic_string_constructor_p,
ecma_make_object_value (obj_p),
true, /* Writable */
false, /* Enumerable */
true, /* Configurable */
false); /* Failure handling */
ecma_deref_ecma_string (magic_string_constructor_p);
ecma_deref_ecma_string (magic_string_constructor_p);
/* 18. */
ecma_property_t *prototype_prop_p;
ecma_property_value_t *prototype_prop_value_p;
prototype_prop_value_p = ecma_create_named_data_property (object_p,
property_name_p,
ECMA_PROPERTY_FLAG_WRITABLE,
&prototype_prop_p);
// 18.
ecma_property_t *prototype_prop_p = ecma_create_named_data_property (obj_p,
property_name_p,
ECMA_PROPERTY_FLAG_WRITABLE);
prototype_prop_value_p->value = ecma_make_object_value (proto_object_p);
ecma_named_data_property_assign_value (obj_p, prototype_prop_p, ecma_make_object_value (proto_p));
ecma_deref_object (proto_object_p);
ecma_deref_object (proto_p);
JERRY_ASSERT (!ecma_is_property_configurable (prototype_prop_p));
return prototype_prop_p;
}
return NULL;
return prototype_prop_p;
} /* ecma_op_function_try_lazy_instantiate_property */
/**
* Implementation-defined extension of [[GetOwnProperty]] ecma function object's operation
*
* Note:
* The [[GetOwnProperty]] is used only for lazy property instantiation,
* i.e. externally visible behaviour of [[GetOwnProperty]] is specification-defined
*
* @return pointer to a property - if it already existed
* or was lazy instantiated in context of
* current invocation,
* NULL (i.e. ecma-undefined) - otherwise.
*/
ecma_property_t *
ecma_op_function_object_get_own_property (ecma_object_t *obj_p, /**< the function object */
ecma_string_t *property_name_p) /**< property name */
{
JERRY_ASSERT (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_FUNCTION);
ecma_property_t *prop_p = ecma_op_general_object_get_own_property (obj_p, property_name_p);
if (prop_p != NULL)
{
return prop_p;
}
else if (!ecma_get_object_is_builtin (obj_p))
{
prop_p = ecma_op_function_try_lazy_instantiate_property (obj_p, property_name_p);
/*
* Only non-configurable properties could be instantiated lazily in the function,
* as configurable properties could be deleted and it would be incorrect
* to reinstantiate them in the function in second time.
*/
JERRY_ASSERT (prop_p == NULL || !ecma_is_property_configurable (prop_p));
}
return prop_p;
} /* ecma_op_function_object_get_own_property */
/**
* External function object creation operation.
*

View File

@ -47,9 +47,6 @@ extern ecma_value_t
ecma_op_function_call (ecma_object_t *, ecma_value_t,
const ecma_value_t *, ecma_length_t);
extern ecma_property_t *
ecma_op_function_object_get_own_property (ecma_object_t *, ecma_string_t *);
extern ecma_value_t
ecma_op_function_construct (ecma_object_t *, const ecma_value_t *, ecma_length_t);

View File

@ -104,24 +104,33 @@ ecma_op_get_value_object_base (ecma_value_t base, /**< base value */
&& !ecma_is_lexical_environment (obj_p));
// 2.
ecma_property_t *prop_p = ecma_op_object_get_property (obj_p, property_name_p);
ecma_property_ref_t property_ref;
ecma_property_t property = ecma_op_object_get_property (obj_p,
property_name_p,
&property_ref,
ECMA_PROPERTY_GET_VALUE);
if (prop_p == NULL)
if (property == ECMA_PROPERTY_TYPE_NOT_FOUND)
{
// 3.
ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
}
else if (ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA)
else if (ECMA_PROPERTY_GET_TYPE (property) == ECMA_PROPERTY_TYPE_NAMEDDATA)
{
// 4.
ret_value = ecma_copy_value (ecma_get_named_data_property_value (prop_p));
ret_value = ecma_copy_value (property_ref.value_p->value);
}
else if (ECMA_PROPERTY_GET_TYPE (property) == ECMA_PROPERTY_TYPE_VIRTUAL)
{
// 4.
ret_value = property_ref.virtual_value;
}
else
{
// 5.
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR);
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (property) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR);
ecma_object_t *obj_p = ecma_get_named_accessor_property_getter (prop_p);
ecma_object_t *obj_p = ecma_get_named_accessor_property_getter (property_ref.value_p);
// 6.
if (obj_p == NULL)

View File

@ -136,7 +136,8 @@ ecma_op_create_mutable_binding (ecma_object_t *lex_env_p, /**< lexical environme
ecma_create_named_data_property (lex_env_p,
name_p,
prop_attributes);
prop_attributes,
NULL);
}
else
{
@ -187,11 +188,14 @@ ecma_op_set_mutable_binding (ecma_object_t *lex_env_p, /**< lexical environment
if (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE)
{
ecma_property_t *property_p = ecma_get_named_data_property (lex_env_p, name_p);
ecma_property_t *property_p = ecma_find_named_property (lex_env_p, name_p);
if (ecma_is_property_writable (property_p))
JERRY_ASSERT (property_p != NULL
&& ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDDATA);
if (ecma_is_property_writable (*property_p))
{
ecma_named_data_property_assign_value (lex_env_p, property_p, value);
ecma_named_data_property_assign_value (lex_env_p, ECMA_PROPERTY_VALUE_PTR (property_p), value);
}
else if (is_strict)
{
@ -242,26 +246,9 @@ ecma_op_get_binding_value (ecma_object_t *lex_env_p, /**< lexical environment */
if (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE)
{
ecma_property_t *property_p = ecma_get_named_data_property (lex_env_p, name_p);
ecma_property_value_t *prop_value_p = ecma_get_named_data_property (lex_env_p, name_p);
ecma_value_t prop_value = ecma_get_named_data_property_value (property_p);
/* is the binding mutable? */
if (!ecma_is_property_writable (property_p)
&& ecma_is_value_empty (prop_value))
{
/* unitialized immutable binding */
if (is_strict)
{
return ecma_raise_reference_error (ECMA_ERR_MSG (""));
}
else
{
return ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
}
}
return ecma_copy_value (prop_value);
return ecma_copy_value (prop_value_p->value);
}
else
{
@ -317,15 +304,15 @@ ecma_op_delete_binding (ecma_object_t *lex_env_p, /**< lexical environment */
}
else
{
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA);
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (*prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA);
if (!ecma_is_property_configurable (prop_p))
if (!ecma_is_property_configurable (*prop_p))
{
ret_val = ECMA_SIMPLE_VALUE_FALSE;
}
else
{
ecma_delete_property (lex_env_p, prop_p);
ecma_delete_property (lex_env_p, ECMA_PROPERTY_VALUE_PTR (prop_p));
ret_val = ECMA_SIMPLE_VALUE_TRUE;
}
@ -388,7 +375,8 @@ ecma_op_implicit_this_value (ecma_object_t *lex_env_p) /**< lexical environment
*/
void
ecma_op_create_immutable_binding (ecma_object_t *lex_env_p, /**< lexical environment */
ecma_string_t *name_p) /**< argument N */
ecma_string_t *name_p, /**< argument N */
ecma_value_t value) /**< argument V */
{
JERRY_ASSERT (lex_env_p != NULL
&& ecma_is_lexical_environment (lex_env_p));
@ -398,39 +386,14 @@ ecma_op_create_immutable_binding (ecma_object_t *lex_env_p, /**< lexical environ
* Warning:
* Whether immutable bindings are deletable seems not to be defined by ECMA v5.
*/
ecma_property_t *prop_p = ecma_create_named_data_property (lex_env_p,
name_p,
ECMA_PROPERTY_FIXED);
ecma_property_value_t *prop_value_p = ecma_create_named_data_property (lex_env_p,
name_p,
ECMA_PROPERTY_FIXED,
NULL);
JERRY_ASSERT (ecma_is_value_undefined (ecma_get_named_data_property_value (prop_p)));
ecma_set_named_data_property_value (prop_p,
ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY));
prop_value_p->value = ecma_copy_value_if_not_object (value);
} /* ecma_op_create_immutable_binding */
/**
* InitializeImmutableBinding operation.
*
* See also: ECMA-262 v5, 10.2.1
*/
void
ecma_op_initialize_immutable_binding (ecma_object_t *lex_env_p, /**< lexical environment */
ecma_string_t *name_p, /**< argument N */
ecma_value_t value) /**< argument V */
{
JERRY_ASSERT (lex_env_p != NULL
&& ecma_is_lexical_environment (lex_env_p));
JERRY_ASSERT (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE);
ecma_property_t *prop_p = ecma_get_named_data_property (lex_env_p, name_p);
/* The binding must be unitialized immutable binding */
JERRY_ASSERT (!ecma_is_property_writable (prop_p)
&& ecma_is_value_empty (ecma_get_named_data_property_value (prop_p)));
ecma_named_data_property_assign_value (lex_env_p, prop_p, value);
} /* ecma_op_initialize_immutable_binding */
/**
* @}
* @}

View File

@ -52,8 +52,7 @@ extern ecma_value_t ecma_op_delete_binding (ecma_object_t *, ecma_string_t *);
extern ecma_value_t ecma_op_implicit_this_value (ecma_object_t *);
/* ECMA-262 v5, Table 18. Additional methods of Declarative Environment Records */
extern void ecma_op_create_immutable_binding (ecma_object_t *, ecma_string_t *);
extern void ecma_op_initialize_immutable_binding (ecma_object_t *, ecma_string_t *, ecma_value_t);
extern void ecma_op_create_immutable_binding (ecma_object_t *, ecma_string_t *, ecma_value_t);
extern ecma_object_t *ecma_op_create_global_environment (ecma_object_t *);

View File

@ -233,10 +233,9 @@ ecma_op_create_arguments_object (ecma_object_t *func_obj_p, /**< callee function
if (is_strict)
{
ecma_op_create_immutable_binding (lex_env_p, arguments_string_p);
ecma_op_initialize_immutable_binding (lex_env_p,
arguments_string_p,
ecma_make_object_value (obj_p));
ecma_op_create_immutable_binding (lex_env_p,
arguments_string_p,
ecma_make_object_value (obj_p));
}
else
{
@ -293,7 +292,7 @@ ecma_arguments_update_mapped_arg_value (ecma_object_t *object_p, /**< the object
JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (value));
ecma_named_data_property_assign_value (object_p, property_p, value);
ecma_named_data_property_assign_value (object_p, ECMA_PROPERTY_VALUE_PTR (property_p), value);
ecma_free_value (value);
/* These properties cannot be cached. This is a temporary
@ -362,15 +361,13 @@ ecma_op_arguments_object_define_own_property (ecma_object_t *obj_p, /**< the obj
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);
ecma_property_t *mapped_prop_p = ecma_op_object_get_own_property (map_p, property_name_p);
ecma_value_t arg_name_prop_value = ecma_get_named_data_property_value (mapped_prop_p);
ecma_string_t *arg_name_p = ecma_get_string_from_value (arg_name_prop_value);
ecma_property_value_t *arg_name_value_p = ecma_get_named_data_property (map_p, property_name_p);
completion = ecma_op_set_mutable_binding (lex_env_p,
arg_name_p,
ecma_get_string_from_value (arg_name_value_p->value),
property_desc_p->value,
true);
JERRY_ASSERT (ecma_is_value_empty (completion));
}

View File

@ -128,27 +128,6 @@ ecma_op_create_object_object_noarg_and_set_prototype (ecma_object_t *object_prot
return obj_p;
} /* ecma_op_create_object_object_noarg_and_set_prototype */
/**
* [[GetOwnProperty]] ecma general object's operation
*
* See also:
* ECMA-262 v5, 8.6.2; ECMA-262 v5, Table 8
* ECMA-262 v5, 8.12.2
*
* @return pointer to a property - if it exists,
* NULL (i.e. ecma-undefined) - otherwise.
*/
ecma_property_t *
ecma_op_general_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);
return ecma_find_named_property (obj_p, property_name_p);
} /* ecma_op_general_object_get_own_property */
/**
* [[Delete]] ecma general object's operation
*
@ -169,19 +148,24 @@ ecma_op_general_object_delete (ecma_object_t *obj_p, /**< the object */
JERRY_ASSERT (property_name_p != NULL);
// 1.
ecma_property_t *desc_p = ecma_op_object_get_own_property (obj_p, property_name_p);
ecma_property_ref_t property_ref;
ecma_property_t property = ecma_op_object_get_own_property (obj_p,
property_name_p,
&property_ref,
ECMA_PROPERTY_GET_NO_OPTIONS);
// 2.
if (desc_p == NULL)
if (property == ECMA_PROPERTY_TYPE_NOT_FOUND)
{
return ecma_make_simple_value (ECMA_SIMPLE_VALUE_TRUE);
}
// 3.
if (ecma_is_property_configurable (desc_p))
if (ecma_is_property_configurable (property))
{
// a.
ecma_delete_property (obj_p, desc_p);
ecma_delete_property (obj_p, property_ref.value_p);
// b.
return ecma_make_simple_value (ECMA_SIMPLE_VALUE_TRUE);
@ -330,9 +314,14 @@ ecma_op_general_object_define_own_property (ecma_object_t *obj_p, /**< the objec
JERRY_ASSERT (property_desc_p->is_writable_defined || !property_desc_p->is_writable);
// 1.
ecma_property_t *current_p = ecma_op_object_get_own_property (obj_p, property_name_p);
ecma_property_ref_t property_ref;
if (current_p == NULL)
ecma_property_t current_prop = ecma_op_object_get_own_property (obj_p,
property_name_p,
&property_ref,
ECMA_PROPERTY_GET_VALUE);
if (current_prop == ECMA_PROPERTY_TYPE_NOT_FOUND)
{
// 3.
if (!ecma_get_object_extensible (obj_p))
@ -365,14 +354,15 @@ ecma_op_general_object_define_own_property (ecma_object_t *obj_p, /**< the objec
prop_attributes = (uint8_t) (prop_attributes | ECMA_PROPERTY_FLAG_WRITABLE);
}
ecma_property_t *new_prop_p = ecma_create_named_data_property (obj_p,
property_name_p,
prop_attributes);
ecma_property_value_t *new_prop_value_p = ecma_create_named_data_property (obj_p,
property_name_p,
prop_attributes,
NULL);
JERRY_ASSERT (property_desc_p->is_value_defined
|| ecma_is_value_undefined (property_desc_p->value));
ecma_named_data_property_assign_value (obj_p, new_prop_p, property_desc_p->value);
new_prop_value_p->value = ecma_copy_value_if_not_object (property_desc_p->value);
}
else
{
@ -400,21 +390,45 @@ ecma_op_general_object_define_own_property (ecma_object_t *obj_p, /**< the objec
}
// 6.
ecma_property_types_t current_property_type = ECMA_PROPERTY_GET_TYPE (current_p);
const bool is_current_configurable = ecma_is_property_configurable (current_p);
ecma_property_types_t current_property_type = ECMA_PROPERTY_GET_TYPE (current_prop);
const bool is_current_configurable = ecma_is_property_configurable (current_prop);
JERRY_ASSERT (current_property_type == ECMA_PROPERTY_TYPE_NAMEDDATA
|| current_property_type == ECMA_PROPERTY_TYPE_NAMEDACCESSOR);
|| current_property_type == ECMA_PROPERTY_TYPE_NAMEDACCESSOR
|| current_property_type == ECMA_PROPERTY_TYPE_VIRTUAL);
// 7. a., b.
if (!is_current_configurable
&& (property_desc_p->is_configurable
|| (property_desc_p->is_enumerable_defined
&& (property_desc_p->is_enumerable != ecma_is_property_enumerable (current_p)))))
&& (property_desc_p->is_enumerable != ecma_is_property_enumerable (current_prop)))))
{
if (current_property_type == ECMA_PROPERTY_TYPE_VIRTUAL)
{
ecma_free_value (property_ref.virtual_value);
}
return ecma_reject (is_throw);
}
if (current_property_type == ECMA_PROPERTY_TYPE_VIRTUAL)
{
JERRY_ASSERT (!is_current_configurable && !ecma_is_property_writable (current_prop));
ecma_value_t result = ecma_make_simple_value (ECMA_SIMPLE_VALUE_TRUE);
if (property_desc_type == ECMA_PROPERTY_TYPE_NAMEDACCESSOR
|| property_desc_p->is_writable
|| (property_desc_p->is_value_defined
&& !ecma_op_same_value (property_desc_p->value,
property_ref.virtual_value)))
{
result = ecma_reject (is_throw);
}
ecma_free_value (property_ref.virtual_value);
return result;
}
// 8.
if (property_desc_type == ECMA_PROPERTY_TYPE_GENERIC)
{
@ -428,11 +442,11 @@ ecma_op_general_object_define_own_property (ecma_object_t *obj_p, /**< the objec
if (property_desc_type == ECMA_PROPERTY_TYPE_NAMEDDATA)
{
// 10. a. i. & ii.
if (!ecma_is_property_writable (current_p)
if (!ecma_is_property_writable (current_prop)
&& (property_desc_p->is_writable
|| (property_desc_p->is_value_defined
&& !ecma_op_same_value (property_desc_p->value,
ecma_get_named_data_property_value (current_p)))))
property_ref.value_p->value))))
{
return ecma_reject (is_throw);
}
@ -443,9 +457,9 @@ ecma_op_general_object_define_own_property (ecma_object_t *obj_p, /**< the objec
// a.
if ((property_desc_p->is_get_defined
&& property_desc_p->get_p != ecma_get_named_accessor_property_getter (current_p))
&& property_desc_p->get_p != ecma_get_named_accessor_property_getter (property_ref.value_p))
|| (property_desc_p->is_set_defined
&& property_desc_p->set_p != ecma_get_named_accessor_property_setter (current_p)))
&& property_desc_p->set_p != ecma_get_named_accessor_property_setter (property_ref.value_p)))
{
// i., ii.
return ecma_reject (is_throw);
@ -466,41 +480,46 @@ ecma_op_general_object_define_own_property (ecma_object_t *obj_p, /**< the objec
* the fields of current_p if this code path is performance critical. */
uint8_t prop_attributes = ECMA_PROPERTY_FLAG_CONFIGURABLE;
if (ecma_is_property_enumerable (current_p))
if (ecma_is_property_enumerable (current_prop))
{
prop_attributes = (uint8_t) (prop_attributes | ECMA_PROPERTY_FLAG_ENUMERABLE);
}
ecma_delete_property (obj_p, current_p);
ecma_delete_property (obj_p, property_ref.value_p);
if (property_desc_type == ECMA_PROPERTY_TYPE_NAMEDACCESSOR)
{
// b.
current_p = ecma_create_named_accessor_property (obj_p,
property_name_p,
NULL,
NULL,
prop_attributes);
property_ref.value_p = ecma_create_named_accessor_property (obj_p,
property_name_p,
NULL,
NULL,
prop_attributes);
}
else
{
// c.
current_p = ecma_create_named_data_property (obj_p,
property_name_p,
prop_attributes);
property_ref.value_p = ecma_create_named_data_property (obj_p,
property_name_p,
prop_attributes,
NULL);
}
}
ecma_property_t *current_p = ecma_find_named_property (obj_p, property_name_p);
JERRY_ASSERT (ECMA_PROPERTY_VALUE_PTR (current_p) == property_ref.value_p);
// 12.
if (property_desc_type == ECMA_PROPERTY_TYPE_NAMEDDATA)
{
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (current_p) == ECMA_PROPERTY_TYPE_NAMEDDATA);
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (*current_p) == ECMA_PROPERTY_TYPE_NAMEDDATA);
if (property_desc_p->is_value_defined)
{
ecma_named_data_property_assign_value (obj_p, current_p, property_desc_p->value);
ecma_named_data_property_assign_value (obj_p, property_ref.value_p, property_desc_p->value);
}
if (property_desc_p->is_writable_defined)
@ -510,16 +529,16 @@ ecma_op_general_object_define_own_property (ecma_object_t *obj_p, /**< the objec
}
else if (property_desc_type == ECMA_PROPERTY_TYPE_NAMEDACCESSOR)
{
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (current_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR);
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (*current_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR);
if (property_desc_p->is_get_defined)
{
ecma_set_named_accessor_property_getter (obj_p, current_p, property_desc_p->get_p);
ecma_set_named_accessor_property_getter (obj_p, property_ref.value_p, property_desc_p->get_p);
}
if (property_desc_p->is_set_defined)
{
ecma_set_named_accessor_property_setter (obj_p, current_p, property_desc_p->set_p);
ecma_set_named_accessor_property_setter (obj_p, property_ref.value_p, property_desc_p->set_p);
}
}

View File

@ -31,7 +31,6 @@ extern ecma_object_t *ecma_op_create_object_object_noarg (void);
extern ecma_value_t ecma_op_create_object_object_arg (ecma_value_t);
extern ecma_object_t *ecma_op_create_object_object_noarg_and_set_prototype (ecma_object_t *);
extern ecma_property_t *ecma_op_general_object_get_own_property (ecma_object_t *, ecma_string_t *);
extern ecma_value_t ecma_op_general_object_delete (ecma_object_t *, ecma_string_t *, bool);
extern ecma_value_t ecma_op_general_object_default_value (ecma_object_t *, ecma_preferred_type_hint_t);
extern ecma_value_t ecma_op_general_object_define_own_property (ecma_object_t *, ecma_string_t *,

View File

@ -18,6 +18,7 @@
#include "ecma-builtins.h"
#include "ecma-builtin-helpers.h"
#include "ecma-exceptions.h"
#include "ecma-gc.h"
#include "ecma-globals.h"
#include "ecma-function-object.h"
#include "ecma-lcache.h"
@ -57,76 +58,6 @@
#define JERRY_ASSERT_OBJECT_TYPE_IS_VALID(type)
#endif /* !JERRY_NDEBUG */
/**
* Long path for ecma_op_object_get_own_property
*
* @return pointer to a property - if it exists,
* NULL (i.e. ecma-undefined) - otherwise.
*/
static ecma_property_t * __attr_noinline___
ecma_op_object_get_own_property_longpath (ecma_object_t *obj_p, /**< the object */
ecma_string_t *property_name_p) /**< property name */
{
const ecma_object_type_t type = ecma_get_object_type (obj_p);
const bool is_builtin = ecma_get_object_is_builtin (obj_p);
ecma_property_t *prop_p = NULL;
switch (type)
{
case ECMA_OBJECT_TYPE_GENERAL:
case ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION:
case ECMA_OBJECT_TYPE_ARRAY:
case ECMA_OBJECT_TYPE_BOUND_FUNCTION:
{
prop_p = ecma_op_general_object_get_own_property (obj_p, property_name_p);
break;
}
case ECMA_OBJECT_TYPE_FUNCTION:
{
prop_p = ecma_op_function_object_get_own_property (obj_p, property_name_p);
break;
}
case ECMA_OBJECT_TYPE_STRING:
{
prop_p = ecma_op_string_object_get_own_property (obj_p, property_name_p);
break;
}
case ECMA_OBJECT_TYPE_ARGUMENTS:
{
prop_p = ecma_op_general_object_get_own_property (obj_p, property_name_p);
if (prop_p != NULL)
{
ecma_arguments_update_mapped_arg_value (obj_p, property_name_p, prop_p);
}
break;
}
default:
{
JERRY_UNREACHABLE ();
break;
}
}
if (unlikely (prop_p == NULL))
{
if (is_builtin)
{
prop_p = ecma_builtin_try_to_instantiate_property (obj_p, property_name_p);
}
}
return prop_p;
} /* ecma_op_object_get_own_property_longpath */
/**
* [[GetOwnProperty]] ecma object's operation
*
@ -136,22 +67,123 @@ ecma_op_object_get_own_property_longpath (ecma_object_t *obj_p, /**< the object
* @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 */
ecma_property_t
ecma_op_object_get_own_property (ecma_object_t *object_p, /**< the object */
ecma_string_t *property_name_p, /**< property name */
ecma_property_ref_t *property_ref_p, /**< property reference */
uint32_t options) /**< option bits */
{
JERRY_ASSERT (obj_p != NULL
&& !ecma_is_lexical_environment (obj_p));
JERRY_ASSERT (object_p != NULL
&& !ecma_is_lexical_environment (object_p));
JERRY_ASSERT (property_name_p != NULL);
ecma_property_t *prop_p = ecma_lcache_lookup (obj_p, property_name_p);
ecma_object_type_t type = ecma_get_object_type (object_p);
if (likely (prop_p != NULL))
ecma_property_t *property_p = ecma_find_named_property (object_p, property_name_p);
if (property_p == NULL)
{
return prop_p;
if (type == ECMA_OBJECT_TYPE_STRING)
{
uint32_t index;
if (ecma_string_get_array_index (property_name_p, &index))
{
ecma_value_t *prim_value_p = ecma_get_internal_property (object_p,
ECMA_INTERNAL_PROPERTY_ECMA_VALUE);
ecma_string_t *prim_value_str_p = ecma_get_string_from_value (*prim_value_p);
if (index < ecma_string_get_length (prim_value_str_p))
{
if (options & ECMA_PROPERTY_GET_VALUE)
{
ecma_char_t char_at_idx = ecma_string_get_char_at_pos (prim_value_str_p, index);
ecma_string_t *char_str_p = ecma_new_ecma_string_from_code_unit (char_at_idx);
property_ref_p->virtual_value = ecma_make_string_value (char_str_p);
}
return ECMA_PROPERTY_FLAG_ENUMERABLE | ECMA_PROPERTY_TYPE_VIRTUAL;
}
}
}
if (ecma_get_object_is_builtin (object_p))
{
property_p = ecma_builtin_try_to_instantiate_property (object_p, property_name_p);
}
else if (type == ECMA_OBJECT_TYPE_FUNCTION)
{
if (ecma_string_is_length (property_name_p))
{
if (options & ECMA_PROPERTY_GET_VALUE)
{
/* Get length virtual property. */
ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) object_p;
const ecma_compiled_code_t *bytecode_data_p;
bytecode_data_p = ECMA_GET_INTERNAL_VALUE_POINTER (const ecma_compiled_code_t,
ext_func_p->u.function.bytecode_cp);
uint32_t len;
if (bytecode_data_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS)
{
cbc_uint16_arguments_t *args_p = (cbc_uint16_arguments_t *) bytecode_data_p;
len = args_p->argument_end;
}
else
{
cbc_uint8_arguments_t *args_p = (cbc_uint8_arguments_t *) bytecode_data_p;
len = args_p->argument_end;
}
property_ref_p->virtual_value = ecma_make_uint32_value (len);
}
return ECMA_PROPERTY_TYPE_VIRTUAL;
}
/* Get prototype physical property. */
property_p = ecma_op_function_try_lazy_instantiate_property (object_p, property_name_p);
}
if (property_p == NULL)
{
return ECMA_PROPERTY_TYPE_NOT_FOUND;
}
}
else if (type == ECMA_OBJECT_TYPE_ARGUMENTS)
{
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_own (*map_prop_p, map_p, property_name_p);
if (ecma_is_value_found (arg_name))
{
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 binding_value = ecma_op_get_binding_value (lex_env_p, arg_name_p, true);
ecma_deref_ecma_string (arg_name_p);
ecma_named_data_property_assign_value (object_p,
ECMA_PROPERTY_VALUE_PTR (property_p),
binding_value);
ecma_free_value (binding_value);
}
}
return ecma_op_object_get_own_property_longpath (obj_p, property_name_p);
if (property_ref_p != NULL)
{
property_ref_p->value_p = ECMA_PROPERTY_VALUE_PTR (property_p);
}
return *property_p;
} /* ecma_op_object_get_own_property */
/**
@ -163,20 +195,25 @@ ecma_op_object_get_own_property (ecma_object_t *obj_p, /**< the object */
* @return pointer to a property - if it exists,
* NULL (i.e. ecma-undefined) - otherwise.
*/
ecma_property_t *
ecma_property_t
ecma_op_object_get_property (ecma_object_t *object_p, /**< the object */
ecma_string_t *property_name_p) /**< property name */
ecma_string_t *property_name_p, /**< property name */
ecma_property_ref_t *property_ref_p, /**< property reference */
uint32_t options) /**< option bits */
{
/* Circular reference is possible in JavaScript and testing it is complicated. */
int max_depth = 128;
do
{
ecma_property_t *property_p = ecma_op_object_get_own_property (object_p, property_name_p);
ecma_property_t property = ecma_op_object_get_own_property (object_p,
property_name_p,
property_ref_p,
options);
if (property_p != NULL)
if (property != ECMA_PROPERTY_TYPE_NOT_FOUND)
{
return property_p;
return property;
}
if (--max_depth == 0)
@ -188,7 +225,7 @@ ecma_op_object_get_property (ecma_object_t *object_p, /**< the object */
}
while (object_p != NULL);
return NULL;
return ECMA_PROPERTY_TYPE_NOT_FOUND;
} /* ecma_op_object_get_property */
/**
@ -201,7 +238,11 @@ inline bool __attr_always_inline___
ecma_op_object_has_own_property (ecma_object_t *object_p, /**< the object */
ecma_string_t *property_name_p) /**< property name */
{
return ecma_op_object_get_own_property (object_p, property_name_p) != NULL;
ecma_property_t property = ecma_op_object_get_own_property (object_p,
property_name_p,
NULL,
ECMA_PROPERTY_GET_NO_OPTIONS);
return property != ECMA_PROPERTY_TYPE_NOT_FOUND;
} /* ecma_op_object_has_own_property */
/**
@ -214,7 +255,11 @@ inline bool __attr_always_inline___
ecma_op_object_has_property (ecma_object_t *object_p, /**< the object */
ecma_string_t *property_name_p) /**< property name */
{
return ecma_op_object_get_property (object_p, property_name_p) != NULL;
ecma_property_t property = ecma_op_object_get_property (object_p,
property_name_p,
NULL,
ECMA_PROPERTY_GET_NO_OPTIONS);
return property != ECMA_PROPERTY_TYPE_NOT_FOUND;
} /* ecma_op_object_has_property */
/**
@ -322,12 +367,16 @@ ecma_op_object_find_own (ecma_value_t base_value, /**< base value */
}
}
if (ECMA_PROPERTY_GET_TYPE (property_p) == ECMA_PROPERTY_TYPE_NAMEDDATA)
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 (ecma_get_named_data_property_value (property_p));
return ecma_fast_copy_value (prop_value_p->value);
}
ecma_object_t *getter_p = ecma_get_named_accessor_property_getter (property_p);
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)
{
@ -387,15 +436,22 @@ inline ecma_value_t __attr_always_inline___
ecma_op_object_get_own_data_prop (ecma_object_t *object_p, /**< the object */
ecma_string_t *property_name_p) /**< property name */
{
ecma_value_t result = ecma_op_object_find_own (ecma_make_object_value (object_p),
object_p,
property_name_p);
#ifndef JERRY_NDEBUG
ecma_property_t *property_p = ecma_op_object_get_own_property (object_p, property_name_p);
/* Because ecma_op_object_find_own might create a property
* this check is executed after the function return. */
ecma_property_t *property_p = ecma_find_named_property (object_p,
property_name_p);
JERRY_ASSERT (property_p != NULL
&& ECMA_PROPERTY_GET_TYPE (property_p) == ECMA_PROPERTY_TYPE_NAMEDDATA
&& !ecma_is_property_configurable (property_p));
&& ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDDATA
&& !ecma_is_property_configurable (*property_p));
#endif /* !JERRY_NDEBUG */
return ecma_op_object_find (object_p, property_name_p);
return result;
} /* ecma_op_object_get_own_data_prop */
/**
@ -411,14 +467,29 @@ ecma_value_t
ecma_op_object_get (ecma_object_t *object_p, /**< the object */
ecma_string_t *property_name_p) /**< property name */
{
ecma_value_t value = ecma_op_object_find (object_p, property_name_p);
/* Circular reference is possible in JavaScript and testing it is complicated. */
int max_depth = 128;
if (!ecma_is_value_found (value))
ecma_value_t base_value = ecma_make_object_value (object_p);
do
{
value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
}
ecma_value_t value = ecma_op_object_find_own (base_value, object_p, property_name_p);
return value;
if (ecma_is_value_found (value))
{
return value;
}
if (--max_depth == 0)
{
break;
}
object_p = ecma_get_object_prototype (object_p);
}
while (object_p != NULL);
return ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
} /* ecma_op_object_get */
/**
@ -514,9 +585,9 @@ ecma_op_object_put (ecma_object_t *object_p, /**< the object */
if (property_p != NULL)
{
if (ECMA_PROPERTY_GET_TYPE (property_p) == ECMA_PROPERTY_TYPE_NAMEDDATA)
if (ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDDATA)
{
if (ecma_is_property_writable (property_p))
if (ecma_is_property_writable (*property_p))
{
if (type == ECMA_OBJECT_TYPE_ARRAY && ecma_string_is_length (property_name_p))
{
@ -534,15 +605,17 @@ ecma_op_object_put (ecma_object_t *object_p, /**< the object */
/* There is no need for special casing arrays here because changing the
* value of an existing property never changes the length of an array. */
ecma_named_data_property_assign_value (object_p, property_p, value);
ecma_named_data_property_assign_value (object_p,
ECMA_PROPERTY_VALUE_PTR (property_p),
value);
return ecma_make_simple_value (ECMA_SIMPLE_VALUE_TRUE);
}
}
else
{
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (property_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR);
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR);
setter_p = ecma_get_named_accessor_property_setter (property_p);
setter_p = ecma_get_named_accessor_property_setter (ECMA_PROPERTY_VALUE_PTR (property_p));
}
}
else
@ -552,18 +625,23 @@ ecma_op_object_put (ecma_object_t *object_p, /**< the object */
if (proto_p != NULL)
{
ecma_property_t *inherited_property_p = ecma_op_object_get_property (proto_p, property_name_p);
ecma_property_ref_t property_ref;
if (inherited_property_p != NULL)
ecma_property_t inherited_property = ecma_op_object_get_property (proto_p,
property_name_p,
&property_ref,
ECMA_PROPERTY_GET_NO_OPTIONS);
if (inherited_property != ECMA_PROPERTY_TYPE_NOT_FOUND)
{
if (ECMA_PROPERTY_GET_TYPE (inherited_property_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR)
if (ECMA_PROPERTY_GET_TYPE (inherited_property) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR)
{
setter_p = ecma_get_named_accessor_property_setter (inherited_property_p);
setter_p = ecma_get_named_accessor_property_setter (property_ref.value_p);
create_new_property = false;
}
else
{
create_new_property = ecma_is_property_writable (inherited_property_p);
create_new_property = ecma_is_property_writable (inherited_property);
}
}
}
@ -597,33 +675,34 @@ ecma_op_object_put (ecma_object_t *object_p, /**< the object */
ecma_string_t magic_string_length;
ecma_init_ecma_length_string (&magic_string_length);
ecma_property_t *len_prop_p = ecma_op_object_get_own_property (object_p, &magic_string_length);
ecma_property_t *len_prop_p = ecma_find_named_property (object_p, &magic_string_length);
JERRY_ASSERT (len_prop_p != NULL
&& ECMA_PROPERTY_GET_TYPE (len_prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA);
&& ECMA_PROPERTY_GET_TYPE (*len_prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA);
uint32_t old_len = ecma_get_uint32_from_value (ecma_get_named_data_property_value (len_prop_p));
ecma_property_value_t *len_prop_value_p = ECMA_PROPERTY_VALUE_PTR (len_prop_p);
uint32_t old_len = ecma_get_uint32_from_value (len_prop_value_p->value);
if (index < UINT32_MAX
&& index >= old_len)
{
if (!ecma_is_property_writable (len_prop_p))
if (!ecma_is_property_writable (*len_prop_p))
{
return ecma_reject (is_throw);
}
ecma_property_value_t *len_prop_value_p = ECMA_PROPERTY_VALUE_PTR (len_prop_p);
ecma_value_assign_uint32 (&len_prop_value_p->value, index + 1);
}
}
ecma_property_t *new_prop_p;
new_prop_p = ecma_create_named_data_property (object_p,
property_name_p,
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE);
ecma_property_value_t *new_prop_value_p;
new_prop_value_p = ecma_create_named_data_property (object_p,
property_name_p,
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE,
NULL);
JERRY_ASSERT (ecma_is_value_undefined (ecma_get_named_data_property_value (new_prop_p)));
ecma_set_named_data_property_value (new_prop_p, ecma_copy_value_if_not_object (value));
JERRY_ASSERT (ecma_is_value_undefined (new_prop_value_p->value));
new_prop_value_p->value = ecma_copy_value_if_not_object (value);
return ecma_make_simple_value (ECMA_SIMPLE_VALUE_TRUE);
}
}
@ -796,6 +875,83 @@ ecma_op_object_define_own_property (ecma_object_t *obj_p, /**< the object */
}
} /* ecma_op_object_define_own_property */
/**
* Get property descriptor from specified property
*
* depending on the property type the following fields are set:
* - for named data properties: { [Value], [Writable], [Enumerable], [Configurable] };
* - for named accessor properties: { [Get] - if defined,
* [Set] - if defined,
* [Enumerable], [Configurable]
* }.
*
* @return true if property found
* false otherwise
*/
bool
ecma_op_object_get_own_property_descriptor (ecma_object_t *object_p, /**< the object */
ecma_string_t *property_name_p, /**< property name */
ecma_property_descriptor_t *prop_desc_p) /**< property descriptor */
{
ecma_property_ref_t property_ref;
ecma_property_t property = ecma_op_object_get_own_property (object_p,
property_name_p,
&property_ref,
ECMA_PROPERTY_GET_VALUE);
if (property == ECMA_PROPERTY_TYPE_NOT_FOUND)
{
return false;
}
*prop_desc_p = ecma_make_empty_property_descriptor ();
prop_desc_p->is_enumerable = ecma_is_property_enumerable (property);
prop_desc_p->is_enumerable_defined = true;
prop_desc_p->is_configurable = ecma_is_property_configurable (property);
prop_desc_p->is_configurable_defined = true;
ecma_property_types_t type = ECMA_PROPERTY_GET_TYPE (property);
if (type != ECMA_PROPERTY_TYPE_NAMEDACCESSOR)
{
if (type == ECMA_PROPERTY_TYPE_NAMEDDATA)
{
prop_desc_p->value = ecma_copy_value (property_ref.value_p->value);
}
else
{
JERRY_ASSERT (type == ECMA_PROPERTY_TYPE_VIRTUAL);
prop_desc_p->value = property_ref.virtual_value;
}
prop_desc_p->is_value_defined = true;
prop_desc_p->is_writable = ecma_is_property_writable (property);
prop_desc_p->is_writable_defined = true;
}
else
{
prop_desc_p->get_p = ecma_get_named_accessor_property_getter (property_ref.value_p);
prop_desc_p->is_get_defined = true;
if (prop_desc_p->get_p != NULL)
{
ecma_ref_object (prop_desc_p->get_p);
}
prop_desc_p->set_p = ecma_get_named_accessor_property_setter (property_ref.value_p);
prop_desc_p->is_set_defined = true;
if (prop_desc_p->set_p != NULL)
{
ecma_ref_object (prop_desc_p->set_p);
}
}
return true;
} /* ecma_op_object_get_own_property_descriptor */
/**
* [[HasInstance]] ecma object's operation
*
@ -976,7 +1132,7 @@ ecma_op_object_get_property_names (ecma_object_t *obj_p, /**< object */
ecma_property_header_t *prop_iter_p = ecma_get_property_list (prototype_chain_iter_p);
if (prop_iter_p != NULL
&& ECMA_PROPERTY_GET_TYPE (prop_iter_p->types + 0) == ECMA_PROPERTY_TYPE_HASHMAP)
&& ECMA_PROPERTY_GET_TYPE (prop_iter_p->types[0]) == ECMA_PROPERTY_TYPE_HASHMAP)
{
prop_iter_p = ECMA_GET_POINTER (ecma_property_header_t,
prop_iter_p->next_property_cp);
@ -990,13 +1146,13 @@ ecma_op_object_get_property_names (ecma_object_t *obj_p, /**< object */
{
ecma_property_t *property_p = prop_iter_p->types + i;
if (ECMA_PROPERTY_GET_TYPE (property_p) == ECMA_PROPERTY_TYPE_NAMEDDATA
|| ECMA_PROPERTY_GET_TYPE (property_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR)
if (ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDDATA
|| ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR)
{
ecma_property_pair_t *prop_pair_p = (ecma_property_pair_t *) prop_iter_p;
ecma_string_t *name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t, prop_pair_p->names_cp[i]);
if (!(is_enumerable_only && !ecma_is_property_enumerable (property_p)))
if (!(is_enumerable_only && !ecma_is_property_enumerable (*property_p)))
{
uint8_t hash = (uint8_t) name_p->hash;
uint32_t bitmap_row = (uint32_t) (hash / bitmap_row_size);
@ -1031,7 +1187,7 @@ ecma_op_object_get_property_names (ecma_object_t *obj_p, /**< object */
}
else
{
JERRY_ASSERT (is_enumerable_only && !ecma_is_property_enumerable (property_p));
JERRY_ASSERT (is_enumerable_only && !ecma_is_property_enumerable (*property_p));
ecma_append_to_values_collection (skipped_non_enumerable_p,
ecma_make_string_value (name_p),

View File

@ -26,8 +26,10 @@
* @{
*/
extern ecma_property_t *ecma_op_object_get_own_property (ecma_object_t *, ecma_string_t *);
extern ecma_property_t *ecma_op_object_get_property (ecma_object_t *, ecma_string_t *);
extern ecma_property_t ecma_op_object_get_own_property (ecma_object_t *, ecma_string_t *,
ecma_property_ref_t *, uint32_t);
extern ecma_property_t ecma_op_object_get_property (ecma_object_t *, ecma_string_t *,
ecma_property_ref_t *, uint32_t);
extern bool ecma_op_object_has_own_property (ecma_object_t *, ecma_string_t *);
extern bool ecma_op_object_has_property (ecma_object_t *, ecma_string_t *);
extern ecma_value_t ecma_op_object_find_own (ecma_value_t, ecma_object_t *, ecma_string_t *);
@ -39,6 +41,8 @@ extern ecma_value_t ecma_op_object_delete (ecma_object_t *, ecma_string_t *, boo
extern ecma_value_t ecma_op_object_default_value (ecma_object_t *, ecma_preferred_type_hint_t);
extern ecma_value_t ecma_op_object_define_own_property (ecma_object_t *, ecma_string_t *,
const ecma_property_descriptor_t *, bool);
extern bool ecma_op_object_get_own_property_descriptor (ecma_object_t *, ecma_string_t *,
ecma_property_descriptor_t *);
extern ecma_value_t ecma_op_object_has_instance (ecma_object_t *, ecma_value_t);
extern bool ecma_op_object_is_prototype_of (ecma_object_t *, ecma_object_t *);
extern ecma_collection_header_t * ecma_op_object_get_property_names (ecma_object_t *, bool, bool, bool);

View File

@ -66,8 +66,7 @@ ecma_op_resolve_reference_base (ecma_object_t *lex_env_p, /**< starting lexical
*/
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 */
bool is_strict) /**< strict mode */
ecma_string_t *name_p) /**< identifier's name */
{
JERRY_ASSERT (lex_env_p != NULL);
@ -79,23 +78,7 @@ ecma_op_resolve_reference_value (ecma_object_t *lex_env_p, /**< starting lexical
if (property_p != NULL)
{
ecma_value_t prop_value = ecma_get_named_data_property_value (property_p);
/* is the binding mutable? */
if (unlikely (!ecma_is_property_writable (property_p)
&& ecma_is_value_empty (prop_value)))
{
/* unitialized mutable binding */
if (is_strict)
{
return ecma_raise_reference_error (ECMA_ERR_MSG (""));
}
else
{
return ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
}
}
return ecma_fast_copy_value (prop_value);
return ecma_fast_copy_value (ECMA_PROPERTY_VALUE_PTR (property_p)->value);
}
}
else

View File

@ -27,7 +27,7 @@
*/
extern ecma_object_t *ecma_op_resolve_reference_base (ecma_object_t *, ecma_string_t *);
extern ecma_value_t ecma_op_resolve_reference_value (ecma_object_t *, ecma_string_t *, bool);
extern ecma_value_t ecma_op_resolve_reference_value (ecma_object_t *, ecma_string_t *);
/**
* @}

View File

@ -126,90 +126,86 @@ re_parse_regexp_flags (ecma_string_t *flags_str_p, /**< Input string with flags
return ret_value;
} /* re_parse_regexp_flags */
/**
* Set a data property value for a regexp object.
*/
static void
re_set_data_property (ecma_object_t *re_object_p, /**< RegExp object */
ecma_string_t *property_name_p, /**< property name */
uint8_t prop_attributes, /**< property attributes */
ecma_value_t value) /**< property value */
{
ecma_property_ref_t property_ref;
ecma_property_t property = ecma_op_object_get_own_property (re_object_p,
property_name_p,
&property_ref,
ECMA_PROPERTY_GET_VALUE);
if (property == ECMA_PROPERTY_TYPE_NOT_FOUND)
{
property_ref.value_p = ecma_create_named_data_property (re_object_p,
property_name_p,
prop_attributes,
NULL);
}
else
{
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (property) == ECMA_PROPERTY_TYPE_NAMEDDATA
&& !ecma_is_property_configurable (property));
}
ecma_named_data_property_assign_value (re_object_p, property_ref.value_p, value);
} /* re_set_data_property */
/**
* Initializes the source, global, ignoreCase, multiline, and lastIndex properties of RegExp instance.
*/
void
re_initialize_props (ecma_object_t *re_obj_p, /**< RegExp obejct */
re_initialize_props (ecma_object_t *re_obj_p, /**< RegExp object */
ecma_string_t *source_p, /**< source string */
uint16_t flags) /**< flags */
{
/* Set source property. ECMA-262 v5, 15.10.7.1 */
ecma_string_t *magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_SOURCE);
ecma_property_t *prop_p = ecma_find_named_property (re_obj_p, magic_string_p);
if (prop_p == NULL)
{
prop_p = ecma_create_named_data_property (re_obj_p,
magic_string_p,
ECMA_PROPERTY_FIXED);
}
ecma_string_t *magic_string_p;
magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_SOURCE);
re_set_data_property (re_obj_p,
magic_string_p,
ECMA_PROPERTY_FIXED,
ecma_make_string_value (source_p));
ecma_deref_ecma_string (magic_string_p);
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA);
ecma_named_data_property_assign_value (re_obj_p,
prop_p,
ecma_make_string_value (source_p));
/* Set global property. ECMA-262 v5, 15.10.7.2 */
magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_GLOBAL);
prop_p = ecma_find_named_property (re_obj_p, magic_string_p);
if (prop_p == NULL)
{
prop_p = ecma_create_named_data_property (re_obj_p,
magic_string_p,
ECMA_PROPERTY_FIXED);
}
re_set_data_property (re_obj_p,
magic_string_p,
ECMA_PROPERTY_FIXED,
ecma_make_boolean_value (flags & RE_FLAG_GLOBAL));
ecma_deref_ecma_string (magic_string_p);
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA);
ecma_set_named_data_property_value (prop_p, ecma_make_boolean_value (flags & RE_FLAG_GLOBAL));
/* Set ignoreCase property. ECMA-262 v5, 15.10.7.3 */
magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_IGNORECASE_UL);
prop_p = ecma_find_named_property (re_obj_p, magic_string_p);
if (prop_p == NULL)
{
prop_p = ecma_create_named_data_property (re_obj_p,
magic_string_p,
ECMA_PROPERTY_FIXED);
}
re_set_data_property (re_obj_p,
magic_string_p,
ECMA_PROPERTY_FIXED,
ecma_make_boolean_value (flags & RE_FLAG_IGNORE_CASE));
ecma_deref_ecma_string (magic_string_p);
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA);
ecma_set_named_data_property_value (prop_p, ecma_make_boolean_value (flags & RE_FLAG_IGNORE_CASE));
/* Set multiline property. ECMA-262 v5, 15.10.7.4 */
magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_MULTILINE);
prop_p = ecma_find_named_property (re_obj_p, magic_string_p);
if (prop_p == NULL)
{
prop_p = ecma_create_named_data_property (re_obj_p,
magic_string_p,
ECMA_PROPERTY_FIXED);
}
re_set_data_property (re_obj_p,
magic_string_p,
ECMA_PROPERTY_FIXED,
ecma_make_boolean_value (flags & RE_FLAG_MULTILINE));
ecma_deref_ecma_string (magic_string_p);
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA);
ecma_set_named_data_property_value (prop_p, ecma_make_boolean_value (flags & RE_FLAG_MULTILINE));
/* Set lastIndex property. ECMA-262 v5, 15.10.7.5 */
magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_LASTINDEX_UL);
prop_p = ecma_find_named_property (re_obj_p, magic_string_p);
if (prop_p == NULL)
{
prop_p = ecma_create_named_data_property (re_obj_p,
magic_string_p,
ECMA_PROPERTY_FLAG_WRITABLE);
}
re_set_data_property (re_obj_p,
magic_string_p,
ECMA_PROPERTY_FLAG_WRITABLE,
ecma_make_integer_value (0));
ecma_deref_ecma_string (magic_string_p);
ecma_named_data_property_assign_value (re_obj_p, prop_p, ecma_make_integer_value (0));
} /* re_initialize_props */
/**
@ -1432,11 +1428,12 @@ ecma_regexp_exec_helper (ecma_value_t regexp_value, /**< RegExp object */
capture_value = ecma_make_string_value (capture_str_p);
}
ecma_property_t *prop_p;
prop_p = ecma_create_named_data_property (result_array_obj_p,
index_str_p,
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE);
ecma_set_named_data_property_value (prop_p, capture_value);
ecma_property_value_t *prop_value_p;
prop_value_p = ecma_create_named_data_property (result_array_obj_p,
index_str_p,
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE,
NULL);
prop_value_p->value = capture_value;
JERRY_ASSERT (!ecma_is_value_object (capture_value));
ecma_deref_ecma_string (index_str_p);

View File

@ -100,115 +100,20 @@ ecma_op_create_string_object (const ecma_value_t *arguments_list_p, /**< list of
// 15.5.5.1
ecma_string_t *length_magic_string_p = ecma_new_ecma_length_string ();
ecma_property_t *length_prop_p = ecma_create_named_data_property (obj_p,
length_magic_string_p,
ECMA_PROPERTY_FIXED);
ecma_set_named_data_property_value (length_prop_p, ecma_make_number_value (length_value));
ecma_property_value_t *length_prop_value_p = ecma_create_named_data_property (obj_p,
length_magic_string_p,
ECMA_PROPERTY_FIXED,
NULL);
ecma_deref_ecma_string (length_magic_string_p);
length_prop_value_p->value = ecma_make_number_value (length_value);
return ecma_make_object_value (obj_p);
} /* ecma_op_create_string_object */
/**
* [[GetOwnProperty]] ecma String object's operation
*
* See also:
* ECMA-262 v5, 8.6.2; ECMA-262 v5, Table 8
* ECMA-262 v5, 15.5.5.2
*
* @return ecma value
* Returned value must be freed with ecma_free_value
*/
ecma_property_t *
ecma_op_string_object_get_own_property (ecma_object_t *obj_p, /**< a String object */
ecma_string_t *property_name_p) /**< property name */
{
JERRY_ASSERT (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_STRING);
// 1.
ecma_property_t *prop_p = ecma_op_general_object_get_own_property (obj_p, property_name_p);
// 2.
if (prop_p != NULL)
{
return prop_p;
}
// 3., 5.
uint32_t uint32_index;
ecma_string_t *new_prop_name_p;
if (ECMA_STRING_GET_CONTAINER (property_name_p) == ECMA_STRING_CONTAINER_UINT32_IN_DESC)
{
uint32_index = property_name_p->u.uint32_number;
new_prop_name_p = property_name_p;
ecma_ref_ecma_string (new_prop_name_p);
}
else
{
ecma_number_t index = ecma_string_to_number (property_name_p);
uint32_index = ecma_number_to_uint32 (index);
ecma_string_t *to_str_p = ecma_new_ecma_string_from_uint32 (uint32_index);
bool are_equal = ecma_compare_ecma_strings (to_str_p, property_name_p);
if (!are_equal)
{
ecma_deref_ecma_string (to_str_p);
return NULL;
}
else
{
new_prop_name_p = to_str_p;
}
}
// 4.
ecma_value_t *prim_value_p = ecma_get_internal_property (obj_p,
ECMA_INTERNAL_PROPERTY_ECMA_VALUE);
ecma_string_t *prim_value_str_p = ecma_get_string_from_value (*prim_value_p);
// 6.
ecma_length_t length = ecma_string_get_length (prim_value_str_p);
ecma_property_t *new_prop_p;
if (uint32_index >= (uint32_t) length)
{
// 7.
new_prop_p = NULL;
}
else
{
// 8.
ecma_char_t c = ecma_string_get_char_at_pos (prim_value_str_p, uint32_index);
// 9.
ecma_string_t *new_prop_str_value_p = ecma_new_ecma_string_from_code_unit (c);
new_prop_p = ecma_create_named_data_property (obj_p,
new_prop_name_p,
ECMA_PROPERTY_FLAG_ENUMERABLE);
ecma_set_named_data_property_value (new_prop_p,
ecma_make_string_value (new_prop_str_value_p));
}
ecma_deref_ecma_string (new_prop_name_p);
return new_prop_p;
} /* ecma_op_string_object_get_own_property */
/**
* List names of a String object's lazy instantiated properties
*
* See also:
* ecma_op_string_object_get_own_property
*
* @return string values collection
*/
void

View File

@ -28,9 +28,6 @@
extern ecma_value_t
ecma_op_create_string_object (const ecma_value_t *, ecma_length_t);
extern ecma_property_t *
ecma_op_string_object_get_own_property (ecma_object_t *, ecma_string_t *);
extern void
ecma_op_string_list_lazy_property_names (ecma_object_t *,
bool,

View File

@ -1390,16 +1390,15 @@ jerry_get_own_property_descriptor (const jerry_value_t obj_val, /**< object val
return false;
}
ecma_property_t *property_p = ecma_op_object_get_property (ecma_get_object_from_value (obj_val),
ecma_get_string_from_value (prop_name_val));
ecma_property_descriptor_t prop_desc;
if (property_p == NULL)
if (!ecma_op_object_get_own_property_descriptor (ecma_get_object_from_value (obj_val),
ecma_get_string_from_value (prop_name_val),
&prop_desc))
{
return false;
}
ecma_property_descriptor_t prop_desc = ecma_get_property_descriptor_from_property (property_p);
prop_desc_p->is_configurable_defined = true;
prop_desc_p->is_configurable = prop_desc.is_configurable;
prop_desc_p->is_enumerable_defined = true;

View File

@ -157,9 +157,10 @@ opfunc_set_accessor (bool is_getter, /**< is getter accessor */
ecma_string_t *accessor_name_p = ecma_get_string_from_value (ecma_op_to_string (accessor_name));
ecma_property_t *property_p = ecma_find_named_property (object_p, accessor_name_p);
if (property_p != NULL && ECMA_PROPERTY_GET_TYPE (property_p) != ECMA_PROPERTY_TYPE_NAMEDACCESSOR)
if (property_p != NULL
&& ECMA_PROPERTY_GET_TYPE (*property_p) != ECMA_PROPERTY_TYPE_NAMEDACCESSOR)
{
ecma_delete_property (object_p, property_p);
ecma_delete_property (object_p, ECMA_PROPERTY_VALUE_PTR (property_p));
property_p = NULL;
}
@ -188,7 +189,7 @@ opfunc_set_accessor (bool is_getter, /**< is getter accessor */
ecma_object_t *getter_func_p = ecma_get_object_from_value (accessor);
ecma_set_named_accessor_property_getter (object_p,
property_p,
ECMA_PROPERTY_VALUE_PTR (property_p),
getter_func_p);
}
else
@ -196,7 +197,7 @@ opfunc_set_accessor (bool is_getter, /**< is getter accessor */
ecma_object_t *setter_func_p = ecma_get_object_from_value (accessor);
ecma_set_named_accessor_property_setter (object_p,
property_p,
ECMA_PROPERTY_VALUE_PTR (property_p),
setter_func_p);
}

View File

@ -79,9 +79,9 @@ vm_op_get_value (ecma_value_t object, /**< base object */
ecma_property_t *property_p = ecma_lcache_lookup (object_p, property_name_p);
if (property_p != NULL &&
ECMA_PROPERTY_GET_TYPE (property_p) == ECMA_PROPERTY_TYPE_NAMEDDATA)
ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDDATA)
{
return ecma_fast_copy_value (ecma_get_named_data_property_value (property_p));
return ecma_fast_copy_value (ECMA_PROPERTY_VALUE_PTR (property_p)->value);
}
/* There is no need to free the name. */
@ -481,8 +481,7 @@ opfunc_construct (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
ecma_string_t *name_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t, \
literal_start_p[literal_index]); \
result = ecma_op_resolve_reference_value (frame_ctx_p->lex_env_p, \
name_p, \
is_strict); \
name_p); \
\
if (ECMA_IS_VALUE_ERROR (result)) \
{ \
@ -618,10 +617,7 @@ vm_init_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
if (self_reference == literal_start_p[value_index])
{
ecma_op_create_immutable_binding (frame_ctx_p->lex_env_p, name_p);
ecma_op_initialize_immutable_binding (frame_ctx_p->lex_env_p,
name_p,
lit_value);
ecma_op_create_immutable_binding (frame_ctx_p->lex_env_p, name_p, lit_value);
}
else
{
@ -947,20 +943,28 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
property_p = ecma_find_named_property (object_p, prop_name_p);
if (property_p != NULL && ECMA_PROPERTY_GET_TYPE (property_p) != ECMA_PROPERTY_TYPE_NAMEDDATA)
if (property_p != NULL
&& ECMA_PROPERTY_GET_TYPE (*property_p) != ECMA_PROPERTY_TYPE_NAMEDDATA)
{
ecma_delete_property (object_p, property_p);
ecma_delete_property (object_p, ECMA_PROPERTY_VALUE_PTR (property_p));
property_p = NULL;
}
ecma_property_value_t *prop_value_p;
if (property_p == NULL)
{
property_p = ecma_create_named_data_property (object_p,
prop_name_p,
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE);
prop_value_p = ecma_create_named_data_property (object_p,
prop_name_p,
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE,
NULL);
}
else
{
prop_value_p = ECMA_PROPERTY_VALUE_PTR (property_p);
}
ecma_named_data_property_assign_value (object_p, property_p, left_value);
ecma_named_data_property_assign_value (object_p, prop_value_p, left_value);
if (!ecma_is_value_string (right_value))
{
@ -1000,7 +1004,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
{
ecma_object_t *array_obj_p;
ecma_string_t length_str;
ecma_property_t *length_prop_p;
ecma_property_value_t *length_prop_value_p;
uint32_t length_num;
uint32_t values_length = *byte_code_p++;
@ -1008,11 +1012,9 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
array_obj_p = ecma_get_object_from_value (stack_top_p[-1]);
ecma_init_ecma_length_string (&length_str);
length_prop_p = ecma_get_named_property (array_obj_p, &length_str);
length_prop_value_p = ecma_get_named_data_property (array_obj_p, &length_str);
JERRY_ASSERT (length_prop_p != NULL);
left_value = ecma_get_named_data_property_value (length_prop_p);
left_value = length_prop_value_p->value;
length_num = ecma_get_uint32_from_value (left_value);
for (uint32_t i = 0; i < values_length; i++)
@ -1021,14 +1023,14 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
{
ecma_string_t *index_str_p = ecma_new_ecma_string_from_uint32 (length_num);
ecma_property_t *prop_p;
prop_p = ecma_create_named_data_property (array_obj_p,
index_str_p,
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE);
ecma_property_value_t *prop_value_p;
prop_value_p = ecma_create_named_data_property (array_obj_p,
index_str_p,
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE,
NULL);
JERRY_ASSERT (ecma_is_value_undefined (ecma_get_named_data_property_value (prop_p)));
ecma_set_named_data_property_value (prop_p, stack_top_p[i]);
JERRY_ASSERT (ecma_is_value_undefined (prop_value_p->value));
prop_value_p->value = stack_top_p[i];
/* The reference is moved so no need to free stack_top_p[i] except for objects. */
if (ecma_is_value_object (stack_top_p[i]))
@ -1042,8 +1044,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
length_num++;
}
ecma_value_assign_uint32 (&ECMA_PROPERTY_VALUE_PTR (length_prop_p)->value,
length_num);
ecma_value_assign_uint32 (&length_prop_value_p->value, length_num);
continue;
}
case VM_OC_PUSH_UNDEFINED_BASE: