From 9d45f6837090562f2512f6ada59d913930844602 Mon Sep 17 00:00:00 2001 From: Ruben Ayrapetyan Date: Thu, 28 Aug 2014 15:17:49 +0400 Subject: [PATCH] Introducing 'opcode counter' type for 'meta' opcode; replacing 'jmp_down' opcodes that are used as pointers only with 'meta' opcodes of the introduced type. --- src/globals.h | 2 +- src/libcoreint/opcodes.c | 53 ++++++++++++++++++++++++++-------- src/libcoreint/opcodes.h | 6 +++- src/libjsparser/parser.c | 31 +++++++++++++++----- tests/jerry/function_args.js | 5 ++-- tests/jerry/nested_function.js | 15 +++++----- 6 files changed, 81 insertions(+), 31 deletions(-) diff --git a/src/globals.h b/src/globals.h index e1cca6eea..46f04d8a1 100644 --- a/src/globals.h +++ b/src/globals.h @@ -37,7 +37,7 @@ typedef signed long ssize_t; /** * Constants */ -#define JERRY_BITSINBYTE 8 +#define JERRY_BITSINBYTE 8u /** * Error codes diff --git a/src/libcoreint/opcodes.c b/src/libcoreint/opcodes.c index 0a20f72e2..38f5a1f04 100644 --- a/src/libcoreint/opcodes.c +++ b/src/libcoreint/opcodes.c @@ -467,18 +467,15 @@ function_declaration (int_data_t *int_data, /**< interpreter context */ const bool is_strict = int_data->is_strict; const bool is_configurable_bindings = int_data->is_eval_code; - const opcode_counter_t jmp_down_opcode_idx = (opcode_counter_t) (int_data->pos); - opcode_t jmp_down_opcode = read_opcode (jmp_down_opcode_idx); - JERRY_ASSERT (jmp_down_opcode.op_idx == __op__idx_jmp_down); - int_data->pos = (opcode_counter_t) (jmp_down_opcode_idx + jmp_down_opcode.data.jmp_down.opcode_count); + const opcode_counter_t function_code_begin_oc = (opcode_counter_t) (int_data->pos + 1); - const opcode_counter_t function_code_opcode_idx = (opcode_counter_t) (jmp_down_opcode_idx + 1); + int_data->pos = read_meta_opcode_counter (int_data); ecma_string_t *function_name_string_p = ecma_new_ecma_string_from_lit_index (function_name_lit_idx); ecma_completion_value_t ret_value = ecma_op_function_declaration (int_data->lex_env_p, function_name_string_p, - function_code_opcode_idx, + function_code_begin_oc, args_names, args_number, is_strict, @@ -618,12 +615,9 @@ opfunc_func_expr_n (opcode_t opdata, /**< operation data */ fill_params_list (int_data, params_number, params_names); - const opcode_counter_t jmp_down_opcode_idx = (opcode_counter_t) (int_data->pos); - opcode_t jmp_down_opcode = read_opcode (jmp_down_opcode_idx); - JERRY_ASSERT (jmp_down_opcode.op_idx == __op__idx_jmp_down); - int_data->pos = (opcode_counter_t) (jmp_down_opcode_idx + jmp_down_opcode.data.jmp_down.opcode_count); + const opcode_counter_t function_code_begin_oc = (opcode_counter_t) (int_data->pos + 1); - const opcode_counter_t function_code_opcode_idx = (opcode_counter_t) (jmp_down_opcode_idx + 1); + int_data->pos = read_meta_opcode_counter (int_data); ecma_object_t *scope_p; ecma_string_t *function_name_string_p = NULL; @@ -644,7 +638,7 @@ opfunc_func_expr_n (opcode_t opdata, /**< operation data */ params_number, scope_p, is_strict, - function_code_opcode_idx); + function_code_begin_oc); ecma_completion_value_t ret_value = set_variable_value (int_data, dst_var_idx, @@ -1752,6 +1746,7 @@ opfunc_meta (opcode_t opdata, /**< operation data */ case OPCODE_META_TYPE_VARG_PROP_DATA: case OPCODE_META_TYPE_VARG_PROP_GETTER: case OPCODE_META_TYPE_VARG_PROP_SETTER: + case OPCODE_META_TYPE_OPCODE_COUNTER: { JERRY_UNREACHABLE (); } @@ -1760,6 +1755,40 @@ opfunc_meta (opcode_t opdata, /**< operation data */ JERRY_UNREACHABLE (); } /* opfunc_meta */ +/** + * Calculate opcode counter from 'meta' opcode's data arguments. + * + * @return opcode counter + */ +opcode_counter_t +calc_meta_opcode_counter_from_meta_data (const idx_t data_1, /**< first data argument */ + const idx_t data_2) /**< second data argument */ +{ + opcode_counter_t counter; + + counter = data_1; + counter = (opcode_counter_t) (counter << (sizeof (data_2) * JERRY_BITSINBYTE)); + counter = (opcode_counter_t) (counter | data_2); + + return counter; +} /* calc_meta_opcode_counter_from_meta_data */ + +/** + * Read opcode counter from current opcode, + * that should be 'meta' opcode of type 'opcode counter'. + */ +opcode_counter_t +read_meta_opcode_counter (int_data_t *int_data) /**< interpreter context */ +{ + opcode_t meta_opcode = read_opcode (int_data->pos); + JERRY_ASSERT (meta_opcode.data.meta.type == OPCODE_META_TYPE_OPCODE_COUNTER); + + const idx_t data_1 = meta_opcode.data.meta.data_1; + const idx_t data_2 = meta_opcode.data.meta.data_2; + + return calc_meta_opcode_counter_from_meta_data (data_1, data_2); +} /* read_meta_opcode_counter */ + #define GETOP_DEF_1(a, name, field1) \ inline opcode_t getop_##name (idx_t arg1) \ { \ diff --git a/src/libcoreint/opcodes.h b/src/libcoreint/opcodes.h index b2cf22ebe..362dd27a0 100644 --- a/src/libcoreint/opcodes.h +++ b/src/libcoreint/opcodes.h @@ -57,7 +57,8 @@ typedef enum 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 */ OPCODE_META_TYPE_VARG_PROP_SETTER, /**< name (lit_idx) and setter (var_idx) for an accessor property descriptor */ - OPCODE_META_TYPE_END_WITH /**< end of with statement */ + OPCODE_META_TYPE_END_WITH, /**< end of with statement */ + OPCODE_META_TYPE_OPCODE_COUNTER /**< opcode counter */ } opcode_meta_type; typedef struct @@ -72,6 +73,9 @@ typedef struct ecma_value_t *regs_p; /**< register variables */ } int_data_t; +opcode_counter_t calc_meta_opcode_counter_from_meta_data (const idx_t data_1, const idx_t data_2); +opcode_counter_t read_meta_opcode_counter (int_data_t *int_data); + #define OP_CALLS_AND_ARGS(p, a) \ p##_2 (a, call_0, lhs, name_lit_idx) \ p##_3 (a, call_1, lhs, name_lit_idx, arg1_lit_idx) \ diff --git a/src/libjsparser/parser.c b/src/libjsparser/parser.c index 878e0f925..b37c521ed 100644 --- a/src/libjsparser/parser.c +++ b/src/libjsparser/parser.c @@ -894,6 +894,20 @@ parse_argument_list (argument_list_type alt, idx_t obj) return lhs; } +static void +rewrite_meta_opcode_counter (opcode_counter_t meta_oc, + opcode_counter_t new_value) +{ + JERRY_STATIC_ASSERT (sizeof (idx_t) == 1); + + const idx_t data_1 = (idx_t) (new_value >> JERRY_BITSINBYTE); + const idx_t data_2 = (idx_t) (new_value & ((1 << JERRY_BITSINBYTE) - 1)); + + JERRY_ASSERT (new_value == calc_meta_opcode_counter_from_meta_data (data_1, data_2)); + + REWRITE_OPCODE_3 (meta_oc, meta, OPCODE_META_TYPE_OPCODE_COUNTER, data_1, data_2); +} + /* function_declaration : 'function' LT!* Identifier LT!* '(' (LT!* Identifier (LT!* ',' LT!* Identifier)*) ? LT!* ')' LT!* function_body @@ -905,7 +919,7 @@ static void parse_function_declaration (void) { idx_t name; - opcode_counter_t jmp_oc; + opcode_counter_t meta_oc; assert_keyword (KW_FUNCTION); @@ -916,8 +930,8 @@ parse_function_declaration (void) skip_newlines (); parse_argument_list (AL_FUNC_DECL, name); - jmp_oc = opcode_counter; - DUMP_OPCODE_1 (jmp_down, INVALID_VALUE); + meta_oc = opcode_counter; + DUMP_OPCODE_3 (meta, OPCODE_META_TYPE_OPCODE_COUNTER, INVALID_VALUE, INVALID_VALUE); token_after_newlines_must_be (TOK_OPEN_BRACE); @@ -929,7 +943,8 @@ parse_function_declaration (void) next_token_must_be (TOK_CLOSE_BRACE); DUMP_VOID_OPCODE (ret); - REWRITE_OPCODE_1 (jmp_oc, jmp_down, opcode_counter - jmp_oc); + + rewrite_meta_opcode_counter (meta_oc, opcode_counter); } /* function_expression @@ -939,7 +954,7 @@ static idx_t parse_function_expression (void) { idx_t name, lhs; - opcode_counter_t jmp_oc; + opcode_counter_t meta_oc; assert_keyword (KW_FUNCTION); @@ -957,8 +972,8 @@ parse_function_expression (void) skip_newlines (); lhs = parse_argument_list (AL_FUNC_EXPR, name); - jmp_oc = opcode_counter; - DUMP_OPCODE_1 (jmp_down, INVALID_VALUE); + meta_oc = opcode_counter; + DUMP_OPCODE_3 (meta, OPCODE_META_TYPE_OPCODE_COUNTER, INVALID_VALUE, INVALID_VALUE); token_after_newlines_must_be (TOK_OPEN_BRACE); @@ -970,7 +985,7 @@ parse_function_expression (void) token_after_newlines_must_be (TOK_CLOSE_BRACE); DUMP_VOID_OPCODE (ret); - REWRITE_OPCODE_1 (jmp_oc, jmp_down, opcode_counter - jmp_oc); + rewrite_meta_opcode_counter (meta_oc, opcode_counter); return lhs; } diff --git a/tests/jerry/function_args.js b/tests/jerry/function_args.js index 15f3612c5..96f45d628 100644 --- a/tests/jerry/function_args.js +++ b/tests/jerry/function_args.js @@ -30,16 +30,17 @@ function f1(x) assert(t === false); } +var i; var t = true; -for(var i = 1; i <= 10; i++) +for(i = 1; i <= 10; i++) { f1(i); } t = false; -for(var i = 11; i <= 20; i++) +for(i = 11; i <= 20; i++) { f1(i); } diff --git a/tests/jerry/nested_function.js b/tests/jerry/nested_function.js index 44321a401..0d645082a 100644 --- a/tests/jerry/nested_function.js +++ b/tests/jerry/nested_function.js @@ -12,14 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -var k; - function f1() { - k = 17; - - f2(); - function f2() { assert(k > 0); @@ -32,9 +26,16 @@ function f1() f2(); } + + k = 17; + + f2(); } -for(var i = 0; i < 10000; i++) +var k; +var i; + +for(i = 0; i < 10000; i++) { f1(); }