diff --git a/jerry-core/ecma/base/ecma-alloc.c b/jerry-core/ecma/base/ecma-alloc.c index 8ecf888b6..47ad33709 100644 --- a/jerry-core/ecma/base/ecma-alloc.c +++ b/jerry-core/ecma/base/ecma-alloc.c @@ -92,18 +92,19 @@ DECLARE_ROUTINES_FOR (external_pointer) * @return pointer to allocated memory */ inline ecma_extended_object_t * __attr_always_inline___ -ecma_alloc_extended_object (void) +ecma_alloc_extended_object (size_t size) /**< size of object */ { - return jmem_heap_alloc_block (sizeof (ecma_extended_object_t)); + return jmem_heap_alloc_block (size); } /* ecma_alloc_extended_object */ /** * Dealloc memory of an extended object */ inline void __attr_always_inline___ -ecma_dealloc_extended_object (ecma_extended_object_t *ext_object_p) /**< property pair to be freed */ +ecma_dealloc_extended_object (ecma_extended_object_t *ext_object_p, /**< property pair to be freed */ + size_t size) /**< size of object */ { - jmem_heap_free_block (ext_object_p, sizeof (ecma_extended_object_t)); + jmem_heap_free_block (ext_object_p, size); } /* ecma_dealloc_extended_object */ /** diff --git a/jerry-core/ecma/base/ecma-alloc.h b/jerry-core/ecma/base/ecma-alloc.h index ab400be99..97653636f 100644 --- a/jerry-core/ecma/base/ecma-alloc.h +++ b/jerry-core/ecma/base/ecma-alloc.h @@ -114,12 +114,12 @@ extern void ecma_dealloc_external_pointer (ecma_external_pointer_t *); * * @return pointer to allocated memory */ -extern ecma_extended_object_t *ecma_alloc_extended_object (void); +extern ecma_extended_object_t *ecma_alloc_extended_object (size_t); /** * Dealloc memory of an extended object */ -extern void ecma_dealloc_extended_object (ecma_extended_object_t *); +extern void ecma_dealloc_extended_object (ecma_extended_object_t *, size_t); /** * Allocate memory for ecma-property pair diff --git a/jerry-core/ecma/base/ecma-gc.c b/jerry-core/ecma/base/ecma-gc.c index a1361fbe5..0c8ac43d4 100644 --- a/jerry-core/ecma/base/ecma-gc.c +++ b/jerry-core/ecma/base/ecma-gc.c @@ -203,10 +203,6 @@ ecma_gc_mark_property (ecma_property_t *property_p) /**< property */ switch (ECMA_PROPERTY_GET_INTERNAL_PROPERTY_TYPE (property_p)) { - case ECMA_INTERNAL_PROPERTY_ECMA_VALUE: /* an ecma_value_t except object */ - case ECMA_INTERNAL_PROPERTY_DATE_FLOAT: /* pointer to a ecma_number_t */ - case ECMA_INTERNAL_PROPERTY_CLASS: /* an enum */ - case ECMA_INTERNAL_PROPERTY_REGEXP_BYTECODE: /* pointer to a regexp bytecode array */ case ECMA_INTERNAL_PROPERTY_NATIVE_HANDLE: /* an external pointer */ case ECMA_INTERNAL_PROPERTY_FREE_CALLBACK: /* an object's native free callback */ case ECMA_INTERNAL_PROPERTY_INSTANTIATED_MASK_32_63: /* an integer (bit-mask) */ @@ -440,10 +436,64 @@ ecma_gc_sweep (ecma_object_t *object_p) /**< object to free */ if (!ecma_is_lexical_environment (object_p)) { + if (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_CLASS) + { + ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p; + + switch (ext_object_p->u.class_prop.class_id) + { + /* The undefined id represents an uninitialized class. */ + case LIT_MAGIC_STRING_UNDEFINED: + case LIT_MAGIC_STRING_ARGUMENTS_UL: + case LIT_MAGIC_STRING_BOOLEAN_UL: + case LIT_MAGIC_STRING_ERROR_UL: + { + break; + } + + case LIT_MAGIC_STRING_STRING_UL: + case LIT_MAGIC_STRING_NUMBER_UL: + { + ecma_free_value (ext_object_p->u.class_prop.value); + break; + } + + case LIT_MAGIC_STRING_DATE_UL: + { + ecma_number_t *num_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_number_t, + ext_object_p->u.class_prop.value); + ecma_dealloc_number (num_p); + break; + } + + case LIT_MAGIC_STRING_REGEXP_UL: + { + ecma_compiled_code_t *bytecode_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_compiled_code_t, + ext_object_p->u.class_prop.value); + if (bytecode_p != NULL) + { + ecma_bytecode_deref (bytecode_p); + } + break; + } + + default: + { + JERRY_UNREACHABLE (); + break; + } + } + + size_t size = (ecma_get_object_is_builtin (object_p) ? sizeof (ecma_extended_built_in_object_t) + : sizeof (ecma_extended_object_t)); + ecma_dealloc_extended_object ((ecma_extended_object_t *) object_p, size); + return; + } + if (ecma_get_object_is_builtin (object_p) || ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION) { - ecma_dealloc_extended_object ((ecma_extended_object_t *) object_p); + ecma_dealloc_extended_object ((ecma_extended_object_t *) object_p, sizeof (ecma_extended_object_t)); return; } @@ -455,7 +505,7 @@ ecma_gc_sweep (ecma_object_t *object_p) /**< object to free */ ecma_bytecode_deref (ECMA_GET_INTERNAL_VALUE_POINTER (ecma_compiled_code_t, ext_func_p->u.function.bytecode_cp)); - ecma_dealloc_extended_object (ext_func_p); + ecma_dealloc_extended_object (ext_func_p, sizeof (ecma_extended_object_t)); return; } } diff --git a/jerry-core/ecma/base/ecma-globals.h b/jerry-core/ecma/base/ecma-globals.h index 09e3e53b4..45d30cc77 100644 --- a/jerry-core/ecma/base/ecma-globals.h +++ b/jerry-core/ecma/base/ecma-globals.h @@ -197,15 +197,11 @@ typedef uintptr_t ecma_external_pointer_t; */ typedef enum { - ECMA_INTERNAL_PROPERTY_CLASS, /**< [[Class]] */ ECMA_INTERNAL_PROPERTY_SCOPE, /**< [[Scope]] */ ECMA_INTERNAL_PROPERTY_PARAMETERS_MAP, /**< [[ParametersMap]] */ - ECMA_INTERNAL_PROPERTY_REGEXP_BYTECODE, /**< pointer to RegExp bytecode array */ ECMA_INTERNAL_PROPERTY_NATIVE_HANDLE, /**< native handle associated with an object */ ECMA_INTERNAL_PROPERTY_FREE_CALLBACK, /**< object's native free callback */ - ECMA_INTERNAL_PROPERTY_ECMA_VALUE, /**< [[Primitive value]] for String, Number, and Boolean */ - ECMA_INTERNAL_PROPERTY_DATE_FLOAT, /**< float number value type for date objects */ /** Bound function internal properties **/ ECMA_INTERNAL_PROPERTY_BOUND_FUNCTION_TARGET_FUNCTION, @@ -479,10 +475,10 @@ typedef enum { 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) */ - ECMA_OBJECT_TYPE_STRING = 4, /**< String objects (15.5) */ + ECMA_OBJECT_TYPE_CLASS = 1, /**< Objects with class property */ + ECMA_OBJECT_TYPE_FUNCTION = 2, /**< Function objects (15.3), created through 13.2 routine */ + ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION = 3, /**< External (host) function object */ + ECMA_OBJECT_TYPE_ARRAY = 4, /**< Array object (15.4) */ ECMA_OBJECT_TYPE_BOUND_FUNCTION = 5, /**< Function objects (15.3), created through 15.3.4.5 routine */ ECMA_OBJECT_TYPE_ARGUMENTS = 6, /**< Arguments object (10.6) */ @@ -565,6 +561,17 @@ typedef struct jmem_cpointer_t prototype_or_outer_reference_cp; } ecma_object_t; +/** + * Description of built-in properties of an object. + */ +typedef struct +{ + uint8_t id; /**< built-in id */ + uint8_t length; /**< length for built-in functions */ + uint16_t routine_id; /**< routine id for built-in functions */ + uint32_t instantiated_bitset; /**< bit set for instantiated properties */ +} ecma_built_in_props_t; + /** * Description of extended ECMA-object. * @@ -579,16 +586,16 @@ typedef struct */ union { + ecma_built_in_props_t built_in; /**< built-in object part */ + /* - * Description of built-in objects. + * Description of objects with class. */ struct { - uint8_t id; /**< built-in id */ - uint8_t length; /**< length for built-in functions */ - uint16_t routine_id; /**< routine id for built-in functions */ - uint32_t instantiated_bitset; /**< bit set for instantiated properties */ - } built_in; + uint16_t class_id; /**< class id of the object */ + ecma_value_t value; /**< value of the object (e.g. boolean, number, string, etc.) */ + } class_prop; /* * Description of function objects. @@ -603,6 +610,15 @@ typedef struct } u; } ecma_extended_object_t; +/** + * Description of built-in extended ECMA-object. + */ +typedef struct +{ + ecma_extended_object_t extended_object; /**< extended object part */ + ecma_built_in_props_t built_in; /**< built-in object part */ +} ecma_extended_built_in_object_t; + /** * Description of ECMA property descriptor * diff --git a/jerry-core/ecma/base/ecma-helpers.c b/jerry-core/ecma/base/ecma-helpers.c index dd3e86de1..f0eadff7f 100644 --- a/jerry-core/ecma/base/ecma-helpers.c +++ b/jerry-core/ecma/base/ecma-helpers.c @@ -90,21 +90,21 @@ JERRY_STATIC_ASSERT ((ECMA_OBJECT_MAX_REF | (ECMA_OBJECT_REF_ONE - 1)) == UINT16 */ ecma_object_t * ecma_create_object (ecma_object_t *prototype_object_p, /**< pointer to prototybe of the object (or NULL) */ - bool is_extended, /**< extended object */ - bool is_extensible, /**< value of extensible attribute */ + size_t ext_object_size, /**< size of extended objects */ ecma_object_type_t type) /**< object type */ { - ecma_object_t *new_object_p = (is_extended ? ((ecma_object_t *) ecma_alloc_extended_object ()) - : ecma_alloc_object ()); + ecma_object_t *new_object_p; - uint16_t type_flags = (uint16_t) type; - - if (is_extensible) + if (ext_object_size > 0) { - type_flags = (uint16_t) (type_flags | ECMA_OBJECT_FLAG_EXTENSIBLE); + new_object_p = (ecma_object_t *) ecma_alloc_extended_object (ext_object_size); + } + else + { + new_object_p = ecma_alloc_object (); } - new_object_p->type_flags_refs = type_flags; + new_object_p->type_flags_refs = (uint16_t) (type | ECMA_OBJECT_FLAG_EXTENSIBLE); ecma_init_gc_info (new_object_p); @@ -775,22 +775,6 @@ ecma_free_internal_property (ecma_property_t *property_p) /**< the property */ switch (ECMA_PROPERTY_GET_INTERNAL_PROPERTY_TYPE (property_p)) { - case ECMA_INTERNAL_PROPERTY_ECMA_VALUE: /* ecma-value property except object */ - { - JERRY_ASSERT (!ecma_is_value_object (property_value)); - ecma_free_value (property_value); - - break; - } - - case ECMA_INTERNAL_PROPERTY_DATE_FLOAT: /* pointer to a ecma_number_t */ - { - ecma_number_t *num_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_number_t, property_value); - ecma_dealloc_number (num_p); - - break; - } - case ECMA_INTERNAL_PROPERTY_NATIVE_HANDLE: /* an external pointer */ case ECMA_INTERNAL_PROPERTY_FREE_CALLBACK: /* an external pointer */ { @@ -801,7 +785,6 @@ ecma_free_internal_property (ecma_property_t *property_p) /**< the property */ case ECMA_INTERNAL_PROPERTY_SCOPE: /* a lexical environment */ case ECMA_INTERNAL_PROPERTY_PARAMETERS_MAP: /* an object */ - case ECMA_INTERNAL_PROPERTY_CLASS: /* an enum */ case ECMA_INTERNAL_PROPERTY_INSTANTIATED_MASK_32_63: /* an integer (bit-mask) */ case ECMA_INTERNAL_PROPERTY_BOUND_FUNCTION_TARGET_FUNCTION: { @@ -831,17 +814,6 @@ ecma_free_internal_property (ecma_property_t *property_p) /**< the property */ JERRY_UNREACHABLE (); break; } - - case ECMA_INTERNAL_PROPERTY_REGEXP_BYTECODE: /* compressed pointer to a regexp bytecode array */ - { - ecma_compiled_code_t *bytecode_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_compiled_code_t, property_value); - - if (bytecode_p != NULL) - { - ecma_bytecode_deref (bytecode_p); - } - break; - } } } /* ecma_free_internal_property */ diff --git a/jerry-core/ecma/base/ecma-helpers.h b/jerry-core/ecma/base/ecma-helpers.h index c3d836baa..ee3257eda 100644 --- a/jerry-core/ecma/base/ecma-helpers.h +++ b/jerry-core/ecma/base/ecma-helpers.h @@ -250,7 +250,7 @@ extern bool ecma_collection_iterator_next (ecma_collection_iterator_t *); /* ecma-helpers.c */ -extern ecma_object_t *ecma_create_object (ecma_object_t *, bool, bool, ecma_object_type_t); +extern ecma_object_t *ecma_create_object (ecma_object_t *, size_t, ecma_object_type_t); extern ecma_object_t *ecma_create_decl_lex_env (ecma_object_t *); extern ecma_object_t *ecma_create_object_lex_env (ecma_object_t *, ecma_object_t *, bool); extern bool ecma_is_lexical_environment (const ecma_object_t *) __attr_pure___; diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-boolean-prototype.c b/jerry-core/ecma/builtin-objects/ecma-builtin-boolean-prototype.c index f9651cb31..4249f0320 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-boolean-prototype.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-boolean-prototype.c @@ -100,16 +100,15 @@ ecma_builtin_boolean_prototype_object_value_of (ecma_value_t this_arg) /**< this } else if (ecma_is_value_object (this_arg)) { - ecma_object_t *obj_p = ecma_get_object_from_value (this_arg); + ecma_object_t *object_p = ecma_get_object_from_value (this_arg); - if (ecma_object_get_class_name (obj_p) == LIT_MAGIC_STRING_BOOLEAN_UL) + if (ecma_object_class_is (object_p, LIT_MAGIC_STRING_BOOLEAN_UL)) { - ecma_value_t *prim_value_prop_p = ecma_get_internal_property (obj_p, - ECMA_INTERNAL_PROPERTY_ECMA_VALUE); + ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p; - JERRY_ASSERT (ecma_is_value_boolean (*prim_value_prop_p)); + JERRY_ASSERT (ecma_is_value_boolean (ext_object_p->u.class_prop.value)); - return *prim_value_prop_p; + return ext_object_p->u.class_prop.value; } } diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-date-prototype.c b/jerry-core/ecma/builtin-objects/ecma-builtin-date-prototype.c index c719f8445..d29302f8b 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-date-prototype.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-date-prototype.c @@ -94,7 +94,7 @@ ecma_builtin_date_prototype_to_date_string (ecma_value_t this_arg) /**< this arg ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY); if (!ecma_is_value_object (this_arg) - || ecma_object_get_class_name (ecma_get_object_from_value (this_arg)) != LIT_MAGIC_STRING_DATE_UL) + || !ecma_object_class_is (ecma_get_object_from_value (this_arg), LIT_MAGIC_STRING_DATE_UL)) { ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Incompatible type")); } @@ -104,10 +104,10 @@ ecma_builtin_date_prototype_to_date_string (ecma_value_t this_arg) /**< this arg ecma_op_to_object (this_arg), ret_value); - ecma_object_t *obj_p = ecma_get_object_from_value (obj_this); - ecma_value_t *date_prop_p = ecma_get_internal_property (obj_p, - ECMA_INTERNAL_PROPERTY_DATE_FLOAT); - ecma_number_t *date_num_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_number_t, *date_prop_p); + ecma_object_t *object_p = ecma_get_object_from_value (obj_this); + ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p; + ecma_number_t *date_num_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_number_t, + ext_object_p->u.class_prop.value); if (ecma_number_is_nan (*date_num_p)) { @@ -140,7 +140,7 @@ ecma_builtin_date_prototype_to_time_string (ecma_value_t this_arg) /**< this arg ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY); if (!ecma_is_value_object (this_arg) - || ecma_object_get_class_name (ecma_get_object_from_value (this_arg)) != LIT_MAGIC_STRING_DATE_UL) + || !ecma_object_class_is (ecma_get_object_from_value (this_arg), LIT_MAGIC_STRING_DATE_UL)) { ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Incompatible type")); } @@ -150,10 +150,10 @@ ecma_builtin_date_prototype_to_time_string (ecma_value_t this_arg) /**< this arg ecma_op_to_object (this_arg), ret_value); - ecma_object_t *obj_p = ecma_get_object_from_value (obj_this); - ecma_value_t *prim_prop_p = ecma_get_internal_property (obj_p, - ECMA_INTERNAL_PROPERTY_DATE_FLOAT); - ecma_number_t *prim_value_num_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_number_t, *prim_prop_p); + ecma_object_t *object_p = ecma_get_object_from_value (obj_this); + ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p; + ecma_number_t *prim_value_num_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_number_t, + ext_object_p->u.class_prop.value); if (ecma_number_is_nan (*prim_value_num_p)) { @@ -245,13 +245,14 @@ ecma_builtin_date_prototype_get_time (ecma_value_t this_arg) /**< this argument { if (ecma_is_value_object (this_arg)) { - ecma_object_t *obj_p = ecma_get_object_from_value (this_arg); - if (ecma_object_get_class_name (obj_p) == LIT_MAGIC_STRING_DATE_UL) - { - ecma_value_t *date_prop_p = ecma_get_internal_property (obj_p, - ECMA_INTERNAL_PROPERTY_DATE_FLOAT); + ecma_object_t *object_p = ecma_get_object_from_value (this_arg); - ecma_number_t *date_num_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_number_t, *date_prop_p); + if (ecma_object_class_is (object_p, LIT_MAGIC_STRING_DATE_UL)) + { + ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p; + + ecma_number_t *date_num_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_number_t, + ext_object_p->u.class_prop.value); return ecma_make_number_value (*date_num_p); } } @@ -341,7 +342,7 @@ ecma_builtin_date_prototype_set_time (ecma_value_t this_arg, /**< this argument ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY); if (!ecma_is_value_object (this_arg) - || ecma_object_get_class_name (ecma_get_object_from_value (this_arg)) != LIT_MAGIC_STRING_DATE_UL) + || !ecma_object_class_is (ecma_get_object_from_value (this_arg), LIT_MAGIC_STRING_DATE_UL)) { ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Incompatible type")); } @@ -352,12 +353,11 @@ ecma_builtin_date_prototype_set_time (ecma_value_t this_arg, /**< this argument ecma_number_t value = ecma_date_time_clip (t); /* 2. */ - ecma_object_t *obj_p = ecma_get_object_from_value (this_arg); + ecma_object_t *object_p = ecma_get_object_from_value (this_arg); + ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p; + ecma_number_t *date_num_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_number_t, + ext_object_p->u.class_prop.value); - ecma_value_t *date_prop_p = ecma_get_internal_property (obj_p, - ECMA_INTERNAL_PROPERTY_DATE_FLOAT); - - ecma_number_t *date_num_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_number_t, *date_prop_p); *date_num_p = value; /* 3. */ diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-date.c b/jerry-core/ecma/builtin-objects/ecma-builtin-date.c index a941a7b13..c55e6cd83 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-date.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-date.c @@ -481,9 +481,12 @@ ecma_builtin_date_dispatch_construct (const ecma_value_t *arguments_list_p, /**< ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_DATE_PROTOTYPE); ecma_object_t *obj_p = ecma_create_object (prototype_obj_p, - false, - true, - ECMA_OBJECT_TYPE_GENERAL); + sizeof (ecma_extended_object_t), + ECMA_OBJECT_TYPE_CLASS); + + ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) obj_p; + ext_object_p->u.class_prop.class_id = LIT_MAGIC_STRING_UNDEFINED; + ecma_deref_object (prototype_obj_p); if (arguments_list_len == 0) @@ -546,16 +549,11 @@ ecma_builtin_date_dispatch_construct (const ecma_value_t *arguments_list_p, /**< prim_value_num = ecma_number_make_nan (); } - ecma_value_t *class_prop_p = ecma_create_internal_property (obj_p, - ECMA_INTERNAL_PROPERTY_CLASS); - *class_prop_p = LIT_MAGIC_STRING_DATE_UL; - - ecma_value_t *date_prop_p = ecma_create_internal_property (obj_p, - ECMA_INTERNAL_PROPERTY_DATE_FLOAT); + ext_object_p->u.class_prop.class_id = LIT_MAGIC_STRING_DATE_UL; ecma_number_t *date_num_p = ecma_alloc_number (); *date_num_p = prim_value_num; - ECMA_SET_INTERNAL_VALUE_POINTER (*date_prop_p, date_num_p); + ECMA_SET_INTERNAL_VALUE_POINTER (ext_object_p->u.class_prop.value, date_num_p); ret_value = ecma_make_object_value (obj_p); } diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-function-prototype.c b/jerry-core/ecma/builtin-objects/ecma-builtin-function-prototype.c index 3a91537fc..408e68487 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-function-prototype.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-function-prototype.c @@ -238,8 +238,7 @@ ecma_builtin_function_prototype_object_bind (ecma_value_t this_arg, /**< this ar /* 4. 11. 18. */ ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE); ecma_object_t *function_p = ecma_create_object (prototype_obj_p, - false, - true, + 0, ECMA_OBJECT_TYPE_BOUND_FUNCTION); ecma_deref_object (prototype_obj_p); diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers-date.c b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers-date.c index 44ab86865..8d1ca4912 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers-date.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers-date.c @@ -897,12 +897,10 @@ ecma_date_set_internal_property (ecma_value_t this_arg, /**< this argument */ ecma_number_t value = ecma_date_time_clip (date); - ecma_object_t *obj_p = ecma_get_object_from_value (this_arg); + ecma_object_t *object_p = ecma_get_object_from_value (this_arg); + ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p; - ecma_value_t *date_value_prop_p = ecma_get_internal_property (obj_p, - ECMA_INTERNAL_PROPERTY_DATE_FLOAT); - - *ECMA_GET_INTERNAL_VALUE_POINTER (ecma_number_t, *date_value_prop_p) = value; + *ECMA_GET_INTERNAL_VALUE_POINTER (ecma_number_t, ext_object_p->u.class_prop.value) = value; return ecma_make_number_value (value); } /* ecma_date_set_internal_property */ @@ -1292,18 +1290,17 @@ ecma_date_get_primitive_value (ecma_value_t this_arg) /**< this argument */ ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY); if (!ecma_is_value_object (this_arg) - || ecma_object_get_class_name (ecma_get_object_from_value (this_arg)) != LIT_MAGIC_STRING_DATE_UL) + || !ecma_object_class_is (ecma_get_object_from_value (this_arg), LIT_MAGIC_STRING_DATE_UL)) { ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Incompatible type")); } else { - ecma_object_t *obj_p = ecma_get_object_from_value (this_arg); - ecma_value_t *date_value_prop_p = ecma_get_internal_property (obj_p, - ECMA_INTERNAL_PROPERTY_DATE_FLOAT); - JERRY_ASSERT (date_value_prop_p != NULL); + ecma_object_t *object_p = ecma_get_object_from_value (this_arg); + ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p; - ecma_number_t date_num = *ECMA_GET_INTERNAL_VALUE_POINTER (ecma_number_t, *date_value_prop_p); + ecma_number_t date_num = *ECMA_GET_INTERNAL_VALUE_POINTER (ecma_number_t, + ext_object_p->u.class_prop.value); ret_value = ecma_make_number_value (date_num); } diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-number-prototype.c b/jerry-core/ecma/builtin-objects/ecma-builtin-number-prototype.c index c90ee65b6..83e2e0e2d 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-number-prototype.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-number-prototype.c @@ -451,16 +451,15 @@ ecma_builtin_number_prototype_object_value_of (ecma_value_t this_arg) /**< this } else if (ecma_is_value_object (this_arg)) { - ecma_object_t *obj_p = ecma_get_object_from_value (this_arg); + ecma_object_t *object_p = ecma_get_object_from_value (this_arg); - if (ecma_object_get_class_name (obj_p) == LIT_MAGIC_STRING_NUMBER_UL) + if (ecma_object_class_is (object_p, LIT_MAGIC_STRING_NUMBER_UL)) { - ecma_value_t *prim_value_p = ecma_get_internal_property (obj_p, - ECMA_INTERNAL_PROPERTY_ECMA_VALUE); + ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p; - JERRY_ASSERT (ecma_is_value_number (*prim_value_p)); + JERRY_ASSERT (ecma_is_value_number (ext_object_p->u.class_prop.value)); - return ecma_copy_value (*prim_value_p); + return ecma_copy_value (ext_object_p->u.class_prop.value); } } diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-regexp-prototype.c b/jerry-core/ecma/builtin-objects/ecma-builtin-regexp-prototype.c index 973410ed8..1d193b94b 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-regexp-prototype.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-regexp-prototype.c @@ -66,7 +66,7 @@ ecma_builtin_regexp_prototype_compile (ecma_value_t this_arg, /**< this argument ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY); if (!ecma_is_value_object (this_arg) - || ecma_object_get_class_name (ecma_get_object_from_value (this_arg)) != LIT_MAGIC_STRING_REGEXP_UL) + || !ecma_object_class_is (ecma_get_object_from_value (this_arg), LIT_MAGIC_STRING_REGEXP_UL)) { ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Incomplete RegExp type")); } @@ -75,7 +75,7 @@ ecma_builtin_regexp_prototype_compile (ecma_value_t this_arg, /**< this argument uint16_t flags = 0; if (ecma_is_value_object (pattern_arg) - && ecma_object_get_class_name (ecma_get_object_from_value (pattern_arg)) == LIT_MAGIC_STRING_REGEXP_UL) + && ecma_object_class_is (ecma_get_object_from_value (pattern_arg), LIT_MAGIC_STRING_REGEXP_UL)) { if (!ecma_is_value_undefined (flags_arg)) { @@ -130,8 +130,7 @@ ecma_builtin_regexp_prototype_compile (ecma_value_t this_arg, /**< this argument ecma_object_t *this_obj_p = ecma_get_object_from_value (obj_this); /* Get bytecode property. */ - ecma_value_t *bc_prop_p = ecma_get_internal_property (this_obj_p, - ECMA_INTERNAL_PROPERTY_REGEXP_BYTECODE); + ecma_value_t *bc_prop_p = &(((ecma_extended_object_t *) this_obj_p)->u.class_prop.value); /* TODO: We currently have to re-compile the bytecode, because * we can't copy it without knowing its length. */ @@ -206,8 +205,7 @@ ecma_builtin_regexp_prototype_compile (ecma_value_t this_arg, /**< this argument ECMA_TRY_CATCH (obj_this, ecma_op_to_object (this_arg), ret_value); ecma_object_t *this_obj_p = ecma_get_object_from_value (obj_this); - ecma_value_t *bc_prop_p = ecma_get_internal_property (this_obj_p, - ECMA_INTERNAL_PROPERTY_REGEXP_BYTECODE); + ecma_value_t *bc_prop_p = &(((ecma_extended_object_t *) this_obj_p)->u.class_prop.value); /* Try to compile bytecode from new source. */ const re_compiled_code_t *new_bc_p = NULL; @@ -262,7 +260,7 @@ ecma_builtin_regexp_prototype_exec (ecma_value_t this_arg, /**< this argument */ ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY); if (!ecma_is_value_object (this_arg) - || ecma_object_get_class_name (ecma_get_object_from_value (this_arg)) != LIT_MAGIC_STRING_REGEXP_UL) + || !ecma_object_class_is (ecma_get_object_from_value (this_arg), LIT_MAGIC_STRING_REGEXP_UL)) { ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Incomplete RegExp type")); } @@ -275,8 +273,7 @@ ecma_builtin_regexp_prototype_exec (ecma_value_t this_arg, /**< this argument */ ret_value); ecma_object_t *obj_p = ecma_get_object_from_value (obj_this); - ecma_value_t *bytecode_prop_p = ecma_get_internal_property (obj_p, - ECMA_INTERNAL_PROPERTY_REGEXP_BYTECODE); + ecma_value_t *bytecode_prop_p = &(((ecma_extended_object_t *) obj_p)->u.class_prop.value); void *bytecode_p = ECMA_GET_INTERNAL_VALUE_POINTER (void, *bytecode_prop_p); @@ -352,7 +349,7 @@ ecma_builtin_regexp_prototype_to_string (ecma_value_t this_arg) /**< this argume ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY); if (!ecma_is_value_object (this_arg) - || ecma_object_get_class_name (ecma_get_object_from_value (this_arg)) != LIT_MAGIC_STRING_REGEXP_UL) + || !ecma_object_class_is (ecma_get_object_from_value (this_arg), LIT_MAGIC_STRING_REGEXP_UL)) { ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Incomplete RegExp type")); } diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-regexp.c b/jerry-core/ecma/builtin-objects/ecma-builtin-regexp.c index 730448b8d..1db0f7aea 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-regexp.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-regexp.c @@ -81,7 +81,7 @@ ecma_builtin_regexp_dispatch_construct (const ecma_value_t *arguments_list_p, /* } if (ecma_is_value_object (pattern_value) - && ecma_object_get_class_name (ecma_get_object_from_value (pattern_value)) == LIT_MAGIC_STRING_REGEXP_UL) + && ecma_object_class_is (ecma_get_object_from_value (pattern_value), LIT_MAGIC_STRING_REGEXP_UL)) { if (ecma_is_value_undefined (flags_value)) { diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-string-prototype.c b/jerry-core/ecma/builtin-objects/ecma-builtin-string-prototype.c index 899592bb2..2b3e0ab9a 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-string-prototype.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-string-prototype.c @@ -72,14 +72,15 @@ ecma_builtin_string_prototype_object_to_string (ecma_value_t this_arg) /**< this } else if (ecma_is_value_object (this_arg)) { - ecma_object_t *obj_p = ecma_get_object_from_value (this_arg); + ecma_object_t *object_p = ecma_get_object_from_value (this_arg); - if (ecma_object_get_class_name (obj_p) == LIT_MAGIC_STRING_STRING_UL) + if (ecma_object_class_is (object_p, LIT_MAGIC_STRING_STRING_UL)) { - ecma_value_t *prim_value_p = ecma_get_internal_property (obj_p, - ECMA_INTERNAL_PROPERTY_ECMA_VALUE); + ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p; - return ecma_copy_value (*prim_value_p); + JERRY_ASSERT (ecma_is_value_string (ext_object_p->u.class_prop.value)); + + return ecma_copy_value (ext_object_p->u.class_prop.value); } } @@ -408,7 +409,7 @@ ecma_builtin_string_prototype_object_match (ecma_value_t this_arg, /**< this arg ecma_value_t regexp_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY); /* 3. */ if (ecma_is_value_object (arg) - && ecma_object_get_class_name (ecma_get_object_from_value (arg)) == LIT_MAGIC_STRING_REGEXP_UL) + && ecma_object_class_is (ecma_get_object_from_value (arg), LIT_MAGIC_STRING_REGEXP_UL)) { regexp_value = ecma_copy_value (arg); } @@ -1245,7 +1246,7 @@ ecma_builtin_string_prototype_object_replace (ecma_value_t this_arg, /**< this a ecma_builtin_replace_search_ctx_t context; if (ecma_is_value_object (search_value) - && ecma_object_get_class_name (ecma_get_object_from_value (search_value)) == LIT_MAGIC_STRING_REGEXP_UL) + && ecma_object_class_is (ecma_get_object_from_value (search_value), LIT_MAGIC_STRING_REGEXP_UL)) { ecma_object_t *regexp_obj_p = ecma_get_object_from_value (search_value); ecma_string_t *global_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_GLOBAL); @@ -1337,7 +1338,7 @@ ecma_builtin_string_prototype_object_search (ecma_value_t this_arg, /**< this ar /* 3. */ if (ecma_is_value_object (regexp_arg) - && ecma_object_get_class_name (ecma_get_object_from_value (regexp_arg)) == LIT_MAGIC_STRING_REGEXP_UL) + && ecma_object_class_is (ecma_get_object_from_value (regexp_arg), LIT_MAGIC_STRING_REGEXP_UL)) { regexp_value = ecma_copy_value (regexp_arg); } @@ -1500,7 +1501,7 @@ ecma_builtin_helper_split_match (ecma_value_t input_string, /**< first argument /* 1. */ if (ecma_is_value_object (separator) - && ecma_object_get_class_name (ecma_get_object_from_value (separator)) == LIT_MAGIC_STRING_REGEXP_UL) + && ecma_object_class_is (ecma_get_object_from_value (separator), LIT_MAGIC_STRING_REGEXP_UL)) { ecma_value_t regexp_value = ecma_copy_value_if_not_object (separator); @@ -1687,7 +1688,7 @@ ecma_builtin_string_prototype_object_split (ecma_value_t this_arg, /**< this arg ecma_value_t separator = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY); if (ecma_is_value_object (arg1) - && ecma_object_get_class_name (ecma_get_object_from_value (arg1)) == LIT_MAGIC_STRING_REGEXP_UL) + && ecma_object_class_is (ecma_get_object_from_value (arg1), LIT_MAGIC_STRING_REGEXP_UL)) { separator = ecma_copy_value (arg1); } diff --git a/jerry-core/ecma/builtin-objects/ecma-builtins.c b/jerry-core/ecma/builtin-objects/ecma-builtins.c index 37c559aaa..ff44eabcf 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtins.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtins.c @@ -104,7 +104,15 @@ ecma_builtin_init_object (ecma_builtin_id_t obj_builtin_id, /**< built-in ID */ ecma_object_type_t obj_type, /**< object's type */ bool is_extensible) /**< value of object's [[Extensible]] property */ { - ecma_object_t *obj_p = ecma_create_object (prototype_obj_p, true, is_extensible, obj_type); + size_t ext_object_size = (obj_type == ECMA_OBJECT_TYPE_CLASS ? sizeof (ecma_extended_built_in_object_t) + : sizeof (ecma_extended_object_t)); + + ecma_object_t *obj_p = ecma_create_object (prototype_obj_p, ext_object_size, obj_type); + + if (!is_extensible) + { + ecma_set_object_extensible (obj_p, false); + } /* * [[Class]] property of built-in object is not stored explicitly. @@ -113,11 +121,20 @@ ecma_builtin_init_object (ecma_builtin_id_t obj_builtin_id, /**< built-in ID */ */ ecma_set_object_is_builtin (obj_p); + ecma_built_in_props_t *built_in_props_p; - ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) obj_p; - ext_obj_p->u.built_in.id = obj_builtin_id; - ext_obj_p->u.built_in.routine_id = obj_builtin_id; - ext_obj_p->u.built_in.instantiated_bitset = 0; + if (obj_type == ECMA_OBJECT_TYPE_CLASS) + { + built_in_props_p = &((ecma_extended_built_in_object_t *) obj_p)->built_in; + } + else + { + built_in_props_p = &((ecma_extended_object_t *) obj_p)->u.built_in; + } + + built_in_props_p->id = obj_builtin_id; + built_in_props_p->routine_id = obj_builtin_id; + built_in_props_p->instantiated_bitset = 0; /** Initializing [[PrimitiveValue]] properties of built-in prototype objects */ switch (obj_builtin_id) @@ -125,6 +142,7 @@ ecma_builtin_init_object (ecma_builtin_id_t obj_builtin_id, /**< built-in ID */ #ifndef CONFIG_DISABLE_ARRAY_BUILTIN case ECMA_BUILTIN_ID_ARRAY_PROTOTYPE: { + JERRY_ASSERT (obj_type != ECMA_OBJECT_TYPE_CLASS); ecma_string_t *length_str_p = ecma_new_ecma_length_string (); ecma_property_value_t *length_prop_value_p; @@ -143,11 +161,12 @@ ecma_builtin_init_object (ecma_builtin_id_t obj_builtin_id, /**< built-in ID */ #ifndef CONFIG_DISABLE_STRING_BUILTIN case ECMA_BUILTIN_ID_STRING_PROTOTYPE: { - ecma_string_t *prim_prop_str_value_p = ecma_get_magic_string (LIT_MAGIC_STRING__EMPTY); + JERRY_ASSERT (obj_type == ECMA_OBJECT_TYPE_CLASS); + ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) obj_p; - ecma_value_t *prim_value_p = ecma_create_internal_property (obj_p, - ECMA_INTERNAL_PROPERTY_ECMA_VALUE); - *prim_value_p = ecma_make_string_value (prim_prop_str_value_p); + ext_object_p->u.class_prop.class_id = LIT_MAGIC_STRING_STRING_UL; + ecma_string_t *prim_prop_str_value_p = ecma_get_magic_string (LIT_MAGIC_STRING__EMPTY); + ext_object_p->u.class_prop.value = ecma_make_string_value (prim_prop_str_value_p); break; } #endif /* !CONFIG_DISABLE_STRING_BUILTIN */ @@ -155,9 +174,11 @@ ecma_builtin_init_object (ecma_builtin_id_t obj_builtin_id, /**< built-in ID */ #ifndef CONFIG_DISABLE_NUMBER_BUILTIN case ECMA_BUILTIN_ID_NUMBER_PROTOTYPE: { - ecma_value_t *prim_value_p = ecma_create_internal_property (obj_p, - ECMA_INTERNAL_PROPERTY_ECMA_VALUE); - *prim_value_p = ecma_make_integer_value (0); + JERRY_ASSERT (obj_type == ECMA_OBJECT_TYPE_CLASS); + ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) obj_p; + + ext_object_p->u.class_prop.class_id = LIT_MAGIC_STRING_NUMBER_UL; + ext_object_p->u.class_prop.value = ecma_make_integer_value (0); break; } #endif /* !CONFIG_DISABLE_NUMBER_BUILTIN */ @@ -165,9 +186,11 @@ ecma_builtin_init_object (ecma_builtin_id_t obj_builtin_id, /**< built-in ID */ #ifndef CONFIG_DISABLE_BOOLEAN_BUILTIN case ECMA_BUILTIN_ID_BOOLEAN_PROTOTYPE: { - ecma_value_t *prim_value_p = ecma_create_internal_property (obj_p, - ECMA_INTERNAL_PROPERTY_ECMA_VALUE); - *prim_value_p = ecma_make_simple_value (ECMA_SIMPLE_VALUE_FALSE); + JERRY_ASSERT (obj_type == ECMA_OBJECT_TYPE_CLASS); + ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) obj_p; + + ext_object_p->u.class_prop.class_id = LIT_MAGIC_STRING_BOOLEAN_UL; + ext_object_p->u.class_prop.value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_FALSE); break; } #endif /* !CONFIG_DISABLE_BOOLEAN_BUILTIN */ @@ -175,12 +198,14 @@ ecma_builtin_init_object (ecma_builtin_id_t obj_builtin_id, /**< built-in ID */ #ifndef CONFIG_DISABLE_DATE_BUILTIN case ECMA_BUILTIN_ID_DATE_PROTOTYPE: { + JERRY_ASSERT (obj_type == ECMA_OBJECT_TYPE_CLASS); + ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) obj_p; + + ext_object_p->u.class_prop.class_id = LIT_MAGIC_STRING_DATE_UL; + ecma_number_t *prim_prop_num_value_p = ecma_alloc_number (); *prim_prop_num_value_p = ecma_number_make_nan (); - - ecma_value_t *prim_value_p = ecma_create_internal_property (obj_p, - ECMA_INTERNAL_PROPERTY_DATE_FLOAT); - ECMA_SET_INTERNAL_VALUE_POINTER (*prim_value_p, prim_prop_num_value_p); + ECMA_SET_INTERNAL_VALUE_POINTER (ext_object_p->u.class_prop.value, prim_prop_num_value_p); break; } #endif /* !CONFIG_DISABLE_DATE_BUILTIN */ @@ -188,14 +213,17 @@ ecma_builtin_init_object (ecma_builtin_id_t obj_builtin_id, /**< built-in ID */ #ifndef CONFIG_DISABLE_REGEXP_BUILTIN case ECMA_BUILTIN_ID_REGEXP_PROTOTYPE: { - ecma_value_t *bytecode_prop_p = ecma_create_internal_property (obj_p, - ECMA_INTERNAL_PROPERTY_REGEXP_BYTECODE); - *bytecode_prop_p = ECMA_NULL_POINTER; + JERRY_ASSERT (obj_type == ECMA_OBJECT_TYPE_CLASS); + ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) obj_p; + + ext_object_p->u.class_prop.class_id = LIT_MAGIC_STRING_REGEXP_UL; + ext_object_p->u.class_prop.value = ECMA_NULL_POINTER; break; } #endif /* !CONFIG_DISABLE_REGEXP_BUILTIN */ default: { + JERRY_ASSERT (obj_type != ECMA_OBJECT_TYPE_CLASS); break; } } @@ -288,7 +316,9 @@ ecma_builtin_make_function_object_for_routine (ecma_builtin_id_t builtin_id, /** { ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE); - ecma_object_t *func_obj_p = ecma_create_object (prototype_obj_p, true, true, ECMA_OBJECT_TYPE_FUNCTION); + ecma_object_t *func_obj_p = ecma_create_object (prototype_obj_p, + sizeof (ecma_extended_object_t), + ECMA_OBJECT_TYPE_FUNCTION); ecma_deref_object (prototype_obj_p); @@ -333,8 +363,6 @@ ecma_builtin_try_to_instantiate_property (ecma_object_t *object_p, /**< object * { JERRY_ASSERT (ecma_get_object_is_builtin (object_p)); - ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) object_p; - if (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_FUNCTION && ecma_builtin_function_is_routine (object_p)) { @@ -354,6 +382,7 @@ ecma_builtin_try_to_instantiate_property (ecma_object_t *object_p, /**< object * ECMA_PROPERTY_FIXED, &len_prop_p); + ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) object_p; len_prop_value_p->value = ecma_make_integer_value (ext_obj_p->u.built_in.length); return len_prop_p; @@ -369,7 +398,18 @@ ecma_builtin_try_to_instantiate_property (ecma_object_t *object_p, /**< object * return NULL; } - ecma_builtin_id_t builtin_id = (ecma_builtin_id_t) ext_obj_p->u.built_in.id; + ecma_built_in_props_t *built_in_props_p; + + if (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_CLASS) + { + built_in_props_p = &((ecma_extended_built_in_object_t *) object_p)->built_in; + } + else + { + built_in_props_p = &((ecma_extended_object_t *) object_p)->u.built_in; + } + + ecma_builtin_id_t builtin_id = (ecma_builtin_id_t) built_in_props_p->id; JERRY_ASSERT (builtin_id < ECMA_BUILTIN_ID__COUNT); JERRY_ASSERT (ecma_builtin_is (object_p, builtin_id)); @@ -395,13 +435,13 @@ ecma_builtin_try_to_instantiate_property (ecma_object_t *object_p, /**< object * { uint32_t bit_for_index = (uint32_t) 1u << index; - if (ext_obj_p->u.built_in.instantiated_bitset & bit_for_index) + if (built_in_props_p->instantiated_bitset & bit_for_index) { /* This property was instantiated before. */ return NULL; } - ext_obj_p->u.built_in.instantiated_bitset |= bit_for_index; + built_in_props_p->instantiated_bitset |= bit_for_index; } else { @@ -558,8 +598,6 @@ ecma_builtin_list_lazy_property_names (ecma_object_t *object_p, /**< a built-in { JERRY_ASSERT (ecma_get_object_is_builtin (object_p)); - ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) object_p; - if (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_FUNCTION && ecma_builtin_function_is_routine (object_p)) { @@ -575,7 +613,18 @@ ecma_builtin_list_lazy_property_names (ecma_object_t *object_p, /**< a built-in } else { - ecma_builtin_id_t builtin_id = (ecma_builtin_id_t) ext_obj_p->u.built_in.id; + ecma_built_in_props_t *built_in_props_p; + + if (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_CLASS) + { + built_in_props_p = &((ecma_extended_built_in_object_t *) object_p)->built_in; + } + else + { + built_in_props_p = &((ecma_extended_object_t *) object_p)->u.built_in; + } + + ecma_builtin_id_t builtin_id = (ecma_builtin_id_t) built_in_props_p->id; JERRY_ASSERT (builtin_id < ECMA_BUILTIN_ID__COUNT); JERRY_ASSERT (ecma_builtin_is (object_p, builtin_id)); @@ -583,7 +632,7 @@ ecma_builtin_list_lazy_property_names (ecma_object_t *object_p, /**< a built-in const ecma_builtin_property_descriptor_t *curr_property_p = ecma_builtin_property_list_references[builtin_id]; ecma_length_t index = 0; - uint32_t instantiated_bitset = ext_obj_p->u.built_in.instantiated_bitset; + uint32_t instantiated_bitset = built_in_props_p->instantiated_bitset; ecma_collection_header_t *for_non_enumerable_p = (separate_enumerable ? non_enum_collection_p : main_collection_p); @@ -698,6 +747,7 @@ ecma_builtin_dispatch_call (ecma_object_t *obj_p, /**< built-in object */ const ecma_value_t *arguments_list_p, /**< arguments list */ ecma_length_t arguments_list_len) /**< arguments list length */ { + JERRY_ASSERT (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_FUNCTION); JERRY_ASSERT (ecma_get_object_is_builtin (obj_p)); ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY); @@ -713,8 +763,6 @@ ecma_builtin_dispatch_call (ecma_object_t *obj_p, /**< built-in object */ } else { - JERRY_ASSERT (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_FUNCTION); - switch ((ecma_builtin_id_t) ext_obj_p->u.built_in.id) { #define BUILTIN(builtin_id, \ @@ -768,8 +816,6 @@ ecma_builtin_dispatch_construct (ecma_object_t *obj_p, /**< built-in object */ ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) obj_p; - JERRY_ASSERT (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_FUNCTION); - switch (ext_obj_p->u.built_in.id) { #define BUILTIN(builtin_id, \ diff --git a/jerry-core/ecma/builtin-objects/ecma-builtins.inc.h b/jerry-core/ecma/builtin-objects/ecma-builtins.inc.h index abfa741b8..c1fc334cf 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtins.inc.h +++ b/jerry-core/ecma/builtin-objects/ecma-builtins.inc.h @@ -53,7 +53,7 @@ BUILTIN (ECMA_BUILTIN_ID_ARRAY, #ifndef CONFIG_DISABLE_STRING_BUILTIN /* The String.prototype object (15.5.4) */ BUILTIN (ECMA_BUILTIN_ID_STRING_PROTOTYPE, - ECMA_OBJECT_TYPE_GENERAL, + ECMA_OBJECT_TYPE_CLASS, ECMA_BUILTIN_ID_OBJECT_PROTOTYPE, true, true, @@ -71,7 +71,7 @@ BUILTIN (ECMA_BUILTIN_ID_STRING, #ifndef CONFIG_DISABLE_BOOLEAN_BUILTIN /* The Boolean.prototype object (15.6.4) */ BUILTIN (ECMA_BUILTIN_ID_BOOLEAN_PROTOTYPE, - ECMA_OBJECT_TYPE_GENERAL, + ECMA_OBJECT_TYPE_CLASS, ECMA_BUILTIN_ID_OBJECT_PROTOTYPE, true, true, @@ -89,7 +89,7 @@ BUILTIN (ECMA_BUILTIN_ID_BOOLEAN, #ifndef CONFIG_DISABLE_NUMBER_BUILTIN /* The Number.prototype object (15.7.4) */ BUILTIN (ECMA_BUILTIN_ID_NUMBER_PROTOTYPE, - ECMA_OBJECT_TYPE_GENERAL, + ECMA_OBJECT_TYPE_CLASS, ECMA_BUILTIN_ID_OBJECT_PROTOTYPE, true, true, @@ -143,7 +143,7 @@ BUILTIN (ECMA_BUILTIN_ID_JSON, #ifndef CONFIG_DISABLE_DATE_BUILTIN /* The Date.prototype object (15.9.4) */ BUILTIN (ECMA_BUILTIN_ID_DATE_PROTOTYPE, - ECMA_OBJECT_TYPE_GENERAL, + ECMA_OBJECT_TYPE_CLASS, ECMA_BUILTIN_ID_OBJECT_PROTOTYPE, true, true, @@ -161,7 +161,7 @@ BUILTIN (ECMA_BUILTIN_ID_DATE, #ifndef CONFIG_DISABLE_REGEXP_BUILTIN /* The RegExp.prototype object (15.10.6) */ BUILTIN (ECMA_BUILTIN_ID_REGEXP_PROTOTYPE, - ECMA_OBJECT_TYPE_GENERAL, + ECMA_OBJECT_TYPE_CLASS, ECMA_BUILTIN_ID_OBJECT_PROTOTYPE, true, true, diff --git a/jerry-core/ecma/operations/ecma-array-object.c b/jerry-core/ecma/operations/ecma-array-object.c index 05264e63d..d019991e6 100644 --- a/jerry-core/ecma/operations/ecma-array-object.c +++ b/jerry-core/ecma/operations/ecma-array-object.c @@ -92,8 +92,7 @@ ecma_op_create_array_object (const ecma_value_t *arguments_list_p, /**< list of #endif /* !CONFIG_DISABLE_ARRAY_BUILTIN */ ecma_object_t *obj_p = ecma_create_object (array_prototype_obj_p, - false, - true, + 0, ECMA_OBJECT_TYPE_ARRAY); ecma_deref_object (array_prototype_obj_p); diff --git a/jerry-core/ecma/operations/ecma-boolean-object.c b/jerry-core/ecma/operations/ecma-boolean-object.c index e876c3116..57aa5f4d9 100644 --- a/jerry-core/ecma/operations/ecma-boolean-object.c +++ b/jerry-core/ecma/operations/ecma-boolean-object.c @@ -49,18 +49,17 @@ ecma_op_create_boolean_object (ecma_value_t arg) /**< argument passed to the Boo ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE); #endif /* !CONFIG_DISABLE_BOOLEAN_BUILTIN */ - ecma_object_t *obj_p = ecma_create_object (prototype_obj_p, false, true, ECMA_OBJECT_TYPE_GENERAL); + ecma_object_t *object_p = ecma_create_object (prototype_obj_p, + sizeof (ecma_extended_object_t), + ECMA_OBJECT_TYPE_CLASS); + ecma_deref_object (prototype_obj_p); - ecma_value_t *class_prop_p = ecma_create_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_CLASS); - *class_prop_p = LIT_MAGIC_STRING_BOOLEAN_UL; + ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p; + ext_object_p->u.class_prop.class_id = LIT_MAGIC_STRING_BOOLEAN_UL; + ext_object_p->u.class_prop.value = ecma_make_boolean_value (boolean_value); - ecma_value_t *prim_value_p = ecma_create_internal_property (obj_p, - ECMA_INTERNAL_PROPERTY_ECMA_VALUE); - - *prim_value_p = ecma_make_boolean_value (boolean_value); - - return ecma_make_object_value (obj_p); + return ecma_make_object_value (object_p); } /* ecma_op_create_boolean_object */ /** diff --git a/jerry-core/ecma/operations/ecma-exceptions.c b/jerry-core/ecma/operations/ecma-exceptions.c index 7356c5b1a..1ea2424b1 100644 --- a/jerry-core/ecma/operations/ecma-exceptions.c +++ b/jerry-core/ecma/operations/ecma-exceptions.c @@ -92,15 +92,12 @@ ecma_new_standard_error (ecma_standard_error_t error_type) /**< native error typ ecma_object_t *prototype_obj_p = ecma_builtin_get (prototype_id); ecma_object_t *new_error_obj_p = ecma_create_object (prototype_obj_p, - false, - true, - ECMA_OBJECT_TYPE_GENERAL); + sizeof (ecma_extended_object_t), + ECMA_OBJECT_TYPE_CLASS); ecma_deref_object (prototype_obj_p); - ecma_value_t *class_prop_p = ecma_create_internal_property (new_error_obj_p, - ECMA_INTERNAL_PROPERTY_CLASS); - *class_prop_p = LIT_MAGIC_STRING_ERROR_UL; + ((ecma_extended_object_t *) new_error_obj_p)->u.class_prop.class_id = LIT_MAGIC_STRING_ERROR_UL; return new_error_obj_p; } /* ecma_new_standard_error */ diff --git a/jerry-core/ecma/operations/ecma-function-object.c b/jerry-core/ecma/operations/ecma-function-object.c index bdd0d2fbc..08ddfb830 100644 --- a/jerry-core/ecma/operations/ecma-function-object.c +++ b/jerry-core/ecma/operations/ecma-function-object.c @@ -153,7 +153,9 @@ ecma_op_create_function_object (ecma_object_t *scope_p, /**< function's scope */ // 1., 4., 13. ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE); - ecma_object_t *func_p = ecma_create_object (prototype_obj_p, true, true, ECMA_OBJECT_TYPE_FUNCTION); + ecma_object_t *func_p = ecma_create_object (prototype_obj_p, + sizeof (ecma_extended_object_t), + ECMA_OBJECT_TYPE_FUNCTION); ecma_deref_object (prototype_obj_p); @@ -355,7 +357,9 @@ ecma_op_create_external_function_object (ecma_external_pointer_t code_p) /**< po ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE); ecma_object_t *function_obj_p; - function_obj_p = ecma_create_object (prototype_obj_p, true, true, ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION); + function_obj_p = ecma_create_object (prototype_obj_p, + sizeof (ecma_extended_object_t), + ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION); ecma_deref_object (prototype_obj_p); @@ -679,8 +683,7 @@ ecma_op_function_construct_simple_or_external (ecma_object_t *func_obj_p, /**< F { // 6. obj_p = ecma_create_object (ecma_get_object_from_value (func_obj_prototype_prop_value), - false, - true, + 0, ECMA_OBJECT_TYPE_GENERAL); } else @@ -688,7 +691,7 @@ ecma_op_function_construct_simple_or_external (ecma_object_t *func_obj_p, /**< F // 7. ecma_object_t *prototype_p = ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE); - obj_p = ecma_create_object (prototype_p, false, true, ECMA_OBJECT_TYPE_GENERAL); + obj_p = ecma_create_object (prototype_p, 0, ECMA_OBJECT_TYPE_GENERAL); ecma_deref_object (prototype_p); } diff --git a/jerry-core/ecma/operations/ecma-number-object.c b/jerry-core/ecma/operations/ecma-number-object.c index fb66b3f7f..5f924142c 100644 --- a/jerry-core/ecma/operations/ecma-number-object.c +++ b/jerry-core/ecma/operations/ecma-number-object.c @@ -54,22 +54,19 @@ ecma_op_create_number_object (ecma_value_t arg) /**< argument passed to the Numb ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE); #endif /* !CONFIG_DISABLE_NUMBER_BUILTIN */ - ecma_object_t *obj_p = ecma_create_object (prototype_obj_p, - false, - true, - ECMA_OBJECT_TYPE_GENERAL); + ecma_object_t *object_p = ecma_create_object (prototype_obj_p, + sizeof (ecma_extended_object_t), + ECMA_OBJECT_TYPE_CLASS); + ecma_deref_object (prototype_obj_p); - ecma_value_t *class_prop_p = ecma_create_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_CLASS); - *class_prop_p = LIT_MAGIC_STRING_NUMBER_UL; - - ecma_value_t *prim_value_p = ecma_create_internal_property (obj_p, - ECMA_INTERNAL_PROPERTY_ECMA_VALUE); + ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p; + ext_object_p->u.class_prop.class_id = LIT_MAGIC_STRING_NUMBER_UL; /* Pass reference (no need to free conv_to_num_completion). */ - *prim_value_p = conv_to_num_completion; + ext_object_p->u.class_prop.value = conv_to_num_completion; - return ecma_make_object_value (obj_p); + return ecma_make_object_value (object_p); } /* ecma_op_create_number_object */ /** diff --git a/jerry-core/ecma/operations/ecma-objects-arguments.c b/jerry-core/ecma/operations/ecma-objects-arguments.c index 742fb84e3..f83f46ae0 100644 --- a/jerry-core/ecma/operations/ecma-objects-arguments.c +++ b/jerry-core/ecma/operations/ecma-objects-arguments.c @@ -49,10 +49,46 @@ ecma_op_create_arguments_object (ecma_object_t *func_obj_p, /**< callee function ecma_length_t arguments_number, /**< length of arguments list */ const ecma_compiled_code_t *bytecode_data_p) /**< byte code */ { + bool is_strict = (bytecode_data_p->status_flags & CBC_CODE_FLAGS_STRICT_MODE) != 0; + + ecma_length_t formal_params_number; + jmem_cpointer_t *literal_p; + + if (bytecode_data_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS) + { + cbc_uint16_arguments_t *args_p = (cbc_uint16_arguments_t *) bytecode_data_p; + uint8_t *byte_p = (uint8_t *) bytecode_data_p; + + formal_params_number = args_p->argument_end; + literal_p = (jmem_cpointer_t *) (byte_p + sizeof (cbc_uint16_arguments_t)); + } + else + { + cbc_uint8_arguments_t *args_p = (cbc_uint8_arguments_t *) bytecode_data_p; + uint8_t *byte_p = (uint8_t *) bytecode_data_p; + + formal_params_number = args_p->argument_end; + literal_p = (jmem_cpointer_t *) (byte_p + sizeof (cbc_uint8_arguments_t)); + } + + bool class_not_required = (!is_strict && arguments_number > 0 && formal_params_number > 0); + // 2., 3., 6. ecma_object_t *prototype_p = ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE); - ecma_object_t *obj_p = ecma_create_object (prototype_p, false, true, ECMA_OBJECT_TYPE_GENERAL); + ecma_object_t *obj_p; + + if (class_not_required) + { + obj_p = ecma_create_object (prototype_p, 0, ECMA_OBJECT_TYPE_GENERAL); + } + else + { + obj_p = ecma_create_object (prototype_p, sizeof (ecma_extended_object_t), ECMA_OBJECT_TYPE_CLASS); + + ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) obj_p; + ext_object_p->u.class_prop.class_id = LIT_MAGIC_STRING_ARGUMENTS_UL; + } ecma_deref_object (prototype_p); @@ -77,10 +113,6 @@ ecma_op_create_arguments_object (ecma_object_t *func_obj_p, /**< callee function ecma_deref_ecma_string (indx_string_p); } - bool is_strict = (bytecode_data_p->status_flags & CBC_CODE_FLAGS_STRICT_MODE) != 0; - - // 1. - // 7. ecma_string_t *length_magic_string_p = ecma_new_ecma_length_string (); ecma_value_t completion = ecma_builtin_helper_def_prop (obj_p, @@ -96,29 +128,7 @@ ecma_op_create_arguments_object (ecma_object_t *func_obj_p, /**< callee function ecma_property_descriptor_t prop_desc = ecma_make_empty_property_descriptor (); - ecma_length_t formal_params_number; - jmem_cpointer_t *literal_p; - - if (bytecode_data_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS) - { - cbc_uint16_arguments_t *args_p = (cbc_uint16_arguments_t *) bytecode_data_p; - uint8_t *byte_p = (uint8_t *) bytecode_data_p; - - formal_params_number = args_p->argument_end; - literal_p = (jmem_cpointer_t *) (byte_p + sizeof (cbc_uint16_arguments_t)); - } - else - { - cbc_uint8_arguments_t *args_p = (cbc_uint8_arguments_t *) bytecode_data_p; - uint8_t *byte_p = (uint8_t *) bytecode_data_p; - - formal_params_number = args_p->argument_end; - literal_p = (jmem_cpointer_t *) (byte_p + sizeof (cbc_uint8_arguments_t)); - } - - if (!is_strict - && arguments_number > 0 - && formal_params_number > 0) + if (class_not_required) { // 8. ecma_object_t *map_p = ecma_op_create_object_object_noarg (); @@ -165,12 +175,6 @@ ecma_op_create_arguments_object (ecma_object_t *func_obj_p, /**< callee function ecma_deref_object (map_p); } - else - { - // 4. - ecma_value_t *class_prop_p = ecma_create_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_CLASS); - *class_prop_p = LIT_MAGIC_STRING_ARGUMENTS_UL; - } // 13. if (!is_strict) diff --git a/jerry-core/ecma/operations/ecma-objects-general.c b/jerry-core/ecma/operations/ecma-objects-general.c index b8e3c2773..3fc2daa0e 100644 --- a/jerry-core/ecma/operations/ecma-objects-general.c +++ b/jerry-core/ecma/operations/ecma-objects-general.c @@ -115,7 +115,7 @@ ecma_op_create_object_object_noarg_and_set_prototype (ecma_object_t *object_prot the object (can be NULL) */ { - ecma_object_t *obj_p = ecma_create_object (object_prototype_p, false, true, ECMA_OBJECT_TYPE_GENERAL); + ecma_object_t *obj_p = ecma_create_object (object_prototype_p, 0, ECMA_OBJECT_TYPE_GENERAL); /* * [[Class]] property of ECMA_OBJECT_TYPE_GENERAL type objects @@ -203,7 +203,7 @@ ecma_op_general_object_default_value (ecma_object_t *obj_p, /**< the object */ if (hint == ECMA_PREFERRED_TYPE_NO) { - if (ecma_object_get_class_name (obj_p) == LIT_MAGIC_STRING_DATE_UL) + if (ecma_object_class_is (obj_p, LIT_MAGIC_STRING_DATE_UL)) { hint = ECMA_PREFERRED_TYPE_STRING; } diff --git a/jerry-core/ecma/operations/ecma-objects.c b/jerry-core/ecma/operations/ecma-objects.c index adae5e198..8725c703c 100644 --- a/jerry-core/ecma/operations/ecma-objects.c +++ b/jerry-core/ecma/operations/ecma-objects.c @@ -48,10 +48,10 @@ #ifndef JERRY_NDEBUG #define JERRY_ASSERT_OBJECT_TYPE_IS_VALID(type) \ JERRY_ASSERT (type == ECMA_OBJECT_TYPE_GENERAL \ + || type == ECMA_OBJECT_TYPE_CLASS \ || type == ECMA_OBJECT_TYPE_FUNCTION \ || type == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION \ || type == ECMA_OBJECT_TYPE_ARRAY \ - || type == ECMA_OBJECT_TYPE_STRING \ || type == ECMA_OBJECT_TYPE_BOUND_FUNCTION \ || type == ECMA_OBJECT_TYPE_ARGUMENTS); #else /* JERRY_NDEBUG */ @@ -84,43 +84,44 @@ ecma_op_object_get_own_property (ecma_object_t *object_p, /**< the object */ if (property_p == NULL) { - if (type == ECMA_OBJECT_TYPE_STRING) + if (type == ECMA_OBJECT_TYPE_CLASS) { - if (ecma_string_is_length (property_name_p)) + ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p; + + if (ext_object_p->u.class_prop.class_id == LIT_MAGIC_STRING_STRING_UL) { - if (options & ECMA_PROPERTY_GET_VALUE) - { - 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); - ecma_length_t length = ecma_string_get_length (prim_value_str_p); - - property_ref_p->virtual_value = ecma_make_uint32_value (length); - } - - return ECMA_PROPERTY_TYPE_VIRTUAL; - } - - 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 (ecma_string_is_length (property_name_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); + ecma_value_t prim_value_p = ext_object_p->u.class_prop.value; + ecma_string_t *prim_value_str_p = ecma_get_string_from_value (prim_value_p); + + ecma_length_t length = ecma_string_get_length (prim_value_str_p); + property_ref_p->virtual_value = ecma_make_uint32_value (length); } - return ECMA_PROPERTY_FLAG_ENUMERABLE | ECMA_PROPERTY_TYPE_VIRTUAL; + return ECMA_PROPERTY_TYPE_VIRTUAL; + } + + uint32_t index; + + if (ecma_string_get_array_index (property_name_p, &index)) + { + ecma_value_t prim_value_p = ext_object_p->u.class_prop.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; + } } } } @@ -330,32 +331,35 @@ ecma_op_object_find_own (ecma_value_t base_value, /**< base value */ if (property_p == NULL) { - if (type == ECMA_OBJECT_TYPE_STRING) + if (type == ECMA_OBJECT_TYPE_CLASS) { - if (ecma_string_is_length (property_name_p)) + ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p; + + if (ext_object_p->u.class_prop.class_id == LIT_MAGIC_STRING_STRING_UL) { - 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); - ecma_length_t length = ecma_string_get_length (prim_value_str_p); - - return ecma_make_uint32_value (length); - } - - 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 (ecma_string_is_length (property_name_p)) { - ecma_char_t char_at_idx = ecma_string_get_char_at_pos (prim_value_str_p, index); - return ecma_make_string_value (ecma_new_ecma_string_from_code_unit (char_at_idx)); + ecma_value_t prim_value_p = ext_object_p->u.class_prop.value; + + ecma_string_t *prim_value_str_p = ecma_get_string_from_value (prim_value_p); + ecma_length_t length = ecma_string_get_length (prim_value_str_p); + + return ecma_make_uint32_value (length); + } + + uint32_t index; + + if (ecma_string_get_array_index (property_name_p, &index)) + { + ecma_value_t prim_value_p = ext_object_p->u.class_prop.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)) + { + ecma_char_t char_at_idx = ecma_string_get_char_at_pos (prim_value_str_p, index); + return ecma_make_string_value (ecma_new_ecma_string_from_code_unit (char_at_idx)); + } } } } @@ -582,20 +586,23 @@ ecma_op_object_put (ecma_object_t *object_p, /**< the object */ if (property_p == NULL) { - if (type == ECMA_OBJECT_TYPE_STRING) + if (type == ECMA_OBJECT_TYPE_CLASS) { - uint32_t index; + ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p; - if (ecma_string_get_array_index (property_name_p, &index)) + if (ext_object_p->u.class_prop.class_id == LIT_MAGIC_STRING_STRING_UL) { - ecma_value_t *prim_value_p = ecma_get_internal_property (object_p, - ECMA_INTERNAL_PROPERTY_ECMA_VALUE); + uint32_t index; - 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 (ecma_string_get_array_index (property_name_p, &index)) { - return ecma_reject (is_throw); + ecma_value_t prim_value_p = ext_object_p->u.class_prop.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)) + { + return ecma_reject (is_throw); + } } } } @@ -776,10 +783,10 @@ ecma_op_object_delete (ecma_object_t *obj_p, /**< the object */ switch (type) { case ECMA_OBJECT_TYPE_GENERAL: + case ECMA_OBJECT_TYPE_CLASS: case ECMA_OBJECT_TYPE_FUNCTION: case ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION: case ECMA_OBJECT_TYPE_ARRAY: - case ECMA_OBJECT_TYPE_STRING: case ECMA_OBJECT_TYPE_BOUND_FUNCTION: { return ecma_op_general_object_delete (obj_p, @@ -825,10 +832,10 @@ ecma_op_object_default_value (ecma_object_t *obj_p, /**< the object */ * static const default_value_ptr_t default_value [ECMA_OBJECT_TYPE__COUNT] = * { * [ECMA_OBJECT_TYPE_GENERAL] = &ecma_op_general_object_default_value, + * [ECMA_OBJECT_TYPE_CLASS] = &ecma_op_general_object_default_value, * [ECMA_OBJECT_TYPE_FUNCTION] = &ecma_op_general_object_default_value, * [ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION] = &ecma_op_general_object_default_value, * [ECMA_OBJECT_TYPE_ARRAY] = &ecma_op_general_object_default_value, - * [ECMA_OBJECT_TYPE_STRING] = &ecma_op_general_object_default_value, * [ECMA_OBJECT_TYPE_BOUND_FUNCTION] = &ecma_op_general_object_default_value, * [ECMA_OBJECT_TYPE_ARGUMENTS] = &ecma_op_general_object_default_value * }; @@ -864,9 +871,9 @@ ecma_op_object_define_own_property (ecma_object_t *obj_p, /**< the object */ switch (type) { case ECMA_OBJECT_TYPE_GENERAL: + case ECMA_OBJECT_TYPE_CLASS: case ECMA_OBJECT_TYPE_FUNCTION: case ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION: - case ECMA_OBJECT_TYPE_STRING: case ECMA_OBJECT_TYPE_BOUND_FUNCTION: { return ecma_op_general_object_define_own_property (obj_p, @@ -994,8 +1001,8 @@ ecma_op_object_has_instance (ecma_object_t *obj_p, /**< the object */ switch (type) { case ECMA_OBJECT_TYPE_GENERAL: + case ECMA_OBJECT_TYPE_CLASS: case ECMA_OBJECT_TYPE_ARRAY: - case ECMA_OBJECT_TYPE_STRING: case ECMA_OBJECT_TYPE_ARGUMENTS: { return ecma_raise_type_error (ECMA_ERR_MSG ("Expected a function object.")); @@ -1100,6 +1107,14 @@ ecma_op_object_get_property_names (ecma_object_t *obj_p, /**< object */ { switch (type) { + case ECMA_OBJECT_TYPE_GENERAL: + case ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION: + case ECMA_OBJECT_TYPE_ARRAY: + case ECMA_OBJECT_TYPE_BOUND_FUNCTION: + case ECMA_OBJECT_TYPE_ARGUMENTS: + { + break; + } case ECMA_OBJECT_TYPE_FUNCTION: { ecma_op_function_list_lazy_property_names (is_enumerable_only, @@ -1107,22 +1122,17 @@ ecma_op_object_get_property_names (ecma_object_t *obj_p, /**< object */ skipped_non_enumerable_p); break; } - - case ECMA_OBJECT_TYPE_STRING: + case ECMA_OBJECT_TYPE_CLASS: { - ecma_op_string_list_lazy_property_names (obj_p, - is_enumerable_only, - prop_names_p, - skipped_non_enumerable_p); - break; - } + ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) obj_p; - case ECMA_OBJECT_TYPE_GENERAL: - case ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION: - case ECMA_OBJECT_TYPE_ARRAY: - case ECMA_OBJECT_TYPE_BOUND_FUNCTION: - case ECMA_OBJECT_TYPE_ARGUMENTS: - { + if (ext_object_p->u.class_prop.class_id == LIT_MAGIC_STRING_STRING_UL) + { + ecma_op_string_list_lazy_property_names (obj_p, + is_enumerable_only, + prop_names_p, + skipped_non_enumerable_p); + } break; } default: @@ -1413,9 +1423,10 @@ ecma_object_get_class_name (ecma_object_t *obj_p) /**< object */ { return LIT_MAGIC_STRING_ARRAY_UL; } - case ECMA_OBJECT_TYPE_STRING: + case ECMA_OBJECT_TYPE_CLASS: { - return LIT_MAGIC_STRING_STRING_UL; + ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) obj_p; + return ext_object_p->u.class_prop.class_id; } case ECMA_OBJECT_TYPE_ARGUMENTS: { @@ -1441,24 +1452,6 @@ ecma_object_get_class_name (ecma_object_t *obj_p) /**< object */ { return LIT_MAGIC_STRING_OBJECT_UL; } -#ifndef CONFIG_DISABLE_STRING_BUILTIN - case ECMA_BUILTIN_ID_STRING_PROTOTYPE: - { - return LIT_MAGIC_STRING_STRING_UL; - } -#endif /* !CONFIG_DISABLE_STRING_BUILTIN */ -#ifndef CONFIG_DISABLE_BOOLEAN_BUILTIN - case ECMA_BUILTIN_ID_BOOLEAN_PROTOTYPE: - { - return LIT_MAGIC_STRING_BOOLEAN_UL; - } -#endif /* !CONFIG_DISABLE_BOOLEAN_BUILTIN */ -#ifndef CONFIG_DISABLE_NUMBER_BUILTIN - case ECMA_BUILTIN_ID_NUMBER_PROTOTYPE: - { - return LIT_MAGIC_STRING_NUMBER_UL; - } -#endif /* !CONFIG_DISABLE_NUMBER_BUILTIN */ #ifndef CONFIG_DISABLE_MATH_BUILTIN case ECMA_BUILTIN_ID_MATH: { @@ -1483,18 +1476,6 @@ ecma_object_get_class_name (ecma_object_t *obj_p) /**< object */ { return LIT_MAGIC_STRING_ERROR_UL; } -#ifndef CONFIG_DISABLE_DATE_BUILTIN - case ECMA_BUILTIN_ID_DATE_PROTOTYPE: - { - return LIT_MAGIC_STRING_DATE_UL; - } -#endif /* !CONFIG_DISABLE_DATE_BUILTIN */ -#ifndef CONFIG_DISABLE_REGEXP_BUILTIN - case ECMA_BUILTIN_ID_REGEXP_PROTOTYPE: - { - return LIT_MAGIC_STRING_REGEXP_UL; - } -#endif /* !CONFIG_DISABLE_REGEXP_BUILTIN */ default: { JERRY_ASSERT (ecma_builtin_is (obj_p, ECMA_BUILTIN_ID_GLOBAL)); @@ -1505,22 +1486,35 @@ ecma_object_get_class_name (ecma_object_t *obj_p) /**< object */ } else { - ecma_value_t *class_name_prop_p = ecma_find_internal_property (obj_p, - ECMA_INTERNAL_PROPERTY_CLASS); - - if (class_name_prop_p == NULL) - { - return LIT_MAGIC_STRING_OBJECT_UL; - } - else - { - return *class_name_prop_p; - } + return LIT_MAGIC_STRING_OBJECT_UL; } } } } /* ecma_object_get_class_name */ +/** + * Get value of an object if the class matches + * + * @return value of the object if the class matches + * ECMA_SIMPLE_VALUE_NOT_FOUND otherwise + */ +inline bool __attr_always_inline___ +ecma_object_class_is (ecma_object_t *object_p, /**< object */ + uint32_t class_id) /**< class id */ +{ + if (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_CLASS) + { + ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p; + + if (ext_object_p->u.class_prop.class_id == class_id) + { + return true; + } + } + + return false; +} /* ecma_object_class_is */ + /** * @} * @} diff --git a/jerry-core/ecma/operations/ecma-objects.h b/jerry-core/ecma/operations/ecma-objects.h index c65004d9f..a7c51022a 100644 --- a/jerry-core/ecma/operations/ecma-objects.h +++ b/jerry-core/ecma/operations/ecma-objects.h @@ -48,6 +48,7 @@ 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); extern lit_magic_string_id_t ecma_object_get_class_name (ecma_object_t *); +extern bool ecma_object_class_is (ecma_object_t *, uint32_t); /** * @} diff --git a/jerry-core/ecma/operations/ecma-regexp-object.c b/jerry-core/ecma/operations/ecma-regexp-object.c index 0ef78f16e..6eb99bef3 100644 --- a/jerry-core/ecma/operations/ecma-regexp-object.c +++ b/jerry-core/ecma/operations/ecma-regexp-object.c @@ -223,24 +223,27 @@ ecma_op_create_regexp_object_from_bytecode (re_compiled_code_t *bytecode_p) /**< ecma_object_t *re_prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_REGEXP_PROTOTYPE); - ecma_object_t *obj_p = ecma_create_object (re_prototype_obj_p, false, true, ECMA_OBJECT_TYPE_GENERAL); + ecma_object_t *object_p = ecma_create_object (re_prototype_obj_p, + sizeof (ecma_extended_object_t), + ECMA_OBJECT_TYPE_CLASS); + ecma_deref_object (re_prototype_obj_p); + ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p; + /* Set the internal [[Class]] property */ - ecma_value_t *class_prop_p = ecma_create_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_CLASS); - *class_prop_p = LIT_MAGIC_STRING_REGEXP_UL; + ext_object_p->u.class_prop.class_id = LIT_MAGIC_STRING_REGEXP_UL; /* Set bytecode internal property. */ - ecma_value_t *bytecode_prop_p = ecma_create_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_REGEXP_BYTECODE); - ECMA_SET_INTERNAL_VALUE_POINTER (*bytecode_prop_p, bytecode_p); + ECMA_SET_INTERNAL_VALUE_POINTER (ext_object_p->u.class_prop.value, bytecode_p); ecma_bytecode_ref ((ecma_compiled_code_t *) bytecode_p); /* Initialize RegExp object properties */ - re_initialize_props (obj_p, + re_initialize_props (object_p, ECMA_GET_NON_NULL_POINTER (ecma_string_t, bytecode_p->pattern_cp), bytecode_p->header.status_flags); - return ecma_make_object_value (obj_p); + return ecma_make_object_value (object_p); } /* ecma_op_create_regexp_object_from_bytecode */ /** @@ -274,31 +277,32 @@ ecma_op_create_regexp_object (ecma_string_t *pattern_p, /**< input pattern */ ecma_object_t *re_prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_REGEXP_PROTOTYPE); - ecma_object_t *obj_p = ecma_create_object (re_prototype_obj_p, false, true, ECMA_OBJECT_TYPE_GENERAL); + ecma_object_t *object_p = ecma_create_object (re_prototype_obj_p, + sizeof (ecma_extended_object_t), + ECMA_OBJECT_TYPE_CLASS); + ecma_deref_object (re_prototype_obj_p); - /* Set the internal [[Class]] property */ - ecma_value_t *class_prop_p = ecma_create_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_CLASS); - *class_prop_p = LIT_MAGIC_STRING_REGEXP_UL; + ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p; + ext_object_p->u.class_prop.class_id = LIT_MAGIC_STRING_UNDEFINED; - re_initialize_props (obj_p, pattern_p, flags); - - /* Set bytecode internal property. */ - ecma_value_t *bytecode_prop_p = ecma_create_internal_property (obj_p, - ECMA_INTERNAL_PROPERTY_REGEXP_BYTECODE); + re_initialize_props (object_p, pattern_p, flags); /* Compile bytecode. */ const re_compiled_code_t *bc_p = NULL; ECMA_TRY_CATCH (empty, re_compile_bytecode (&bc_p, pattern_p, flags), ret_value); - ECMA_SET_INTERNAL_VALUE_POINTER (*bytecode_prop_p, bc_p); - ret_value = ecma_make_object_value (obj_p); + /* Set [[Class]] and bytecode internal properties. */ + ext_object_p->u.class_prop.class_id = LIT_MAGIC_STRING_REGEXP_UL; + ECMA_SET_INTERNAL_VALUE_POINTER (ext_object_p->u.class_prop.value, bc_p); + + ret_value = ecma_make_object_value (object_p); ECMA_FINALIZE (empty); if (ECMA_IS_VALUE_ERROR (ret_value)) { - ecma_deref_object (obj_p); + ecma_deref_object (object_p); } return ret_value; @@ -1235,11 +1239,11 @@ ecma_regexp_exec_helper (ecma_value_t regexp_value, /**< RegExp object */ ecma_object_t *regexp_object_p = ecma_get_object_from_value (regexp_value); - JERRY_ASSERT (ecma_object_get_class_name (regexp_object_p) == LIT_MAGIC_STRING_REGEXP_UL); + JERRY_ASSERT (ecma_object_class_is (regexp_object_p, LIT_MAGIC_STRING_REGEXP_UL)); - ecma_value_t *bytecode_prop_p = ecma_get_internal_property (regexp_object_p, - ECMA_INTERNAL_PROPERTY_REGEXP_BYTECODE); - re_compiled_code_t *bc_p = ECMA_GET_INTERNAL_VALUE_POINTER (re_compiled_code_t, *bytecode_prop_p); + ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) regexp_object_p; + re_compiled_code_t *bc_p = ECMA_GET_INTERNAL_VALUE_POINTER (re_compiled_code_t, + ext_object_p->u.class_prop.value); if (bc_p == NULL) { diff --git a/jerry-core/ecma/operations/ecma-string-object.c b/jerry-core/ecma/operations/ecma-string-object.c index 7c690adad..81221ea46 100644 --- a/jerry-core/ecma/operations/ecma-string-object.c +++ b/jerry-core/ecma/operations/ecma-string-object.c @@ -76,23 +76,17 @@ ecma_op_create_string_object (const ecma_value_t *arguments_list_p, /**< list of ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE); #endif /* !CONFIG_DISABLE_STRING_BUILTIN */ - ecma_object_t *obj_p = ecma_create_object (prototype_obj_p, - false, - true, - ECMA_OBJECT_TYPE_STRING); + ecma_object_t *object_p = ecma_create_object (prototype_obj_p, + sizeof (ecma_extended_object_t), + ECMA_OBJECT_TYPE_CLASS); + ecma_deref_object (prototype_obj_p); - /* - * [[Class]] property is not stored explicitly for objects of ECMA_OBJECT_TYPE_STRING type. - * - * See also: ecma_object_get_class_name - */ + ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p; + ext_object_p->u.class_prop.class_id = LIT_MAGIC_STRING_STRING_UL; + ext_object_p->u.class_prop.value = ecma_make_string_value (prim_prop_str_value_p); - ecma_value_t *prim_value_prop_p = ecma_create_internal_property (obj_p, - ECMA_INTERNAL_PROPERTY_ECMA_VALUE); - *prim_value_prop_p = ecma_make_string_value (prim_prop_str_value_p); - - return ecma_make_object_value (obj_p); + return ecma_make_object_value (object_p); } /* ecma_op_create_string_object */ /** @@ -116,15 +110,16 @@ ecma_op_string_list_lazy_property_names (ecma_object_t *obj_p, /**< a String obj * collection */ { - JERRY_ASSERT (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_STRING); + JERRY_ASSERT (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_CLASS); ecma_collection_header_t *for_enumerable_p = main_collection_p; ecma_collection_header_t *for_non_enumerable_p = separate_enumerable ? non_enum_collection_p : main_collection_p; - 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); + ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) obj_p; + JERRY_ASSERT (ext_object_p->u.class_prop.class_id == LIT_MAGIC_STRING_STRING_UL); + + ecma_string_t *prim_value_str_p = ecma_get_string_from_value (ext_object_p->u.class_prop.value); ecma_length_t length = ecma_string_get_length (prim_value_str_p); diff --git a/jerry-core/vm/vm.c b/jerry-core/vm/vm.c index 868974995..695f69a14 100644 --- a/jerry-core/vm/vm.c +++ b/jerry-core/vm/vm.c @@ -912,9 +912,9 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ { ecma_object_t *prototype_p = ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE); ecma_object_t *obj_p = ecma_create_object (prototype_p, - false, - true, + 0, ECMA_OBJECT_TYPE_GENERAL); + ecma_deref_object (prototype_p); *stack_top_p++ = ecma_make_object_value (obj_p); continue;