Support of multiple bytecode arrays in interpreter and ecma-runtime.

JerryScript-DCO-1.0-Signed-off-by: Ruben Ayrapetyan r.ayrapetyan@samsung.com
This commit is contained in:
Ruben Ayrapetyan 2015-06-09 21:14:08 +03:00
parent 3577261261
commit 8ea0e23ea3
10 changed files with 65 additions and 38 deletions

View File

@ -320,7 +320,8 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */
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_CODE_BYTECODE: /* compressed pointer to a bytecode array */
case ECMA_INTERNAL_PROPERTY_CODE_FLAGS_AND_OFFSET: /* an integer */
case ECMA_INTERNAL_PROPERTY_NATIVE_CODE: /* an external pointer */
case ECMA_INTERNAL_PROPERTY_NATIVE_HANDLE: /* an external pointer */
case ECMA_INTERNAL_PROPERTY_FREE_CALLBACK: /* an object's native free callback */

View File

@ -217,7 +217,9 @@ typedef enum
ECMA_INTERNAL_PROPERTY_EXTENSIBLE, /**< [[Extensible]] */
ECMA_INTERNAL_PROPERTY_SCOPE, /**< [[Scope]] */
ECMA_INTERNAL_PROPERTY_PARAMETERS_MAP, /**< [[ParametersMap]] */
ECMA_INTERNAL_PROPERTY_CODE, /**< [[Code]] */
ECMA_INTERNAL_PROPERTY_CODE_BYTECODE, /**< first part of [[Code]] - compressed pointer to bytecode array */
ECMA_INTERNAL_PROPERTY_CODE_FLAGS_AND_OFFSET, /**< second part of [[Code]] - offset in bytecode array and code flags
* (see also: ecma_pack_code_internal_property_value) */
ECMA_INTERNAL_PROPERTY_NATIVE_CODE, /**< native handler location descriptor */
ECMA_INTERNAL_PROPERTY_NATIVE_HANDLE, /**< native handle associated with an object */
ECMA_INTERNAL_PROPERTY_FREE_CALLBACK, /**< object's native free callback */

View File

@ -793,7 +793,8 @@ ecma_free_internal_property (ecma_property_t *property_p) /**< the property */
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_CLASS: /* an enum */
case ECMA_INTERNAL_PROPERTY_CODE: /* an integer */
case ECMA_INTERNAL_PROPERTY_CODE_BYTECODE: /* compressed pointer to a bytecode array */
case ECMA_INTERNAL_PROPERTY_CODE_FLAGS_AND_OFFSET: /* 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_EXTENSION_ID: /* an integer */

View File

