Replacing 'this_arg' meta opcode with more general 'call site additional information' meta opcode with flags describing the call site features, and, optionally, 'this' argument.

Introducing opcode_call_flags_t for argument of the new meta opcode, currently with two flags: 'have this argument' and '"direct call to eval" form'.

JerryScript-DCO-1.0-Signed-off-by: Ruben Ayrapetyan r.ayrapetyan@samsung.com
This commit is contained in:
Ruben Ayrapetyan
2015-06-10 21:47:09 +03:00
parent 6fadcd3f84
commit 446e8bf989
7 changed files with 149 additions and 49 deletions
+15 -19
View File
@@ -653,44 +653,40 @@ opfunc_call_n (opcode_t opdata, /**< operation data */
int_data->pos++;
bool this_arg_var_idx_set = false;
idx_t this_arg_var_idx = INVALID_VALUE;
idx_t args_number;
opcode_call_flags_t call_flags = OPCODE_CALL_FLAGS__EMPTY;
opcode_t next_opcode = vm_get_opcode (int_data->opcodes_p, int_data->pos);
if (next_opcode.op_idx == __op__idx_meta
&& next_opcode.data.meta.type == OPCODE_META_TYPE_THIS_ARG)
&& next_opcode.data.meta.type == OPCODE_META_TYPE_CALL_SITE_INFO)
{
this_arg_var_idx = next_opcode.data.meta.data_1;
JERRY_ASSERT (is_reg_variable (int_data, this_arg_var_idx));
call_flags = (opcode_call_flags_t) next_opcode.data.meta.data_1;
this_arg_var_idx_set = true;
JERRY_ASSERT (args_number_idx > 0);
args_number = (idx_t) (args_number_idx - 1);
if (call_flags & OPCODE_CALL_FLAGS_HAVE_THIS_ARG)
{
this_arg_var_idx = next_opcode.data.meta.data_2;
JERRY_ASSERT (is_reg_variable (int_data, this_arg_var_idx));
}
int_data->pos++;
}
else
{
args_number = args_number_idx;
}
MEM_DEFINE_LOCAL_ARRAY (arg_values, args_number, ecma_value_t);
MEM_DEFINE_LOCAL_ARRAY (arg_values, args_number_idx, ecma_value_t);
ecma_length_t args_read;
ecma_completion_value_t get_arg_completion = fill_varg_list (int_data,
args_number,
args_number_idx,
arg_values,
&args_read);
if (ecma_is_completion_value_empty (get_arg_completion))
{
JERRY_ASSERT (args_read == args_number);
JERRY_ASSERT (args_read == args_number_idx);
ecma_completion_value_t get_this_completion_value;
if (this_arg_var_idx_set)
if (call_flags & OPCODE_CALL_FLAGS_HAVE_THIS_ARG)
{
get_this_completion_value = get_variable_value (int_data, this_arg_var_idx, false);
}
@@ -714,7 +710,7 @@ opfunc_call_n (opcode_t opdata, /**< operation data */
ecma_op_function_call (func_obj_p,
this_value,
arg_values,
args_number),
args_number_idx),
ret_value);
ret_value = set_variable_value (int_data, lit_oc,
@@ -1680,7 +1676,7 @@ opfunc_meta (opcode_t opdata, /**< operation data */
case OPCODE_META_TYPE_SCOPE_CODE_FLAGS:
case OPCODE_META_TYPE_UNDEFINED:
case OPCODE_META_TYPE_THIS_ARG:
case OPCODE_META_TYPE_CALL_SITE_INFO:
case OPCODE_META_TYPE_FUNCTION_END:
case OPCODE_META_TYPE_CATCH_EXCEPTION_IDENTIFIER:
{
+13 -1
View File
@@ -59,7 +59,8 @@ typedef enum
typedef enum
{
OPCODE_META_TYPE_UNDEFINED, /**< undefined meta (should be rewritten) */
OPCODE_META_TYPE_THIS_ARG, /**< value (var_idx) of this used during call */
OPCODE_META_TYPE_CALL_SITE_INFO, /**< optional additional information about call site
* (includes opcode_call_flags_t and can include 'this' argument) */
OPCODE_META_TYPE_VARG, /**< element (var_idx) of arguments' list */
OPCODE_META_TYPE_VARG_PROP_DATA, /**< name (lit_idx) and value (var_idx) for a data property descriptor */
OPCODE_META_TYPE_VARG_PROP_GETTER, /**< name (lit_idx) and getter (var_idx) for an accessor property descriptor */
@@ -74,6 +75,17 @@ typedef enum
* (See also: opcode_scope_code_flags_t) */
} opcode_meta_type;
typedef enum : idx_t
{
OPCODE_CALL_FLAGS__EMPTY = (0u), /**< initializer for empty flag set */
OPCODE_CALL_FLAGS_HAVE_THIS_ARG = (1u << 0), /**< flag, indicating that call is performed
* with 'this' argument specified */
OPCODE_CALL_FLAGS_DIRECT_CALL_TO_EVAL_FORM = (1u << 1) /**< flag, indicating that call is performed
* in form 'eval (...)', i.e. through 'eval' string
* without object base (i.e. with lexical environment
* as base), so it can be a direct call to eval */
} opcode_call_flags_t;
/**
* Flags indicating various properties of a scope's code
*/
+22 -13
View File
@@ -266,15 +266,9 @@ pp_op_meta (opcode_counter_t oc, op_meta opm, bool rewrite)
}
case NAME_TO_ID (call_n):
{
if (opm.op.data.call_n.arg_list == 0)
{
pp_printf ("%s = %s ();", opm.op, opm.lit_id, oc, 1);
}
else
{
vargs_num = opm.op.data.call_n.arg_list;
seen_vargs = 0;
}
vargs_num = opm.op.data.call_n.arg_list;
seen_vargs = 0;
break;
}
case NAME_TO_ID (native_call):
@@ -381,13 +375,17 @@ pp_op_meta (opcode_counter_t oc, op_meta opm, bool rewrite)
printf ("unknown meta;");
break;
}
case OPCODE_META_TYPE_THIS_ARG:
case OPCODE_META_TYPE_CALL_SITE_INFO:
case OPCODE_META_TYPE_VARG:
case OPCODE_META_TYPE_VARG_PROP_DATA:
case OPCODE_META_TYPE_VARG_PROP_GETTER:
case OPCODE_META_TYPE_VARG_PROP_SETTER:
{
seen_vargs++;
if (opm.op.data.meta.type != OPCODE_META_TYPE_CALL_SITE_INFO)
{
seen_vargs++;
}
if (seen_vargs == vargs_num)
{
bool found = false;
@@ -473,15 +471,26 @@ pp_op_meta (opcode_counter_t oc, op_meta opm, bool rewrite)
for (opcode_counter_t counter = start; counter <= oc; counter++)
{
opcode_t meta_op = serializer_get_opcode (counter);
switch (meta_op.op_idx)
{
case NAME_TO_ID (meta):
{
switch (meta_op.data.meta.type)
{
case OPCODE_META_TYPE_THIS_ARG:
case OPCODE_META_TYPE_CALL_SITE_INFO:
{
pp_printf ("this_arg = %s", meta_op, NULL, counter, 2);
opcode_call_flags_t call_flags = (opcode_call_flags_t) meta_op.data.meta.data_1;
if (call_flags & OPCODE_CALL_FLAGS_HAVE_THIS_ARG)
{
pp_printf ("this_arg = %s", meta_op, NULL, counter, 3);
}
if (call_flags & OPCODE_CALL_FLAGS_DIRECT_CALL_TO_EVAL_FORM)
{
printf ("['direct call to eval' form]");
}
break;
}
case OPCODE_META_TYPE_VARG: