Skip to content

Instantiation of Arguments object #102

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
May 29, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
199 changes: 140 additions & 59 deletions jerry-core/ecma/operations/ecma-function-object.cpp

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions jerry-core/ecma/operations/ecma-function-object.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ ecma_op_create_function_object (ecma_string_t* formal_parameter_list_p[],
ecma_length_t formal_parameters_number,
ecma_object_t *scope_p,
bool is_strict,
bool do_instantiate_arguments_object,
opcode_counter_t first_opcode_idx);
extern ecma_object_t*
ecma_op_create_external_function_object (ecma_external_pointer_t code_p);
Expand All @@ -60,6 +61,7 @@ ecma_op_function_declaration (ecma_object_t *lex_env_p,
ecma_string_t* formal_parameter_list_p[],
ecma_length_t formal_parameter_list_length,
bool is_strict,
bool do_instantiate_arguments_object,
bool is_configurable_bindings);

/**
Expand Down
194 changes: 106 additions & 88 deletions jerry-core/ecma/operations/ecma-objects-arguments.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,13 @@
* @return pointer to newly created Arguments object
*/
ecma_object_t*
ecma_create_arguments_object (ecma_object_t *func_obj_p, /**< callee function */
ecma_object_t *lex_env_p, /**< lexical environment the Arguments
object is created for */
ecma_collection_iterator_t *formal_params_iter_p, /**< formal parameters
collection iterator */
const ecma_value_t *arguments_list_p, /**< list of arguments */
ecma_length_t arguments_list_length, /**< length of arguments' list */
bool is_strict) /**< flag indicating whether strict mode is enabled */
ecma_op_create_arguments_object (ecma_object_t *func_obj_p, /**< callee function */
ecma_object_t *lex_env_p, /**< lexical environment the Arguments
object is created for */
ecma_collection_header_t *formal_params_p, /**< formal parameters collection */
const ecma_value_t *arguments_list_p, /**< list of arguments */
ecma_length_t arguments_list_length, /**< length of arguments' list */
bool is_strict) /**< flag indicating whether strict mode is enabled */
{
// 1.
ecma_number_t *len_p = ecma_alloc_number ();
Expand Down Expand Up @@ -110,7 +109,7 @@ ecma_create_arguments_object (ecma_object_t *func_obj_p, /**< callee function */
prop_desc.is_configurable = true;
}

ecma_string_t *indx_string_p = ecma_new_ecma_string_from_number (ecma_uint32_to_number (indx));
ecma_string_t *indx_string_p = ecma_new_ecma_string_from_uint32 (indx);

completion = ecma_op_object_define_own_property (obj_p,
indx_string_p,
Expand All @@ -121,84 +120,96 @@ ecma_create_arguments_object (ecma_object_t *func_obj_p, /**< callee function */
ecma_deref_ecma_string (indx_string_p);
}

const ecma_length_t formal_params_number = formal_params_iter_p->header_p->unit_number;
if (!is_strict
&& arguments_list_length > 0
&& formal_params_number > 0)
if (formal_params_p != NULL)
{
// 8.
ecma_object_t *map_p = ecma_op_create_object_object_noarg ();
const ecma_length_t formal_params_number = formal_params_p->unit_number;

// 11.c
MEM_DEFINE_LOCAL_ARRAY (formal_params, formal_params_number, ecma_string_t *);
ecma_collection_iterator_t formal_params_iterator;
ecma_collection_iterator_init (&formal_params_iterator, formal_params_p);

JERRY_ASSERT (formal_params_iter_p->current_value_p == NULL);
uint32_t param_index;
for (param_index = 0;
ecma_collection_iterator_next (formal_params_iter_p);
param_index++)
if (!is_strict
&& arguments_list_length > 0
&& formal_params_number > 0)
{
JERRY_ASSERT (formal_params_iter_p->current_value_p != NULL);
JERRY_ASSERT (param_index < formal_params_number);
// 8.
ecma_object_t *map_p = ecma_op_create_object_object_noarg ();

JERRY_ASSERT (ecma_is_value_string (*formal_params_iter_p->current_value_p));
formal_params[param_index] = ecma_get_string_from_value (*formal_params_iter_p->current_value_p);
}
JERRY_ASSERT (param_index == formal_params_number);
// 11.c
MEM_DEFINE_LOCAL_ARRAY (formal_params, formal_params_number, ecma_string_t *);

for (int32_t indx = formal_params_number - 1;
indx >= 0;
indx--)
{
// i.
ecma_string_t *name_p = formal_params[indx];
bool is_first_occurence = true;

// ii.
for (int32_t indx2 = indx + 1;
indx2 < formal_params_number;
indx2++)
JERRY_ASSERT (formal_params_iterator.current_value_p == NULL);
uint32_t param_index;
for (param_index = 0;
ecma_collection_iterator_next (&formal_params_iterator);
param_index++)
{
if (ecma_compare_ecma_strings (name_p, formal_params[indx2]))
{
is_first_occurence = false;
}
JERRY_ASSERT (formal_params_iterator.current_value_p != NULL);
JERRY_ASSERT (param_index < formal_params_number);

JERRY_ASSERT (ecma_is_value_string (*formal_params_iterator.current_value_p));
formal_params[param_index] = ecma_get_string_from_value (*formal_params_iterator.current_value_p);
}
JERRY_ASSERT (param_index == formal_params_number);

if (is_first_occurence)
for (int32_t indx = formal_params_number - 1;
indx >= 0;
indx--)
{
ecma_string_t *indx_string_p = ecma_new_ecma_string_from_number (ecma_uint32_to_number ((uint32_t) indx));
// i.
ecma_string_t *name_p = formal_params[indx];
bool is_first_occurence = true;

prop_desc = ecma_make_empty_property_descriptor ();
// ii.
for (int32_t indx2 = indx + 1;
indx2 < formal_params_number;
indx2++)
{
prop_desc.is_value_defined = true;
prop_desc.value = ecma_make_string_value (name_p);
if (ecma_compare_ecma_strings (name_p, formal_params[indx2]))
{
is_first_occurence = false;

break;
}
}

completion = ecma_op_object_define_own_property (map_p,
indx_string_p,
&prop_desc,
false);
JERRY_ASSERT (ecma_is_completion_value_normal_true (completion));
if (is_first_occurence)
{
ecma_string_t *indx_string_p = ecma_new_ecma_string_from_uint32 ((uint32_t) indx);

prop_desc = ecma_make_empty_property_descriptor ();
{
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;
}

ecma_deref_ecma_string (indx_string_p);
completion = ecma_op_object_define_own_property (map_p,
indx_string_p,
&prop_desc,
false);
JERRY_ASSERT (ecma_is_completion_value_normal_true (completion));

ecma_deref_ecma_string (indx_string_p);
}
}
}

MEM_FINALIZE_LOCAL_ARRAY (formal_params);
MEM_FINALIZE_LOCAL_ARRAY (formal_params);

// 12.
ecma_set_object_type (obj_p, ECMA_OBJECT_TYPE_ARGUMENTS);
// 12.
ecma_set_object_type (obj_p, ECMA_OBJECT_TYPE_ARGUMENTS);

ecma_property_t *parameters_map_prop_p = ecma_create_internal_property (obj_p,
ECMA_INTERNAL_PROPERTY_PARAMETERS_MAP);
ECMA_SET_POINTER (parameters_map_prop_p->u.internal_property.value, map_p);
ecma_property_t *parameters_map_prop_p = ecma_create_internal_property (obj_p,
ECMA_INTERNAL_PROPERTY_PARAMETERS_MAP);
ECMA_SET_POINTER (parameters_map_prop_p->u.internal_property.value, map_p);

ecma_property_t *scope_prop_p = ecma_create_internal_property (map_p,
ECMA_INTERNAL_PROPERTY_SCOPE);
ECMA_SET_POINTER (scope_prop_p->u.internal_property.value, lex_env_p);
ecma_property_t *scope_prop_p = ecma_create_internal_property (map_p,
ECMA_INTERNAL_PROPERTY_SCOPE);
ECMA_SET_POINTER (scope_prop_p->u.internal_property.value, lex_env_p);

ecma_deref_object (map_p);
ecma_deref_object (map_p);
}
}

// 13.
Expand Down Expand Up @@ -264,11 +275,14 @@ ecma_create_arguments_object (ecma_object_t *func_obj_p, /**< callee function */
}

return obj_p;
} /* ecma_create_arguments_object */
} /* 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 completion value
* Returned value must be freed with ecma_free_completion_value
*/
Expand Down Expand Up @@ -437,32 +451,36 @@ ecma_op_arguments_object_define_own_property (ecma_object_t *obj_p, /**< the obj
// i.
if (property_desc_p->is_value_defined)
{
completion = ecma_op_object_put (map_p,
property_name_p,
property_desc_p->value,
is_throw);
}
/* emulating execution of function described by MakeArgSetter */
ecma_property_t *scope_prop_p = ecma_get_internal_property (map_p, ECMA_INTERNAL_PROPERTY_SCOPE);
ecma_object_t *lex_env_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t,
scope_prop_p->u.internal_property.value);