@ -157,7 +157,8 @@ ecma_op_create_function_object (ecma_string_t* formal_parameter_list_p[], /**< f
bool is_strict, /**< 'strict' flag */
bool do_instantiate_arguments_object, /**< should an Arguments object be instantiated
* for the function object upon call */
opcode_counter_t first_opcode_idx) /**< index of first opcode of function's body */
const opcode_t *opcodes_p, /**< byte-code array */
opcode_counter_t first_opcode_index) /**< index of first opcode of function's body */
{
// 1., 4., 13.
ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE);
@ -199,10 +200,13 @@ ecma_op_create_function_object (ecma_string_t* formal_parameter_list_p[], /**< f
}
// 12.
ecma_property_t *code_prop_p = ecma_create_internal_property (f, ECMA_INTERNAL_PROPERTY_CODE);
ecma_property_t *opcodes_prop_p = ecma_create_internal_property (f, ECMA_INTERNAL_PROPERTY_CODE_BYTECODE);
MEM_CP_SET_NON_NULL_POINTER (opcodes_prop_p->u.internal_property.value, opcodes_p);
ecma_property_t *code_prop_p = ecma_create_internal_property (f, ECMA_INTERNAL_PROPERTY_CODE_FLAGS_AND_OFFSET);
code_prop_p->u.internal_property.value = ecma_pack_code_internal_property_value (is_strict,
do_instantiate_arguments_object,
first_opcode_idx);
first_opcode_index);
// 14.
ecma_number_t* len_p = ecma_alloc_number ();
@ -612,15 +616,18 @@ ecma_op_function_call (ecma_object_t *func_obj_p, /**< Function object */
{
/* Entering Function Code (ECMA-262 v5, 10.4.3) */
ecma_property_t *scope_prop_p = ecma_get_internal_property (func_obj_p, ECMA_INTERNAL_PROPERTY_SCOPE);
ecma_property_t *code_prop_p = ecma_get_internal_property (func_obj_p, ECMA_INTERNAL_PROPERTY_CODE);
ecma_property_t *opcodes_prop_p = ecma_get_internal_property (func_obj_p, ECMA_INTERNAL_PROPERTY_CODE_BYTECODE);
ecma_property_t *code_prop_p = ecma_get_internal_property (func_obj_p,
ECMA_INTERNAL_PROPERTY_CODE_FLAGS_AND_OFFSET);
ecma_object_t *scope_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t,
scope_prop_p->u.internal_property.value);
uint32_t code_prop_value = code_prop_p->u.internal_property.value;
// 8.
bool is_strict;
bool do_instantiate_args_obj;
// 8.
const opcode_t *opcodes_p = MEM_CP_GET_POINTER (const opcode_t, opcodes_prop_p->u.internal_property.value);
opcode_counter_t code_first_opcode_idx = ecma_unpack_code_internal_property_value (code_prop_value,
&is_strict,
&do_instantiate_args_obj);
@ -659,7 +666,8 @@ ecma_op_function_call (ecma_object_t *func_obj_p, /**< Function object */
do_instantiate_args_obj),
ret_value);
ecma_completion_value_t completion = vm_run_from_pos (code_first_opcode_idx,
ecma_completion_value_t completion = vm_run_from_pos (opcodes_p,
code_first_opcode_idx,
this_binding,
local_env_p,
is_strict,
@ -853,6 +861,7 @@ ecma_op_function_construct (ecma_object_t *func_obj_p, /**< Function object */
ecma_completion_value_t
ecma_op_function_declaration (ecma_object_t *lex_env_p, /**< lexical environment */
ecma_string_t *function_name_p, /**< function name */
const opcode_t *opcodes_p, /**< byte-code array */
opcode_counter_t function_code_opcode_idx, /**< index of first opcode of function code */
ecma_string_t* formal_parameter_list_p[], /**< formal parameters list */
ecma_length_t formal_parameter_list_length, /**< length of formal parameters list */
@ -869,6 +878,7 @@ ecma_op_function_declaration (ecma_object_t *lex_env_p, /**< lexical environment
lex_env_p,
is_strict,
do_instantiate_arguments_object,
opcodes_p,
function_code_opcode_idx);
// c.

View File

@ -35,6 +35,7 @@ ecma_op_create_function_object (ecma_string_t* formal_parameter_list_p[],
ecma_object_t *scope_p,
bool is_strict,
bool do_instantiate_arguments_object,
const opcode_t *opcodes_p,
opcode_counter_t first_opcode_idx);
extern ecma_object_t*
ecma_op_create_external_function_object (ecma_external_pointer_t code_p);
@ -57,6 +58,7 @@ ecma_op_function_has_instance (ecma_object_t *func_obj_p,
extern ecma_completion_value_t
ecma_op_function_declaration (ecma_object_t *lex_env_p,
ecma_string_t *function_name_p,
const opcode_t *opcodes_p,
opcode_counter_t function_code_opcode_idx,
ecma_string_t* formal_parameter_list_p[],
ecma_length_t formal_parameter_list_length,

View File

@ -43,7 +43,7 @@ opfunc_try_block (opcode_t opdata, /**< operation data */
|| (ecma_is_completion_value_empty (try_completion) && int_data->pos == try_end_oc));
int_data->pos = try_end_oc;
opcode_t next_opcode = vm_get_opcode (int_data->pos);
opcode_t next_opcode = vm_get_opcode (int_data->opcodes_p, int_data->pos);
JERRY_ASSERT (next_opcode.op_idx == __op__idx_meta);
if (ecma_is_completion_value_exit (try_completion))
@ -59,7 +59,7 @@ opfunc_try_block (opcode_t opdata, /**< operation data */
if (ecma_is_completion_value_throw (try_completion))
{
next_opcode = vm_get_opcode (int_data->pos);
next_opcode = vm_get_opcode (int_data->opcodes_p, int_data->pos);
JERRY_ASSERT (next_opcode.op_idx == __op__idx_meta);
JERRY_ASSERT (next_opcode.data.meta.type == OPCODE_META_TYPE_CATCH_EXCEPTION_IDENTIFIER);
@ -103,7 +103,7 @@ opfunc_try_block (opcode_t opdata, /**< operation data */
int_data->pos = catch_end_oc;
}
next_opcode = vm_get_opcode (int_data->pos);
next_opcode = vm_get_opcode (int_data->opcodes_p, int_data->pos);
JERRY_ASSERT (next_opcode.op_idx == __op__idx_meta);
if (ecma_is_completion_value_exit (try_completion))
@ -131,7 +131,7 @@ opfunc_try_block (opcode_t opdata, /**< operation data */
}
}
next_opcode = vm_get_opcode (int_data->pos++);
next_opcode = vm_get_opcode (int_data->opcodes_p, int_data->pos++);
JERRY_ASSERT (next_opcode.op_idx == __op__idx_meta);
JERRY_ASSERT (next_opcode.data.meta.type == OPCODE_META_TYPE_END_TRY_CATCH_FINALLY);

View File

@ -44,7 +44,7 @@ fill_varg_list (int_data_t *int_data, /**< interpreter context */
if (ecma_is_completion_value_normal (evaluate_arg_completion))
{
opcode_t next_opcode = vm_get_opcode (int_data->pos);
opcode_t next_opcode = vm_get_opcode (int_data->opcodes_p, int_data->pos);
JERRY_ASSERT (next_opcode.op_idx == __op__idx_meta);
JERRY_ASSERT (next_opcode.data.meta.type == OPCODE_META_TYPE_VARG);
@ -92,7 +92,7 @@ fill_params_list (int_data_t *int_data, /**< interpreter context */
param_index < params_number;
param_index++)
{
opcode_t next_opcode = vm_get_opcode (int_data->pos);
opcode_t next_opcode = vm_get_opcode (int_data->opcodes_p, int_data->pos);
JERRY_ASSERT (next_opcode.op_idx == __op__idx_meta);
JERRY_ASSERT (next_opcode.data.meta.type == OPCODE_META_TYPE_VARG);

View File

@ -448,7 +448,7 @@ function_declaration (int_data_t *int_data, /**< interpreter context */
read_meta_opcode_counter (OPCODE_META_TYPE_FUNCTION_END, int_data) + int_data->pos);
int_data->pos++;
opcode_scope_code_flags_t scope_flags = vm_get_scope_flags (int_data->pos++);
opcode_scope_code_flags_t scope_flags = vm_get_scope_flags (int_data->opcodes_p, int_data->pos++);
if (scope_flags & OPCODE_SCOPE_CODE_FLAGS_STRICT)
{
@ -467,6 +467,7 @@ function_declaration (int_data_t *int_data, /**< interpreter context */
ecma_completion_value_t ret_value = ecma_op_function_declaration (int_data->lex_env_p,
function_name_string_p,
int_data->opcodes_p,
int_data->pos,
args_names,
args_number,
@ -556,7 +557,8 @@ opfunc_func_expr_n (opcode_t opdata, /**< operation data */
int_data) + int_data->pos);
int_data->pos++;
opcode_scope_code_flags_t scope_flags = vm_get_scope_flags (int_data->pos++);
opcode_scope_code_flags_t scope_flags = vm_get_scope_flags (int_data->opcodes_p,
int_data->pos++);
if (scope_flags & OPCODE_SCOPE_CODE_FLAGS_STRICT)
{
@ -596,6 +598,7 @@ opfunc_func_expr_n (opcode_t opdata, /**< operation data */
scope_p,
is_strict,
do_instantiate_arguments_object,
int_data->opcodes_p,
int_data->pos);
ret_value = set_variable_value (int_data, lit_oc,
@ -654,7 +657,7 @@ opfunc_call_n (opcode_t opdata, /**< operation data */
idx_t this_arg_var_idx = INVALID_VALUE;
idx_t args_number;
opcode_t next_opcode = vm_get_opcode (int_data->pos);
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)
{
@ -918,7 +921,7 @@ opfunc_obj_decl (opcode_t opdata, /**< operation data */
{
JERRY_ASSERT (ecma_is_completion_value_empty (evaluate_prop_completion));
opcode_t next_opcode = vm_get_opcode (int_data->pos);
opcode_t next_opcode = vm_get_opcode (int_data->opcodes_p, int_data->pos);
JERRY_ASSERT (next_opcode.op_idx == __op__idx_meta);
const opcode_meta_type type = (opcode_meta_type) next_opcode.data.meta.type;
@ -1326,7 +1329,7 @@ opfunc_with (opcode_t opdata, /**< operation data */
int_data->lex_env_p = new_env_p;
#ifndef JERRY_NDEBUG
opcode_t meta_opcode = vm_get_opcode (with_end_oc);
opcode_t meta_opcode = vm_get_opcode (int_data->opcodes_p, with_end_oc);
JERRY_ASSERT (meta_opcode.op_idx == __op__idx_meta);
JERRY_ASSERT (meta_opcode.data.meta.type == OPCODE_META_TYPE_END_WITH);
#endif /* !JERRY_NDEBUG */
@ -1714,7 +1717,7 @@ opcode_counter_t
read_meta_opcode_counter (opcode_meta_type expected_type, /**< expected type of meta opcode */
int_data_t *int_data) /**< interpreter context */
{
opcode_t meta_opcode = vm_get_opcode (int_data->pos);
opcode_t meta_opcode = vm_get_opcode (int_data->opcodes_p, int_data->pos);
JERRY_ASSERT (meta_opcode.data.meta.type == expected_type);
const idx_t data_1 = meta_opcode.data.meta.data_1;

View File

@ -214,7 +214,8 @@ interp_mem_stats_context_exit (int_data_t *int_data_p,
}
static void
interp_mem_stats_opcode_enter (opcode_counter_t opcode_position,
interp_mem_stats_opcode_enter (const opcode_t *opcodes_p,
opcode_counter_t opcode_position,
mem_heap_stats_t *out_heap_stats_p,
mem_pools_stats_t *out_pools_stats_p)
{
@ -235,7 +236,7 @@ interp_mem_stats_opcode_enter (opcode_counter_t opcode_position,
out_pools_stats_p,
true, false);
opcode_t opcode = vm_get_opcode (opcode_position);
opcode_t opcode = vm_get_opcode (opcodes_p, opcode_position);
printf ("%s-- Opcode: %s (position %u) --\n",
indent_prefix, __op_names[opcode.op_idx], (uint32_t) opcode_position);
@ -280,7 +281,7 @@ interp_mem_stats_opcode_exit (int_data_t *int_data_p,
int_data_p->context_peak_allocated_pool_chunks = JERRY_MAX (int_data_p->context_peak_allocated_pool_chunks,
pools_stats_after.allocated_chunks);
opcode_t opcode = vm_get_opcode (opcode_position);
opcode_t opcode = vm_get_opcode (int_data_p->opcodes_p, opcode_position);
printf ("%s Allocated heap bytes: %5u -> %5u (%+5d, local %5u, peak %5u)\n",
indent_prefix,
@ -375,7 +376,8 @@ vm_run_global (void)
bool is_strict = false;
opcode_counter_t start_pos = 0;
opcode_scope_code_flags_t scope_flags = vm_get_scope_flags (start_pos++);
opcode_scope_code_flags_t scope_flags = vm_get_scope_flags (__program,
start_pos++);
if (scope_flags & OPCODE_SCOPE_CODE_FLAGS_STRICT)
{
@ -385,7 +387,8 @@ vm_run_global (void)
ecma_object_t *glob_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_GLOBAL);
ecma_object_t *lex_env_p = ecma_get_global_environment ();
ecma_completion_value_t completion = vm_run_from_pos (start_pos,
ecma_completion_value_t completion = vm_run_from_pos (__program,
start_pos,
ecma_make_object_value (glob_obj_p),
lex_env_p,
is_strict,
@ -454,12 +457,13 @@ vm_loop (int_data_t *int_data_p, /**< interpreter context */
|| (run_scope_p->start_oc <= int_data_p->pos
&& int_data_p->pos <= run_scope_p->end_oc));
const opcode_t *curr = &__program[int_data_p->pos];
const opcode_t *curr = &int_data_p->opcodes_p[int_data_p->pos];
#ifdef MEM_STATS
const opcode_counter_t opcode_pos = int_data_p->pos;
interp_mem_stats_opcode_enter (opcode_pos,
interp_mem_stats_opcode_enter (int_data_p->opcodes_p,
opcode_pos,
&heap_stats_before,
&pools_stats_before);
#endif /* MEM_STATS */
@ -514,7 +518,8 @@ vm_loop (int_data_t *int_data_p, /**< interpreter context */
* Run the code, starting from specified opcode
*/
ecma_completion_value_t
vm_run_from_pos (opcode_counter_t start_pos, /**< identifier of starting opcode */
vm_run_from_pos (const opcode_t *opcodes_p, /**< byte-code array */
opcode_counter_t start_pos, /**< identifier of starting opcode */
ecma_value_t this_binding_value, /**< value of 'ThisBinding' */
ecma_object_t *lex_env_p, /**< lexical environment to use */
bool is_strict, /**< is the code is strict mode code (ECMA-262 v5, 10.1.1) */
@ -522,7 +527,7 @@ vm_run_from_pos (opcode_counter_t start_pos, /**< identifier of starting opcode
{
ecma_completion_value_t completion;
const opcode_t *curr = &__program[start_pos];
const opcode_t *curr = &opcodes_p[start_pos];
JERRY_ASSERT (curr->op_idx == __op__idx_reg_var_decl);
const idx_t min_reg_num = curr->data.reg_var_decl.min;
@ -534,7 +539,7 @@ vm_run_from_pos (opcode_counter_t start_pos, /**< identifier of starting opcode
MEM_DEFINE_LOCAL_ARRAY (regs, regs_num, ecma_value_t);
int_data_t int_data;
int_data.opcodes_p = __program;
int_data.opcodes_p = opcodes_p;
int_data.pos = (opcode_counter_t) (start_pos + 1);
int_data.this_binding = this_binding_value;
int_data.lex_env_p = lex_env_p;
@ -578,9 +583,10 @@ vm_run_from_pos (opcode_counter_t start_pos, /**< identifier of starting opcode
* Get specified opcode from the program.
*/
opcode_t
vm_get_opcode (opcode_counter_t counter) /**< opcode counter */
vm_get_opcode (const opcode_t *opcodes_p, /**< byte-code array */
opcode_counter_t counter) /**< opcode counter */
{
return __program[ counter ];
return opcodes_p[ counter ];
} /* vm_get_opcode */
/**
@ -589,9 +595,10 @@ vm_get_opcode (opcode_counter_t counter) /**< opcode counter */
* @return mask of scope code flags
*/
opcode_scope_code_flags_t
vm_get_scope_flags (opcode_counter_t counter) /**< opcode counter */
vm_get_scope_flags (const opcode_t *opcodes_p, /**< byte-code array */
opcode_counter_t counter) /**< opcode counter */
{
opcode_t flags_opcode = vm_get_opcode (counter);
opcode_t flags_opcode = vm_get_opcode (opcodes_p, counter);
JERRY_ASSERT (flags_opcode.op_idx == __op__idx_meta
&& flags_opcode.data.meta.type == OPCODE_META_TYPE_SCOPE_CODE_FLAGS);
return (opcode_scope_code_flags_t) flags_opcode.data.meta.data_1;

View File

@ -24,14 +24,15 @@ extern void vm_init (const opcode_t* program_p, bool dump_mem_stats);
extern void vm_finalize (void);
extern jerry_completion_code_t vm_run_global (void);
extern ecma_completion_value_t vm_loop (int_data_t *int_data, vm_run_scope_t *run_scope_p);
extern ecma_completion_value_t vm_run_from_pos (opcode_counter_t start_pos,
extern ecma_completion_value_t vm_run_from_pos (const opcode_t *opcodes_p,
opcode_counter_t start_pos,
ecma_value_t this_binding_value,
ecma_object_t *lex_env_p,
bool is_strict,
bool is_eval_code);
extern opcode_t vm_get_opcode (opcode_counter_t counter);
extern opcode_scope_code_flags_t vm_get_scope_flags (opcode_counter_t counter);
extern opcode_t vm_get_opcode (const opcode_t*, opcode_counter_t counter);
extern opcode_scope_code_flags_t vm_get_scope_flags (const opcode_t*, opcode_counter_t counter);
extern ecma_value_t vm_get_this_binding (void);
extern ecma_object_t* vm_get_lex_env (void);