From 62cc3cc604ed19c1678590b66f16dbf6fab54b0a Mon Sep 17 00:00:00 2001 From: Ilmir Usmanov Date: Sun, 5 Oct 2014 21:39:15 +0400 Subject: [PATCH] Fix && and || parsing --- src/libintstructs/stack.h | 2 +- src/libjsparser/parser.c | 86 ++++++++++++++++++++++++++++++++++++++- tests/jerry/and_or.js | 36 ++++++++++++++++ 3 files changed, 121 insertions(+), 3 deletions(-) create mode 100644 tests/jerry/and_or.js diff --git a/src/libintstructs/stack.h b/src/libintstructs/stack.h index 399873b2c..5b5b024d1 100644 --- a/src/libintstructs/stack.h +++ b/src/libintstructs/stack.h @@ -245,7 +245,7 @@ do { \ #define STACK_DROP(NAME, I) \ do { \ JERRY_ASSERT ((I) >= 0); \ - for (size_t i = 0; i < (size_t) (I); i++) { \ + for (size_t i = 0, till = (size_t) (I); i < till; i++) { \ decrease_##NAME##_stack_size (); } } while (0) #define STACK_CLEAN(NAME) \ diff --git a/src/libjsparser/parser.c b/src/libjsparser/parser.c index 81f3e733e..c30f89896 100644 --- a/src/libjsparser/parser.c +++ b/src/libjsparser/parser.c @@ -1828,12 +1828,94 @@ PARSE_OF (bitwise_or_expression, bitwise_xor_expression, OR, b_or) /* logical_and_expression : bitwise_or_expression (LT!* '&&' LT!* bitwise_or_expression)* ; */ -PARSE_OF (logical_and_expression, bitwise_or_expression, DOUBLE_AND, logical_and) +static void +parse_logical_and_expression (void) +{ + STACK_DECLARE_USAGE (IDX) + STACK_DECLARE_USAGE (U16) + STACK_DECLARE_USAGE (U8) + + STACK_PUSH (U8, STACK_SIZE (U16)); + + parse_bitwise_or_expression (); + + skip_newlines (); + while (true) + { + if (token_is (TOK_DOUBLE_AND)) + { + STACK_PUSH (U16, OPCODE_COUNTER ()); + DUMP_OPCODE_3 (is_false_jmp_down, ID (1), INVALID_VALUE, INVALID_VALUE); + NEXT (bitwise_or_expression); + DUMP_OPCODE_3 (logical_and, ID (2), ID (2), ID (1)); + STACK_DROP (IDX, 1); + } + else + { + lexer_save_token (TOK ()); + break; + } + skip_newlines (); + } + + for (uint8_t i = STACK_TOP (U8); i < STACK_SIZE (U16); i++) + { + REWRITE_COND_JMP (STACK_ELEMENT (U16, i), is_false_jmp_down, OPCODE_COUNTER () - STACK_ELEMENT (U16, i)); + } + + STACK_DROP (U16, STACK_SIZE (U16) - STACK_TOP (U8)); + STACK_DROP (U8, 1); + + STACK_CHECK_USAGE (U16); + STACK_CHECK_USAGE (U8); + STACK_CHECK_USAGE_LHS (); +} /* logical_or_expression : logical_and_expression (LT!* '||' LT!* logical_and_expression)* ; */ -PARSE_OF (logical_or_expression, logical_and_expression, DOUBLE_OR, logical_or) +static void +parse_logical_or_expression (void) +{ + STACK_DECLARE_USAGE (IDX) + STACK_DECLARE_USAGE (U16) + STACK_DECLARE_USAGE (U8) + + STACK_PUSH (U8, STACK_SIZE (U16)); + + parse_logical_and_expression (); + + skip_newlines (); + while (true) + { + if (token_is (TOK_DOUBLE_OR)) + { + STACK_PUSH (U16, OPCODE_COUNTER ()); + DUMP_OPCODE_3 (is_true_jmp_down, ID (1), INVALID_VALUE, INVALID_VALUE); + NEXT (logical_and_expression); + DUMP_OPCODE_3 (logical_or, ID (2), ID (2), ID (1)); + STACK_DROP (IDX, 1); + } + else + { + lexer_save_token (TOK ()); + break; + } + skip_newlines (); + } + + for (uint8_t i = STACK_TOP (U8); i < STACK_SIZE (U16); i++) + { + REWRITE_COND_JMP (STACK_ELEMENT (U16, i), is_true_jmp_down, OPCODE_COUNTER () - STACK_ELEMENT (U16, i)); + } + + STACK_DROP (U16, STACK_SIZE (U16) - STACK_TOP (U8)); + STACK_DROP (U8, 1); + + STACK_CHECK_USAGE (U16); + STACK_CHECK_USAGE (U8); + STACK_CHECK_USAGE_LHS (); +} /* conditional_expression : logical_or_expression (LT!* '?' LT!* assignment_expression LT!* ':' LT!* assignment_expression)? diff --git a/tests/jerry/and_or.js b/tests/jerry/and_or.js new file mode 100644 index 000000000..013ca5cac --- /dev/null +++ b/tests/jerry/and_or.js @@ -0,0 +1,36 @@ +// 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. + +function fail() { + assert (0); + return true; +} + +if (false && fail()) { + assert (0); +} + +if (true && false && fail()) { + assert (0); +} + +if (true || fail()) { +} else { + assert (0); +} + +if (false || true || fail()) { +} else { + assert (0); +}