Storing provideThis flag and pointer to binding object immediately in descriptor of object-bound lexical environment.

This commit is contained in:
Ruben Ayrapetyan 2014-11-21 20:31:39 +03:00
parent 958126f5c8
commit 5b8077b976
5 changed files with 211 additions and 174 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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 */

View File

@ -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);

View File

@ -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);