Rework arguments object. (#1401)

Instead of allocating a helper object, argument names are appended right
after the arguments objects. This reduces memory consumption and improve
performance as well. In the future this could be further improved by a
bitfield, but that would require a reference to the byte code which
might increase memory consumption in a few corner cases.

JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
Zoltan Herczeg
2016-10-21 11:58:42 +02:00
committed by yichoi
parent 3e0d3e588f
commit c8f2747209
6 changed files with 237 additions and 268 deletions
+37 -7
View File
@@ -247,8 +247,6 @@ ecma_gc_mark_property (ecma_property_t *property_p) /**< property */
}
case ECMA_INTERNAL_PROPERTY_BOUND_FUNCTION_TARGET_FUNCTION: /* an object */
case ECMA_INTERNAL_PROPERTY_SCOPE: /* a lexical environment */
case ECMA_INTERNAL_PROPERTY_PARAMETERS_MAP: /* an object */
{
ecma_object_t *obj_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t, property_value);
@@ -308,8 +306,17 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */
ecma_gc_set_object_visited (proto_p, true);
}
if (!ecma_get_object_is_builtin (object_p)
&& ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_FUNCTION)
if (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_ARGUMENTS)
{
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p;
ecma_object_t *lex_env_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t,
ext_object_p->u.arguments.lex_env_cp);
ecma_gc_set_object_visited (lex_env_p, true);
}
else if (!ecma_get_object_is_builtin (object_p)
&& ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_FUNCTION)
{
ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) object_p;
@@ -436,7 +443,9 @@ 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_object_type_t object_type = ecma_get_object_type (object_p);
if (object_type == ECMA_OBJECT_TYPE_CLASS)
{
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p;
@@ -491,13 +500,13 @@ ecma_gc_sweep (ecma_object_t *object_p) /**< object to free */
}
if (ecma_get_object_is_builtin (object_p)
|| ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION)
|| object_type == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION)
{
ecma_dealloc_extended_object ((ecma_extended_object_t *) object_p, sizeof (ecma_extended_object_t));
return;
}
if (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_FUNCTION)
if (object_type == ECMA_OBJECT_TYPE_FUNCTION)
{
/* Function with byte-code (not a built-in function). */
ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) object_p;
@@ -508,6 +517,27 @@ ecma_gc_sweep (ecma_object_t *object_p) /**< object to free */
ecma_dealloc_extended_object (ext_func_p, sizeof (ecma_extended_object_t));
return;
}
if (object_type == ECMA_OBJECT_TYPE_ARGUMENTS)
{
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p;
ecma_length_t formal_params_number = ext_object_p->u.arguments.length;
jmem_cpointer_t *arg_Literal_p = (jmem_cpointer_t *) (ext_object_p + 1);
for (ecma_length_t i = 0; i < formal_params_number; i++)
{
if (arg_Literal_p[i] != JMEM_CP_NULL)
{
ecma_string_t *name_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t, arg_Literal_p[i]);
ecma_deref_ecma_string (name_p);
}
}
size_t formal_params_size = formal_params_number * sizeof (jmem_cpointer_t);
ecma_dealloc_extended_object (ext_object_p, sizeof (ecma_extended_object_t) + formal_params_size);
return;
}
}
ecma_dealloc_object (object_p);
+9 -3
View File
@@ -197,9 +197,6 @@ typedef uintptr_t ecma_external_pointer_t;
*/
typedef enum
{
ECMA_INTERNAL_PROPERTY_SCOPE, /**< [[Scope]] */
ECMA_INTERNAL_PROPERTY_PARAMETERS_MAP, /**< [[ParametersMap]] */
ECMA_INTERNAL_PROPERTY_NATIVE_HANDLE, /**< native handle associated with an object */
ECMA_INTERNAL_PROPERTY_FREE_CALLBACK, /**< object's native free callback */
@@ -606,6 +603,15 @@ typedef struct
ecma_value_t bytecode_cp; /**< function byte code */
} function;
/*
* Description of arguments objects.
*/
struct
{
ecma_value_t lex_env_cp; /**< lexical environment */
uint32_t length; /**< length of names */
} arguments;
ecma_external_pointer_t external_function; /**< external function */
} u;
} ecma_extended_object_t;
-2
View File
@@ -783,8 +783,6 @@ ecma_free_internal_property (ecma_property_t *property_p) /**< the property */
break;
}
case ECMA_INTERNAL_PROPERTY_SCOPE: /* a lexical environment */
case ECMA_INTERNAL_PROPERTY_PARAMETERS_MAP: /* an object */
case ECMA_INTERNAL_PROPERTY_INSTANTIATED_MASK_32_63: /* an integer (bit-mask) */
case ECMA_INTERNAL_PROPERTY_BOUND_FUNCTION_TARGET_FUNCTION:
{
@@ -71,16 +71,36 @@ ecma_op_create_arguments_object (ecma_object_t *func_obj_p, /**< callee function
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;
if (class_not_required)
if (!is_strict && arguments_number > 0 && formal_params_number > 0)
{
obj_p = ecma_create_object (prototype_p, 0, ECMA_OBJECT_TYPE_GENERAL);
size_t formal_params_size = formal_params_number * sizeof (jmem_cpointer_t);
obj_p = ecma_create_object (prototype_p,
sizeof (ecma_extended_object_t) + formal_params_size,
ECMA_OBJECT_TYPE_ARGUMENTS);
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) obj_p;
ECMA_SET_INTERNAL_VALUE_POINTER (ext_object_p->u.arguments.lex_env_cp, lex_env_p);
ext_object_p->u.arguments.length = formal_params_number;
jmem_cpointer_t *arg_Literal_p = (jmem_cpointer_t *) (ext_object_p + 1);
memcpy (arg_Literal_p, literal_p, formal_params_size);
for (ecma_length_t i = 0; i < formal_params_number; i++)
{
if (arg_Literal_p[i] != JMEM_CP_NULL)
{
ecma_string_t *name_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t, arg_Literal_p[i]);
ecma_ref_ecma_string (name_p);
}
}
}
else
{
@@ -92,104 +112,50 @@ ecma_op_create_arguments_object (ecma_object_t *func_obj_p, /**< callee function
ecma_deref_object (prototype_p);
ecma_property_value_t *prop_value_p;
// 11.a, 11.b
for (ecma_length_t indx = 0;
indx < arguments_number;
indx++)
{
ecma_value_t completion;
ecma_string_t *indx_string_p = ecma_new_ecma_string_from_uint32 (indx);
completion = ecma_builtin_helper_def_prop (obj_p,
indx_string_p,
arguments_list_p[indx],
true, /* Writable */
true, /* Enumerable */
true, /* Configurable */
false); /* Failure handling */
prop_value_p = ecma_create_named_data_property (obj_p,
indx_string_p,
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE,
NULL);
JERRY_ASSERT (ecma_is_value_true (completion));
prop_value_p->value = ecma_copy_value_if_not_object (arguments_list_p[indx]);
ecma_deref_ecma_string (indx_string_p);
}
// 7.
ecma_string_t *length_magic_string_p = ecma_new_ecma_length_string ();
ecma_value_t completion = ecma_builtin_helper_def_prop (obj_p,
length_magic_string_p,
ecma_make_uint32_value (arguments_number),
true, /* Writable */
false, /* Enumerable */
true, /* Configurable */
false); /* Failure handling */
JERRY_ASSERT (ecma_is_value_true (completion));
prop_value_p = ecma_create_named_data_property (obj_p,
length_magic_string_p,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE,
NULL);
prop_value_p->value = ecma_make_uint32_value (arguments_number);
ecma_deref_ecma_string (length_magic_string_p);
ecma_property_descriptor_t prop_desc = ecma_make_empty_property_descriptor ();
if (class_not_required)
{
// 8.
ecma_object_t *map_p = ecma_op_create_object_object_noarg ();
// 11.c
for (uint32_t indx = 0;
indx < formal_params_number;
indx++)
{
// i.
if (literal_p[indx] == JMEM_CP_NULL)
{
continue;
}
ecma_string_t *name_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t, literal_p[indx]);
ecma_string_t *indx_string_p = ecma_new_ecma_string_from_uint32 ((uint32_t) indx);
prop_desc.is_value_defined = true;
prop_desc.value = ecma_make_string_value (name_p);
prop_desc.is_configurable_defined = true;
prop_desc.is_configurable = true;
completion = ecma_op_object_define_own_property (map_p,
indx_string_p,
&prop_desc,
false);
JERRY_ASSERT (ecma_is_value_true (completion));
ecma_deref_ecma_string (indx_string_p);
}
// 12.
ecma_set_object_type (obj_p, ECMA_OBJECT_TYPE_ARGUMENTS);
ecma_value_t *parameters_map_prop_p = ecma_create_internal_property (obj_p,
ECMA_INTERNAL_PROPERTY_PARAMETERS_MAP);
ECMA_SET_INTERNAL_VALUE_POINTER (*parameters_map_prop_p, map_p);
ecma_value_t *scope_prop_p = ecma_create_internal_property (map_p,
ECMA_INTERNAL_PROPERTY_SCOPE);
ECMA_SET_INTERNAL_VALUE_POINTER (*scope_prop_p, lex_env_p);
ecma_deref_object (map_p);
}
// 13.
if (!is_strict)
{
ecma_string_t *callee_magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_CALLEE);
completion = ecma_builtin_helper_def_prop (obj_p,
callee_magic_string_p,
ecma_make_object_value (func_obj_p),
true, /* Writable */
false, /* Enumerable */
true, /* Configurable */
false); /* Failure handling */
prop_value_p = ecma_create_named_data_property (obj_p,
callee_magic_string_p,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE,
NULL);
JERRY_ASSERT (ecma_is_value_true (completion));
prop_value_p->value = ecma_make_object_value (func_obj_p);
ecma_deref_ecma_string (callee_magic_string_p);
}
@@ -215,10 +181,11 @@ ecma_op_create_arguments_object (ecma_object_t *func_obj_p, /**< callee function
ecma_string_t *callee_magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_CALLEE);
completion = ecma_op_object_define_own_property (obj_p,
callee_magic_string_p,
&prop_desc,
false);
ecma_value_t completion = ecma_op_object_define_own_property (obj_p,
callee_magic_string_p,
&prop_desc,
false);
JERRY_ASSERT (ecma_is_value_true (completion));
ecma_deref_ecma_string (callee_magic_string_p);
@@ -260,53 +227,6 @@ ecma_op_create_arguments_object (ecma_object_t *func_obj_p, /**< callee function
ecma_deref_object (obj_p);
} /* ecma_op_create_arguments_object */
/**
* Get value of function's argument mapped to index of Arguments object.
*
* Note:
* The procedure emulates execution of function described by MakeArgGetter
*
* @return ecma value
* Returned value must be freed with ecma_free_value
*/
void
ecma_arguments_update_mapped_arg_value (ecma_object_t *object_p, /**< the object */
ecma_string_t *property_name_p, /**< property name */
ecma_property_t *property_p) /**< property value */
{
ecma_value_t *map_prop_p = ecma_get_internal_property (object_p, ECMA_INTERNAL_PROPERTY_PARAMETERS_MAP);
ecma_object_t *map_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t, *map_prop_p);
ecma_value_t arg_name = ecma_op_object_find (map_p, property_name_p);
if (!ecma_is_value_found (arg_name))
{
return;
}
ecma_value_t *scope_prop_p = ecma_get_internal_property (map_p, ECMA_INTERNAL_PROPERTY_SCOPE);
ecma_object_t *lex_env_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t, *scope_prop_p);
JERRY_ASSERT (lex_env_p != NULL
&& ecma_is_lexical_environment (lex_env_p));
ecma_string_t *arg_name_p = ecma_get_string_from_value (arg_name);
ecma_value_t value = ecma_op_get_binding_value (lex_env_p, arg_name_p, true);
ecma_deref_ecma_string (arg_name_p);
JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (value));
ecma_named_data_property_assign_value (object_p, ECMA_PROPERTY_VALUE_PTR (property_p), value);
ecma_free_value (value);
/* These properties cannot be cached. This is a temporary
* workaround until the property management is fully rewritten. */
if (ecma_is_property_lcached (property_p))
{
ecma_lcache_invalidate (object_p, property_name_p, property_p);
}
} /* ecma_arguments_update_mapped_arg_value */
/**
* [[DefineOwnProperty]] ecma Arguments object's operation
*
@@ -318,84 +238,75 @@ ecma_arguments_update_mapped_arg_value (ecma_object_t *object_p, /**< the object
* Returned value must be freed with ecma_free_value
*/
ecma_value_t
ecma_op_arguments_object_define_own_property (ecma_object_t *obj_p, /**< the object */
ecma_op_arguments_object_define_own_property (ecma_object_t *object_p, /**< the object */
ecma_string_t *property_name_p, /**< property name */
const ecma_property_descriptor_t *property_desc_p, /**< property
* descriptor */
bool is_throw) /**< flag that controls failure handling */
{
// 1.
ecma_value_t *map_prop_p = ecma_get_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_PARAMETERS_MAP);
ecma_object_t *map_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t, *map_prop_p);
// 3.
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
ecma_value_t ret_value = ecma_op_general_object_define_own_property (object_p,
property_name_p,
property_desc_p,
is_throw);
ECMA_TRY_CATCH (defined,
ecma_op_general_object_define_own_property (obj_p,
property_name_p,
property_desc_p,
is_throw),
ret_value);
// 5.
if (ecma_op_object_has_own_property (map_p, property_name_p))
if (ECMA_IS_VALUE_ERROR (ret_value))
{
// a.
if (property_desc_p->is_get_defined
|| property_desc_p->is_set_defined)
{
ecma_value_t completion = ecma_op_object_delete (map_p, property_name_p, false);
return ret_value;
}
JERRY_ASSERT (ecma_is_value_true (completion));
uint32_t index;
// 6.
ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_TRUE);
}
else
{
// b.
if (!ecma_string_get_array_index (property_name_p, &index))
{
return ret_value;
}
ecma_value_t completion = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p;
// i.
if (property_desc_p->is_value_defined)
{
/* emulating execution of function described by MakeArgSetter */
ecma_value_t *scope_prop_p = ecma_get_internal_property (map_p, ECMA_INTERNAL_PROPERTY_SCOPE);
ecma_object_t *lex_env_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t, *scope_prop_p);
if (index >= ext_object_p->u.arguments.length)
{
return ret_value;
}
ecma_property_value_t *arg_name_value_p = ecma_get_named_data_property (map_p, property_name_p);
jmem_cpointer_t *arg_Literal_p = (jmem_cpointer_t *) (ext_object_p + 1);
completion = ecma_op_set_mutable_binding (lex_env_p,
ecma_get_string_from_value (arg_name_value_p->value),
property_desc_p->value,
true);
if (arg_Literal_p[index] == JMEM_CP_NULL)
{
return ret_value;
}
JERRY_ASSERT (ecma_is_value_empty (completion));
}
ecma_string_t *name_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t, arg_Literal_p[index]);
// ii.
if (property_desc_p->is_writable_defined
&& !property_desc_p->is_writable)
{
completion = ecma_op_object_delete (map_p,
property_name_p,
false);
JERRY_ASSERT (ecma_is_value_true (completion));
}
// 6.
ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_TRUE);
}
if (property_desc_p->is_get_defined
|| property_desc_p->is_set_defined)
{
ecma_deref_ecma_string (name_p);
arg_Literal_p[index] = JMEM_CP_NULL;
}
else
{
ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_TRUE);
}
if (property_desc_p->is_value_defined)
{
/* emulating execution of function described by MakeArgSetter */
ecma_object_t *lex_env_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t,
ext_object_p->u.arguments.lex_env_cp);
ECMA_FINALIZE (defined);
ecma_value_t completion = ecma_op_set_mutable_binding (lex_env_p,
name_p,
property_desc_p->value,
true);
JERRY_ASSERT (ecma_is_value_empty (completion));
}
if (property_desc_p->is_writable_defined
&& !property_desc_p->is_writable)
{
ecma_deref_ecma_string (name_p);
arg_Literal_p[index] = JMEM_CP_NULL;
}
}
return ret_value;
} /* ecma_op_arguments_object_define_own_property */
@@ -411,41 +322,43 @@ ecma_op_arguments_object_define_own_property (ecma_object_t *obj_p, /**< the obj
* Returned value must be freed with ecma_free_value
*/
ecma_value_t
ecma_op_arguments_object_delete (ecma_object_t *obj_p, /**< the object */
ecma_op_arguments_object_delete (ecma_object_t *object_p, /**< the object */
ecma_string_t *property_name_p, /**< property name */
bool is_throw) /**< flag that controls failure handling */
{
// 1.
ecma_value_t *map_prop_p = ecma_get_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_PARAMETERS_MAP);
ecma_object_t *map_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t, *map_prop_p);
// 3.
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
ecma_value_t ret_value = ecma_op_general_object_delete (object_p, property_name_p, is_throw);
ECMA_TRY_CATCH (delete_in_args_ret,
ecma_op_general_object_delete (obj_p,
property_name_p,
is_throw),
ret_value);
if (ecma_is_value_true (delete_in_args_ret))
if (ECMA_IS_VALUE_ERROR (ret_value))
{
if (ecma_op_object_has_own_property (map_p, property_name_p))
return ret_value;
}
JERRY_ASSERT (ecma_is_value_boolean (ret_value));
if (ecma_is_value_true (ret_value))
{
uint32_t index;
if (ecma_string_get_array_index (property_name_p, &index))
{
ecma_value_t delete_in_map_completion = ecma_op_object_delete (map_p, property_name_p, false);
JERRY_ASSERT (ecma_is_value_true (delete_in_map_completion));
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p;
if (index < ext_object_p->u.arguments.length)
{
jmem_cpointer_t *arg_Literal_p = (jmem_cpointer_t *) (ext_object_p + 1);
if (arg_Literal_p[index] != JMEM_CP_NULL)
{
ecma_string_t *name_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t, arg_Literal_p[index]);
ecma_deref_ecma_string (name_p);
arg_Literal_p[index] = JMEM_CP_NULL;
}
}
}
ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_TRUE);
}
else
{
JERRY_ASSERT (ecma_is_value_boolean (delete_in_args_ret));
ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_FALSE);
}
ECMA_FINALIZE (delete_in_args_ret);
return ret_value;
} /* ecma_op_arguments_object_delete */
@@ -23,8 +23,6 @@ extern void
ecma_op_create_arguments_object (ecma_object_t *, ecma_object_t *, const ecma_value_t *,
ecma_length_t, const ecma_compiled_code_t *);
extern void
ecma_arguments_update_mapped_arg_value (ecma_object_t *, ecma_string_t *, ecma_property_t *);
extern ecma_value_t
ecma_op_arguments_object_delete (ecma_object_t *, ecma_string_t *, bool);
extern ecma_value_t
+67 -43
View File
@@ -170,29 +170,38 @@ ecma_op_object_get_own_property (ecma_object_t *object_p, /**< the object */
return ECMA_PROPERTY_TYPE_NOT_FOUND;
}
}
else if (type == ECMA_OBJECT_TYPE_ARGUMENTS)
else if (type == ECMA_OBJECT_TYPE_ARGUMENTS
&& property_ref_p != NULL)
{
ecma_value_t *map_prop_p = ecma_get_internal_property (object_p, ECMA_INTERNAL_PROPERTY_PARAMETERS_MAP);
ecma_object_t *map_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t, *map_prop_p);
uint32_t index;
ecma_value_t arg_name = ecma_op_object_find_own (*map_prop_p, map_p, property_name_p);
if (ecma_is_value_found (arg_name))
if (ecma_string_get_array_index (property_name_p, &index))
{
ecma_value_t *scope_prop_p = ecma_get_internal_property (map_p, ECMA_INTERNAL_PROPERTY_SCOPE);
ecma_object_t *lex_env_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t, *scope_prop_p);
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p;
JERRY_ASSERT (lex_env_p != NULL
&& ecma_is_lexical_environment (lex_env_p));
if (index < ext_object_p->u.arguments.length)
{
jmem_cpointer_t *arg_Literal_p = (jmem_cpointer_t *) (ext_object_p + 1);
ecma_string_t *arg_name_p = ecma_get_string_from_value (arg_name);
ecma_value_t binding_value = ecma_op_get_binding_value (lex_env_p, arg_name_p, true);
ecma_deref_ecma_string (arg_name_p);
if (arg_Literal_p[index] != JMEM_CP_NULL)
{
ecma_string_t *arg_name_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t,
arg_Literal_p[index]);
ecma_named_data_property_assign_value (object_p,
ECMA_PROPERTY_VALUE_PTR (property_p),
binding_value);
ecma_free_value (binding_value);
ecma_object_t *lex_env_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t,
ext_object_p->u.arguments.lex_env_cp);
JERRY_ASSERT (lex_env_p != NULL
&& ecma_is_lexical_environment (lex_env_p));
ecma_value_t binding_value = ecma_op_get_binding_value (lex_env_p, arg_name_p, true);
ecma_named_data_property_assign_value (object_p,
ECMA_PROPERTY_VALUE_PTR (property_p),
binding_value);
ecma_free_value (binding_value);
}
}
}
}
@@ -307,23 +316,30 @@ ecma_op_object_find_own (ecma_value_t base_value, /**< base value */
if (unlikely (type == ECMA_OBJECT_TYPE_ARGUMENTS))
{
ecma_value_t *map_prop_p = ecma_get_internal_property (object_p, ECMA_INTERNAL_PROPERTY_PARAMETERS_MAP);
ecma_object_t *map_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t, *map_prop_p);
uint32_t index;
ecma_value_t arg_name = ecma_op_object_find_own (*map_prop_p, map_p, property_name_p);
if (ecma_is_value_found (arg_name))
if (ecma_string_get_array_index (property_name_p, &index))
{
ecma_value_t *scope_prop_p = ecma_get_internal_property (map_p, ECMA_INTERNAL_PROPERTY_SCOPE);
ecma_object_t *lex_env_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t, *scope_prop_p);
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p;
JERRY_ASSERT (lex_env_p != NULL
&& ecma_is_lexical_environment (lex_env_p));
if (index < ext_object_p->u.arguments.length)
{
jmem_cpointer_t *arg_Literal_p = (jmem_cpointer_t *) (ext_object_p + 1);
ecma_string_t *arg_name_p = ecma_get_string_from_value (arg_name);
ecma_value_t result = ecma_op_get_binding_value (lex_env_p, arg_name_p, true);
ecma_deref_ecma_string (arg_name_p);
return result;
if (arg_Literal_p[index] != JMEM_CP_NULL)
{
ecma_string_t *arg_name_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t,
arg_Literal_p[index]);
ecma_object_t *lex_env_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t,
ext_object_p->u.arguments.lex_env_cp);
JERRY_ASSERT (lex_env_p != NULL
&& ecma_is_lexical_environment (lex_env_p));
return ecma_op_get_binding_value (lex_env_p, arg_name_p, true);
}
}
}
}
@@ -562,23 +578,31 @@ ecma_op_object_put (ecma_object_t *object_p, /**< the object */
if (type == ECMA_OBJECT_TYPE_ARGUMENTS)
{
ecma_value_t *map_prop_p = ecma_get_internal_property (object_p, ECMA_INTERNAL_PROPERTY_PARAMETERS_MAP);
ecma_object_t *map_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t, *map_prop_p);
uint32_t index;
ecma_value_t arg_name = ecma_op_object_find_own (*map_prop_p, map_p, property_name_p);
if (ecma_is_value_found (arg_name))
if (ecma_string_get_array_index (property_name_p, &index))
{
ecma_value_t *scope_prop_p = ecma_get_internal_property (map_p, ECMA_INTERNAL_PROPERTY_SCOPE);
ecma_object_t *lex_env_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t, *scope_prop_p);
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p;
JERRY_ASSERT (lex_env_p != NULL
&& ecma_is_lexical_environment (lex_env_p));
if (index < ext_object_p->u.arguments.length)
{
jmem_cpointer_t *arg_Literal_p = (jmem_cpointer_t *) (ext_object_p + 1);
ecma_string_t *arg_name_p = ecma_get_string_from_value (arg_name);
ecma_op_set_mutable_binding (lex_env_p, arg_name_p, value, true);
ecma_deref_ecma_string (arg_name_p);
return ecma_make_simple_value (ECMA_SIMPLE_VALUE_TRUE);
if (arg_Literal_p[index] != JMEM_CP_NULL)
{
ecma_string_t *arg_name_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t,
arg_Literal_p[index]);
ecma_object_t *lex_env_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t,
ext_object_p->u.arguments.lex_env_cp);
JERRY_ASSERT (lex_env_p != NULL
&& ecma_is_lexical_environment (lex_env_p));
ecma_op_set_mutable_binding (lex_env_p, arg_name_p, value, true);
return ecma_make_simple_value (ECMA_SIMPLE_VALUE_TRUE);
}
}
}
}