diff --git a/src/libjsparser/lexer.c b/src/libjsparser/lexer.c index 0e4da1cb3..b2e338e2f 100644 --- a/src/libjsparser/lexer.c +++ b/src/libjsparser/lexer.c @@ -14,19 +14,23 @@ */ #include "mem-allocator.h" -#include "globals.h" #include "jerry-libc.h" #include "lexer.h" #include "parser.h" static token saved_token; -static token empty_token = { .type = TOK_EMPTY, .data.uid = 0 }; +static token empty_token = +{ + .type = + TOK_EMPTY, + .data.uid = 0 +}; static bool allow_dump_lines = false; static size_t buffer_size = 0; typedef struct { - int num; + ecma_number_t num; token tok; } num_and_token; @@ -35,12 +39,8 @@ num_and_token; static uint8_t seen_names_count = 0; -static num_and_token seen_nums[MAX_NUMS] = -{ - [0] = { .num = 0, .tok = { .type = TOK_INT, .data.uid = 0 } }, - [1] = { .num = 1, .tok = { .type = TOK_INT, .data.uid = 1 } } -}; -static uint8_t seen_nums_count = 2; +static num_and_token seen_nums[MAX_NUMS]; +static uint8_t seen_nums_count = 0; static bool is_empty (token tok) @@ -574,12 +574,13 @@ add_token_to_seen_names (token_type tt, const char *string) } static token -convert_seen_num_to_token (int num) +convert_seen_num_to_token (ecma_number_t num) { size_t i; for (i = 0; i < seen_nums_count; i++) { + // token must be exactly the same as seen if (seen_nums[i].num == num) { return seen_nums[i].tok; @@ -636,7 +637,7 @@ lexer_get_string_by_id (uint8_t id) } uint8_t -lexer_get_nums (int32_t *nums) +lexer_get_nums (ecma_number_t *nums) { int i; @@ -868,7 +869,16 @@ parse_number (void) token_start = NULL; - known_token = convert_seen_num_to_token (res); + if (res <= 255) + { + return (token) + { + .type = TOK_SMALL_INT, + .data.uid = (uint8_t) res + }; + } + + known_token = convert_seen_num_to_token ((ecma_number_t) res); if (!is_empty (known_token)) { return known_token; @@ -876,12 +886,16 @@ parse_number (void) known_token = (token) { - .type = TOK_INT, .data.uid = seen_nums_count + .type = TOK_NUMBER, + .data.uid = seen_nums_count }; - add_num_to_seen_tokens ((num_and_token) - { - .num = res, .tok = known_token - }); + add_num_to_seen_tokens ( + (num_and_token) + { + .num = (ecma_number_t) res, + .tok = known_token + } + ); return known_token; } @@ -948,10 +962,28 @@ parse_number (void) if (is_fp || is_exp) { - float res = __strtof (token_start, NULL); + ecma_number_t res = __strtof (token_start, NULL); token_start = NULL; - JERRY_UNIMPLEMENTED_REF_UNUSED_VARS (res); - return empty_token; + + known_token = convert_seen_num_to_token (res); + if (!is_empty (known_token)) + { + return known_token; + } + + known_token = (token) + { + .type = TOK_NUMBER, + .data.uid = seen_nums_count + }; + add_num_to_seen_tokens ( + (num_and_token) + { + .num = res, + .tok = known_token + } + ); + return known_token; } tok_length = (size_t) (buffer - token_start);; @@ -962,7 +994,16 @@ parse_number (void) token_start = NULL; - known_token = convert_seen_num_to_token (res); + if (res <= 255) + { + return (token) + { + .type = TOK_SMALL_INT, + .data.uid = (uint8_t) res + }; + } + + known_token = convert_seen_num_to_token ((ecma_number_t) res); if (!is_empty (known_token)) { return known_token; @@ -970,12 +1011,16 @@ parse_number (void) known_token = (token) { - .type = TOK_INT, .data.uid = seen_nums_count + .type = TOK_NUMBER, + .data.uid = seen_nums_count }; - add_num_to_seen_tokens ((num_and_token) - { - .num = res, .tok = known_token - }); + add_num_to_seen_tokens ( + (num_and_token) + { + .num = (ecma_number_t) res, + .tok = known_token + } + ); return known_token; } diff --git a/src/libjsparser/lexer.h b/src/libjsparser/lexer.h index 9b7f3b62d..0d9627e26 100644 --- a/src/libjsparser/lexer.h +++ b/src/libjsparser/lexer.h @@ -17,7 +17,7 @@ #define LEXER_H #include "globals.h" - +#include "ecma-globals.h" /* Keywords. */ typedef uint8_t keyword; @@ -65,8 +65,8 @@ typedef uint8_t token_type; #define TOK_EOF 0 // End of file #define TOK_NAME 1 // Identifier #define TOK_KEYWORD 2 // Keyword -#define TOK_INT 3 -#define TOK_FLOAT 4 +#define TOK_SMALL_INT 3 +#define TOK_NUMBER 4 #define TOK_NULL 5 #define TOK_BOOL 6 @@ -144,7 +144,8 @@ typedef struct uint8_t uid; } data; -} __packed +} +__packed token; void lexer_init (const char *, size_t, bool); @@ -156,7 +157,7 @@ void lexer_dump_buffer_state (void); uint8_t lexer_get_strings (const char **); uint8_t lexer_get_reserved_ids_count (void); const char *lexer_get_string_by_id (uint8_t); -uint8_t lexer_get_nums (int32_t *); +uint8_t lexer_get_nums (ecma_number_t *); void lexer_adjust_num_ids (void); #endif diff --git a/src/libjsparser/parser.c b/src/libjsparser/parser.c index 9428f4c2e..7e72fc012 100644 --- a/src/libjsparser/parser.c +++ b/src/libjsparser/parser.c @@ -38,7 +38,8 @@ typedef struct uint8_t size; uint8_t head; opcode_counter_t *oc_stack; -} __packed +} +__packed rewritable_opcode; #define NESTING_ITERATIONAL 1 @@ -160,7 +161,7 @@ is_keyword (keyword kw) } static void -current_token_must_be(token_type tt) +current_token_must_be (token_type tt) { if (tok.type != tt) { @@ -296,10 +297,10 @@ integer_zero (void) } static T_IDX -integer_one (void) +boolean_true (void) { T_IDX lhs = next_temp_name (); - DUMP_OPCODE_3 (assignment, lhs, OPCODE_ARG_TYPE_SMALLINT, 1); + DUMP_OPCODE_3 (assignment, lhs, OPCODE_ARG_TYPE_SIMPLE, ECMA_SIMPLE_VALUE_TRUE); return lhs; } @@ -416,13 +417,20 @@ dump_intrinsic (T_IDX obj, T_IDX args[3]) static T_IDX parse_property_name (void) { + T_IDX lhs; + switch (tok.type) { case TOK_NAME: case TOK_STRING: - case TOK_INT: + case TOK_NUMBER: return tok.data.uid; + case TOK_SMALL_INT: + lhs = next_temp_name (); + DUMP_OPCODE_3 (assignment, lhs, OPCODE_ARG_TYPE_SMALLINT, tok.data.uid); + return lhs; + default: JERRY_UNREACHABLE (); } @@ -845,7 +853,7 @@ parse_function_expression (void) T_IDX name, lhs; opcode_counter_t jmp_oc; - assert_keyword (KW_FUNCTION); + assert_keyword (KW_FUNCTION); skip_newlines (); if (tok.type == TOK_NAME) @@ -915,11 +923,16 @@ parse_literal (void) tok.data.uid ? ECMA_SIMPLE_VALUE_TRUE : ECMA_SIMPLE_VALUE_FALSE); return lhs; - case TOK_INT: + case TOK_NUMBER: lhs = next_temp_name (); DUMP_OPCODE_3 (assignment, lhs, OPCODE_ARG_TYPE_NUMBER, tok.data.uid); return lhs; + case TOK_SMALL_INT: + lhs = next_temp_name (); + DUMP_OPCODE_3 (assignment, lhs, OPCODE_ARG_TYPE_SMALLINT, tok.data.uid); + return lhs; + case TOK_STRING: lhs = next_temp_name (); DUMP_OPCODE_3 (assignment, lhs, OPCODE_ARG_TYPE_STRING, tok.data.uid); @@ -949,34 +962,38 @@ parse_primary_expression (void) DUMP_OPCODE_1 (this, lhs); return lhs; } - else if (tok.type == TOK_NAME) + + switch (tok.type) { - return tok.data.uid; + case TOK_NAME: + return tok.data.uid; + + case TOK_NULL: + case TOK_BOOL: + case TOK_SMALL_INT: + case TOK_NUMBER: + case TOK_STRING: + return parse_literal (); + + case TOK_OPEN_SQUARE: + return parse_array_literal (); + + case TOK_OPEN_BRACE: + return parse_object_literal (); + + case TOK_OPEN_PAREN: + skip_newlines (); + if (tok.type != TOK_CLOSE_PAREN) + { + lhs = parse_expression (); + token_after_newlines_must_be (TOK_CLOSE_PAREN); + return lhs; + } + // FALLTHRU + + default: + JERRY_UNREACHABLE (); } - else if (tok.type == TOK_NULL || tok.type == TOK_BOOL - || tok.type == TOK_INT || tok.type == TOK_STRING) - { - return parse_literal (); - } - else if (tok.type == TOK_OPEN_SQUARE) - { - return parse_array_literal (); - } - else if (tok.type == TOK_OPEN_BRACE) - { - return parse_object_literal (); - } - else if (tok.type == TOK_OPEN_PAREN) - { - skip_newlines (); - if (tok.type != TOK_CLOSE_PAREN) - { - lhs = parse_expression (); - token_after_newlines_must_be (TOK_CLOSE_PAREN); - return lhs; - } - } - JERRY_UNREACHABLE (); } /* member_expression @@ -1677,7 +1694,7 @@ parse_for_or_for_in_statement (void) T_IDX stop; opcode_counter_t cond_oc, body_oc, step_oc, end_oc; - assert_keyword (KW_FOR); + assert_keyword (KW_FOR); token_after_newlines_must_be (TOK_OPEN_PAREN); skip_newlines (); @@ -1771,7 +1788,7 @@ plain_for: } else { - stop = integer_one (); + stop = boolean_true (); } end_oc = opcode_counter; @@ -2239,5 +2256,5 @@ parser_fatal (jerry_status_t code) __printf ("FATAL: %d\n", code); lexer_dump_buffer_state (); - jerry_exit( code); + jerry_exit (code); } diff --git a/src/liboptimizer/deserializer.c b/src/liboptimizer/deserializer.c index f2f7c88fe..4ec0a3824 100644 --- a/src/liboptimizer/deserializer.c +++ b/src/liboptimizer/deserializer.c @@ -16,7 +16,7 @@ #include "deserializer.h" #include "bytecode-data.h" -int *num_data = NULL; +ecma_number_t *num_data = NULL; uint8_t num_size = 0; const ecma_char_t * @@ -42,7 +42,7 @@ deserialize_string_by_id (uint8_t id) return ((const ecma_char_t *) bytecode_data + offset); } -int +ecma_number_t deserialize_num_by_id (uint8_t id) { uint16_t str_size, str_offset; @@ -65,7 +65,7 @@ deserialize_num_by_id (uint8_t id) data++; num_size = *(++data); - num_data = (int *) ++data; + num_data = (ecma_number_t *) ++data; } if (id >= num_size) diff --git a/src/liboptimizer/deserializer.h b/src/liboptimizer/deserializer.h index d3253f43c..45f067930 100644 --- a/src/liboptimizer/deserializer.h +++ b/src/liboptimizer/deserializer.h @@ -20,7 +20,7 @@ #include "ecma-globals.h" const ecma_char_t *deserialize_string_by_id (uint8_t); -int deserialize_num_by_id (uint8_t); +ecma_number_t deserialize_num_by_id (uint8_t); const void *deserialize_bytecode (void); uint8_t deserialize_min_temp (void); diff --git a/src/liboptimizer/pretty-printer.c b/src/liboptimizer/pretty-printer.c index 2535a2815..865d5254f 100644 --- a/src/liboptimizer/pretty-printer.c +++ b/src/liboptimizer/pretty-printer.c @@ -52,14 +52,14 @@ pp_strings (const char *strings[], uint8_t size) } void -pp_nums (const int32_t nums[], uint8_t size, uint8_t strings_num) +pp_nums (const ecma_number_t nums[], uint8_t size, uint8_t strings_num) { uint8_t i; __printf ("NUMS %d:\n", size); for (i = 0; i < size; i++) { - __printf ("%3d %7d\n", i + strings_num, nums[i]); + __printf ("%3d %7d\n", i + strings_num, (int) nums[i]); } __printf ("\n"); } diff --git a/src/liboptimizer/pretty-printer.h b/src/liboptimizer/pretty-printer.h index 608b482d5..bb22b550c 100644 --- a/src/liboptimizer/pretty-printer.h +++ b/src/liboptimizer/pretty-printer.h @@ -20,6 +20,6 @@ void pp_opcode (opcode_counter_t, OPCODE, bool); void pp_strings (const char **, uint8_t); -void pp_nums (const int32_t *, uint8_t, uint8_t); +void pp_nums (const ecma_number_t *, uint8_t, uint8_t); #endif // PRETTY_PRINTER diff --git a/src/liboptimizer/serializer.c b/src/liboptimizer/serializer.c index 731238808..55debc942 100644 --- a/src/liboptimizer/serializer.c +++ b/src/liboptimizer/serializer.c @@ -72,14 +72,14 @@ serializer_dump_strings (const char *strings[], uint8_t size) } void -serializer_dump_nums (const int32_t nums[], uint8_t size, uint16_t offset, uint8_t strings_num) +serializer_dump_nums (const ecma_number_t nums[], uint8_t size, uint16_t offset, uint8_t strings_num) { - uint8_t i, *data; + uint8_t i, *data, type_size = sizeof (ecma_number_t); if (print_opcodes) pp_nums (nums, size, strings_num); - data = mem_heap_alloc_block ((size_t) (offset + size * 4 + 1), MEM_HEAP_ALLOC_LONG_TERM); + data = mem_heap_alloc_block ((size_t) (offset + size * type_size + 1), MEM_HEAP_ALLOC_LONG_TERM); if (!data) parser_fatal (ERR_MEMORY); @@ -91,8 +91,8 @@ serializer_dump_nums (const int32_t nums[], uint8_t size, uint16_t offset, uint8 data++; for (i = 0; i < size; i++) { - __memcpy (data, nums + i, 4); - data += 4; + __memcpy (data, nums + i, type_size); + data += type_size; } #ifndef JERRY_NDEBUG diff --git a/src/liboptimizer/serializer.h b/src/liboptimizer/serializer.h index efb4f938b..38a8eb7a6 100644 --- a/src/liboptimizer/serializer.h +++ b/src/liboptimizer/serializer.h @@ -24,7 +24,7 @@ void serializer_init (bool show_opcodes); uint16_t serializer_dump_strings (const char **, uint8_t); -void serializer_dump_nums (const int32_t *, uint8_t, uint16_t, uint8_t); +void serializer_dump_nums (const ecma_number_t *, uint8_t, uint16_t, uint8_t); void serializer_dump_opcode (OPCODE); diff --git a/src/main.c b/src/main.c index 07ce24a54..569cf83cf 100644 --- a/src/main.c +++ b/src/main.c @@ -36,7 +36,7 @@ static const OPCODE * parser_run (const char *script_source, size_t script_source_size, bool is_show_opcodes) { const char *strings[MAX_STRINGS]; - int32_t nums[MAX_NUMS]; + ecma_number_t nums[MAX_NUMS]; uint8_t strings_num, nums_count; uint16_t offset; const OPCODE *opcodes;