Initial implementation of class fields (#4191)
Missing features: - this binding in static fields are not supported - static field evaluation order is wrong - function names are not supported JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
@@ -192,7 +192,8 @@ ecma_gc_mark_properties (ecma_property_pair_t *property_pair_p) /**< property pa
|
||||
case ECMA_PROPERTY_TYPE_INTERNAL:
|
||||
{
|
||||
JERRY_ASSERT (ECMA_PROPERTY_GET_NAME_TYPE (property) == ECMA_DIRECT_STRING_MAGIC
|
||||
&& property_pair_p->names_cp[index] >= LIT_FIRST_INTERNAL_MAGIC_STRING);
|
||||
&& property_pair_p->names_cp[index] >= LIT_INTERNAL_MAGIC_STRING_FIRST_DATA
|
||||
&& property_pair_p->names_cp[index] < LIT_MAGIC_STRING__COUNT);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -1054,33 +1055,51 @@ ecma_gc_free_properties (ecma_object_t *object_p) /**< object */
|
||||
ecma_property_t *property_p = (ecma_property_t *) (prop_iter_p->types + i);
|
||||
jmem_cpointer_t name_cp = prop_pair_p->names_cp[i];
|
||||
|
||||
if (ECMA_PROPERTY_GET_NAME_TYPE (*property_p) == ECMA_DIRECT_STRING_MAGIC)
|
||||
if (ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_INTERNAL)
|
||||
{
|
||||
JERRY_ASSERT (ECMA_PROPERTY_GET_NAME_TYPE (*property_p) == ECMA_DIRECT_STRING_MAGIC);
|
||||
|
||||
/* Call the native's free callback. */
|
||||
if (JERRY_UNLIKELY (name_cp == LIT_INTERNAL_MAGIC_STRING_NATIVE_POINTER))
|
||||
switch (name_cp)
|
||||
{
|
||||
ecma_gc_free_native_pointer (property_p);
|
||||
}
|
||||
#if ENABLED (JERRY_BUILTIN_WEAKMAP) || ENABLED (JERRY_BUILTIN_WEAKSET)
|
||||
else if (JERRY_UNLIKELY (name_cp == LIT_INTERNAL_MAGIC_STRING_WEAK_REFS))
|
||||
{
|
||||
ecma_collection_t *refs_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_collection_t,
|
||||
ECMA_PROPERTY_VALUE_PTR (property_p)->value);
|
||||
for (uint32_t j = 0; j < refs_p->item_count; j++)
|
||||
case LIT_INTERNAL_MAGIC_STRING_WEAK_REFS:
|
||||
{
|
||||
const ecma_value_t value = refs_p->buffer_p[j];
|
||||
if (!ecma_is_value_empty (value))
|
||||
ecma_collection_t *refs_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_collection_t,
|
||||
prop_pair_p->values[i].value);
|
||||
for (uint32_t j = 0; j < refs_p->item_count; j++)
|
||||
{
|
||||
ecma_object_t *container_p = ecma_get_object_from_value (value);
|
||||
const ecma_value_t value = refs_p->buffer_p[j];
|
||||
if (!ecma_is_value_empty (value))
|
||||
{
|
||||
ecma_object_t *container_p = ecma_get_object_from_value (value);
|
||||
|
||||
ecma_op_container_remove_weak_entry (container_p,
|
||||
ecma_make_object_value (object_p));
|
||||
ecma_op_container_remove_weak_entry (container_p,
|
||||
ecma_make_object_value (object_p));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ecma_collection_destroy (refs_p);
|
||||
}
|
||||
ecma_collection_destroy (refs_p);
|
||||
break;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_BUILTIN_WEAKMAP) || ENABLED (JERRY_BUILTIN_WEAKSET) */
|
||||
#if ENABLED (JERRY_ESNEXT)
|
||||
case LIT_INTERNAL_MAGIC_STRING_CLASS_FIELD_COMPUTED:
|
||||
{
|
||||
ecma_value_t *compact_collection_p;
|
||||
compact_collection_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_value_t,
|
||||
prop_pair_p->values[i].value);
|
||||
ecma_compact_collection_free (compact_collection_p);
|
||||
break;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ESNEXT) */
|
||||
default:
|
||||
{
|
||||
JERRY_ASSERT (name_cp == LIT_INTERNAL_MAGIC_STRING_NATIVE_POINTER);
|
||||
ecma_gc_free_native_pointer (property_p);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (prop_iter_p->types[i] != ECMA_PROPERTY_TYPE_DELETED)
|
||||
|
||||
@@ -113,17 +113,21 @@ typedef enum
|
||||
ECMA_PARSE_DIRECT_EVAL = (1u << 3), /**< eval is called directly (ECMA-262 v5, 15.1.2.1.1) */
|
||||
ECMA_PARSE_CLASS_CONSTRUCTOR = (1u << 4), /**< a class constructor is being parsed */
|
||||
|
||||
/* These four status flags must be in this order. The first three are also parser status flags.
|
||||
/* These five status flags must be in this order. The first four are also parser status flags.
|
||||
* See PARSER_SAVE_STATUS_FLAGS / PARSER_RESTORE_STATUS_FLAGS. */
|
||||
ECMA_PARSE_ALLOW_SUPER = (1u << 5), /**< allow super property access */
|
||||
ECMA_PARSE_ALLOW_SUPER_CALL = (1u << 6), /**< allow super constructor call */
|
||||
ECMA_PARSE_ALLOW_NEW_TARGET = (1u << 7), /**< allow new.target access */
|
||||
ECMA_PARSE_FUNCTION_CONTEXT = (1u << 8), /**< function context is present (ECMA_PARSE_DIRECT_EVAL must be set) */
|
||||
ECMA_PARSE_INSIDE_CLASS_FIELD = (1u << 7), /**< a class field is being parsed */
|
||||
ECMA_PARSE_ALLOW_NEW_TARGET = (1u << 8), /**< allow new.target access */
|
||||
ECMA_PARSE_FUNCTION_CONTEXT = (1u << 9), /**< function context is present (ECMA_PARSE_DIRECT_EVAL must be set) */
|
||||
|
||||
ECMA_PARSE_GENERATOR_FUNCTION = (1u << 9), /**< generator function is parsed */
|
||||
ECMA_PARSE_ASYNC_FUNCTION = (1u << 10), /**< async function is parsed */
|
||||
ECMA_PARSE_GENERATOR_FUNCTION = (1u << 10), /**< generator function is parsed */
|
||||
ECMA_PARSE_ASYNC_FUNCTION = (1u << 11), /**< async function is parsed */
|
||||
|
||||
/* These flags are internally used by the parser. */
|
||||
#if ENABLED (JERRY_ESNEXT)
|
||||
ECMA_PARSE_INTERNAL_PRE_SCANNING = (1u << 12),
|
||||
#endif /* ENABLED (JERRY_ESNEXT) */
|
||||
#ifndef JERRY_NDEBUG
|
||||
/**
|
||||
* This flag represents an error in for in/of statements, which cannot be set
|
||||
@@ -1439,6 +1443,17 @@ typedef struct
|
||||
*/
|
||||
#define ECMA_COLLECTION_INITIAL_SIZE ECMA_COLLECTION_ALLOCATED_SIZE (ECMA_COLLECTION_INITIAL_CAPACITY)
|
||||
|
||||
/**
|
||||
* Size shift of a compact collection
|
||||
*/
|
||||
#define ECMA_COMPACT_COLLECTION_SIZE_SHIFT 3
|
||||
|
||||
/**
|
||||
* Get the size of the compact collection
|
||||
*/
|
||||
#define ECMA_COMPACT_COLLECTION_GET_SIZE(compact_collection_p) \
|
||||
((compact_collection_p)[0] >> ECMA_COMPACT_COLLECTION_SIZE_SHIFT)
|
||||
|
||||
/**
|
||||
* Direct string types (2 bit).
|
||||
*/
|
||||
|
||||
@@ -248,6 +248,134 @@ ecma_collection_has_string_value (ecma_collection_t *collection_p, /**< collecti
|
||||
return false;
|
||||
} /* ecma_collection_has_string_value */
|
||||
|
||||
/**
|
||||
* Initial capacity of an ecma-collection
|
||||
*/
|
||||
#define ECMA_COMPACT_COLLECTION_GROWTH 8
|
||||
|
||||
/**
|
||||
* Set the size of the compact collection
|
||||
*/
|
||||
#define ECMA_COMPACT_COLLECTION_SET_SIZE(compact_collection_p, item_count, unused_items) \
|
||||
((compact_collection_p)[0] = (((item_count) << ECMA_COMPACT_COLLECTION_SIZE_SHIFT) | (unused_items)))
|
||||
|
||||
/**
|
||||
* Set the size of the compact collection
|
||||
*/
|
||||
#define ECMA_COMPACT_COLLECTION_GET_UNUSED_ITEM_COUNT(compact_collection_p) \
|
||||
((compact_collection_p)[0] & ((1 << ECMA_COMPACT_COLLECTION_SIZE_SHIFT) - 1))
|
||||
|
||||
/**
|
||||
* Allocate a compact collection of ecma values
|
||||
*
|
||||
* @return pointer to the compact collection
|
||||
*/
|
||||
ecma_value_t *
|
||||
ecma_new_compact_collection (void)
|
||||
{
|
||||
size_t size = (ECMA_COMPACT_COLLECTION_GROWTH / 2) * sizeof (ecma_value_t);
|
||||
ecma_value_t *compact_collection_p = (ecma_value_t *) jmem_heap_alloc_block (size);
|
||||
|
||||
ECMA_COMPACT_COLLECTION_SET_SIZE (compact_collection_p,
|
||||
ECMA_COMPACT_COLLECTION_GROWTH / 2,
|
||||
(ECMA_COMPACT_COLLECTION_GROWTH / 2) - 1);
|
||||
return compact_collection_p;
|
||||
} /* ecma_new_compact_collection */
|
||||
|
||||
/**
|
||||
* Append a value to the compact collection
|
||||
*
|
||||
* @return updated pointer to the compact collection
|
||||
*/
|
||||
ecma_value_t *
|
||||
ecma_compact_collection_push_back (ecma_value_t *compact_collection_p, /**< compact collection */
|
||||
ecma_value_t value) /**< ecma value to append */
|
||||
{
|
||||
ecma_value_t size = ECMA_COMPACT_COLLECTION_GET_SIZE (compact_collection_p);
|
||||
ecma_value_t unused_items = ECMA_COMPACT_COLLECTION_GET_UNUSED_ITEM_COUNT (compact_collection_p);
|
||||
|
||||
if (unused_items > 0)
|
||||
{
|
||||
compact_collection_p[size - unused_items] = value;
|
||||
(*compact_collection_p)--;
|
||||
return compact_collection_p;
|
||||
}
|
||||
|
||||
if (size == ECMA_COMPACT_COLLECTION_GROWTH / 2)
|
||||
{
|
||||
size_t old_size = (ECMA_COMPACT_COLLECTION_GROWTH / 2) * sizeof (ecma_value_t);
|
||||
size_t new_size = ECMA_COMPACT_COLLECTION_GROWTH * sizeof (ecma_value_t);
|
||||
compact_collection_p = jmem_heap_realloc_block (compact_collection_p, old_size, new_size);
|
||||
|
||||
compact_collection_p[ECMA_COMPACT_COLLECTION_GROWTH / 2] = value;
|
||||
|
||||
ECMA_COMPACT_COLLECTION_SET_SIZE (compact_collection_p,
|
||||
ECMA_COMPACT_COLLECTION_GROWTH,
|
||||
(ECMA_COMPACT_COLLECTION_GROWTH / 2) - 1);
|
||||
return compact_collection_p;
|
||||
}
|
||||
|
||||
size_t old_size = size * sizeof (ecma_value_t);
|
||||
size_t new_size = old_size + (ECMA_COMPACT_COLLECTION_GROWTH * sizeof (ecma_value_t));
|
||||
|
||||
compact_collection_p = jmem_heap_realloc_block (compact_collection_p, old_size, new_size);
|
||||
compact_collection_p[size] = value;
|
||||
|
||||
ECMA_COMPACT_COLLECTION_SET_SIZE (compact_collection_p,
|
||||
size + ECMA_COMPACT_COLLECTION_GROWTH,
|
||||
ECMA_COMPACT_COLLECTION_GROWTH - 1);
|
||||
return compact_collection_p;
|
||||
} /* ecma_compact_collection_push_back */
|
||||
|
||||
/**
|
||||
* Discard the unused elements of a compact collection
|
||||
*
|
||||
* Note:
|
||||
* further items should not be added after this call
|
||||
*
|
||||
* @return updated pointer to the compact collection
|
||||
*/
|
||||
ecma_value_t *
|
||||
ecma_compact_collection_shrink (ecma_value_t *compact_collection_p) /**< compact collection */
|
||||
{
|
||||
ecma_value_t unused_items = ECMA_COMPACT_COLLECTION_GET_UNUSED_ITEM_COUNT (compact_collection_p);
|
||||
|
||||
if (unused_items == 0)
|
||||
{
|
||||
return compact_collection_p;
|
||||
}
|
||||
|
||||
ecma_value_t size = ECMA_COMPACT_COLLECTION_GET_SIZE (compact_collection_p);
|
||||
|
||||
size_t old_size = size * sizeof (ecma_value_t);
|
||||
size_t new_size = (size - unused_items) * sizeof (ecma_value_t);
|
||||
|
||||
compact_collection_p = jmem_heap_realloc_block (compact_collection_p, old_size, new_size);
|
||||
|
||||
ECMA_COMPACT_COLLECTION_SET_SIZE (compact_collection_p, size - unused_items, 0);
|
||||
return compact_collection_p;
|
||||
} /* ecma_compact_collection_shrink */
|
||||
|
||||
/**
|
||||
* Free a compact collection
|
||||
*/
|
||||
void
|
||||
ecma_compact_collection_free (ecma_value_t *compact_collection_p) /**< compact collection */
|
||||
{
|
||||
ecma_value_t size = ECMA_COMPACT_COLLECTION_GET_SIZE (compact_collection_p);
|
||||
ecma_value_t unused_items = ECMA_COMPACT_COLLECTION_GET_UNUSED_ITEM_COUNT (compact_collection_p);
|
||||
|
||||
ecma_value_t *end_p = compact_collection_p + size - unused_items;
|
||||
ecma_value_t *current_p = compact_collection_p + 1;
|
||||
|
||||
while (current_p < end_p)
|
||||
{
|
||||
ecma_free_value (*current_p++);
|
||||
}
|
||||
|
||||
jmem_heap_free_block (compact_collection_p, size * sizeof (ecma_value_t));
|
||||
} /* ecma_compact_collection_free */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
|
||||
@@ -784,7 +784,8 @@ ecma_free_property (ecma_object_t *object_p, /**< object the property belongs to
|
||||
|
||||
/* Must be a native pointer. */
|
||||
JERRY_ASSERT (ECMA_PROPERTY_GET_NAME_TYPE (*property_p) == ECMA_DIRECT_STRING_MAGIC
|
||||
&& name_cp >= LIT_FIRST_INTERNAL_MAGIC_STRING);
|
||||
&& name_cp >= LIT_INTERNAL_MAGIC_STRING_FIRST_DATA
|
||||
&& name_cp < LIT_MAGIC_STRING__COUNT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -464,6 +464,11 @@ void ecma_collection_free_objects (ecma_collection_t *collection_p);
|
||||
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);
|
||||
|
||||
ecma_value_t *ecma_new_compact_collection (void);
|
||||
ecma_value_t *ecma_compact_collection_push_back (ecma_value_t *compact_collection_p, ecma_value_t value);
|
||||
ecma_value_t *ecma_compact_collection_shrink (ecma_value_t *compact_collection_p);
|
||||
void ecma_compact_collection_free (ecma_value_t *compact_collection_p);
|
||||
|
||||
/* ecma-helpers.c */
|
||||
ecma_object_t *ecma_create_object (ecma_object_t *prototype_object_p, size_t ext_object_size, ecma_object_type_t type);
|
||||
ecma_object_t *ecma_create_decl_lex_env (ecma_object_t *outer_lexical_environment_p);
|
||||
|
||||
Reference in New Issue
Block a user