From 70cc5128cc3cf2f582d0e1a013fc3699c45ece0e Mon Sep 17 00:00:00 2001 From: Ilmir Usmanov Date: Wed, 17 Sep 2014 18:57:36 +0400 Subject: [PATCH] Add test try_catch_finally.js. Fix parser and interpreter --- src/libcoreint/opcodes-agnostic.c | 12 +++--- .../opcodes-ecma-try-catch-finally.c | 5 ++- src/libjsparser/parser.c | 32 +++++++++++---- tests/jerry/try_catch_finally.js | 39 +++++++++++++++++++ 4 files changed, 73 insertions(+), 15 deletions(-) create mode 100644 tests/jerry/try_catch_finally.js diff --git a/src/libcoreint/opcodes-agnostic.c b/src/libcoreint/opcodes-agnostic.c index 35d25d3e5..01dc10eae 100644 --- a/src/libcoreint/opcodes-agnostic.c +++ b/src/libcoreint/opcodes-agnostic.c @@ -40,7 +40,7 @@ opfunc_is_true_jmp_down (opcode_t opdata, /**< operation data */ if (ecma_is_value_true (to_bool_completion.u.value)) { - JERRY_ASSERT (offset != 0 && (int_data->pos + offset < MAX_OPCODES)); + JERRY_ASSERT (offset != 0 && ((uint32_t) int_data->pos + offset < MAX_OPCODES)); int_data->pos = (opcode_counter_t) (int_data->pos + offset); } else @@ -73,7 +73,7 @@ opfunc_is_true_jmp_up (opcode_t opdata, /**< operation data */ if (ecma_is_value_true (to_bool_completion.u.value)) { - JERRY_ASSERT (offset != 0 && int_data->pos >= offset); + JERRY_ASSERT (offset != 0 && (uint32_t) int_data->pos >= offset); int_data->pos = (opcode_counter_t) (int_data->pos - offset); } else @@ -112,7 +112,7 @@ opfunc_is_false_jmp_down (opcode_t opdata, /**< operation data */ if (!ecma_is_value_true (to_bool_completion.u.value)) { - JERRY_ASSERT (offset != 0 && (int_data->pos + offset < MAX_OPCODES)); + JERRY_ASSERT (offset != 0 && ((uint32_t) int_data->pos + offset < MAX_OPCODES)); int_data->pos = (opcode_counter_t) (int_data->pos + offset); } else @@ -145,7 +145,7 @@ opfunc_is_false_jmp_up (opcode_t opdata, /**< operation data */ if (!ecma_is_value_true (to_bool_completion.u.value)) { - JERRY_ASSERT (offset != 0 && int_data->pos >= offset); + JERRY_ASSERT (offset != 0 && (uint32_t) int_data->pos >= offset); int_data->pos = (opcode_counter_t) (int_data->pos - offset); } else @@ -173,7 +173,7 @@ opfunc_jmp_down (opcode_t opdata, /**< operation data */ const opcode_counter_t offset = calc_opcode_counter_from_idx_idx (opdata.data.jmp_down.opcode_1, opdata.data.jmp_down.opcode_2); - JERRY_ASSERT (offset != 0 && (int_data->pos + offset < MAX_OPCODES)); + JERRY_ASSERT (offset != 0 && ((uint32_t) int_data->pos + offset < MAX_OPCODES)); int_data->pos = (opcode_counter_t) (int_data->pos + offset); @@ -192,7 +192,7 @@ opfunc_jmp_up (opcode_t opdata, /**< operation data */ { const opcode_counter_t offset = calc_opcode_counter_from_idx_idx (opdata.data.jmp_up.opcode_1, opdata.data.jmp_up.opcode_2); - JERRY_ASSERT (offset != 0 && int_data->pos >= offset); + JERRY_ASSERT (offset != 0 && (uint32_t) int_data->pos >= offset); int_data->pos = (opcode_counter_t) (int_data->pos - offset); diff --git a/src/libcoreint/opcodes-ecma-try-catch-finally.c b/src/libcoreint/opcodes-ecma-try-catch-finally.c index 6cb26b44f..af19f19b9 100644 --- a/src/libcoreint/opcodes-ecma-try-catch-finally.c +++ b/src/libcoreint/opcodes-ecma-try-catch-finally.c @@ -87,10 +87,11 @@ opfunc_try (opcode_t opdata, /**< operation data */ int_data->lex_env_p = old_env_p; ecma_deref_object (catch_env_p); + + JERRY_ASSERT ((!ecma_is_completion_value_empty (try_completion) && int_data->pos < catch_end_oc) + || (ecma_is_completion_value_empty (try_completion) && int_data->pos == catch_end_oc)); } - JERRY_ASSERT ((!ecma_is_completion_value_empty (try_completion) && int_data->pos < catch_end_oc) - || (ecma_is_completion_value_empty (try_completion) && int_data->pos == catch_end_oc)); int_data->pos = catch_end_oc; } diff --git a/src/libjsparser/parser.c b/src/libjsparser/parser.c index a291e01fb..92585321d 100644 --- a/src/libjsparser/parser.c +++ b/src/libjsparser/parser.c @@ -427,6 +427,20 @@ token_after_newlines_must_be_keyword (keyword kw) CHECK_USAGE (IDX) \ } while (0) +#define REWRITE_TRY(OC) \ + do { \ + DECLARE_USAGE (IDX) \ + JERRY_STATIC_ASSERT (sizeof (idx_t) == 1); \ + PUSH (IDX, (idx_t) ((OPCODE_COUNTER ()) >> JERRY_BITSINBYTE)); \ + PUSH (IDX, (idx_t) ((OPCODE_COUNTER ()) & ((1 << JERRY_BITSINBYTE) - 1))); \ + JERRY_ASSERT ((OPCODE_COUNTER ()) \ + == calc_opcode_counter_from_idx_idx (HEAD (IDX, 2), HEAD (IDX, 1))); \ + OPCODE()=getop_try (HEAD (IDX, 2), HEAD (IDX, 1)); \ + serializer_rewrite_opcode ((OC), OPCODE()); \ + DROP (IDX, 2); \ + CHECK_USAGE (IDX) \ + } while (0) + static void integer_zero (void) { @@ -1111,17 +1125,17 @@ parse_primary_expression (void) case TOK_STRING: { parse_literal (); - goto cleanup; + break; } case TOK_OPEN_SQUARE: { parse_array_literal (); - goto cleanup; + break; } case TOK_OPEN_BRACE: { parse_object_literal (); - goto cleanup; + break; } case TOK_OPEN_PAREN: { @@ -1130,7 +1144,7 @@ parse_primary_expression (void) { parse_expression (); token_after_newlines_must_be (TOK_CLOSE_PAREN); - goto cleanup; + break; } /* FALLTHRU */ } @@ -2104,7 +2118,7 @@ parse_statement_list (void) if (token_is (TOK_CLOSE_BRACE)) { lexer_save_token (TOK ()); - return; + break; } } @@ -2295,6 +2309,7 @@ parse_catch_clause (void) DUMP_OPCODE_3 (meta, OPCODE_META_TYPE_CATCH_EXCEPTION_IDENTIFIER, HEAD (IDX, 1), INVALID_VALUE); token_after_newlines_must_be (TOK_OPEN_BRACE); + skip_newlines (); parse_statement_list (); next_token_must_be (TOK_CLOSE_BRACE); @@ -2322,6 +2337,7 @@ parse_finally_clause (void) DUMP_OPCODE_3 (meta, OPCODE_META_TYPE_FINALLY, INVALID_VALUE, INVALID_VALUE); token_after_newlines_must_be (TOK_OPEN_BRACE); + skip_newlines (); parse_statement_list (); next_token_must_be (TOK_CLOSE_BRACE); @@ -2344,13 +2360,14 @@ parse_try_statement (void) assert_keyword (KW_TRY); PUSH (U16, OPCODE_COUNTER ()) - DUMP_OPCODE_2 (try, HEAD (U16, 1) + 1, INVALID_VALUE); + DUMP_OPCODE_2 (try, INVALID_VALUE, INVALID_VALUE); token_after_newlines_must_be (TOK_OPEN_BRACE); + skip_newlines (); parse_statement_list (); next_token_must_be (TOK_CLOSE_BRACE); - REWRITE_OPCODE_2 (HEAD (U16, 1), try, HEAD (U16, 1) + 1, opcode_counter); + REWRITE_TRY (HEAD (U16, 1)); token_after_newlines_must_be (TOK_KEYWORD); if (is_keyword (KW_CATCH)) @@ -2561,6 +2578,7 @@ parse_statement (void) insert_semicolon (); DUMP_OPCODE_1 (throw, HEAD (IDX, 1)); + DROP (IDX, 1); goto cleanup; } if (is_keyword (KW_TRY)) diff --git a/tests/jerry/try_catch_finally.js b/tests/jerry/try_catch_finally.js new file mode 100644 index 000000000..13ffc74a7 --- /dev/null +++ b/tests/jerry/try_catch_finally.js @@ -0,0 +1,39 @@ +// 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. + +var was_catch = false, was_finally = false; + +try { +} catch (err) { + was_catch = true; +} finally { + was_finally = true; +} + +assert (!was_catch && was_finally); + +was_catch = false; +was_finally = false; + +try { + throw 1; + assert (0); +} catch (err) { + assert (err === 1); + was_catch = true; +} finally { + was_finally = true; +} + +assert (was_catch && was_finally); \ No newline at end of file