diff --git a/src/libecmaobjects/ecma-gc.c b/src/libecmaobjects/ecma-gc.c index 416c65058..956462c1c 100644 --- a/src/libecmaobjects/ecma-gc.c +++ b/src/libecmaobjects/ecma-gc.c @@ -109,7 +109,7 @@ ecma_gc_get_object_next (ecma_object_t *object_p) /**< object */ { JERRY_ASSERT (object_p != NULL); - JERRY_ASSERT (sizeof (uintptr_t) * JERRY_BITSINBYTE >= ECMA_OBJECT_PROPERTIES_CP_WIDTH); + JERRY_ASSERT (sizeof (uintptr_t) * JERRY_BITSINBYTE >= ECMA_OBJECT_GC_NEXT_CP_WIDTH); uintptr_t next_cp = (uintptr_t) jrt_extract_bit_field (object_p->container, ECMA_OBJECT_GC_NEXT_CP_POS, ECMA_OBJECT_GC_NEXT_CP_WIDTH); @@ -129,7 +129,7 @@ ecma_gc_set_object_next (ecma_object_t *object_p, /**< object */ uintptr_t next_cp; ECMA_SET_POINTER (next_cp, next_object_p); - JERRY_ASSERT (sizeof (uintptr_t) * JERRY_BITSINBYTE >= ECMA_OBJECT_PROPERTIES_CP_WIDTH); + JERRY_ASSERT (sizeof (uintptr_t) * JERRY_BITSINBYTE >= ECMA_OBJECT_GC_NEXT_CP_WIDTH); object_p->container = jrt_set_bit_field_value (object_p->container, next_cp, ECMA_OBJECT_GC_NEXT_CP_POS, @@ -289,6 +289,7 @@ ecma_gc_mark (ecma_object_t *object_p, /**< start object */ ecma_gc_set_object_visited (object_p, true); bool does_reference_object_to_traverse = false; + bool traverse_properties = true; if (ecma_is_lexical_environment (object_p)) { @@ -303,6 +304,22 @@ ecma_gc_mark (ecma_object_t *object_p, /**< start object */ does_reference_object_to_traverse = true; } + + if (ecma_get_lex_env_type (object_p) == ECMA_LEXICAL_ENVIRONMENT_OBJECTBOUND) + { + ecma_object_t *binding_object_p = ecma_get_lex_env_binding_object (object_p); + if (ecma_gc_get_object_generation (binding_object_p) <= maximum_gen_to_traverse) + { + if (!ecma_gc_is_object_visited (binding_object_p)) + { + ecma_gc_mark (binding_object_p, ECMA_GC_GEN_COUNT); + } + + does_reference_object_to_traverse = true; + } + + traverse_properties = false; + } } else { @@ -319,127 +336,128 @@ ecma_gc_mark (ecma_object_t *object_p, /**< start object */ } } - for (ecma_property_t *property_p = ecma_get_property_list (object_p), *next_property_p; - property_p != NULL; - property_p = next_property_p) + if (traverse_properties) { - next_property_p = ECMA_GET_POINTER(property_p->next_property_p); - - switch ((ecma_property_type_t) property_p->type) + for (ecma_property_t *property_p = ecma_get_property_list (object_p), *next_property_p; + property_p != NULL; + property_p = next_property_p) { - case ECMA_PROPERTY_NAMEDDATA: + next_property_p = ECMA_GET_POINTER(property_p->next_property_p); + + switch ((ecma_property_type_t) property_p->type) { - ecma_value_t value = property_p->u.named_data_property.value; - - if (ecma_is_value_object (value)) + case ECMA_PROPERTY_NAMEDDATA: { - ecma_object_t *value_obj_p = ECMA_GET_NON_NULL_POINTER(value.value); + ecma_value_t value = property_p->u.named_data_property.value; - if (ecma_gc_get_object_generation (value_obj_p) <= maximum_gen_to_traverse) + if (ecma_is_value_object (value)) { - if (!ecma_gc_is_object_visited (value_obj_p)) + ecma_object_t *value_obj_p = ECMA_GET_NON_NULL_POINTER(value.value); + + if (ecma_gc_get_object_generation (value_obj_p) <= maximum_gen_to_traverse) { - ecma_gc_mark (value_obj_p, ECMA_GC_GEN_COUNT); - } - - does_reference_object_to_traverse = true; - } - } - - break; - } - - case ECMA_PROPERTY_NAMEDACCESSOR: - { - ecma_object_t *getter_obj_p = ECMA_GET_POINTER(property_p->u.named_accessor_property.get_p); - ecma_object_t *setter_obj_p = ECMA_GET_POINTER(property_p->u.named_accessor_property.set_p); - - if (getter_obj_p != NULL) - { - if (ecma_gc_get_object_generation (getter_obj_p) <= maximum_gen_to_traverse) - { - if (!ecma_gc_is_object_visited (getter_obj_p)) - { - ecma_gc_mark (getter_obj_p, ECMA_GC_GEN_COUNT); - } - - does_reference_object_to_traverse = true; - } - } - - if (setter_obj_p != NULL) - { - if (ecma_gc_get_object_generation (setter_obj_p) <= maximum_gen_to_traverse) - { - if (!ecma_gc_is_object_visited (setter_obj_p)) - { - ecma_gc_mark (setter_obj_p, ECMA_GC_GEN_COUNT); - } - - does_reference_object_to_traverse = true; - } - } - - break; - } - - case ECMA_PROPERTY_INTERNAL: - { - ecma_internal_property_id_t property_id = property_p->u.internal_property.type; - uint32_t property_value = property_p->u.internal_property.value; - - switch (property_id) - { - case ECMA_INTERNAL_PROPERTY_NUMBER_INDEXED_ARRAY_VALUES: /* a collection of ecma-values */ - case ECMA_INTERNAL_PROPERTY_STRING_INDEXED_ARRAY_VALUES: /* a collection of ecma-values */ - { - JERRY_UNIMPLEMENTED("Indexed array storage is not implemented yet."); - } - - case ECMA_INTERNAL_PROPERTY_PROTOTYPE: /* the property's value is located in ecma_object_t - (see above in the routine) */ - case ECMA_INTERNAL_PROPERTY_EXTENSIBLE: /* the property's value is located in ecma_object_t - (see above in the routine) */ - { - JERRY_UNREACHABLE(); - } - - case ECMA_INTERNAL_PROPERTY_FORMAL_PARAMETERS: /* a collection of strings */ - case ECMA_INTERNAL_PROPERTY_PRIMITIVE_STRING_VALUE: /* compressed pointer to a ecma_string_t */ - case ECMA_INTERNAL_PROPERTY_PRIMITIVE_NUMBER_VALUE: /* compressed pointer to a ecma_number_t */ - case ECMA_INTERNAL_PROPERTY_PRIMITIVE_BOOLEAN_VALUE: /* a simple boolean value */ - case ECMA_INTERNAL_PROPERTY_PROVIDE_THIS: /* a boolean */ - case ECMA_INTERNAL_PROPERTY_CLASS: /* an enum */ - case ECMA_INTERNAL_PROPERTY_CODE: /* an integer */ - case ECMA_INTERNAL_PROPERTY_BUILT_IN_ID: /* an integer */ - case ECMA_INTERNAL_PROPERTY_BUILT_IN_ROUTINE_ID: /* an integer */ - case ECMA_INTERNAL_PROPERTY_NON_INSTANTIATED_BUILT_IN_MASK_0_31: /* an integer (bit-mask) */ - case ECMA_INTERNAL_PROPERTY_NON_INSTANTIATED_BUILT_IN_MASK_32_63: /* an integer (bit-mask) */ - { - break; - } - - case ECMA_INTERNAL_PROPERTY_SCOPE: /* a lexical environment */ - case ECMA_INTERNAL_PROPERTY_PARAMETERS_MAP: /* an object */ - case ECMA_INTERNAL_PROPERTY_BINDING_OBJECT: /* an object */ - { - ecma_object_t *obj_p = ECMA_GET_NON_NULL_POINTER(property_value); - - if (ecma_gc_get_object_generation (obj_p) <= maximum_gen_to_traverse) - { - if (!ecma_gc_is_object_visited (obj_p)) + if (!ecma_gc_is_object_visited (value_obj_p)) { - ecma_gc_mark (obj_p, ECMA_GC_GEN_COUNT); + ecma_gc_mark (value_obj_p, ECMA_GC_GEN_COUNT); } does_reference_object_to_traverse = true; } - - break; } + + break; } - break; + case ECMA_PROPERTY_NAMEDACCESSOR: + { + ecma_object_t *getter_obj_p = ECMA_GET_POINTER(property_p->u.named_accessor_property.get_p); + ecma_object_t *setter_obj_p = ECMA_GET_POINTER(property_p->u.named_accessor_property.set_p); + + if (getter_obj_p != NULL) + { + if (ecma_gc_get_object_generation (getter_obj_p) <= maximum_gen_to_traverse) + { + if (!ecma_gc_is_object_visited (getter_obj_p)) + { + ecma_gc_mark (getter_obj_p, ECMA_GC_GEN_COUNT); + } + + does_reference_object_to_traverse = true; + } + } + + if (setter_obj_p != NULL) + { + if (ecma_gc_get_object_generation (setter_obj_p) <= maximum_gen_to_traverse) + { + if (!ecma_gc_is_object_visited (setter_obj_p)) + { + ecma_gc_mark (setter_obj_p, ECMA_GC_GEN_COUNT); + } + + does_reference_object_to_traverse = true; + } + } + + break; + } + + case ECMA_PROPERTY_INTERNAL: + { + ecma_internal_property_id_t property_id = property_p->u.internal_property.type; + uint32_t property_value = property_p->u.internal_property.value; + + switch (property_id) + { + case ECMA_INTERNAL_PROPERTY_NUMBER_INDEXED_ARRAY_VALUES: /* a collection of ecma-values */ + case ECMA_INTERNAL_PROPERTY_STRING_INDEXED_ARRAY_VALUES: /* a collection of ecma-values */ + { + JERRY_UNIMPLEMENTED("Indexed array storage is not implemented yet."); + } + + case ECMA_INTERNAL_PROPERTY_PROTOTYPE: /* the property's value is located in ecma_object_t + (see above in the routine) */ + case ECMA_INTERNAL_PROPERTY_EXTENSIBLE: /* the property's value is located in ecma_object_t + (see above in the routine) */ + { + JERRY_UNREACHABLE(); + } + + case ECMA_INTERNAL_PROPERTY_FORMAL_PARAMETERS: /* a collection of strings */ + case ECMA_INTERNAL_PROPERTY_PRIMITIVE_STRING_VALUE: /* compressed pointer to a ecma_string_t */ + case ECMA_INTERNAL_PROPERTY_PRIMITIVE_NUMBER_VALUE: /* compressed pointer to a ecma_number_t */ + case ECMA_INTERNAL_PROPERTY_PRIMITIVE_BOOLEAN_VALUE: /* a simple boolean value */ + case ECMA_INTERNAL_PROPERTY_CLASS: /* an enum */ + case ECMA_INTERNAL_PROPERTY_CODE: /* an integer */ + case ECMA_INTERNAL_PROPERTY_BUILT_IN_ID: /* an integer */ + case ECMA_INTERNAL_PROPERTY_BUILT_IN_ROUTINE_ID: /* an integer */ + case ECMA_INTERNAL_PROPERTY_NON_INSTANTIATED_BUILT_IN_MASK_0_31: /* an integer (bit-mask) */ + case ECMA_INTERNAL_PROPERTY_NON_INSTANTIATED_BUILT_IN_MASK_32_63: /* an integer (bit-mask) */ + { + break; + } + + case ECMA_INTERNAL_PROPERTY_SCOPE: /* a lexical environment */ + case ECMA_INTERNAL_PROPERTY_PARAMETERS_MAP: /* an object */ + { + ecma_object_t *obj_p = ECMA_GET_NON_NULL_POINTER(property_value); + + if (ecma_gc_get_object_generation (obj_p) <= maximum_gen_to_traverse) + { + if (!ecma_gc_is_object_visited (obj_p)) + { + ecma_gc_mark (obj_p, ECMA_GC_GEN_COUNT); + } + + does_reference_object_to_traverse = true; + } + + break; + } + } + + break; + } } } } @@ -460,14 +478,17 @@ ecma_gc_sweep (ecma_object_t *object_p) /**< object to free */ && !ecma_gc_is_object_visited (object_p) && ecma_gc_get_object_refs (object_p) == 0); - for (ecma_property_t *property = ecma_get_property_list (object_p), - *next_property_p; - property != NULL; - property = next_property_p) + if (!ecma_is_lexical_environment (object_p) || + ecma_get_lex_env_type (object_p) != ECMA_LEXICAL_ENVIRONMENT_OBJECTBOUND) { - next_property_p = ECMA_GET_POINTER(property->next_property_p); + for (ecma_property_t *property = ecma_get_property_list (object_p), *next_property_p; + property != NULL; + property = next_property_p) + { + next_property_p = ECMA_GET_POINTER(property->next_property_p); - ecma_free_property (object_p, property); + ecma_free_property (object_p, property); + } } ecma_dealloc_object (object_p); diff --git a/src/libecmaobjects/ecma-globals.h b/src/libecmaobjects/ecma-globals.h index 61d300602..5dc47796e 100644 --- a/src/libecmaobjects/ecma-globals.h +++ b/src/libecmaobjects/ecma-globals.h @@ -187,12 +187,6 @@ typedef enum ECMA_INTERNAL_PROPERTY_PRIMITIVE_NUMBER_VALUE, /**< [[Primitive value]] for Number objects */ ECMA_INTERNAL_PROPERTY_PRIMITIVE_BOOLEAN_VALUE, /**< [[Primitive value]] for Boolean objects */ - /** provideThis property of lexical environment */ - ECMA_INTERNAL_PROPERTY_PROVIDE_THIS, - - /** binding object of lexical environment */ - ECMA_INTERNAL_PROPERTY_BINDING_OBJECT, - /** Part of an array, that is indexed by numbers */ ECMA_INTERNAL_PROPERTY_NUMBER_INDEXED_ARRAY_VALUES, @@ -354,15 +348,15 @@ typedef struct /** * Compressed pointer to property list */ -#define ECMA_OBJECT_PROPERTIES_CP_POS (0) -#define ECMA_OBJECT_PROPERTIES_CP_WIDTH (ECMA_POINTER_FIELD_WIDTH) +#define ECMA_OBJECT_PROPERTIES_OR_BOUND_OBJECT_CP_POS (0) +#define ECMA_OBJECT_PROPERTIES_OR_BOUND_OBJECT_CP_WIDTH (ECMA_POINTER_FIELD_WIDTH) /** * Flag indicating whether it is a general object (false) * or a lexical environment (true) */ -#define ECMA_OBJECT_IS_LEXICAL_ENVIRONMENT_POS (ECMA_OBJECT_PROPERTIES_CP_POS + \ - ECMA_OBJECT_PROPERTIES_CP_WIDTH) +#define ECMA_OBJECT_IS_LEXICAL_ENVIRONMENT_POS (ECMA_OBJECT_PROPERTIES_OR_BOUND_OBJECT_CP_POS + \ + ECMA_OBJECT_PROPERTIES_OR_BOUND_OBJECT_CP_WIDTH) #define ECMA_OBJECT_IS_LEXICAL_ENVIRONMENT_WIDTH (1) /** @@ -455,11 +449,18 @@ typedef struct ECMA_OBJECT_LEX_ENV_TYPE_WIDTH) #define ECMA_OBJECT_LEX_ENV_OUTER_REFERENCE_CP_WIDTH (ECMA_POINTER_FIELD_WIDTH) +/** + * 'provideThis' property of object-bound lexical environments + */ +#define ECMA_OBJECT_LEX_ENV_PROVIDE_THIS_POS (ECMA_OBJECT_LEX_ENV_OUTER_REFERENCE_CP_POS + \ + ECMA_OBJECT_LEX_ENV_OUTER_REFERENCE_CP_WIDTH) +#define ECMA_OBJECT_LEX_ENV_PROVIDE_THIS_WIDTH (1) + /** * Size of structure for lexical environments */ -#define ECMA_OBJECT_LEX_ENV_TYPE_SIZE (ECMA_OBJECT_LEX_ENV_OUTER_REFERENCE_CP_POS + \ - ECMA_OBJECT_LEX_ENV_OUTER_REFERENCE_CP_WIDTH) +#define ECMA_OBJECT_LEX_ENV_TYPE_SIZE (ECMA_OBJECT_LEX_ENV_PROVIDE_THIS_POS + \ + ECMA_OBJECT_LEX_ENV_PROVIDE_THIS_WIDTH) uint64_t container; /**< container for fields described above */ } ecma_object_t; diff --git a/src/libecmaobjects/ecma-helpers.c b/src/libecmaobjects/ecma-helpers.c index e3a030698..763b55bd0 100644 --- a/src/libecmaobjects/ecma-helpers.c +++ b/src/libecmaobjects/ecma-helpers.c @@ -46,8 +46,8 @@ ecma_create_object (ecma_object_t *prototype_object_p, /**< pointer to prototybe object_p->container = jrt_set_bit_field_value (object_p->container, ECMA_NULL_POINTER, - ECMA_OBJECT_PROPERTIES_CP_POS, - ECMA_OBJECT_PROPERTIES_CP_WIDTH); + ECMA_OBJECT_PROPERTIES_OR_BOUND_OBJECT_CP_POS, + ECMA_OBJECT_PROPERTIES_OR_BOUND_OBJECT_CP_WIDTH); object_p->container = jrt_set_bit_field_value (object_p->container, false, ECMA_OBJECT_IS_LEXICAL_ENVIRONMENT_POS, @@ -92,8 +92,8 @@ ecma_create_decl_lex_env (ecma_object_t *outer_lexical_environment_p) /**< outer new_lexical_environment_p->container = jrt_set_bit_field_value (new_lexical_environment_p->container, ECMA_NULL_POINTER, - ECMA_OBJECT_PROPERTIES_CP_POS, - ECMA_OBJECT_PROPERTIES_CP_WIDTH); + ECMA_OBJECT_PROPERTIES_OR_BOUND_OBJECT_CP_POS, + ECMA_OBJECT_PROPERTIES_OR_BOUND_OBJECT_CP_WIDTH); new_lexical_environment_p->container = jrt_set_bit_field_value (new_lexical_environment_p->container, true, ECMA_OBJECT_IS_LEXICAL_ENVIRONMENT_POS, @@ -135,10 +135,6 @@ ecma_create_object_lex_env (ecma_object_t *outer_lexical_environment_p, /**< out ecma_object_t *new_lexical_environment_p = ecma_alloc_object (); ecma_init_gc_info (new_lexical_environment_p); - new_lexical_environment_p->container = jrt_set_bit_field_value (new_lexical_environment_p->container, - ECMA_NULL_POINTER, - ECMA_OBJECT_PROPERTIES_CP_POS, - ECMA_OBJECT_PROPERTIES_CP_WIDTH); new_lexical_environment_p->container = jrt_set_bit_field_value (new_lexical_environment_p->container, true, ECMA_OBJECT_IS_LEXICAL_ENVIRONMENT_POS, @@ -156,13 +152,17 @@ ecma_create_object_lex_env (ecma_object_t *outer_lexical_environment_p, /**< out ECMA_OBJECT_LEX_ENV_OUTER_REFERENCE_CP_POS, ECMA_OBJECT_LEX_ENV_OUTER_REFERENCE_CP_WIDTH); - ecma_property_t *provide_this_prop_p = ecma_create_internal_property (new_lexical_environment_p, - ECMA_INTERNAL_PROPERTY_PROVIDE_THIS); - provide_this_prop_p->u.internal_property.value = provide_this; + new_lexical_environment_p->container = jrt_set_bit_field_value (new_lexical_environment_p->container, + provide_this, + ECMA_OBJECT_LEX_ENV_PROVIDE_THIS_POS, + ECMA_OBJECT_LEX_ENV_PROVIDE_THIS_WIDTH); - ecma_property_t *binding_object_prop_p = ecma_create_internal_property (new_lexical_environment_p, - ECMA_INTERNAL_PROPERTY_BINDING_OBJECT); - ECMA_SET_POINTER(binding_object_prop_p->u.internal_property.value, binding_obj_p); + uint64_t bound_object_cp; + ECMA_SET_NON_NULL_POINTER (bound_object_cp, binding_obj_p); + new_lexical_environment_p->container = jrt_set_bit_field_value (new_lexical_environment_p->container, + bound_object_cp, + ECMA_OBJECT_PROPERTIES_OR_BOUND_OBJECT_CP_POS, + ECMA_OBJECT_PROPERTIES_OR_BOUND_OBJECT_CP_WIDTH); ecma_gc_update_may_ref_younger_object_flag_by_object (new_lexical_environment_p, binding_obj_p); return new_lexical_environment_p; @@ -250,7 +250,7 @@ ecma_get_object_prototype (const ecma_object_t *object_p) /**< object */ JERRY_ASSERT (object_p != NULL); JERRY_ASSERT (!ecma_is_lexical_environment (object_p)); - JERRY_ASSERT (sizeof (uintptr_t) * JERRY_BITSINBYTE >= ECMA_OBJECT_PROPERTIES_CP_WIDTH); + JERRY_ASSERT (sizeof (uintptr_t) * JERRY_BITSINBYTE >= ECMA_OBJECT_OBJ_PROTOTYPE_OBJECT_CP_WIDTH); uintptr_t prototype_object_cp = (uintptr_t) jrt_extract_bit_field (object_p->container, ECMA_OBJECT_OBJ_PROTOTYPE_OBJECT_CP_POS, ECMA_OBJECT_OBJ_PROTOTYPE_OBJECT_CP_WIDTH); @@ -322,7 +322,7 @@ ecma_get_lex_env_outer_reference (const ecma_object_t *object_p) /**< lexical en JERRY_ASSERT (object_p != NULL); JERRY_ASSERT (ecma_is_lexical_environment (object_p)); - JERRY_ASSERT (sizeof (uintptr_t) * JERRY_BITSINBYTE >= ECMA_OBJECT_PROPERTIES_CP_WIDTH); + JERRY_ASSERT (sizeof (uintptr_t) * JERRY_BITSINBYTE >= ECMA_OBJECT_LEX_ENV_OUTER_REFERENCE_CP_WIDTH); uintptr_t outer_reference_cp = (uintptr_t) jrt_extract_bit_field (object_p->container, ECMA_OBJECT_LEX_ENV_OUTER_REFERENCE_CP_POS, ECMA_OBJECT_LEX_ENV_OUTER_REFERENCE_CP_WIDTH); @@ -336,11 +336,13 @@ ecma_property_t* __attribute_pure__ ecma_get_property_list (const ecma_object_t *object_p) /**< object or lexical environment */ { JERRY_ASSERT (object_p != NULL); + JERRY_ASSERT (!ecma_is_lexical_environment (object_p) || + ecma_get_lex_env_type (object_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE); - JERRY_ASSERT (sizeof (uintptr_t) * JERRY_BITSINBYTE >= ECMA_OBJECT_PROPERTIES_CP_WIDTH); + JERRY_ASSERT (sizeof (uintptr_t) * JERRY_BITSINBYTE >= ECMA_OBJECT_PROPERTIES_OR_BOUND_OBJECT_CP_WIDTH); uintptr_t properties_cp = (uintptr_t) jrt_extract_bit_field (object_p->container, - ECMA_OBJECT_PROPERTIES_CP_POS, - ECMA_OBJECT_PROPERTIES_CP_WIDTH); + ECMA_OBJECT_PROPERTIES_OR_BOUND_OBJECT_CP_POS, + ECMA_OBJECT_PROPERTIES_OR_BOUND_OBJECT_CP_WIDTH); return ECMA_GET_POINTER (properties_cp); } /* ecma_get_property_list */ @@ -352,16 +354,53 @@ ecma_set_property_list (ecma_object_t *object_p, /**< object or lexical environm ecma_property_t *property_list_p) /**< properties' list */ { JERRY_ASSERT (object_p != NULL); + JERRY_ASSERT (!ecma_is_lexical_environment (object_p) || + ecma_get_lex_env_type (object_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE); uint64_t properties_cp; ECMA_SET_POINTER (properties_cp, property_list_p); object_p->container = jrt_set_bit_field_value (object_p->container, properties_cp, - ECMA_OBJECT_PROPERTIES_CP_POS, - ECMA_OBJECT_PROPERTIES_CP_WIDTH); + ECMA_OBJECT_PROPERTIES_OR_BOUND_OBJECT_CP_POS, + ECMA_OBJECT_PROPERTIES_OR_BOUND_OBJECT_CP_WIDTH); } /* ecma_set_property_list */ +/** + * Get lexical environment's 'provideThis' property + */ +bool __attribute_pure__ +ecma_get_lex_env_provide_this (const ecma_object_t *object_p) /**< object-bound lexical environment */ +{ + JERRY_ASSERT (object_p != NULL); + JERRY_ASSERT (ecma_is_lexical_environment (object_p) && + ecma_get_lex_env_type (object_p) == ECMA_LEXICAL_ENVIRONMENT_OBJECTBOUND); + + JERRY_ASSERT (sizeof (uintptr_t) * JERRY_BITSINBYTE >= ECMA_OBJECT_PROPERTIES_OR_BOUND_OBJECT_CP_WIDTH); + bool provide_this = (jrt_extract_bit_field (object_p->container, + ECMA_OBJECT_LEX_ENV_PROVIDE_THIS_POS, + ECMA_OBJECT_LEX_ENV_PROVIDE_THIS_WIDTH) != 0); + + return provide_this; +} /* ecma_get_lex_env_provide_this */ + +/** + * Get lexical environment's bound object. + */ +ecma_object_t* __attribute_pure__ +ecma_get_lex_env_binding_object (const ecma_object_t *object_p) /**< object-bound lexical environment */ +{ + JERRY_ASSERT (object_p != NULL); + JERRY_ASSERT (ecma_is_lexical_environment (object_p) && + ecma_get_lex_env_type (object_p) == ECMA_LEXICAL_ENVIRONMENT_OBJECTBOUND); + + JERRY_ASSERT (sizeof (uintptr_t) * JERRY_BITSINBYTE >= ECMA_OBJECT_PROPERTIES_OR_BOUND_OBJECT_CP_WIDTH); + uintptr_t object_cp = (uintptr_t) jrt_extract_bit_field (object_p->container, + ECMA_OBJECT_PROPERTIES_OR_BOUND_OBJECT_CP_POS, + ECMA_OBJECT_PROPERTIES_OR_BOUND_OBJECT_CP_WIDTH); + return ECMA_GET_NON_NULL_POINTER (object_cp); +} /* ecma_get_lex_env_binding_object */ + /** * Create internal property in an object and link it into * the object's properties' linked-list (at start of the list). @@ -690,10 +729,8 @@ ecma_free_internal_property (ecma_property_t *property_p) /**< the property */ case ECMA_INTERNAL_PROPERTY_PRIMITIVE_BOOLEAN_VALUE: /* a simple boolean value */ case ECMA_INTERNAL_PROPERTY_SCOPE: /* a lexical environment */ case ECMA_INTERNAL_PROPERTY_PARAMETERS_MAP: /* an object */ - case ECMA_INTERNAL_PROPERTY_BINDING_OBJECT: /* an object */ case ECMA_INTERNAL_PROPERTY_PROTOTYPE: /* the property's value is located in ecma_object_t */ case ECMA_INTERNAL_PROPERTY_EXTENSIBLE: /* the property's value is located in ecma_object_t */ - case ECMA_INTERNAL_PROPERTY_PROVIDE_THIS: /* a boolean */ case ECMA_INTERNAL_PROPERTY_CLASS: /* an enum */ case ECMA_INTERNAL_PROPERTY_CODE: /* an integer */ case ECMA_INTERNAL_PROPERTY_BUILT_IN_ID: /* an integer */ diff --git a/src/libecmaobjects/ecma-helpers.h b/src/libecmaobjects/ecma-helpers.h index 4a1855176..d87876417 100644 --- a/src/libecmaobjects/ecma-helpers.h +++ b/src/libecmaobjects/ecma-helpers.h @@ -227,6 +227,8 @@ extern void ecma_set_object_is_builtin (ecma_object_t *object_p, extern ecma_lexical_environment_type_t __attribute_pure__ ecma_get_lex_env_type (const ecma_object_t *object_p); extern ecma_object_t* __attribute_pure__ ecma_get_lex_env_outer_reference (const ecma_object_t *object_p); extern ecma_property_t* __attribute_pure__ ecma_get_property_list (const ecma_object_t *object_p); +extern ecma_object_t* __attribute_pure__ ecma_get_lex_env_binding_object (const ecma_object_t *object_p); +extern bool __attribute_pure__ ecma_get_lex_env_provide_this (const ecma_object_t *object_p); extern ecma_property_t* ecma_create_internal_property (ecma_object_t *object_p, ecma_internal_property_id_t property_id); diff --git a/src/libecmaoperations/ecma-lex-env.c b/src/libecmaoperations/ecma-lex-env.c index e5c41ea00..5044b9c13 100644 --- a/src/libecmaoperations/ecma-lex-env.c +++ b/src/libecmaoperations/ecma-lex-env.c @@ -31,25 +31,6 @@ * @{ */ -/** - * Get binding object of object lexical environment. - * - * @return pointer to binding object - */ -static ecma_object_t* -ecma_get_lex_env_binding_object (ecma_object_t* obj_lex_env_p) /**< object lexical environment */ -{ - JERRY_ASSERT(obj_lex_env_p != NULL - && ecma_is_lexical_environment (obj_lex_env_p) - && ecma_get_lex_env_type (obj_lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_OBJECTBOUND); - - ecma_property_t *binding_obj_prop_p = ecma_get_property_list (obj_lex_env_p); - JERRY_ASSERT(binding_obj_prop_p != NULL - && binding_obj_prop_p->u.internal_property.type == ECMA_INTERNAL_PROPERTY_BINDING_OBJECT); - - return ECMA_GET_NON_NULL_POINTER (binding_obj_prop_p->u.internal_property.value); -} /* ecma_get_lex_env_binding_object */ - /** * HasBinding operation. * @@ -408,12 +389,7 @@ ecma_op_implicit_this_value (ecma_object_t *lex_env_p) /**< lexical environment } case ECMA_LEXICAL_ENVIRONMENT_OBJECTBOUND: { - ecma_property_t *provide_this_prop_p = ecma_get_internal_property (lex_env_p, - ECMA_INTERNAL_PROPERTY_PROVIDE_THIS); - - bool provide_this = provide_this_prop_p->u.internal_property.value; - - if (provide_this) + if (ecma_get_lex_env_provide_this (lex_env_p)) { ecma_object_t *binding_obj_p = ecma_get_lex_env_binding_object (lex_env_p); ecma_ref_object (binding_obj_p);