Template literal arrays should not be marked. (#4352)
Make array object big endian compatible. JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
@@ -626,13 +626,6 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */
|
||||
}
|
||||
else
|
||||
{
|
||||
jmem_cpointer_t proto_cp = object_p->u2.prototype_cp;
|
||||
|
||||
if (proto_cp != JMEM_CP_NULL)
|
||||
{
|
||||
ecma_gc_set_object_visited (ECMA_GET_NON_NULL_POINTER (ecma_object_t, proto_cp));
|
||||
}
|
||||
|
||||
switch (ecma_get_object_type (object_p))
|
||||
{
|
||||
case ECMA_OBJECT_TYPE_CLASS:
|
||||
@@ -765,6 +758,15 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */
|
||||
{
|
||||
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p;
|
||||
|
||||
#if ENABLED (JERRY_ESNEXT)
|
||||
if (JERRY_UNLIKELY (ext_object_p->u.array.length_prop_and_hole_count & ECMA_ARRAY_TEMPLATE_LITERAL))
|
||||
{
|
||||
/* Template objects are never marked. */
|
||||
JERRY_ASSERT (object_p->type_flags_refs >= ECMA_OBJECT_REF_ONE);
|
||||
return;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ESNEXT) */
|
||||
|
||||
if (ecma_op_array_is_fast_array (ext_object_p))
|
||||
{
|
||||
if (object_p->u1.property_list_cp != JMEM_CP_NULL)
|
||||
@@ -780,6 +782,12 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */
|
||||
}
|
||||
}
|
||||
|
||||
jmem_cpointer_t proto_cp = object_p->u2.prototype_cp;
|
||||
|
||||
if (proto_cp != JMEM_CP_NULL)
|
||||
{
|
||||
ecma_gc_set_object_visited (ECMA_GET_NON_NULL_POINTER (ecma_object_t, proto_cp));
|
||||
}
|
||||
return;
|
||||
}
|
||||
break;
|
||||
@@ -792,6 +800,13 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */
|
||||
* Aside from the tag bits every other bit should be zero,
|
||||
*/
|
||||
JERRY_ASSERT ((object_p->u1.property_list_cp & ~JMEM_TAG_MASK) == 0);
|
||||
|
||||
jmem_cpointer_t proto_cp = object_p->u2.prototype_cp;
|
||||
|
||||
if (proto_cp != JMEM_CP_NULL)
|
||||
{
|
||||
ecma_gc_set_object_visited (ECMA_GET_NON_NULL_POINTER (ecma_object_t, proto_cp));
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_BUILTIN_PROXY) */
|
||||
@@ -907,6 +922,13 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
jmem_cpointer_t proto_cp = object_p->u2.prototype_cp;
|
||||
|
||||
if (proto_cp != JMEM_CP_NULL)
|
||||
{
|
||||
ecma_gc_set_object_visited (ECMA_GET_NON_NULL_POINTER (ecma_object_t, proto_cp));
|
||||
}
|
||||
}
|
||||
|
||||
jmem_cpointer_t prop_iter_cp = object_p->u1.property_list_cp;
|
||||
|
||||
@@ -942,13 +942,8 @@ typedef struct
|
||||
struct
|
||||
{
|
||||
uint32_t length; /**< length property value */
|
||||
union
|
||||
{
|
||||
ecma_property_t length_prop; /**< length property */
|
||||
uint32_t hole_count; /**< number of array holes in a fast access mode array
|
||||
* multiplied ECMA_FAST_ACCESS_HOLE_ONE */
|
||||
} u;
|
||||
|
||||
uint32_t length_prop_and_hole_count; /**< length property attributes and number of array holes in
|
||||
* a fast access mode array multiplied ECMA_FAST_ACCESS_HOLE_ONE */
|
||||
} array;
|
||||
|
||||
/**
|
||||
@@ -997,6 +992,17 @@ typedef struct
|
||||
ecma_built_in_props_t built_in; /**< built-in object part */
|
||||
} ecma_extended_built_in_object_t;
|
||||
|
||||
/**
|
||||
* Flags for array.length_prop_and_hole_count
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
ECMA_FAST_ARRAY_FLAG = 1u << (ECMA_PROPERTY_NAME_TYPE_SHIFT + 0),
|
||||
#if ENABLED (JERRY_ESNEXT)
|
||||
ECMA_ARRAY_TEMPLATE_LITERAL = 1u << (ECMA_PROPERTY_NAME_TYPE_SHIFT + 1),
|
||||
#endif /* ENABLED (JERRY_ESNEXT) */
|
||||
} ecma_array_length_prop_and_hole_count_flags_t;
|
||||
|
||||
/**
|
||||
* Alignment for the fast access mode array length.
|
||||
* The real length is aligned up for allocating the underlying buffer.
|
||||
|
||||
@@ -79,6 +79,46 @@ ecma_collection_free_objects (ecma_collection_t *collection_p) /**< value collec
|
||||
ecma_collection_destroy (collection_p);
|
||||
} /* ecma_collection_free_objects */
|
||||
|
||||
#if ENABLED (JERRY_ESNEXT)
|
||||
|
||||
/**
|
||||
* Free the template literal objects and deallocate the collection
|
||||
*/
|
||||
void
|
||||
ecma_collection_free_template_literal (ecma_collection_t *collection_p) /**< value collection */
|
||||
{
|
||||
for (uint32_t i = 0; i < collection_p->item_count; i++)
|
||||
{
|
||||
ecma_object_t *object_p = ecma_get_object_from_value (collection_p->buffer_p[i]);
|
||||
|
||||
JERRY_ASSERT (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_ARRAY);
|
||||
|
||||
ecma_extended_object_t *array_object_p = (ecma_extended_object_t *) object_p;
|
||||
|
||||
JERRY_ASSERT (array_object_p->u.array.length_prop_and_hole_count & ECMA_ARRAY_TEMPLATE_LITERAL);
|
||||
array_object_p->u.array.length_prop_and_hole_count &= (uint32_t) ECMA_ARRAY_TEMPLATE_LITERAL;
|
||||
|
||||
ecma_property_value_t *property_value_p;
|
||||
|
||||
property_value_p = ecma_get_named_data_property (object_p, ecma_get_magic_string (LIT_MAGIC_STRING_RAW));
|
||||
ecma_object_t *raw_object_p = ecma_get_object_from_value (property_value_p->value);
|
||||
|
||||
JERRY_ASSERT (ecma_get_object_type (raw_object_p) == ECMA_OBJECT_TYPE_ARRAY);
|
||||
|
||||
array_object_p = (ecma_extended_object_t *) raw_object_p;
|
||||
|
||||
JERRY_ASSERT (array_object_p->u.array.length_prop_and_hole_count & ECMA_ARRAY_TEMPLATE_LITERAL);
|
||||
array_object_p->u.array.length_prop_and_hole_count &= (uint32_t) ECMA_ARRAY_TEMPLATE_LITERAL;
|
||||
|
||||
ecma_deref_object (raw_object_p);
|
||||
ecma_deref_object (object_p);
|
||||
}
|
||||
|
||||
ecma_collection_destroy (collection_p);
|
||||
} /* ecma_collection_free_template_literal */
|
||||
|
||||
#endif /* ENABLED (JERRY_ESNEXT) */
|
||||
|
||||
/**
|
||||
* Free the non-object collection elements and deallocate the collection
|
||||
*/
|
||||
|
||||
@@ -1476,8 +1476,8 @@ ecma_bytecode_deref (ecma_compiled_code_t *bytecode_p) /**< byte code pointer */
|
||||
|
||||
/* Since the objects in the tagged template collection are not strong referenced anymore by the compiled code
|
||||
we can treat them as 'new' objects. */
|
||||
JERRY_CONTEXT (ecma_gc_new_objects) += collection_p->item_count;
|
||||
ecma_collection_free (collection_p);
|
||||
JERRY_CONTEXT (ecma_gc_new_objects) += collection_p->item_count * 2;
|
||||
ecma_collection_free_template_literal (collection_p);
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ESNEXT) */
|
||||
|
||||
|
||||
@@ -439,6 +439,9 @@ void ecma_collection_destroy (ecma_collection_t *collection_p);
|
||||
void ecma_collection_free (ecma_collection_t *collection_p);
|
||||
void ecma_collection_free_if_not_object (ecma_collection_t *collection_p);
|
||||
void ecma_collection_free_objects (ecma_collection_t *collection_p);
|
||||
#if ENABLED (JERRY_ESNEXT)
|
||||
void ecma_collection_free_template_literal (ecma_collection_t *collection_p);
|
||||
#endif /* ENABLED (JERRY_ESNEXT) */
|
||||
bool ecma_collection_check_duplicated_entries (ecma_collection_t *collection_p);
|
||||
bool ecma_collection_has_string_value (ecma_collection_t *collection_p, ecma_string_t *string_p);
|
||||
|
||||
|
||||
@@ -465,7 +465,7 @@ ecma_builtin_array_prototype_object_push (const ecma_value_t *argument_list_p, /
|
||||
buffer_p[index] = ecma_copy_value_if_not_object (argument_list_p[index]);
|
||||
}
|
||||
|
||||
ext_obj_p->u.array.u.hole_count -= ECMA_FAST_ARRAY_HOLE_ONE * arguments_number;
|
||||
ext_obj_p->u.array.length_prop_and_hole_count -= ECMA_FAST_ARRAY_HOLE_ONE * arguments_number;
|
||||
|
||||
return ecma_make_uint32_value (new_length);
|
||||
}
|
||||
@@ -539,7 +539,7 @@ ecma_builtin_array_prototype_object_reverse (ecma_value_t this_arg, /**< this ar
|
||||
uint32_t middle = (uint32_t) len / 2;
|
||||
ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) obj_p;
|
||||
|
||||
if (ext_obj_p->u.array.u.hole_count < ECMA_FAST_ARRAY_HOLE_ONE
|
||||
if (ext_obj_p->u.array.length_prop_and_hole_count < ECMA_FAST_ARRAY_HOLE_ONE
|
||||
&& len != 0
|
||||
&& ecma_op_ordinary_object_is_extensible (obj_p))
|
||||
{
|
||||
@@ -725,7 +725,7 @@ ecma_builtin_array_prototype_object_shift (ecma_object_t *obj_p, /**< object */
|
||||
{
|
||||
ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) obj_p;
|
||||
|
||||
if (ext_obj_p->u.array.u.hole_count < ECMA_FAST_ARRAY_HOLE_ONE
|
||||
if (ext_obj_p->u.array.length_prop_and_hole_count < ECMA_FAST_ARRAY_HOLE_ONE
|
||||
&& len != 0
|
||||
&& ecma_op_ordinary_object_is_extensible (obj_p))
|
||||
{
|
||||
@@ -873,7 +873,7 @@ ecma_builtin_array_prototype_object_slice (ecma_value_t arg1, /**< start */
|
||||
{
|
||||
ecma_extended_object_t *ext_from_obj_p = (ecma_extended_object_t *) obj_p;
|
||||
|
||||
if (ext_from_obj_p->u.array.u.hole_count < ECMA_FAST_ARRAY_HOLE_ONE)
|
||||
if (ext_from_obj_p->u.array.length_prop_and_hole_count < ECMA_FAST_ARRAY_HOLE_ONE)
|
||||
{
|
||||
if (JERRY_UNLIKELY (obj_p->u1.property_list_cp == JMEM_CP_NULL))
|
||||
{
|
||||
@@ -921,7 +921,7 @@ ecma_builtin_array_prototype_object_slice (ecma_value_t arg1, /**< start */
|
||||
to_buffer_p[n] = ecma_copy_value_if_not_object (from_buffer_p[k]);
|
||||
}
|
||||
|
||||
ext_to_obj_p->u.array.u.hole_count &= ECMA_FAST_ARRAY_HOLE_ONE - 1;
|
||||
ext_to_obj_p->u.array.length_prop_and_hole_count &= ECMA_FAST_ARRAY_HOLE_ONE - 1;
|
||||
|
||||
return ecma_make_object_value (new_array_p);
|
||||
}
|
||||
@@ -1513,7 +1513,7 @@ ecma_builtin_array_prototype_object_unshift (const ecma_value_t args[], /**< arg
|
||||
{
|
||||
ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) obj_p;
|
||||
|
||||
if (ext_obj_p->u.array.u.hole_count < ECMA_FAST_ARRAY_HOLE_ONE
|
||||
if (ext_obj_p->u.array.length_prop_and_hole_count < ECMA_FAST_ARRAY_HOLE_ONE
|
||||
&& len != 0
|
||||
&& ecma_op_ordinary_object_is_extensible (obj_p))
|
||||
{
|
||||
@@ -1539,7 +1539,7 @@ ecma_builtin_array_prototype_object_unshift (const ecma_value_t args[], /**< arg
|
||||
index++;
|
||||
}
|
||||
|
||||
ext_obj_p->u.array.u.hole_count -= args_number * ECMA_FAST_ARRAY_HOLE_ONE;
|
||||
ext_obj_p->u.array.length_prop_and_hole_count -= args_number * ECMA_FAST_ARRAY_HOLE_ONE;
|
||||
|
||||
return ecma_make_uint32_value (new_length);
|
||||
}
|
||||
@@ -1670,7 +1670,7 @@ ecma_builtin_array_prototype_object_index_of (const ecma_value_t args[], /**< ar
|
||||
{
|
||||
ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) obj_p;
|
||||
|
||||
if (ext_obj_p->u.array.u.hole_count < ECMA_FAST_ARRAY_HOLE_ONE)
|
||||
if (ext_obj_p->u.array.length_prop_and_hole_count < ECMA_FAST_ARRAY_HOLE_ONE)
|
||||
{
|
||||
if (JERRY_UNLIKELY (obj_p->u1.property_list_cp == JMEM_CP_NULL))
|
||||
{
|
||||
@@ -1776,7 +1776,7 @@ ecma_builtin_array_prototype_object_last_index_of (const ecma_value_t args[], /*
|
||||
{
|
||||
ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) obj_p;
|
||||
|
||||
if (ext_obj_p->u.array.u.hole_count < ECMA_FAST_ARRAY_HOLE_ONE)
|
||||
if (ext_obj_p->u.array.length_prop_and_hole_count < ECMA_FAST_ARRAY_HOLE_ONE)
|
||||
{
|
||||
if (JERRY_UNLIKELY (obj_p->u1.property_list_cp == JMEM_CP_NULL))
|
||||
{
|
||||
@@ -2302,7 +2302,7 @@ ecma_builtin_array_prototype_fill (ecma_value_t value, /**< value */
|
||||
{
|
||||
ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) obj_p;
|
||||
|
||||
if (ext_obj_p->u.array.u.hole_count < ECMA_FAST_ARRAY_HOLE_ONE
|
||||
if (ext_obj_p->u.array.length_prop_and_hole_count < ECMA_FAST_ARRAY_HOLE_ONE
|
||||
&& ecma_op_ordinary_object_is_extensible (obj_p))
|
||||
{
|
||||
if (JERRY_UNLIKELY (obj_p->u1.property_list_cp == JMEM_CP_NULL))
|
||||
@@ -2501,7 +2501,7 @@ ecma_builtin_array_prototype_object_copy_within (const ecma_value_t args[], /**<
|
||||
ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) obj_p;
|
||||
const uint32_t actual_length = ext_obj_p->u.array.length;
|
||||
|
||||
if (ext_obj_p->u.array.u.hole_count < ECMA_FAST_ARRAY_HOLE_ONE
|
||||
if (ext_obj_p->u.array.length_prop_and_hole_count < ECMA_FAST_ARRAY_HOLE_ONE
|
||||
&& ((forward && (target + count - 1 < actual_length)) || (!forward && (target < actual_length))))
|
||||
{
|
||||
if (obj_p->u1.property_list_cp != JMEM_CP_NULL)
|
||||
@@ -2617,7 +2617,7 @@ ecma_builtin_array_prototype_includes (const ecma_value_t args[], /**< arguments
|
||||
{
|
||||
ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) obj_p;
|
||||
|
||||
if (ext_obj_p->u.array.u.hole_count < ECMA_FAST_ARRAY_HOLE_ONE)
|
||||
if (ext_obj_p->u.array.length_prop_and_hole_count < ECMA_FAST_ARRAY_HOLE_ONE)
|
||||
{
|
||||
if (obj_p->u1.property_list_cp != JMEM_CP_NULL)
|
||||
{
|
||||
|
||||
@@ -439,7 +439,7 @@ ecma_instantiate_builtin (ecma_builtin_id_t obj_builtin_id) /**< built-in id */
|
||||
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) obj_p;
|
||||
|
||||
ext_object_p->u.array.length = 0;
|
||||
ext_object_p->u.array.u.length_prop = ECMA_PROPERTY_FLAG_WRITABLE | ECMA_PROPERTY_TYPE_VIRTUAL;
|
||||
ext_object_p->u.array.length_prop_and_hole_count = ECMA_PROPERTY_FLAG_WRITABLE | ECMA_PROPERTY_TYPE_VIRTUAL;
|
||||
break;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_BUILTIN_ARRAY) */
|
||||
@@ -539,20 +539,6 @@ ecma_finalize_builtins (void)
|
||||
{
|
||||
ecma_object_t *obj_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, JERRY_CONTEXT (ecma_builtin_objects)[id]);
|
||||
ecma_deref_object (obj_p);
|
||||
|
||||
#if ENABLED (JERRY_ESNEXT)
|
||||
/* Note: In ES2015 a function object may contain tagged template literal collection. Whenever
|
||||
this function is assigned to a builtin function or function routine during the GC it may cause unresolvable
|
||||
circle since one part of the circle is a weak reference (marked by GC) and the other part is hard reference
|
||||
(reference count). In this case when the function which contains the tagged template literal collection
|
||||
is getting GC marked the arrays in the collection are still holding weak references to properties/prototypes
|
||||
which prevents these objects from getting freed. Releasing the property list and the prototype reference
|
||||
manually eliminates the existence of the unresolvable circle described above. */
|
||||
ecma_gc_free_properties (obj_p);
|
||||
obj_p->u1.property_list_cp = JMEM_CP_NULL;
|
||||
obj_p->u2.prototype_cp = JMEM_CP_NULL;
|
||||
#endif /* ENABLED (JERRY_ESNEXT) */
|
||||
|
||||
JERRY_CONTEXT (ecma_builtin_objects)[id] = JMEM_CP_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,11 +56,6 @@
|
||||
*/
|
||||
#define ECMA_FAST_ARRAY_UINT32_DIRECT_STRING_PROP_TYPE 0x80
|
||||
|
||||
/**
|
||||
* Property attribute for the array 'length' virtual property to indicate fast access mode array
|
||||
*/
|
||||
#define ECMA_FAST_ARRAY_FLAG (ECMA_DIRECT_STRING_MAGIC << ECMA_PROPERTY_NAME_TYPE_SHIFT)
|
||||
|
||||
/**
|
||||
* Allocate a new array object with the given length
|
||||
*
|
||||
@@ -87,8 +82,7 @@ ecma_op_alloc_array_object (uint32_t length) /**< length of the new array */
|
||||
|
||||
ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) object_p;
|
||||
ext_obj_p->u.array.length = length;
|
||||
ext_obj_p->u.array.u.hole_count = 0;
|
||||
ext_obj_p->u.array.u.length_prop = ECMA_PROPERTY_FLAG_WRITABLE | ECMA_PROPERTY_TYPE_VIRTUAL;
|
||||
ext_obj_p->u.array.length_prop_and_hole_count = ECMA_PROPERTY_FLAG_WRITABLE | ECMA_PROPERTY_TYPE_VIRTUAL;
|
||||
|
||||
return object_p;
|
||||
} /* ecma_op_alloc_array_object */
|
||||
@@ -117,7 +111,7 @@ ecma_op_array_is_fast_array (ecma_extended_object_t *array_p) /**< ecma-array-ob
|
||||
{
|
||||
JERRY_ASSERT (ecma_get_object_type ((ecma_object_t *) array_p) == ECMA_OBJECT_TYPE_ARRAY);
|
||||
|
||||
return array_p->u.array.u.length_prop & ECMA_FAST_ARRAY_FLAG;
|
||||
return array_p->u.array.length_prop_and_hole_count & ECMA_FAST_ARRAY_FLAG;
|
||||
} /* ecma_op_array_is_fast_array */
|
||||
|
||||
/**
|
||||
@@ -151,8 +145,8 @@ ecma_op_new_array_object (uint32_t length) /**< length of the new array */
|
||||
}
|
||||
|
||||
ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) object_p;
|
||||
ext_obj_p->u.array.u.length_prop = (uint8_t) (ext_obj_p->u.array.u.length_prop | ECMA_FAST_ARRAY_FLAG);
|
||||
ext_obj_p->u.array.u.hole_count += length * ECMA_FAST_ARRAY_HOLE_ONE;
|
||||
ext_obj_p->u.array.length_prop_and_hole_count |= ECMA_FAST_ARRAY_FLAG;
|
||||
ext_obj_p->u.array.length_prop_and_hole_count += length * ECMA_FAST_ARRAY_HOLE_ONE;
|
||||
|
||||
for (uint32_t i = 0; i < aligned_length; i++)
|
||||
{
|
||||
@@ -210,7 +204,7 @@ ecma_op_new_array_object_from_buffer (const ecma_value_t *args_p, /**< array ele
|
||||
if (values_p != NULL)
|
||||
{
|
||||
ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) object_p;
|
||||
ext_obj_p->u.array.u.length_prop = (uint8_t) (ext_obj_p->u.array.u.length_prop | ECMA_FAST_ARRAY_FLAG);
|
||||
ext_obj_p->u.array.length_prop_and_hole_count |= ECMA_FAST_ARRAY_FLAG;
|
||||
JERRY_ASSERT (object_p->u1.property_list_cp == JMEM_CP_NULL);
|
||||
|
||||
for (uint32_t i = 0; i < length; i++)
|
||||
@@ -277,9 +271,9 @@ ecma_op_new_array_object_from_collection (ecma_collection_t *collection_p, /**<
|
||||
object_p = ecma_op_alloc_array_object (item_count);
|
||||
|
||||
ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) object_p;
|
||||
ext_obj_p->u.array.u.length_prop = (uint8_t) (ext_obj_p->u.array.u.length_prop | ECMA_FAST_ARRAY_FLAG);
|
||||
ext_obj_p->u.array.length_prop_and_hole_count |= ECMA_FAST_ARRAY_FLAG;
|
||||
JERRY_ASSERT (object_p->u1.property_list_cp == JMEM_CP_NULL);
|
||||
JERRY_ASSERT (ext_obj_p->u.array.u.hole_count < ECMA_FAST_ARRAY_HOLE_ONE);
|
||||
JERRY_ASSERT (ext_obj_p->u.array.length_prop_and_hole_count < ECMA_FAST_ARRAY_HOLE_ONE);
|
||||
ECMA_SET_POINTER (object_p->u1.property_list_cp, buffer_p);
|
||||
|
||||
if (JERRY_UNLIKELY (unref_objects))
|
||||
@@ -312,7 +306,7 @@ ecma_fast_array_convert_to_normal (ecma_object_t *object_p) /**< fast access mod
|
||||
|
||||
if (object_p->u1.property_list_cp == JMEM_CP_NULL)
|
||||
{
|
||||
ext_obj_p->u.array.u.length_prop = (uint8_t) (ext_obj_p->u.array.u.length_prop & ~ECMA_FAST_ARRAY_FLAG);
|
||||
ext_obj_p->u.array.length_prop_and_hole_count &= (uint32_t) ~ECMA_FAST_ARRAY_FLAG;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -358,7 +352,7 @@ ecma_fast_array_convert_to_normal (ecma_object_t *object_p) /**< fast access mod
|
||||
prop_index = !prop_index;
|
||||
}
|
||||
|
||||
ext_obj_p->u.array.u.length_prop = (uint8_t) (ext_obj_p->u.array.u.length_prop & ~ECMA_FAST_ARRAY_FLAG);
|
||||
ext_obj_p->u.array.length_prop_and_hole_count &= (uint32_t) ~ECMA_FAST_ARRAY_FLAG;
|
||||
jmem_heap_free_block (values_p, aligned_length * sizeof (ecma_value_t));
|
||||
ECMA_SET_POINTER (object_p->u1.property_list_cp, property_pair_p);
|
||||
|
||||
@@ -392,7 +386,7 @@ ecma_fast_array_set_property (ecma_object_t *object_p, /**< fast access mode arr
|
||||
|
||||
if (ecma_is_value_array_hole (values_p[index]))
|
||||
{
|
||||
ext_obj_p->u.array.u.hole_count -= ECMA_FAST_ARRAY_HOLE_ONE;
|
||||
ext_obj_p->u.array.length_prop_and_hole_count -= ECMA_FAST_ARRAY_HOLE_ONE;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -404,7 +398,7 @@ ecma_fast_array_set_property (ecma_object_t *object_p, /**< fast access mode arr
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t old_holes = ext_obj_p->u.array.u.hole_count;
|
||||
uint32_t old_holes = ext_obj_p->u.array.length_prop_and_hole_count;
|
||||
uint32_t new_holes = index - old_length;
|
||||
|
||||
if (JERRY_UNLIKELY (new_holes > ECMA_FAST_ARRAY_MAX_NEW_HOLES_COUNT
|
||||
@@ -426,15 +420,15 @@ ecma_fast_array_set_property (ecma_object_t *object_p, /**< fast access mode arr
|
||||
JERRY_ASSERT (object_p->u1.property_list_cp != JMEM_CP_NULL);
|
||||
|
||||
values_p = ECMA_GET_NON_NULL_POINTER (ecma_value_t, object_p->u1.property_list_cp);
|
||||
/* This area is filled with ECMA_VALUE_ARRAY_HOLE, but not counted in u.array.u.hole_count */
|
||||
/* This area is filled with ECMA_VALUE_ARRAY_HOLE, but not counted in u.array.length_prop_and_hole_count */
|
||||
JERRY_ASSERT (ecma_is_value_array_hole (values_p[index]));
|
||||
ext_obj_p->u.array.u.hole_count += new_holes * ECMA_FAST_ARRAY_HOLE_ONE;
|
||||
ext_obj_p->u.array.length_prop_and_hole_count += new_holes * ECMA_FAST_ARRAY_HOLE_ONE;
|
||||
ext_obj_p->u.array.length = new_length;
|
||||
}
|
||||
else
|
||||
{
|
||||
values_p = ecma_fast_array_extend (object_p, new_length);
|
||||
ext_obj_p->u.array.u.hole_count -= ECMA_FAST_ARRAY_HOLE_ONE;
|
||||
ext_obj_p->u.array.length_prop_and_hole_count -= ECMA_FAST_ARRAY_HOLE_ONE;
|
||||
}
|
||||
|
||||
values_p[index] = ecma_copy_value_if_not_object (value);
|
||||
@@ -452,7 +446,7 @@ ecma_fast_array_get_hole_count (ecma_object_t *obj_p) /**< fast access mode arra
|
||||
{
|
||||
JERRY_ASSERT (ecma_op_object_is_fast_array (obj_p));
|
||||
|
||||
return ((ecma_extended_object_t *) obj_p)->u.array.u.hole_count >> ECMA_FAST_ARRAY_HOLE_SHIFT;
|
||||
return ((ecma_extended_object_t *) obj_p)->u.array.length_prop_and_hole_count >> ECMA_FAST_ARRAY_HOLE_SHIFT;
|
||||
} /* ecma_fast_array_get_hole_count */
|
||||
|
||||
/**
|
||||
@@ -493,7 +487,7 @@ ecma_fast_array_extend (ecma_object_t *object_p, /**< fast access mode array obj
|
||||
new_values_p[i] = ECMA_VALUE_ARRAY_HOLE;
|
||||
}
|
||||
|
||||
ext_obj_p->u.array.u.hole_count += (new_length - old_length) * ECMA_FAST_ARRAY_HOLE_ONE;
|
||||
ext_obj_p->u.array.length_prop_and_hole_count += (new_length - old_length) * ECMA_FAST_ARRAY_HOLE_ONE;
|
||||
ext_obj_p->u.array.length = new_length;
|
||||
|
||||
ECMA_SET_NON_NULL_POINTER (object_p->u1.property_list_cp, new_values_p);
|
||||
@@ -538,7 +532,7 @@ ecma_array_object_delete_property (ecma_object_t *object_p, /**< object */
|
||||
ecma_free_value_if_not_object (values_p[index]);
|
||||
|
||||
values_p[index] = ECMA_VALUE_ARRAY_HOLE;
|
||||
ext_obj_p->u.array.u.hole_count += ECMA_FAST_ARRAY_HOLE_ONE;
|
||||
ext_obj_p->u.array.length_prop_and_hole_count += ECMA_FAST_ARRAY_HOLE_ONE;
|
||||
} /* ecma_array_object_delete_property */
|
||||
|
||||
/**
|
||||
@@ -565,7 +559,7 @@ ecma_delete_fast_array_properties (ecma_object_t *object_p, /**< fast access mod
|
||||
{
|
||||
if (ecma_is_value_array_hole (values_p[i]))
|
||||
{
|
||||
ext_obj_p->u.array.u.hole_count -= ECMA_FAST_ARRAY_HOLE_ONE;
|
||||
ext_obj_p->u.array.length_prop_and_hole_count -= ECMA_FAST_ARRAY_HOLE_ONE;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -627,7 +621,7 @@ ecma_fast_array_set_length (ecma_object_t *object_p, /**< fast access mode array
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t old_holes = ext_obj_p->u.array.u.hole_count;
|
||||
uint32_t old_holes = ext_obj_p->u.array.length_prop_and_hole_count;
|
||||
uint32_t new_holes = new_length - old_length;
|
||||
|
||||
if (JERRY_UNLIKELY (new_holes > ECMA_FAST_ARRAY_MAX_NEW_HOLES_COUNT
|
||||
@@ -1012,17 +1006,16 @@ ecma_op_array_object_set_length (ecma_object_t *object_p, /**< the array object
|
||||
{
|
||||
if (!(flags & ECMA_ARRAY_OBJECT_SET_LENGTH_FLAG_WRITABLE))
|
||||
{
|
||||
uint8_t new_prop_value = (uint8_t) (ext_object_p->u.array.u.length_prop & ~ECMA_PROPERTY_FLAG_WRITABLE);
|
||||
ext_object_p->u.array.u.length_prop = new_prop_value;
|
||||
ext_object_p->u.array.length_prop_and_hole_count &= (uint32_t) ~ECMA_PROPERTY_FLAG_WRITABLE;
|
||||
}
|
||||
else if (!ecma_is_property_writable (ext_object_p->u.array.u.length_prop))
|
||||
else if (!ecma_is_property_writable ((ecma_property_t) ext_object_p->u.array.length_prop_and_hole_count))
|
||||
{
|
||||
return ecma_reject (is_throw);
|
||||
}
|
||||
}
|
||||
return ECMA_VALUE_TRUE;
|
||||
}
|
||||
else if (!ecma_is_property_writable (ext_object_p->u.array.u.length_prop))
|
||||
else if (!ecma_is_property_writable ((ecma_property_t) ext_object_p->u.array.length_prop_and_hole_count))
|
||||
{
|
||||
return ecma_reject (is_throw);
|
||||
}
|
||||
@@ -1043,8 +1036,7 @@ ecma_op_array_object_set_length (ecma_object_t *object_p, /**< the array object
|
||||
if ((flags & ECMA_ARRAY_OBJECT_SET_LENGTH_FLAG_WRITABLE_DEFINED)
|
||||
&& !(flags & ECMA_ARRAY_OBJECT_SET_LENGTH_FLAG_WRITABLE))
|
||||
{
|
||||
uint8_t new_prop_value = (uint8_t) (ext_object_p->u.array.u.length_prop & ~ECMA_PROPERTY_FLAG_WRITABLE);
|
||||
ext_object_p->u.array.u.length_prop = new_prop_value;
|
||||
ext_object_p->u.array.length_prop_and_hole_count &= (uint32_t) ~ECMA_PROPERTY_FLAG_WRITABLE;
|
||||
}
|
||||
|
||||
if (current_len_uint32 == new_len_uint32)
|
||||
@@ -1166,7 +1158,8 @@ ecma_op_array_object_define_own_property (ecma_object_t *object_p, /**< the arra
|
||||
|
||||
bool update_length = (index >= ext_object_p->u.array.length);
|
||||
|
||||
if (update_length && !ecma_is_property_writable (ext_object_p->u.array.u.length_prop))
|
||||
if (update_length
|
||||
&& !ecma_is_property_writable ((ecma_property_t) ext_object_p->u.array.length_prop_and_hole_count))
|
||||
{
|
||||
return ecma_reject (property_desc_p->flags & ECMA_PROP_IS_THROW);
|
||||
}
|
||||
|
||||
@@ -140,7 +140,8 @@ ecma_op_object_get_own_property (ecma_object_t *object_p, /**< the object */
|
||||
property_ref_p->virtual_value = ecma_make_uint32_value (ext_object_p->u.array.length);
|
||||
}
|
||||
|
||||
return ext_object_p->u.array.u.length_prop & (ECMA_PROPERTY_TYPE_VIRTUAL | ECMA_PROPERTY_FLAG_WRITABLE);
|
||||
uint32_t length_prop = ext_object_p->u.array.length_prop_and_hole_count;
|
||||
return length_prop & (ECMA_PROPERTY_TYPE_VIRTUAL | ECMA_PROPERTY_FLAG_WRITABLE);
|
||||
}
|
||||
|
||||
if (ecma_op_array_is_fast_array (ext_object_p))
|
||||
@@ -1210,7 +1211,7 @@ ecma_op_object_put_with_receiver (ecma_object_t *object_p, /**< the object */
|
||||
|
||||
if (ecma_string_is_length (property_name_p))
|
||||
{
|
||||
if (ecma_is_property_writable (ext_object_p->u.array.u.length_prop))
|
||||
if (ecma_is_property_writable ((ecma_property_t) ext_object_p->u.array.length_prop_and_hole_count))
|
||||
{
|
||||
return ecma_op_array_object_set_length (object_p, value, 0);
|
||||
}
|
||||
@@ -1509,7 +1510,7 @@ ecma_op_object_put_with_receiver (ecma_object_t *object_p, /**< the object */
|
||||
if (index < UINT32_MAX
|
||||
&& index >= ext_object_p->u.array.length)
|
||||
{
|
||||
if (!ecma_is_property_writable (ext_object_p->u.array.u.length_prop))
|
||||
if (!ecma_is_property_writable ((ecma_property_t) ext_object_p->u.array.length_prop_and_hole_count))
|
||||
{
|
||||
return ecma_reject (is_throw);
|
||||
}
|
||||
@@ -3034,16 +3035,6 @@ ecma_op_ordinary_object_set_prototype_of (ecma_object_t *obj_p, /**< base object
|
||||
/* 1. */
|
||||
JERRY_ASSERT (ecma_is_value_object (proto) || ecma_is_value_null (proto));
|
||||
|
||||
/**
|
||||
* If the prototype of a fast array changes it is required to fall back to
|
||||
* a "normal" array object. This ensures that all [[Get]]/[[Set]]/etc. calls
|
||||
* works as expected.
|
||||
*/
|
||||
if (ecma_op_object_is_fast_array (obj_p))
|
||||
{
|
||||
ecma_fast_array_convert_to_normal (obj_p);
|
||||
}
|
||||
|
||||
/* 3. */
|
||||
ecma_object_t *current_proto_p = ECMA_GET_POINTER (ecma_object_t, ecma_op_ordinary_object_get_prototype_of (obj_p));
|
||||
ecma_object_t *new_proto_p = ecma_is_value_null (proto) ? NULL : ecma_get_object_from_value (proto);
|
||||
@@ -3060,6 +3051,16 @@ ecma_op_ordinary_object_set_prototype_of (ecma_object_t *obj_p, /**< base object
|
||||
return ECMA_VALUE_FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* When the prototype of a fast array changes, it is required to convert the
|
||||
* array to a "normal" array. This ensures that all [[Get]]/[[Set]]/etc.
|
||||
* calls works as expected.
|
||||
*/
|
||||
if (ecma_op_object_is_fast_array (obj_p))
|
||||
{
|
||||
ecma_fast_array_convert_to_normal (obj_p);
|
||||
}
|
||||
|
||||
/* 6. */
|
||||
ecma_object_t *iter_p = new_proto_p;
|
||||
|
||||
|
||||
@@ -114,7 +114,6 @@ parser_new_tagged_template_literal (ecma_object_t **raw_strings_p) /**< [out] ra
|
||||
ecma_get_magic_string (LIT_MAGIC_STRING_RAW),
|
||||
ecma_make_object_value (*raw_strings_p),
|
||||
ECMA_PROPERTY_FIXED);
|
||||
ecma_deref_object (*raw_strings_p);
|
||||
|
||||
return template_obj_p;
|
||||
} /* parser_new_tagged_template_literal */
|
||||
@@ -129,8 +128,8 @@ parser_tagged_template_literal_freeze_array (ecma_object_t *obj_p)
|
||||
|
||||
ecma_op_ordinary_object_prevent_extensions (obj_p);
|
||||
ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) obj_p;
|
||||
uint8_t new_prop_value = (uint8_t) (ext_obj_p->u.array.u.length_prop & ~ECMA_PROPERTY_FLAG_WRITABLE);
|
||||
ext_obj_p->u.array.u.length_prop = new_prop_value;
|
||||
ext_obj_p->u.array.length_prop_and_hole_count &= (uint32_t) ~ECMA_PROPERTY_FLAG_WRITABLE;
|
||||
ext_obj_p->u.array.length_prop_and_hole_count |= ECMA_ARRAY_TEMPLATE_LITERAL;
|
||||
} /* parser_tagged_template_literal_freeze_array */
|
||||
|
||||
/**
|
||||
|
||||
@@ -2732,8 +2732,9 @@ parser_raise_error (parser_context_t *context_p, /**< context */
|
||||
#if ENABLED (JERRY_ESNEXT)
|
||||
if (saved_context_p->tagged_template_literal_cp != JMEM_CP_NULL)
|
||||
{
|
||||
ecma_collection_free (ECMA_GET_INTERNAL_VALUE_POINTER (ecma_collection_t,
|
||||
saved_context_p->tagged_template_literal_cp));
|
||||
ecma_collection_t *collection = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_collection_t,
|
||||
saved_context_p->tagged_template_literal_cp);
|
||||
ecma_collection_free_template_literal (collection);
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ESNEXT) */
|
||||
|
||||
@@ -2743,8 +2744,9 @@ parser_raise_error (parser_context_t *context_p, /**< context */
|
||||
#if ENABLED (JERRY_ESNEXT)
|
||||
if (context_p->tagged_template_literal_cp != JMEM_CP_NULL)
|
||||
{
|
||||
ecma_collection_free (ECMA_GET_INTERNAL_VALUE_POINTER (ecma_collection_t,
|
||||
context_p->tagged_template_literal_cp));
|
||||
ecma_collection_t *collection = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_collection_t,
|
||||
context_p->tagged_template_literal_cp);
|
||||
ecma_collection_free_template_literal (collection);
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ESNEXT) */
|
||||
|
||||
|
||||
@@ -605,7 +605,7 @@ opfunc_append_array (ecma_value_t *stack_top_p, /**< current stack top */
|
||||
}
|
||||
}
|
||||
|
||||
ext_array_obj_p->u.array.u.hole_count -= filled_holes * ECMA_FAST_ARRAY_HOLE_ONE;
|
||||
ext_array_obj_p->u.array.length_prop_and_hole_count -= filled_holes * ECMA_FAST_ARRAY_HOLE_ONE;
|
||||
|
||||
if (JERRY_UNLIKELY ((values_length - filled_holes) > ECMA_FAST_ARRAY_MAX_NEW_HOLES_COUNT))
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user