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:
Zoltan Herczeg
2020-12-04 10:41:14 +01:00
committed by GitHub
parent c0fc67f5bd
commit de37e1e049
12 changed files with 148 additions and 96 deletions
+29 -7
View File
@@ -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;
+13 -7
View File
@@ -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
*/
+2 -2
View File
@@ -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) */
+3
View File
@@ -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;
}
}
+25 -32
View File
@@ -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);
}
+14 -13
View File
@@ -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 */
/**
+6 -4
View File
@@ -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) */
+1 -1
View File
@@ -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))
{