if (unlikely (ecma_is_completion_value_throw (completion)))
{
ret_value = completion;
ecma_property_t *mapped_prop_p = ecma_op_object_get_own_property (map_p, property_name_p);
ecma_value_t arg_name_prop_value = ecma_get_named_data_property_value (mapped_prop_p);

ecma_string_t *arg_name_p = ecma_get_string_from_value (arg_name_prop_value);

completion = ecma_op_set_mutable_binding (lex_env_p,
arg_name_p,
property_desc_p->value,
true);
JERRY_ASSERT (ecma_is_completion_value_empty (completion));
}
else
{
// 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_completion_value_normal_true (completion));
}
// ii.
if (property_desc_p->is_writable_defined
&& !property_desc_p->is_writable)
{
completion = ecma_op_object_delete (map_p,
property_name_p,
false);

// 6.
ret_value = ecma_make_simple_completion_value (ECMA_SIMPLE_VALUE_TRUE);
JERRY_ASSERT (ecma_is_completion_value_normal_true (completion));
}

// 6.
ret_value = ecma_make_simple_completion_value (ECMA_SIMPLE_VALUE_TRUE);
}
}
else
Expand Down
12 changes: 6 additions & 6 deletions jerry-core/ecma/operations/ecma-objects-arguments.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@
#include "ecma-helpers.h"

