From 8a517ab03e03928b94c32c1f9c08f60262259a1d Mon Sep 17 00:00:00 2001 From: Ilmir Usmanov Date: Mon, 13 Oct 2014 17:45:20 +0400 Subject: [PATCH] Add support of octal integer literals --- src/libjsparser/lexer.c | 47 +++++++++++++++++++++++++++-------- src/libjsparser/parser.c | 14 +++++++++++ src/libjsparser/parser.h | 1 + src/libjsparser/scopes-tree.c | 15 +++++++++++ src/libjsparser/scopes-tree.h | 3 +++ tests/jerry/octal.js | 15 +++++++++++ 6 files changed, 85 insertions(+), 10 deletions(-) create mode 100644 tests/jerry/octal.js diff --git a/src/libjsparser/lexer.c b/src/libjsparser/lexer.c index 9e94cc38a..fa094f7a8 100644 --- a/src/libjsparser/lexer.c +++ b/src/libjsparser/lexer.c @@ -20,6 +20,7 @@ #include "stack.h" #include "opcodes.h" #include "parse-error.h" +#include "parser.h" static token saved_token, prev_token, sent_token; static token empty_token = @@ -750,22 +751,48 @@ parse_number (void) } tok_length = (size_t) (buffer - token_start);; - for (i = 0; i < tok_length; i++) + if (*token_start == '0' && tok_length != 1) { - if (!is_overflow) + if (parser_strict_mode ()) { - res = res * 10 + hex_to_int (token_start[i]); + PARSE_ERROR ("Octal tnteger literals are not allowed in strict mode", token_start - buffer_start); } - else + for (i = 0; i < tok_length; i++) { - fp_res = fp_res * 10 + (ecma_number_t) hex_to_int (token_start[i]); + if (!is_overflow) + { + res = res * 8 + hex_to_int (token_start[i]); + } + else + { + fp_res = fp_res * 8 + (ecma_number_t) hex_to_int (token_start[i]); + } + if (res > 255) + { + fp_res = (ecma_number_t) res; + is_overflow = true; + res = 0; + } } - - if (res > 255) + } + else + { + for (i = 0; i < tok_length; i++) { - fp_res = (ecma_number_t) res; - is_overflow = true; - res = 0; + if (!is_overflow) + { + res = res * 10 + hex_to_int (token_start[i]); + } + else + { + fp_res = fp_res * 10 + (ecma_number_t) hex_to_int (token_start[i]); + } + if (res > 255) + { + fp_res = (ecma_number_t) res; + is_overflow = true; + res = 0; + } } } diff --git a/src/libjsparser/parser.c b/src/libjsparser/parser.c index 026f8f9e3..5aa770aa4 100644 --- a/src/libjsparser/parser.c +++ b/src/libjsparser/parser.c @@ -3623,6 +3623,7 @@ preparse_scope (bool is_global) { if (token_is (TOK_STRING) && lp_string_equal_s (lexer_get_string_by_id (token_data ()), "use strict")) { + scopes_tree_set_strict_mode (STACK_TOP (scopes), true); REWRITE_OPCODE_3 (STACK_TOP (U16), meta, OPCODE_META_TYPE_STRICT_CODE, INVALID_VALUE, INVALID_VALUE); } else if (is_keyword (KW_VAR)) @@ -3713,6 +3714,19 @@ parser_parse_program (void) STACK_CHECK_USAGE (scopes); } +bool +parser_strict_mode (void) +{ + if (STACK_SIZE (scopes) > 0) + { + return scopes_tree_strict_mode (STACK_TOP (scopes)); + } + else + { + return false; + } +} + void parser_init (const char *source, size_t source_size, bool show_opcodes) { diff --git a/src/libjsparser/parser.h b/src/libjsparser/parser.h index 16ca1e4d0..5b404fb59 100644 --- a/src/libjsparser/parser.h +++ b/src/libjsparser/parser.h @@ -21,5 +21,6 @@ void parser_init (const char *, size_t, bool); void parser_parse_program (void); void parser_free (void); +bool parser_strict_mode (void); #endif diff --git a/src/libjsparser/scopes-tree.c b/src/libjsparser/scopes-tree.c index 60aacd7f3..0c2f780d7 100644 --- a/src/libjsparser/scopes-tree.c +++ b/src/libjsparser/scopes-tree.c @@ -132,6 +132,20 @@ scopes_tree_raw_data (scopes_tree tree, opcode_counter_t *num) return opcodes; } +void +scopes_tree_set_strict_mode (scopes_tree tree, bool strict_mode) +{ + assert_tree (tree); + tree->strict_mode = strict_mode ? 1 : 0; +} + +bool +scopes_tree_strict_mode (scopes_tree tree) +{ + assert_tree (tree); + return (bool) tree->strict_mode; +} + scopes_tree scopes_tree_init (scopes_tree parent) { @@ -153,6 +167,7 @@ scopes_tree_init (scopes_tree parent) parent->t.children_num++; } tree->opcodes_num = 0; + tree->strict_mode = 0; tree->opcodes = linked_list_init (sizeof (opcode_t)); return tree; } diff --git a/src/libjsparser/scopes-tree.h b/src/libjsparser/scopes-tree.h index f3053d813..bab7a8d3d 100644 --- a/src/libjsparser/scopes-tree.h +++ b/src/libjsparser/scopes-tree.h @@ -23,6 +23,7 @@ typedef struct { tree_header t; + unsigned strict_mode:1; opcode_counter_t opcodes_num; linked_list opcodes; } @@ -40,5 +41,7 @@ void scopes_tree_set_opcodes_num (scopes_tree, opcode_counter_t); opcode_t scopes_tree_opcode (scopes_tree, opcode_counter_t); opcode_counter_t scopes_tree_count_opcodes (scopes_tree); opcode_t *scopes_tree_raw_data (scopes_tree, opcode_counter_t *); +void scopes_tree_set_strict_mode (scopes_tree, bool); +bool scopes_tree_strict_mode (scopes_tree); #endif /* SCOPES_TREE_H */ diff --git a/tests/jerry/octal.js b/tests/jerry/octal.js new file mode 100644 index 000000000..b4d1ef0e7 --- /dev/null +++ b/tests/jerry/octal.js @@ -0,0 +1,15 @@ +// 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. + +assert (010 === 8);