From 3b624be0513d1ab55e2b0c078cd3c32d062d2cca Mon Sep 17 00:00:00 2001 From: Ilmir Usmanov Date: Tue, 5 Aug 2014 11:51:49 +0400 Subject: [PATCH] Fix adjusting jumps --- src/liboptimizer/optimizer-passes.c | 4 +- src/libruntime/target/linux/pretty-printer.c | 2 +- tests/unit/common.h | 2 +- tests/unit/test_optimizer_for_loops.c | 97 ++++++++++++++++++++ 4 files changed, 101 insertions(+), 4 deletions(-) create mode 100644 tests/unit/test_optimizer_for_loops.c diff --git a/src/liboptimizer/optimizer-passes.c b/src/liboptimizer/optimizer-passes.c index 7cb328f14..868d72ca0 100644 --- a/src/liboptimizer/optimizer-passes.c +++ b/src/liboptimizer/optimizer-passes.c @@ -192,8 +192,8 @@ optimizer_adjust_jumps (OPCODE *first_opcode, OPCODE *last_opcode, int16_t value 20: is_false_jmp 21 21: assignment */ - if (current_opcode->data.is_true_jmp.opcode <= opcode_to_counter (first_opcode) - && current_opcode->data.is_false_jmp.opcode < opcode_to_counter (last_opcode) - value) + if (current_opcode->data.is_false_jmp.opcode >= opcode_to_counter (first_opcode) + && current_opcode->data.is_false_jmp.opcode <= opcode_to_counter (last_opcode) - value) { current_opcode->data.is_false_jmp.opcode = (T_IDX) (current_opcode->data.is_false_jmp.opcode + value); continue; diff --git a/src/libruntime/target/linux/pretty-printer.c b/src/libruntime/target/linux/pretty-printer.c index c2bec1589..eee7aa9d2 100644 --- a/src/libruntime/target/linux/pretty-printer.c +++ b/src/libruntime/target/linux/pretty-printer.c @@ -315,7 +315,7 @@ pp_opcode (opcode_counter_t oc, OPCODE opcode, bool is_rewrite) uint8_t i = 1; uint8_t opcode_num = opcode.op_idx; - __printf ("%03d: %20s ", oc++, opcode_names[opcode_num]); + __printf ("%03d: %20s ", oc, opcode_names[opcode_num]); if (opcode_num != NAME_TO_ID (nop) && opcode_num != NAME_TO_ID (ret) && opcode_num != NAME_TO_ID (end_with)) { diff --git a/tests/unit/common.h b/tests/unit/common.h index cee109295..2872020c7 100644 --- a/tests/unit/common.h +++ b/tests/unit/common.h @@ -25,7 +25,7 @@ static uint8_t opcode_sizes[] = { }; static bool -opcodes_equal (OPCODE *opcodes1, OPCODE *opcodes2, uint16_t size) +opcodes_equal (const OPCODE *opcodes1, OPCODE *opcodes2, uint16_t size) { uint16_t i; for (i = 0; i < size; i++) diff --git a/tests/unit/test_optimizer_for_loops.c b/tests/unit/test_optimizer_for_loops.c new file mode 100644 index 000000000..fac7a790c --- /dev/null +++ b/tests/unit/test_optimizer_for_loops.c @@ -0,0 +1,97 @@ +/* Copyright 2014 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "globals.h" +#include "serializer.h" +#include "optimizer-passes.h" +#include "jerry-libc.h" +#include "deserializer.h" +#include "common.h" +#include "lexer.h" +#include "parser.h" +#include "mem-allocator.h" + +#define MAX_STRINGS 100 +#define MAX_NUMS 25 +/** + * Unit test's main function. + */ +int +main( int __unused argc, + char __unused **argv) +{ + const char *strings[MAX_STRINGS]; + int32_t nums[MAX_NUMS]; + uint8_t strings_num, nums_count; + uint16_t offset; + const OPCODE *opcodes; + const char *source = "for (var i = 0; i < 10; i++) {\n" + " var j = 10;\n" + "}\n" + "for (var i = 0; i < 10; i++) {\n" + " var j = 10;\n" + "}"; + + mem_init (); + serializer_init (true); + lexer_init (source, __strlen (source), true); + lexer_run_first_pass(); + + strings_num = lexer_get_strings (strings); + nums_count = lexer_get_nums (nums); + lexer_adjust_num_ids (); + + offset = serializer_dump_strings (strings, strings_num); + serializer_dump_nums (nums, nums_count, offset, strings_num); + + parser_init (); + parser_parse_program (); + + opcodes = deserialize_bytecode (); + serializer_print_opcodes (); + if (!opcodes_equal (opcodes, (OPCODE[]) { + [0] = getop_reg_var_decl (5, 8), // var tmp5 .. tmp8; + [1] = getop_var_decl (0), // var i; + [2] = getop_var_decl (1), // var j; + [3] = getop_var_decl (0), // var i; + [4] = getop_var_decl (1), // var j; + [5] = getop_assignment (5, 2, 2), // tmp5 = 0; + [6] = getop_assignment (0, 4, 5), // i = tmp5; + [7] = getop_assignment (7, 2, 4), // tmp7 = 10; + [8] = getop_less_than (6, 0, 7), // tmp6 = i < tmp7; + [9] = getop_is_false_jmp (6, 16), // if (!tmp6) goto 16; + [10] = getop_jmp_down (3), // goto 13; + [11] = getop_post_incr (8, 0), // tmp8 = i ++; + [12] = getop_jmp_up (5), // goto 7; + [13] = getop_assignment (5, 2, 4), // tmp5 = 10; + [14] = getop_assignment (1, 4, 5), // j = tmp5; + [15] = getop_jmp_up (5), // goto 10; + [16] = getop_assignment (5, 2, 2), // tmp5 = 0; + [17] = getop_assignment (0, 4, 5), // i = tmp5; + [18] = getop_assignment (7, 2, 4), // tmp7 = 10; + [19] = getop_less_than (6, 0, 7), // tmp6 = i < tmp7; + [20] = getop_is_false_jmp (6, 27), // if (!tmp6) goto 27; + [21] = getop_jmp_down (3), // goto 24; + [22] = getop_post_incr (8, 0), // tmp8 = i ++; + [23] = getop_jmp_up (5), // goto 18; + [24] = getop_assignment (5, 2, 4), // tmp5 = 10; + [25] = getop_assignment (1, 4, 5), // j = tmp5; + [26] = getop_jmp_up (5), // goto 21; + [27] = getop_exitval (0) // exit 0; + }, 28)) + return 1; + + return 0; +}