extern ecma_object_t*
ecma_create_arguments_object (ecma_object_t *func_obj_p,
ecma_object_t *lex_env_p,
ecma_collection_iterator_t *formal_params_iter_p,
const ecma_value_t *arguments_list_p,
ecma_length_t arguments_list_length,
bool is_strict);
ecma_op_create_arguments_object (ecma_object_t *func_obj_p,
ecma_object_t *lex_env_p,
ecma_collection_header_t *formal_params_p,
const ecma_value_t *arguments_list_p,
ecma_length_t arguments_list_length,
bool is_strict);

extern ecma_completion_value_t ecma_op_arguments_object_get (ecma_object_t *obj_p,
ecma_string_t *property_name_p);
Expand Down
4 changes: 2 additions & 2 deletions jerry-core/jerry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1225,7 +1225,7 @@ jerry_parse (const char* source_p, /**< script source */

bool is_show_mem_stats_per_opcode = ((jerry_flags & JERRY_FLAG_MEM_STATS_PER_OPCODE) != 0);

init_int (opcodes, is_show_mem_stats_per_opcode);
vm_init (opcodes, is_show_mem_stats_per_opcode);

return true;
} /* jerry_parse */
Expand All @@ -1240,7 +1240,7 @@ jerry_run (void)
{
jerry_assert_api_available ();

return run_int ();
return vm_run_global ();
} /* jerry_run */
/**
* Simple jerry runner
Expand Down
22 changes: 19 additions & 3 deletions jerry-core/parser/js/opcodes-dumper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2383,11 +2383,27 @@ dump_variable_declaration (literal_index_t lit_id)
serializer_dump_op_meta (create_op_meta_100 (opcode, lit_id));
}

void
dump_strict_mode_header (void)
opcode_counter_t
dump_scope_code_flags_for_rewrite (void)
{
const opcode_t opcode = getop_meta (OPCODE_META_TYPE_STRICT_CODE, INVALID_VALUE, INVALID_VALUE);
opcode_counter_t oc = serializer_get_current_opcode_counter ();

const opcode_t opcode = getop_meta (OPCODE_META_TYPE_SCOPE_CODE_FLAGS, INVALID_VALUE, INVALID_VALUE);
serializer_dump_op_meta (create_op_meta_000 (opcode));

return oc;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing /* dump_scope_code_flags_for_rewrite */


void
rewrite_scope_code_flags (opcode_counter_t scope_code_flags_oc,
opcode_scope_code_flags_t scope_flags)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing comments on parameters and about the method.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I'll add.
Unfortunately, in the component the style was not used before.
However, maybe, it is better to update the component step by step, fixing style in it.

{
JERRY_ASSERT ((idx_t) scope_flags == scope_flags);

op_meta opm = serializer_get_op_meta (scope_code_flags_oc);
JERRY_ASSERT (opm.op.op_idx == OPCODE (meta));
opm.op.data.meta.data_1 = (idx_t) scope_flags;
serializer_rewrite_op_meta (scope_code_flags_oc, opm);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing /* rewrite_scope_code_flags */


void
Expand Down
4 changes: 3 additions & 1 deletion jerry-core/parser/js/opcodes-dumper.h
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,9 @@ void dump_throw (operand);
bool dumper_variable_declaration_exists (literal_index_t);
void dump_variable_declaration (literal_index_t);

void dump_strict_mode_header (void);
opcode_counter_t dump_scope_code_flags_for_rewrite (void);
void rewrite_scope_code_flags (opcode_counter_t scope_code_flags_oc,
opcode_scope_code_flags_t scope_flags);

void dump_reg_var_decl_for_rewrite (void);
void rewrite_reg_var_decl (void);
Expand Down
Loading