diff --git a/jerry-core/ecma/base/ecma-gc.cpp b/jerry-core/ecma/base/ecma-gc.cpp index 32641e060..00fcf9b86 100644 --- a/jerry-core/ecma/base/ecma-gc.cpp +++ b/jerry-core/ecma/base/ecma-gc.cpp @@ -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 */ diff --git a/jerry-core/ecma/base/ecma-globals.h b/jerry-core/ecma/base/ecma-globals.h index 8aebcdf4d..887fde5a6 100644 --- a/jerry-core/ecma/base/ecma-globals.h +++ b/jerry-core/ecma/base/ecma-globals.h @@ -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 */ diff --git a/jerry-core/ecma/base/ecma-helpers.cpp b/jerry-core/ecma/base/ecma-helpers.cpp index a4badbea4..2db1512dd 100644 --- a/jerry-core/ecma/base/ecma-helpers.cpp +++ b/jerry-core/ecma/base/ecma-helpers.cpp @@ -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 */ diff --git a/jerry-core/ecma/operations/ecma-function-object.cpp b/jerry-core/ecma/operations/ecma-function-object.cpp index b6f46424d..ebbca8150 100644 --- a/jerry-core/ecma/operations/ecma-function-object.cpp +++ b/jerry-core/ecma/operations/ecma-function-object.cpp @@ -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. diff --git a/jerry-core/ecma/operations/ecma-function-object.h b/jerry-core/ecma/operations/ecma-function-object.h index 7e230ac1b..726c705fd 100644 --- a/jerry-core/ecma/operations/ecma-function-object.h +++ b/jerry-core/ecma/operations/ecma-function-object.h @@ -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, diff --git a/jerry-core/vm/opcodes-ecma-try-catch-finally.cpp b/jerry-core/vm/opcodes-ecma-try-catch-finally.cpp index 9087d5d5c..68874c294 100644 --- a/jerry-core/vm/opcodes-ecma-try-catch-finally.cpp +++ b/jerry-core/vm/opcodes-ecma-try-catch-finally.cpp @@ -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); diff --git a/jerry-core/vm/opcodes-varg.cpp b/jerry-core/vm/opcodes-varg.cpp index e395ce5bc..8fd0f7f80 100644 --- a/jerry-core/vm/opcodes-varg.cpp +++ b/jerry-core/vm/opcodes-varg.cpp @@ -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); diff --git a/jerry-core/vm/opcodes.cpp b/jerry-core/vm/opcodes.cpp index 4c2712342..d916242a6 100644 --- a/jerry-core/vm/opcodes.cpp +++ b/jerry-core/vm/opcodes.cpp @@ -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; diff --git a/jerry-core/vm/vm.cpp b/jerry-core/vm/vm.cpp index cabea6ef8..1bbb5ccbc 100644 --- a/jerry-core/vm/vm.cpp +++ b/jerry-core/vm/vm.cpp @@ -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; diff --git a/jerry-core/vm/vm.h b/jerry-core/vm/vm.h index 7ed8acc5c..b4bab7221 100644 --- a/jerry-core/vm/vm.h +++ b/jerry-core/vm/vm.h @@ -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);