diff --git a/jerry-core/CMakeLists.txt b/jerry-core/CMakeLists.txt index 1cbb98ab4d..d60195849c 100644 --- a/jerry-core/CMakeLists.txt +++ b/jerry-core/CMakeLists.txt @@ -100,8 +100,8 @@ project (JerryCore CXX C ASM) ${CMAKE_SOURCE_DIR}/jerry-core/ecma/builtin-objects ${CMAKE_SOURCE_DIR}/jerry-core/ecma/base ${CMAKE_SOURCE_DIR}/jerry-core/ecma/operations - ${CMAKE_SOURCE_DIR}/jerry-core/parser/collections ${CMAKE_SOURCE_DIR}/jerry-core/parser/js + ${CMAKE_SOURCE_DIR}/jerry-core/parser/js/collections ${CMAKE_SOURCE_DIR}/jerry-core/jrt) # Third-party @@ -110,17 +110,17 @@ project (JerryCore CXX C ASM) # Sources # Jerry core - file(GLOB SOURCE_CORE_API *.cpp) - file(GLOB SOURCE_CORE_LIT lit/*.cpp) - file(GLOB SOURCE_CORE_RCS rcs/*.cpp) - file(GLOB SOURCE_CORE_MEM mem/*.cpp) - file(GLOB SOURCE_CORE_VM vm/*.cpp) - file(GLOB SOURCE_CORE_ECMA_BUILTINS ecma/builtin-objects/*.cpp) - file(GLOB SOURCE_CORE_ECMA_BASE ecma/base/*.cpp) - file(GLOB SOURCE_CORE_ECMA_OPERATIONS ecma/operations/*.cpp) - file(GLOB SOURCE_CORE_PARSER_COLLECTIONS parser/collections/*.cpp) - file(GLOB SOURCE_CORE_PARSER_JS parser/js/*.cpp) - file(GLOB SOURCE_CORE_JRT jrt/*.cpp) + file(GLOB SOURCE_CORE_API *.cpp) + file(GLOB SOURCE_CORE_LIT lit/*.cpp) + file(GLOB SOURCE_CORE_RCS rcs/*.cpp) + file(GLOB SOURCE_CORE_MEM mem/*.cpp) + file(GLOB SOURCE_CORE_VM vm/*.cpp) + file(GLOB SOURCE_CORE_ECMA_BUILTINS ecma/builtin-objects/*.cpp) + file(GLOB SOURCE_CORE_ECMA_BASE ecma/base/*.cpp) + file(GLOB SOURCE_CORE_ECMA_OPERATIONS ecma/operations/*.cpp) + file(GLOB SOURCE_CORE_PARSER_JS parser/js/*.cpp) + file(GLOB SOURCE_CORE_PARSER_JS_COLLECTIONS parser/js/collections/*.cpp) + file(GLOB SOURCE_CORE_JRT jrt/*.cpp) set(SOURCE_CORE jerry.cpp @@ -132,8 +132,8 @@ project (JerryCore CXX C ASM) ${SOURCE_CORE_ECMA_BUILTINS} ${SOURCE_CORE_ECMA_BASE} ${SOURCE_CORE_ECMA_OPERATIONS} - ${SOURCE_CORE_PARSER_COLLECTIONS} ${SOURCE_CORE_PARSER_JS} + ${SOURCE_CORE_PARSER_JS_COLLECTIONS} ${SOURCE_CORE_JRT}) # Per-option configuration diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-function.cpp b/jerry-core/ecma/builtin-objects/ecma-builtin-function.cpp index 04fddbe5e5..57eb643e36 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-function.cpp +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-function.cpp @@ -15,6 +15,7 @@ #include "ecma-alloc.h" #include "ecma-conversion.h" +#include "ecma-exceptions.h" #include "ecma-gc.h" #include "ecma-function-object.h" #include "ecma-lex-env.h" @@ -130,52 +131,55 @@ ecma_builtin_function_dispatch_construct (const ecma_value_t *arguments_list_p, zt_string_buffer_pos += sz; } - parser_init (); + const opcode_t* opcodes_p; + bool is_syntax_correct; - /* - * FIXME: - * Handle syntax errors - */ - parser_parse_new_function ((const char **) zt_string_params_p, params_count); - const opcode_t* opcodes_p = (const opcode_t*) serializer_get_bytecode (); - serializer_print_opcodes (); - parser_free (); + is_syntax_correct = parser_parse_new_function ((const char **) zt_string_params_p, + params_count, + &opcodes_p); - bool is_strict = false; - bool do_instantiate_arguments_object = true; - - opcode_scope_code_flags_t scope_flags = vm_get_scope_flags (opcodes_p, - 0); - - if (scope_flags & OPCODE_SCOPE_CODE_FLAGS_STRICT) + if (!is_syntax_correct) { - is_strict = true; + ret_value = ecma_make_throw_obj_completion_value (ecma_new_standard_error (ECMA_ERROR_SYNTAX)); } - - if ((scope_flags & OPCODE_SCOPE_CODE_FLAGS_NOT_REF_ARGUMENTS_IDENTIFIER) - && (scope_flags & OPCODE_SCOPE_CODE_FLAGS_NOT_REF_EVAL_IDENTIFIER)) + else { - /* the code doesn't use 'arguments' identifier - * and doesn't perform direct call to eval, - * so Arguments object can't be referenced */ - do_instantiate_arguments_object = false; + bool is_strict = false; + bool do_instantiate_arguments_object = true; + + opcode_scope_code_flags_t scope_flags = vm_get_scope_flags (opcodes_p, + 0); + + if (scope_flags & OPCODE_SCOPE_CODE_FLAGS_STRICT) + { + is_strict = true; + } + + if ((scope_flags & OPCODE_SCOPE_CODE_FLAGS_NOT_REF_ARGUMENTS_IDENTIFIER) + && (scope_flags & OPCODE_SCOPE_CODE_FLAGS_NOT_REF_EVAL_IDENTIFIER)) + { + /* the code doesn't use 'arguments' identifier + * and doesn't perform direct call to eval, + * so Arguments object can't be referenced */ + do_instantiate_arguments_object = false; + } + + /* 11. */ + ecma_object_t *glob_lex_env_p = ecma_get_global_environment (); + + ecma_object_t *func_obj_p = ecma_op_create_function_object (params_count > 1u ? string_params_p : NULL, + (ecma_length_t) (params_count - 1u), + glob_lex_env_p, + is_strict, + do_instantiate_arguments_object, + opcodes_p, + 1); + + ecma_deref_object (glob_lex_env_p); + + ret_value = ecma_make_normal_completion_value (ecma_make_object_value (func_obj_p)); } - /* 11. */ - ecma_object_t *glob_lex_env_p = ecma_get_global_environment (); - - ecma_object_t *func_obj_p = ecma_op_create_function_object (params_count > 1u ? string_params_p : NULL, - (ecma_length_t) (params_count - 1u), - glob_lex_env_p, - is_strict, - do_instantiate_arguments_object, - opcodes_p, - 1); - - ecma_deref_object (glob_lex_env_p); - - ret_value = ecma_make_normal_completion_value (ecma_make_object_value (func_obj_p)); - MEM_FINALIZE_LOCAL_ARRAY (zt_string_buffer_p); MEM_FINALIZE_LOCAL_ARRAY (zt_string_params_p); } diff --git a/jerry-core/ecma/operations/ecma-eval.cpp b/jerry-core/ecma/operations/ecma-eval.cpp index 85c777204c..eaf38d5664 100644 --- a/jerry-core/ecma/operations/ecma-eval.cpp +++ b/jerry-core/ecma/operations/ecma-eval.cpp @@ -86,22 +86,12 @@ ecma_op_eval_chars_buffer (const ecma_char_t *code_p, /**< code characters buffe ecma_completion_value_t completion; - parser_init (); - bool is_syntax_correct = parser_parse_eval ((const char *) code_p, code_buffer_size); - const opcode_t* opcodes_p = (const opcode_t*) serializer_get_bytecode (); - serializer_print_opcodes (); - parser_free (); - - opcode_counter_t first_opcode_index = 0u; - bool is_strict_prologue = false; - opcode_scope_code_flags_t scope_flags = vm_get_scope_flags (opcodes_p, - first_opcode_index++); - if (scope_flags & OPCODE_SCOPE_CODE_FLAGS_STRICT) - { - is_strict_prologue = true; - } + const opcode_t *opcodes_p; + bool is_syntax_correct; - bool is_strict = (is_strict_prologue || (is_direct && is_called_from_strict_mode_code)); + is_syntax_correct = parser_parse_eval ((const char *) code_p, + code_buffer_size, + &opcodes_p); if (!is_syntax_correct) { @@ -109,6 +99,17 @@ ecma_op_eval_chars_buffer (const ecma_char_t *code_p, /**< code characters buffe } else { + opcode_counter_t first_opcode_index = 0u; + bool is_strict_prologue = false; + opcode_scope_code_flags_t scope_flags = vm_get_scope_flags (opcodes_p, + first_opcode_index++); + if (scope_flags & OPCODE_SCOPE_CODE_FLAGS_STRICT) + { + is_strict_prologue = true; + } + + bool is_strict = (is_strict_prologue || (is_direct && is_called_from_strict_mode_code)); + ecma_value_t this_binding; ecma_object_t *lex_env_p; diff --git a/jerry-core/jerry.cpp b/jerry-core/jerry.cpp index 81f6a008ea..4ca954b942 100644 --- a/jerry-core/jerry.cpp +++ b/jerry-core/jerry.cpp @@ -1244,6 +1244,9 @@ jerry_reg_err_callback (jerry_error_callback_t callback) /**< pointer to callbac /** * Parse script for specified context + * + * @return true - if script was parsed successfully, + * false - otherwise (SyntaxError was raised). */ bool jerry_parse (const char* source_p, /**< script source */ @@ -1254,13 +1257,18 @@ jerry_parse (const char* source_p, /**< script source */ bool is_show_opcodes = ((jerry_flags & JERRY_FLAG_SHOW_OPCODES) != 0); parser_set_show_opcodes (is_show_opcodes); - parser_init (); - parser_parse_script (source_p, source_size); - const opcode_t* opcodes = (const opcode_t*) serializer_get_bytecode (); + const opcode_t *opcodes_p; + bool is_syntax_correct; + + is_syntax_correct = parser_parse_script (source_p, + source_size, + &opcodes_p); - serializer_print_opcodes (); - parser_free (); + if (!is_syntax_correct) + { + return false; + } #ifdef MEM_STATS if (jerry_flags & JERRY_FLAG_MEM_STATS_SEPARATE) @@ -1272,7 +1280,7 @@ jerry_parse (const char* source_p, /**< script source */ bool is_show_mem_stats_per_opcode = ((jerry_flags & JERRY_FLAG_MEM_STATS_PER_OPCODE) != 0); - vm_init (opcodes, is_show_mem_stats_per_opcode); + vm_init (opcodes_p, is_show_mem_stats_per_opcode); return true; } /* jerry_parse */ diff --git a/jerry-core/jerry.h b/jerry-core/jerry.h index a2252a9c2f..b60e1d70c0 100644 --- a/jerry-core/jerry.h +++ b/jerry-core/jerry.h @@ -49,7 +49,6 @@ typedef enum { ERR_OUT_OF_MEMORY = 10, ERR_SYSCALL = 11, - ERR_PARSER = 12, ERR_UNIMPLEMENTED_CASE = 118, ERR_FAILED_INTERNAL_ASSERTION = 120 } jerry_fatal_code_t; diff --git a/jerry-core/jrt/jrt-fatals.cpp b/jerry-core/jrt/jrt-fatals.cpp index 2dcc761ba8..cfae748927 100644 --- a/jerry-core/jrt/jrt-fatals.cpp +++ b/jerry-core/jrt/jrt-fatals.cpp @@ -47,11 +47,6 @@ jerry_fatal (jerry_fatal_code_t code) /**< status code */ /* print nothing as it may invoke syscall recursively */ break; } - case ERR_PARSER: - { - printf ("ERR_PARSER\n"); - break; - } case ERR_UNIMPLEMENTED_CASE: { printf ("ERR_UNIMPLEMENTED_CASE\n"); diff --git a/jerry-core/jrt/jrt-libc-includes.h b/jerry-core/jrt/jrt-libc-includes.h index f694b52c3d..41684e1aa4 100644 --- a/jerry-core/jrt/jrt-libc-includes.h +++ b/jerry-core/jrt/jrt-libc-includes.h @@ -17,6 +17,8 @@ #define JRT_LIBC_INCLUDES_H #include +#include +#include #include #include #include diff --git a/jerry-core/parser/collections/lit-id-hash-table.cpp b/jerry-core/parser/collections/lit-id-hash-table.cpp deleted file mode 100644 index 924299c6ce..0000000000 --- a/jerry-core/parser/collections/lit-id-hash-table.cpp +++ /dev/null @@ -1,64 +0,0 @@ -/* Copyright 2014-2015 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 "lit-id-hash-table.h" -#include "bytecode-data.h" - -lit_id_hash_table * -lit_id_hash_table_init (size_t buckets_count, size_t blocks_count) -{ - size_t size = mem_heap_recommend_allocation_size (sizeof (lit_id_hash_table)); - lit_id_hash_table *table = (lit_id_hash_table *) mem_heap_alloc_block (size, MEM_HEAP_ALLOC_LONG_TERM); - memset (table, 0, size); - size = mem_heap_recommend_allocation_size (sizeof (lit_cpointer_t) * buckets_count); - table->raw_buckets = (lit_cpointer_t *) mem_heap_alloc_block (size, MEM_HEAP_ALLOC_LONG_TERM); - memset (table->raw_buckets, 0, size); - size = mem_heap_recommend_allocation_size (sizeof (lit_cpointer_t *) * blocks_count); - table->buckets = (lit_cpointer_t **) mem_heap_alloc_block (size, MEM_HEAP_ALLOC_LONG_TERM); - memset (table->buckets, 0, size); - table->current_bucket_pos = 0; - return table; -} - -void -lit_id_hash_table_free (lit_id_hash_table *table) -{ - JERRY_ASSERT (table); - mem_heap_free_block ((uint8_t *) table->raw_buckets); - mem_heap_free_block ((uint8_t *) table->buckets); - mem_heap_free_block ((uint8_t *) table); -} - -void -lit_id_hash_table_insert (lit_id_hash_table *table, idx_t uid, opcode_counter_t oc, lit_cpointer_t lit_cp) -{ - JERRY_ASSERT (table); - size_t block_id = oc / BLOCK_SIZE; - if (table->buckets[block_id] == NULL) - { - table->buckets[block_id] = table->raw_buckets + table->current_bucket_pos; - } - table->buckets[block_id][uid] = lit_cp; - table->current_bucket_pos++; -} - -lit_cpointer_t -lit_id_hash_table_lookup (lit_id_hash_table *table, idx_t uid, opcode_counter_t oc) -{ - JERRY_ASSERT (table); - size_t block_id = oc / BLOCK_SIZE; - JERRY_ASSERT (table->buckets[block_id]); - return table->buckets[block_id][uid]; -} diff --git a/jerry-core/parser/js/bytecode-data.h b/jerry-core/parser/js/bytecode-data.h index 207be7ee9a..e741d463d7 100644 --- a/jerry-core/parser/js/bytecode-data.h +++ b/jerry-core/parser/js/bytecode-data.h @@ -18,6 +18,7 @@ #include "opcodes.h" #include "lit-id-hash-table.h" +#include "mem-allocator.h" /* * All literals are kept in the 'literals' array. @@ -35,11 +36,13 @@ #define BLOCK_SIZE 64 /** - * Pointer to lit_id_hash_table precedes every independent bytecode region + * Header of byte-code memory region, containing byte-code array and literal identifiers hash table */ typedef struct __attribute__ ((aligned (MEM_ALIGNMENT))) { - lit_id_hash_table *lit_id_hash; + mem_cpointer_t lit_id_hash_cp; /**< pointer to literal identifiers hash table + * See also: lit_id_hash_table_init */ + mem_cpointer_t next_opcodes_cp; /**< pointer to next byte-code memory region */ } opcodes_header_t; typedef struct @@ -50,14 +53,15 @@ typedef struct } bytecode_data_t; /** - * Macros to get a hash table corresponding to a bytecode region + * Macros to get a pointer to bytecode header by pointer to opcodes start */ -#define GET_HASH_TABLE_FOR_BYTECODE(opcodes) (((opcodes_header_t *) (((uint8_t *) (opcodes)) - \ - sizeof (opcodes_header_t)))->lit_id_hash) +#define GET_BYTECODE_HEADER(opcodes) ((opcodes_header_t *) (((uint8_t *) (opcodes)) - sizeof (opcodes_header_t))) /** - * Macros to get a pointer to bytecode header by pointer to opcodes start + * Macros to get a hash table corresponding to a bytecode region */ -#define GET_BYTECODE_HEADER(opcodes) ((opcodes_header_t *) (((uint8_t *) (opcodes)) - sizeof (opcodes_header_t))) +#define GET_HASH_TABLE_FOR_BYTECODE(opcodes) (MEM_CP_GET_POINTER (lit_id_hash_table, \ + GET_BYTECODE_HEADER (opcodes)->lit_id_hash_cp)) + #endif // BYTECODE_DATA_H diff --git a/jerry-core/parser/collections/array-list.cpp b/jerry-core/parser/js/collections/array-list.cpp similarity index 86% rename from jerry-core/parser/collections/array-list.cpp rename to jerry-core/parser/js/collections/array-list.cpp index f964aed6e7..51422bb4c3 100644 --- a/jerry-core/parser/collections/array-list.cpp +++ b/jerry-core/parser/js/collections/array-list.cpp @@ -14,8 +14,8 @@ */ #include "array-list.h" -#include "mem-heap.h" #include "jrt-libc-includes.h" +#include "jsp-mm.h" typedef struct { @@ -44,14 +44,14 @@ array_list_append (array_list al, void *element) array_list_header *h = extract_header (al); if ((h->len + 1) * h->element_size + sizeof (array_list_header) > h->size) { - size_t size = mem_heap_recommend_allocation_size (h->size + h->element_size); + size_t size = jsp_mm_recommend_size (h->size + h->element_size); JERRY_ASSERT (size > h->size); - uint8_t* new_block_p = (uint8_t*) mem_heap_alloc_block (size, MEM_HEAP_ALLOC_SHORT_TERM); + uint8_t *new_block_p = (uint8_t *) jsp_mm_alloc (size); memcpy (new_block_p, h, h->size); memset (new_block_p + h->size, 0, size - h->size); - mem_heap_free_block ((uint8_t *) h); + jsp_mm_free (h); h = (array_list_header *) new_block_p; h->size = size; @@ -111,8 +111,8 @@ array_list_set_last_element (array_list al, size_t index, void *elem) array_list array_list_init (uint8_t element_size) { - size_t size = mem_heap_recommend_allocation_size (sizeof (array_list_header)); - array_list_header *header = (array_list_header *) mem_heap_alloc_block (size, MEM_HEAP_ALLOC_SHORT_TERM); + size_t size = jsp_mm_recommend_size (sizeof (array_list_header)); + array_list_header *header = (array_list_header *) jsp_mm_alloc (size); memset (header, 0, size); header->element_size = element_size; header->len = 0; @@ -131,5 +131,5 @@ void array_list_free (array_list al) { array_list_header *h = extract_header (al); - mem_heap_free_block ((uint8_t *) h); + jsp_mm_free (h); } diff --git a/jerry-core/parser/collections/array-list.h b/jerry-core/parser/js/collections/array-list.h similarity index 100% rename from jerry-core/parser/collections/array-list.h rename to jerry-core/parser/js/collections/array-list.h diff --git a/jerry-core/parser/collections/hash-table.cpp b/jerry-core/parser/js/collections/hash-table.cpp similarity index 83% rename from jerry-core/parser/collections/hash-table.cpp rename to jerry-core/parser/js/collections/hash-table.cpp index ac5abe6a3c..5b0948335d 100644 --- a/jerry-core/parser/collections/hash-table.cpp +++ b/jerry-core/parser/js/collections/hash-table.cpp @@ -13,10 +13,10 @@ * limitations under the License. */ -#include "hash-table.h" #include "array-list.h" -#include "mem-heap.h" +#include "hash-table.h" #include "jrt-libc-includes.h" +#include "jsp-mm.h" typedef struct { @@ -25,7 +25,6 @@ typedef struct uint16_t size; uint8_t key_size; uint8_t value_size; - mem_heap_alloc_term_t alloc_term; } hash_table_int; static hash_table_int * @@ -65,12 +64,12 @@ hash_table_insert (hash_table ht, void *key, void *value) { list = array_list_init (bucket_size (hti)); } - uint8_t *bucket = (uint8_t*) mem_heap_alloc_block (bucket_size (hti), hti->alloc_term); + uint8_t *bucket = (uint8_t *) jsp_mm_alloc (bucket_size (hti)); memcpy (bucket, key, hti->key_size); memcpy (bucket + hti->key_size, value, hti->value_size); list = array_list_append (list, bucket); hti->data[index] = list; - mem_heap_free_block (bucket); + jsp_mm_free (bucket); } void * @@ -98,15 +97,14 @@ hash_table_lookup (hash_table ht, void *key) hash_table hash_table_init (uint8_t key_size, uint8_t value_size, uint16_t size, - uint16_t (*hash) (void *), mem_heap_alloc_term_t alloc_term) + uint16_t (*hash) (void *)) { - hash_table_int *res = (hash_table_int *) mem_heap_alloc_block (sizeof (hash_table_int), alloc_term); + hash_table_int *res = (hash_table_int *) jsp_mm_alloc (sizeof (hash_table_int)); memset (res, 0, sizeof (hash_table_int)); res->key_size = key_size; res->value_size = value_size; res->size = size; - res->alloc_term = alloc_term; - res->data = (array_list *) mem_heap_alloc_block (size * sizeof (array_list), alloc_term); + res->data = (array_list *) jsp_mm_alloc (size * sizeof (array_list)); memset (res->data, 0, size * sizeof (array_list)); res->hash = hash; return res; @@ -125,6 +123,6 @@ hash_table_free (hash_table ht) set_list (h, i, null_list); } } - mem_heap_free_block ((uint8_t *) h->data); - mem_heap_free_block ((uint8_t *) h); + jsp_mm_free (h->data); + jsp_mm_free (h); } diff --git a/jerry-core/parser/collections/hash-table.h b/jerry-core/parser/js/collections/hash-table.h similarity index 97% rename from jerry-core/parser/collections/hash-table.h rename to jerry-core/parser/js/collections/hash-table.h index 2e47bf9a4b..f284a7eebb 100644 --- a/jerry-core/parser/collections/hash-table.h +++ b/jerry-core/parser/js/collections/hash-table.h @@ -30,7 +30,7 @@ typedef void* hash_table; #define null_hash NULL -hash_table hash_table_init (uint8_t, uint8_t, uint16_t, uint16_t (*hash) (void *), mem_heap_alloc_term_t); +hash_table hash_table_init (uint8_t, uint8_t, uint16_t, uint16_t (*hash) (void *)); void hash_table_free (hash_table); void hash_table_insert (hash_table, void *, void *); void *hash_table_lookup (hash_table, void *); diff --git a/jerry-core/parser/collections/linked-list.cpp b/jerry-core/parser/js/collections/linked-list.cpp similarity index 92% rename from jerry-core/parser/collections/linked-list.cpp rename to jerry-core/parser/js/collections/linked-list.cpp index f9b6c2cfdc..a4329c3f58 100644 --- a/jerry-core/parser/collections/linked-list.cpp +++ b/jerry-core/parser/js/collections/linked-list.cpp @@ -13,9 +13,9 @@ * limitations under the License. */ -#include "linked-list.h" #include "jrt-libc-includes.h" -#include "mem-heap.h" +#include "jsp-mm.h" +#include "linked-list.h" typedef struct linked_list_header { @@ -31,14 +31,14 @@ do { \ static size_t linked_list_block_size (uint16_t element_size) { - return mem_heap_recommend_allocation_size (sizeof (linked_list_header) + element_size) - sizeof (linked_list_header); + return jsp_mm_recommend_size (sizeof (linked_list_header) + element_size) - sizeof (linked_list_header); } linked_list linked_list_init (uint16_t element_size) { size_t size = sizeof (linked_list_header) + linked_list_block_size (element_size); - linked_list list = (linked_list) mem_heap_alloc_block (size, MEM_HEAP_ALLOC_SHORT_TERM); + linked_list list = (linked_list) jsp_mm_alloc (size); if (list == null_list) { printf ("Out of memory"); @@ -60,7 +60,7 @@ linked_list_free (linked_list list) { linked_list_free ((linked_list) header->next); } - mem_heap_free_block (list); + jsp_mm_free (list); } void * diff --git a/jerry-core/parser/collections/linked-list.h b/jerry-core/parser/js/collections/linked-list.h similarity index 100% rename from jerry-core/parser/collections/linked-list.h rename to jerry-core/parser/js/collections/linked-list.h diff --git a/jerry-core/parser/js/collections/lit-id-hash-table.cpp b/jerry-core/parser/js/collections/lit-id-hash-table.cpp new file mode 100644 index 0000000000..8da6188e18 --- /dev/null +++ b/jerry-core/parser/js/collections/lit-id-hash-table.cpp @@ -0,0 +1,129 @@ +/* Copyright 2014-2015 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 "lit-id-hash-table.h" +#include "bytecode-data.h" + +/** \addtogroup jsparser ECMAScript parser + * @{ + * + * \addtogroup collections Collections + * @{ + * + * \addtogroup lit_id_hash_table Literal identifiers hash table + * The hash table connects pairs (opcode block, idx_t value) with literal identifiers. + * @{ + */ + +/** + * Initialize literal identifiers hash table + * + * @return pointer to header of the table + */ +lit_id_hash_table * +lit_id_hash_table_init (uint8_t *table_buffer_p, /**< buffer to initialize hash table in */ + size_t buffer_size, /**< size of the buffer */ + size_t buckets_count, /**< number of pairs */ + size_t blocks_count) /**< number of opcode blocks */ +{ + const size_t header_size = JERRY_ALIGNUP (sizeof (lit_id_hash_table), MEM_ALIGNMENT); + const size_t raw_buckets_size = JERRY_ALIGNUP (sizeof (lit_cpointer_t) * buckets_count, MEM_ALIGNMENT); + const size_t buckets_size = JERRY_ALIGNUP (sizeof (lit_cpointer_t*) * blocks_count, MEM_ALIGNMENT); + + JERRY_ASSERT (header_size + raw_buckets_size + buckets_size <= buffer_size); + + lit_id_hash_table *table_p = (lit_id_hash_table *) table_buffer_p; + + table_p->current_bucket_pos = 0; + table_p->raw_buckets = (lit_cpointer_t*) (table_buffer_p + header_size); + table_p->buckets = (lit_cpointer_t **) (table_buffer_p + header_size + raw_buckets_size); + + memset (table_p->buckets, 0, buckets_size); + + return table_p; +} /* lit_id_hash_table_init */ + +/** + * Get size of buffer, necessary to hold hash table with specified parameters + * + * @return size of buffer + */ +size_t +lit_id_hash_table_get_size_for_table (size_t buckets_count, /**< number of pairs */ + size_t blocks_count) /**< number of opcode blocks */ +{ + const size_t header_size = JERRY_ALIGNUP (sizeof (lit_id_hash_table), MEM_ALIGNMENT); + const size_t raw_buckets_size = JERRY_ALIGNUP (sizeof (lit_cpointer_t) * buckets_count, MEM_ALIGNMENT); + const size_t buckets_size = JERRY_ALIGNUP (sizeof (lit_cpointer_t*) * blocks_count, MEM_ALIGNMENT); + + return header_size + raw_buckets_size + buckets_size; +} /* lit_id_hash_table_get_size_for_table */ + +/** + * Free literal identifiers hash table + */ +void +lit_id_hash_table_free (lit_id_hash_table *table_p) /**< table's header */ +{ + JERRY_ASSERT (table_p != NULL); + + mem_heap_free_block ((uint8_t *) table_p); +} /* lit_id_hash_table_free */ + +/** + * Register pair in the hash table + */ +void +lit_id_hash_table_insert (lit_id_hash_table *table_p, /**< table's header */ + idx_t uid, /**< value of byte-code instruction's argument */ + opcode_counter_t oc, /**< opcode counter of the instruction */ + lit_cpointer_t lit_cp) /**< literal identifier */ +{ + JERRY_ASSERT (table_p != NULL); + + size_t block_id = oc / BLOCK_SIZE; + + if (table_p->buckets[block_id] == NULL) + { + table_p->buckets[block_id] = table_p->raw_buckets + table_p->current_bucket_pos; + } + + table_p->buckets[block_id][uid] = lit_cp; + table_p->current_bucket_pos++; +} /* lit_id_hash_table_insert */ + +/** + * Lookup literal identifier by pair + * + * @return literal identifier + */ +lit_cpointer_t +lit_id_hash_table_lookup (lit_id_hash_table *table_p, /**< table's header */ + idx_t uid, /**< value of byte-code instruction's argument */ + opcode_counter_t oc) /**< opcode counter of the instruction */ +{ + JERRY_ASSERT (table_p != NULL); + + size_t block_id = oc / BLOCK_SIZE; + JERRY_ASSERT (table_p->buckets[block_id] != NULL); + + return table_p->buckets[block_id][uid]; +} /* lit_id_hash_table_lookup */ + +/** + * @} + * @} + * @} + */ diff --git a/jerry-core/parser/collections/lit-id-hash-table.h b/jerry-core/parser/js/collections/lit-id-hash-table.h similarity index 89% rename from jerry-core/parser/collections/lit-id-hash-table.h rename to jerry-core/parser/js/collections/lit-id-hash-table.h index 94ef734690..6905652e5a 100644 --- a/jerry-core/parser/collections/lit-id-hash-table.h +++ b/jerry-core/parser/js/collections/lit-id-hash-table.h @@ -28,7 +28,8 @@ typedef struct lit_cpointer_t **buckets; } lit_id_hash_table; -lit_id_hash_table *lit_id_hash_table_init (size_t, size_t); +lit_id_hash_table *lit_id_hash_table_init (uint8_t*, size_t, size_t, size_t); +size_t lit_id_hash_table_get_size_for_table (size_t, size_t); void lit_id_hash_table_free (lit_id_hash_table *); void lit_id_hash_table_insert (lit_id_hash_table *, idx_t, opcode_counter_t, lit_cpointer_t); lit_cpointer_t lit_id_hash_table_lookup (lit_id_hash_table *, idx_t, opcode_counter_t); diff --git a/jerry-core/parser/collections/stack.h b/jerry-core/parser/js/collections/stack.h similarity index 89% rename from jerry-core/parser/collections/stack.h rename to jerry-core/parser/js/collections/stack.h index 7cd14f5e82..77b4dd9e33 100644 --- a/jerry-core/parser/collections/stack.h +++ b/jerry-core/parser/js/collections/stack.h @@ -117,24 +117,6 @@ static void NAME##_stack_push (TYPE value) { \ NAME.data = array_list_append (NAME.data, &value); \ } -#define DEFINE_CONVERT_TO_RAW_DATA(NAME, TYPE) \ -static TYPE *convert_##NAME##_to_raw_data (void) __attr_unused___; \ -static TYPE *convert_##NAME##_to_raw_data (void) { \ - if (array_list_len (NAME.data) == 0) \ - { \ - return NULL; \ - } \ - size_t size = mem_heap_recommend_allocation_size (array_list_len (NAME.data) * sizeof (NAME##_stack_value_type)); \ - TYPE *DATA = (TYPE *) mem_heap_alloc_block (size, MEM_HEAP_ALLOC_LONG_TERM); \ - if (DATA == NULL) \ - { \ - printf ("Out of memory\n"); \ - JERRY_UNREACHABLE (); \ - } \ - memcpy (DATA, array_list_element (NAME.data, 0), array_list_len (NAME.data) * sizeof (NAME##_stack_value_type)); \ - return DATA; \ -} - #define STACK_PUSH(NAME, VALUE) \ do { NAME##_stack_push (VALUE); } while (0) @@ -207,7 +189,6 @@ NAME##_stack NAME; \ DEFINE_STACK_ELEMENT (NAME, TYPE) \ DEFINE_SET_STACK_ELEMENT (NAME, TYPE) \ DEFINE_STACK_HEAD (NAME, TYPE) \ -DEFINE_CONVERT_TO_RAW_DATA (NAME, TYPE) \ DEFINE_SET_STACK_HEAD (NAME, TYPE) \ DEFINE_STACK_PUSH (NAME, TYPE) @@ -217,7 +198,6 @@ static NAME##_stack NAME; \ DEFINE_STACK_ELEMENT (NAME, TYPE) \ DEFINE_SET_STACK_ELEMENT (NAME, TYPE) \ DEFINE_STACK_HEAD (NAME, TYPE) \ -DEFINE_CONVERT_TO_RAW_DATA (NAME, TYPE) \ DEFINE_SET_STACK_HEAD (NAME, TYPE) \ DEFINE_STACK_PUSH (NAME, TYPE) diff --git a/jerry-core/parser/js/jsp-label.cpp b/jerry-core/parser/js/jsp-label.cpp index 1d2848980b..a546b3ce44 100644 --- a/jerry-core/parser/js/jsp-label.cpp +++ b/jerry-core/parser/js/jsp-label.cpp @@ -47,6 +47,18 @@ jsp_label_finalize (void) JERRY_ASSERT (label_set_p == NULL); } /* jsp_label_finalize */ +/** + * Remove all labels + * + * Note: + * should be used only upon a SyntaxError is raised + */ +void +jsp_label_remove_all_labels (void) +{ + label_set_p = NULL; +} /* jsp_label_remove_all_labels */ + /** * Add label to the current label set */ diff --git a/jerry-core/parser/js/jsp-label.h b/jerry-core/parser/js/jsp-label.h index dd05432187..d37ef43043 100644 --- a/jerry-core/parser/js/jsp-label.h +++ b/jerry-core/parser/js/jsp-label.h @@ -67,6 +67,8 @@ typedef struct jsp_label_t extern void jsp_label_init (void); extern void jsp_label_finalize (void); +extern void jsp_label_remove_all_labels (void); + extern void jsp_label_push (jsp_label_t *out_label_p, jsp_label_type_flag_t type_mask, token id); extern void jsp_label_rewrite_jumps_and_pop (jsp_label_t *label_p, opcode_counter_t break_tgt_oc); diff --git a/jerry-core/parser/js/jsp-mm.cpp b/jerry-core/parser/js/jsp-mm.cpp new file mode 100644 index 0000000000..6fc7b1293b --- /dev/null +++ b/jerry-core/parser/js/jsp-mm.cpp @@ -0,0 +1,163 @@ +/* Copyright 2015 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 "jrt.h" +#include "jsp-mm.h" +#include "mem-allocator.h" +#include "mem-heap.h" + +/** \addtogroup jsparser ECMAScript parser + * @{ + * + * \addtogroup managedmem Managed memory allocation + * @{ + */ + +/** + * Header of a managed block, allocated by parser + */ +typedef struct __attribute__ ((alignment (MEM_ALIGNMENT))) +{ + mem_cpointer_t prev_block_cp; /**< previous managed block */ + mem_cpointer_t next_block_cp; /**< next managed block */ +} jsp_mm_header_t; + +/** + * List used for tracking memory blocks + */ +jsp_mm_header_t *jsp_mm_blocks_p = NULL; + +/** + * Initialize managed memory allocator + */ +void +jsp_mm_init (void) +{ + JERRY_ASSERT (jsp_mm_blocks_p == NULL); +} /* jsp_mm_init */ + +/** + * Finalize managed memory allocator + */ +void +jsp_mm_finalize (void) +{ + JERRY_ASSERT (jsp_mm_blocks_p == NULL); +} /* jsp_mm_finalize */ + +/** + * Recommend allocation size + * + * Note: + * The interface is used by collection allocators + * for storage of data that takes the specified + * amount of bytes upon allocation, but probably + * would require more. + * + * To reduce probability of reallocation in future, + * the allocators can request more space in first + * allocation request. + * + * The interface helps to choose appropriate space + * to allocate, considering amount of heap space, + * that would be waste if allocation size + * would not be increased. + * + * @return recommended allocation size + */ +size_t +jsp_mm_recommend_size (size_t minimum_size) /**< minimum required size */ +{ + size_t block_and_header_size = mem_heap_recommend_allocation_size (minimum_size + sizeof (jsp_mm_header_t)); + return block_and_header_size - sizeof (jsp_mm_header_t); +} /* jsp_mm_recommend_size */ + +/** + * Allocate a managed memory block of specified size + * + * @return pointer to data space of allocated block + */ +void* +jsp_mm_alloc (size_t size) /**< size of block to allocate */ +{ + void *ptr_p = mem_heap_alloc_block (size + sizeof (jsp_mm_header_t), MEM_HEAP_ALLOC_SHORT_TERM); + + jsp_mm_header_t *tmem_header_p = (jsp_mm_header_t*) ptr_p; + + tmem_header_p->prev_block_cp = MEM_CP_NULL; + MEM_CP_SET_POINTER (tmem_header_p->next_block_cp, jsp_mm_blocks_p); + + if (jsp_mm_blocks_p != NULL) + { + MEM_CP_SET_POINTER (jsp_mm_blocks_p->prev_block_cp, tmem_header_p); + } + + jsp_mm_blocks_p = tmem_header_p; + + return (void *) (tmem_header_p + 1); +} /* jsp_mm_alloc */ + +/** + * Free a managed memory block + */ +void +jsp_mm_free (void *ptr) /**< pointer to data space of allocated block */ +{ + jsp_mm_header_t *tmem_header_p = ((jsp_mm_header_t *) ptr) - 1; + + jsp_mm_header_t *prev_block_p = MEM_CP_GET_POINTER (jsp_mm_header_t, + tmem_header_p->prev_block_cp); + jsp_mm_header_t *next_block_p = MEM_CP_GET_POINTER (jsp_mm_header_t, + tmem_header_p->next_block_cp); + + if (prev_block_p != NULL) + { + prev_block_p->next_block_cp = tmem_header_p->next_block_cp; + } + else + { + JERRY_ASSERT (jsp_mm_blocks_p == tmem_header_p); + jsp_mm_blocks_p = next_block_p; + } + + if (next_block_p != NULL) + { + next_block_p->prev_block_cp = tmem_header_p->prev_block_cp; + } + + mem_heap_free_block (tmem_header_p); +} /* jsp_mm_free */ + +/** + * Free all currently allocated managed memory blocks + */ +void +jsp_mm_free_all (void) +{ + while (jsp_mm_blocks_p != NULL) + { + jsp_mm_header_t *next_block_p = MEM_CP_GET_POINTER (jsp_mm_header_t, + jsp_mm_blocks_p->next_block_cp); + + mem_heap_free_block (jsp_mm_blocks_p); + + jsp_mm_blocks_p = next_block_p; + } +} /* jsp_mm_free_all */ + +/** + * @} + * @} + */ diff --git a/jerry-core/parser/js/jsp-mm.h b/jerry-core/parser/js/jsp-mm.h new file mode 100644 index 0000000000..d4157763ea --- /dev/null +++ b/jerry-core/parser/js/jsp-mm.h @@ -0,0 +1,40 @@ +/* Copyright 2015 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. + */ + +#ifndef JSP_MM_H +#define JSP_MM_H + +#include "jrt-libc-includes.h" + +/** \addtogroup jsparser ECMAScript parser + * @{ + * + * \addtogroup managedmem Managed memory allocation + * @{ + */ + +extern void jsp_mm_init (void); +extern void jsp_mm_finalize (void); +extern size_t jsp_mm_recommend_size (size_t); +extern void * jsp_mm_alloc (size_t); +extern void jsp_mm_free (void *); +extern void jsp_mm_free_all (void); + +/** + * @} + * @} + */ + +#endif /* !JSP_MM_H */ diff --git a/jerry-core/parser/js/lexer.cpp b/jerry-core/parser/js/lexer.cpp index 2cafb0ae0b..369cdb1c3b 100644 --- a/jerry-core/parser/js/lexer.cpp +++ b/jerry-core/parser/js/lexer.cpp @@ -13,11 +13,11 @@ * limitations under the License. */ -#include "mem-allocator.h" +#include "ecma-helpers.h" #include "jrt-libc-includes.h" +#include "jsp-mm.h" #include "lexer.h" #include "syntax-errors.h" -#include "ecma-helpers.h" static token saved_token, prev_token, sent_token, empty_token; @@ -474,9 +474,7 @@ convert_string_to_token_transform_escape_seq (token_type tok_type, /**< type of JERRY_ASSERT (source_str_p != NULL); } - MEM_DEFINE_LOCAL_ARRAY (str_buf_p, - source_str_size, - ecma_char_t); + ecma_char_t *str_buf_p = (ecma_char_t*) jsp_mm_alloc (source_str_size * sizeof (ecma_char_t)); const char *source_str_iter_p = source_str_p; ecma_char_t *str_buf_iter_p = str_buf_p; @@ -632,7 +630,7 @@ convert_string_to_token_transform_escape_seq (token_type tok_type, /**< type of PARSE_ERROR ("Malformed escape sequence", source_str_p - buffer_start); } - MEM_FINALIZE_LOCAL_ARRAY (str_buf_p); + jsp_mm_free (str_buf_p); return ret; } /* convert_string_to_token_transform_escape_seq */ @@ -860,13 +858,12 @@ parse_number (void) tok_length = (size_t) (buffer - token_start);; if (is_fp || is_exp) { - ecma_char_t *temp = (ecma_char_t*) mem_heap_alloc_block ((size_t) (tok_length + 1), - MEM_HEAP_ALLOC_SHORT_TERM); + ecma_char_t *temp = (ecma_char_t*) jsp_mm_alloc ((size_t) (tok_length + 1) * sizeof (ecma_char_t)); strncpy ((char *) temp, token_start, (size_t) (tok_length)); temp[tok_length] = '\0'; ecma_number_t res = ecma_zt_string_to_number (temp); JERRY_ASSERT (!ecma_number_is_nan (res)); - mem_heap_free_block (temp); + jsp_mm_free (temp); known_token = convert_seen_num_to_token (res); token_start = NULL; return known_token; @@ -1467,28 +1464,22 @@ lexer_are_tokens_with_same_identifier (token id1, /**< identifier token (TOK_NAM } /* lexer_are_tokens_with_same_identifier */ /** - * Initialize lexer to start parsing of a new source + * Intitialize lexer */ void -lexer_init_source (const char *source, /**< script source */ - size_t source_size) /**< script source size in bytes */ +lexer_init (const char *source, /**< script source */ + size_t source_size /**< script source size in bytes */, + bool show_opcodes) /**< flag indicating if to dump opcodes */ { + empty_token.type = TOK_EMPTY; + empty_token.uid = 0; + empty_token.loc = 0; + saved_token = prev_token = sent_token = empty_token; buffer_size = source_size; lexer_set_source (source); lexer_set_strict_mode (false); -} /* lexer_init_source */ - -/** - * Intitialize lexer - */ -void -lexer_init (bool show_opcodes) /**< flag indicating if to dump opcodes */ -{ - empty_token.type = TOK_EMPTY; - empty_token.uid = 0; - empty_token.loc = 0; #ifndef JERRY_NDEBUG allow_dump_lines = show_opcodes; @@ -1497,8 +1488,3 @@ lexer_init (bool show_opcodes) /**< flag indicating if to dump opcodes */ allow_dump_lines = false; #endif /* JERRY_NDEBUG */ } /* lexer_init */ - -void -lexer_free (void) -{ -} diff --git a/jerry-core/parser/js/lexer.h b/jerry-core/parser/js/lexer.h index 914ad96397..f67b6a9914 100644 --- a/jerry-core/parser/js/lexer.h +++ b/jerry-core/parser/js/lexer.h @@ -169,9 +169,7 @@ typedef struct */ #define TOKEN_EMPTY_INITIALIZER {0, TOK_EMPTY, 0} -void lexer_init (bool); -void lexer_init_source (const char *, size_t); -void lexer_free (void); +void lexer_init (const char *, size_t, bool); token lexer_next_token (void); void lexer_save_token (token); diff --git a/jerry-core/parser/js/parser.cpp b/jerry-core/parser/js/parser.cpp index 011ef6d3c4..2c2179e463 100644 --- a/jerry-core/parser/js/parser.cpp +++ b/jerry-core/parser/js/parser.cpp @@ -13,22 +13,20 @@ * limitations under the License. */ -#include - +#include "ecma-helpers.h" +#include "hash-table.h" #include "jrt-libc-includes.h" #include "jsp-label.h" -#include "parser.h" +#include "jsp-mm.h" #include "opcodes.h" -#include "serializer.h" -#include "vm.h" -#include "stack.h" -#include "hash-table.h" +#include "opcodes-dumper.h" #include "opcodes-native-call.h" +#include "parser.h" #include "scopes-tree.h" -#include "ecma-helpers.h" -#include "syntax-errors.h" -#include "opcodes-dumper.h" #include "serializer.h" +#include "stack.h" +#include "syntax-errors.h" +#include "vm.h" /** * Flag, indicating whether result of expression @@ -2878,72 +2876,134 @@ parse_source_element_list (bool is_global) /**< flag indicating if we are parsin * program * : LT!* source_element_list LT!* EOF! * ; + * + * @return true - if parse finished successfully (no SyntaxError was raised); + * false - otherwise. */ -static void -parser_parse_program (const char *source, /**< source code buffer */ +static bool +parser_parse_program (const char *source_p, /**< source code buffer */ size_t source_size, /**< source code size in bytes */ - bool in_new_function) /**< flag indicating if we are parsing body of a function */ + bool in_function, /**< flag indicating if we are parsing body of a function */ + bool in_eval, /**< flag indicating if we are parsing body of eval code */ + const opcode_t **out_opcodes_p) /**< out: generated byte-code array + * (in case there were no syntax errors) */ { - lexer_init_source (source, source_size); + JERRY_ASSERT (out_opcodes_p != NULL); + + inside_function = in_function; + inside_eval = in_eval; + +#ifndef JERRY_NDEBUG + volatile bool is_parse_finished = false; +#endif /* !JERRY_NDEBUG */ + + bool is_syntax_correct; + jsp_mm_init (); + jsp_label_init (); + + lexer_init (source_p, source_size, parser_show_opcodes); + + serializer_set_show_opcodes (parser_show_opcodes); + dumper_init (); + syntax_init (); + + STACK_INIT (scopes); STACK_PUSH (scopes, scopes_tree_init (NULL)); serializer_set_scope (STACK_TOP (scopes)); lexer_set_strict_mode (scopes_tree_strict_mode (STACK_TOP (scopes))); - skip_newlines (); - parse_source_element_list (true); - - skip_newlines (); - JERRY_ASSERT (token_is (TOK_EOF)); + jmp_buf *syntax_error_label_p = syntax_get_syntax_error_longjmp_label (); + int r = setjmp (*syntax_error_label_p); - if (in_new_function) + if (r == 0) { - dump_ret (); - } - else if (inside_eval) - { - dump_retval (eval_ret_operand ()); + skip_newlines (); + parse_source_element_list (true); + + skip_newlines (); + JERRY_ASSERT (token_is (TOK_EOF)); + + if (in_function) + { + dump_ret (); + } + else if (inside_eval) + { + dump_retval (eval_ret_operand ()); + } + else + { + dump_exit (); + } + +#ifndef JERRY_NDEBUG + is_parse_finished = true; +#endif /* !JERRY_NDEBUG */ + + syntax_free (); + + *out_opcodes_p = serializer_merge_scopes_into_bytecode (); + + dumper_free (); + + serializer_set_scope (NULL); + scopes_tree_free (STACK_TOP (scopes)); + STACK_DROP (scopes, 1); + STACK_FREE (scopes); + + is_syntax_correct = true; } else { - dump_exit (); + /* SyntaxError handling */ + +#ifndef JERRY_NDEBUG + JERRY_ASSERT (!is_parse_finished); +#endif /* !JERRY_NDEBUG */ + + *out_opcodes_p = NULL; + + jsp_label_remove_all_labels (); + jsp_mm_free_all (); + + is_syntax_correct = false; } - serializer_dump_literals (); - serializer_merge_scopes_into_bytecode (); - serializer_set_scope (NULL); + jsp_label_finalize (); + jsp_mm_finalize (); - scopes_tree_free (STACK_TOP (scopes)); - STACK_DROP (scopes, 1); + return is_syntax_correct; } /* parser_parse_program */ /** * Parse source script + * + * @return true - if parse finished successfully (no SyntaxError were raised); + * false - otherwise. */ -void +bool parser_parse_script (const char *source, /**< source script */ - size_t source_size) /**< source script size it bytes */ + size_t source_size, /**< source script size it bytes */ + const opcode_t **opcodes_p) /**< out: generated byte-code array + * (in case there were no syntax errors) */ { - inside_eval = false; - inside_function = false; - parser_parse_program (source, source_size, false); + return parser_parse_program (source, source_size, false, false, opcodes_p); } /* parser_parse_script */ /** * Parse string passed to eval() call * - * @return true if parse succeeds - * false otherwise + * @return true - if parse finished successfully (no SyntaxError were raised); + * false - otherwise. */ -bool parser_parse_eval (const char *source, /**< string passed to eval() */ - size_t source_size) /**< string size in bytes */ +bool +parser_parse_eval (const char *source, /**< string passed to eval() */ + size_t source_size, /**< string size in bytes */ + const opcode_t **opcodes_p) /**< out: generated byte-code array + * (in case there were no syntax errors) */ { - TODO (implement syntax error processing); - - inside_eval = true; - inside_function = false; - parser_parse_program (source, source_size, false); - return true; + return parser_parse_program (source, source_size, false, true, opcodes_p); } /* parser_parse_eval */ /** @@ -2952,14 +3012,16 @@ bool parser_parse_eval (const char *source, /**< string passed to eval() */ * NOTE: Array of arguments should contain at least one element. * In case of new Function() call without parameters, empty string should be passed as argument to this * function. + * + * @return true - if parse finished successfully (no SyntaxError were raised); + * false - otherwise. */ -void +bool parser_parse_new_function (const char **params, /**< array of arguments of new Function (p1, p2, ..., pn, body) call */ - size_t params_count) /**< total number of arguments passed to new Function (...) */ + size_t params_count, /**< total number of arguments passed to new Function (...) */ + const opcode_t **out_opcodes_p) /**< out: generated byte-code array + * (in case there were no syntax errors) */ { - inside_eval = false; - inside_function = true; - // Process arguments JERRY_ASSERT (params_count > 0); for (size_t i = 0; i < params_count - 1; ++i) @@ -2967,22 +3029,9 @@ parser_parse_new_function (const char **params, /**< array of arguments of new F FIXME ("check parameter's name for syntax errors"); lit_find_or_create_literal_from_charset ((ecma_char_t *) params[i], (ecma_length_t) strlen (params[i])); } - parser_parse_program (params[params_count - 1], strlen (params[params_count - 1]), true); + return parser_parse_program (params[params_count - 1], strlen (params[params_count - 1]), true, false, out_opcodes_p); } /* parser_parse_new_function */ -void -parser_init () -{ - lexer_init (parser_show_opcodes); - serializer_set_show_opcodes (parser_show_opcodes); - dumper_init (); - syntax_init (); - - STACK_INIT (scopes); - - jsp_label_init (); -} - /** * Tell parser to dump bytecode */ @@ -2991,15 +3040,3 @@ parser_set_show_opcodes (bool show_opcodes) /**< flag indicating if to dump byte { parser_show_opcodes = show_opcodes; } /* parser_set_show_opcodes */ - -void -parser_free (void) -{ - jsp_label_finalize (); - - STACK_FREE (scopes); - - syntax_free (); - dumper_free (); - lexer_free (); -} diff --git a/jerry-core/parser/js/parser.h b/jerry-core/parser/js/parser.h index 4792d96603..6bbfe6ae8c 100644 --- a/jerry-core/parser/js/parser.h +++ b/jerry-core/parser/js/parser.h @@ -18,11 +18,9 @@ #include "jrt.h" -void parser_init (); void parser_set_show_opcodes (bool); -void parser_parse_script (const char *, size_t); -bool parser_parse_eval (const char *, size_t); -void parser_parse_new_function (const char **, size_t); -void parser_free (void); +bool parser_parse_script (const char *, size_t, const opcode_t **); +bool parser_parse_eval (const char *, size_t, const opcode_t **); +bool parser_parse_new_function (const char **, size_t, const opcode_t **); -#endif +#endif /* PARSER_H */ diff --git a/jerry-core/parser/js/scopes-tree.cpp b/jerry-core/parser/js/scopes-tree.cpp index 5700c2b0b5..ce083e868f 100644 --- a/jerry-core/parser/js/scopes-tree.cpp +++ b/jerry-core/parser/js/scopes-tree.cpp @@ -13,8 +13,9 @@ * limitations under the License. */ -#include "scopes-tree.h" #include "bytecode-data.h" +#include "jsp-mm.h" +#include "scopes-tree.h" #define OPCODE(op) (__op__idx_##op) #define HASH_SIZE 128 @@ -114,8 +115,7 @@ start_new_block_if_necessary (void) hash_table_free (lit_id_to_uid); lit_id_to_uid = null_hash; } - lit_id_to_uid = hash_table_init (sizeof (lit_cpointer_t), sizeof (idx_t), HASH_SIZE, lit_id_hash, - MEM_HEAP_ALLOC_SHORT_TERM); + lit_id_to_uid = hash_table_init (sizeof (lit_cpointer_t), sizeof (idx_t), HASH_SIZE, lit_id_hash); } } @@ -600,7 +600,10 @@ merge_subscopes (scopes_tree tree, opcode_t *data, lit_id_hash_table *lit_ids) Reorder function declarations. Rewrite opcodes' temporary uids with their keys in literal indexes 'hash' table. */ opcode_t * -scopes_tree_raw_data (scopes_tree tree, lit_id_hash_table *lit_ids) +scopes_tree_raw_data (scopes_tree tree, /**< scopes tree to convert to byte-code array */ + uint8_t *buffer_p, /**< buffer for byte-code array and literal identifiers hash table */ + size_t opcodes_array_size, /**< size of space for byte-code array */ + lit_id_hash_table *lit_ids) /**< literal identifiers hash table */ { JERRY_ASSERT (lit_ids); assert_tree (tree); @@ -613,10 +616,12 @@ scopes_tree_raw_data (scopes_tree tree, lit_id_hash_table *lit_ids) global_oc = 0; /* Dump bytecode and fill literal indexes 'hash' table. */ - // +1 for valgrind - size_t size = sizeof (opcodes_header_t) + (size_t) (scopes_tree_count_opcodes (tree) + 1) * sizeof (opcode_t); - opcodes_header_t *opcodes_data = (opcodes_header_t *) mem_heap_alloc_block (size, MEM_HEAP_ALLOC_LONG_TERM); - memset (opcodes_data, 0, size); + JERRY_ASSERT (opcodes_array_size >= + sizeof (opcodes_header_t) + (size_t) (scopes_tree_count_opcodes (tree)) * sizeof (opcode_t)); + + opcodes_header_t *opcodes_data = (opcodes_header_t *) buffer_p; + memset (opcodes_data, 0, opcodes_array_size); + opcode_t *opcodes = (opcode_t *)(((uint8_t*) opcodes_data) + sizeof (opcodes_header_t)); merge_subscopes (tree, opcodes, lit_ids); if (lit_id_to_uid != null_hash) @@ -624,9 +629,11 @@ scopes_tree_raw_data (scopes_tree tree, lit_id_hash_table *lit_ids) hash_table_free (lit_id_to_uid); lit_id_to_uid = null_hash; } - opcodes_data->lit_id_hash = lit_ids; + + MEM_CP_SET_POINTER (opcodes_data->lit_id_hash_cp, lit_ids); + return opcodes; -} +} /* scopes_tree_raw_data */ void scopes_tree_set_strict_mode (scopes_tree tree, bool strict_mode) @@ -645,7 +652,7 @@ scopes_tree_strict_mode (scopes_tree tree) scopes_tree scopes_tree_init (scopes_tree parent) { - scopes_tree tree = (scopes_tree) mem_heap_alloc_block (sizeof (scopes_tree_int), MEM_HEAP_ALLOC_SHORT_TERM); + scopes_tree tree = (scopes_tree) jsp_mm_alloc (sizeof (scopes_tree_int)); memset (tree, 0, sizeof (scopes_tree_int)); tree->t.parent = (tree_header *) parent; tree->t.children = null_list; @@ -680,5 +687,5 @@ scopes_tree_free (scopes_tree tree) linked_list_free (tree->t.children); } linked_list_free (tree->opcodes); - mem_heap_free_block ((uint8_t *) tree); + jsp_mm_free (tree); } diff --git a/jerry-core/parser/js/scopes-tree.h b/jerry-core/parser/js/scopes-tree.h index a18e42b28c..7b7956027f 100644 --- a/jerry-core/parser/js/scopes-tree.h +++ b/jerry-core/parser/js/scopes-tree.h @@ -58,7 +58,7 @@ void scopes_tree_set_opcodes_num (scopes_tree, opcode_counter_t); op_meta scopes_tree_op_meta (scopes_tree, opcode_counter_t); size_t scopes_tree_count_literals_in_blocks (scopes_tree); opcode_counter_t scopes_tree_count_opcodes (scopes_tree); -opcode_t *scopes_tree_raw_data (scopes_tree, lit_id_hash_table *); +opcode_t *scopes_tree_raw_data (scopes_tree, uint8_t *, size_t, lit_id_hash_table *); void scopes_tree_set_strict_mode (scopes_tree, bool); bool scopes_tree_strict_mode (scopes_tree); diff --git a/jerry-core/parser/js/serializer.cpp b/jerry-core/parser/js/serializer.cpp index 21b4bda1e9..03073a4eea 100644 --- a/jerry-core/parser/js/serializer.cpp +++ b/jerry-core/parser/js/serializer.cpp @@ -20,9 +20,12 @@ static bytecode_data_t bytecode_data; static scopes_tree current_scope; -static array_list bytecodes_cache; /**< storage of pointers to byetecodes */ static bool print_opcodes; +static void +serializer_print_opcodes (const opcode_t *opcodes_p, + size_t opcodes_count); + op_meta serializer_get_op_meta (opcode_counter_t oc) { @@ -63,13 +66,6 @@ serializer_get_literal_cp_by_uid (uint8_t id, /**< literal idx */ return lit_id_hash_table_lookup (lit_id_hash, id, oc); } /* serializer_get_literal_cp_by_uid */ -const void * -serializer_get_bytecode (void) -{ - JERRY_ASSERT (bytecode_data.opcodes != NULL); - return bytecode_data.opcodes; -} - void serializer_set_strings_buffer (const ecma_char_t *s) { @@ -82,25 +78,41 @@ serializer_set_scope (scopes_tree new_scope) current_scope = new_scope; } -void +const opcode_t * serializer_merge_scopes_into_bytecode (void) { bytecode_data.opcodes_count = scopes_tree_count_opcodes (current_scope); - lit_id_hash_table *lit_id_hash = lit_id_hash_table_init (scopes_tree_count_literals_in_blocks (current_scope), - (size_t) bytecode_data.opcodes_count / BLOCK_SIZE + 1); - bytecode_data.opcodes = scopes_tree_raw_data (current_scope, lit_id_hash); - bytecodes_cache = array_list_append (bytecodes_cache, &bytecode_data.opcodes); -} -void -serializer_dump_literals (void) -{ -#ifdef JERRY_ENABLE_PRETTY_PRINTER + const size_t buckets_count = scopes_tree_count_literals_in_blocks (current_scope); + const size_t blocks_count = (size_t) bytecode_data.opcodes_count / BLOCK_SIZE + 1; + const size_t opcodes_count = scopes_tree_count_opcodes (current_scope); + + const size_t opcodes_array_size = JERRY_ALIGNUP (sizeof (opcodes_header_t) + opcodes_count * sizeof (opcode_t), + MEM_ALIGNMENT); + const size_t lit_id_hash_table_size = JERRY_ALIGNUP (lit_id_hash_table_get_size_for_table (buckets_count, + blocks_count), + MEM_ALIGNMENT); + + uint8_t *buffer_p = (uint8_t*) mem_heap_alloc_block (opcodes_array_size + lit_id_hash_table_size, + MEM_HEAP_ALLOC_LONG_TERM); + + lit_id_hash_table *lit_id_hash = lit_id_hash_table_init (buffer_p + opcodes_array_size, + lit_id_hash_table_size, + buckets_count, blocks_count); + + const opcode_t *opcodes_p = scopes_tree_raw_data (current_scope, buffer_p, opcodes_array_size, lit_id_hash); + + opcodes_header_t *header_p = (opcodes_header_t*) buffer_p; + MEM_CP_SET_POINTER (header_p->next_opcodes_cp, bytecode_data.opcodes); + bytecode_data.opcodes = opcodes_p; + if (print_opcodes) { lit_dump_literals (); + serializer_print_opcodes (opcodes_p, bytecode_data.opcodes_count); } -#endif + + return opcodes_p; } void @@ -149,24 +161,16 @@ serializer_rewrite_op_meta (const opcode_counter_t loc, op_meta op) #endif } -void -serializer_print_opcodes (void) +static void +serializer_print_opcodes (const opcode_t *opcodes_p, + size_t opcodes_count) { #ifdef JERRY_ENABLE_PRETTY_PRINTER - opcode_counter_t loc; - - if (!print_opcodes) - { - return; - } - - printf ("AFTER OPTIMIZER:\n"); - - for (loc = 0; loc < bytecode_data.opcodes_count; loc++) + for (opcode_counter_t loc = 0; loc < opcodes_count; loc++) { op_meta opm; - opm.op = bytecode_data.opcodes[loc]; + opm.op = opcodes_p[loc]; for (int i = 0; i < 3; i++) { opm.lit_id[i] = NOT_A_LITERAL; @@ -174,6 +178,9 @@ serializer_print_opcodes (void) pp_op_meta (loc, opm, false); } +#else + (void) opcodes_p; + (void) opcodes_count; #endif } @@ -187,8 +194,6 @@ serializer_init () bytecode_data.opcodes = NULL; lit_init (); - - bytecodes_cache = array_list_init (sizeof (opcode_t *)); } void serializer_set_show_opcodes (bool show_opcodes) @@ -206,10 +211,11 @@ serializer_free (void) lit_finalize (); - for (size_t i = 0; i < array_list_len (bytecodes_cache); ++i) + while (bytecode_data.opcodes != NULL) { - lit_id_hash_table_free (GET_BYTECODE_HEADER (*(opcode_t **) array_list_element (bytecodes_cache, i))->lit_id_hash); - mem_heap_free_block (GET_BYTECODE_HEADER (*(opcode_t **) array_list_element (bytecodes_cache, i))); + opcodes_header_t *header_p = GET_BYTECODE_HEADER (bytecode_data.opcodes); + bytecode_data.opcodes = MEM_CP_GET_POINTER (opcode_t, header_p->next_opcodes_cp); + + mem_heap_free_block (header_p); } - array_list_free (bytecodes_cache); } diff --git a/jerry-core/parser/js/serializer.h b/jerry-core/parser/js/serializer.h index b62766ecae..87331e3db1 100644 --- a/jerry-core/parser/js/serializer.h +++ b/jerry-core/parser/js/serializer.h @@ -27,17 +27,14 @@ void serializer_set_show_opcodes (bool show_opcodes); op_meta serializer_get_op_meta (opcode_counter_t); opcode_t serializer_get_opcode (opcode_counter_t); lit_cpointer_t serializer_get_literal_cp_by_uid (uint8_t, const opcode_t*, opcode_counter_t); -const void *serializer_get_bytecode (void); void serializer_set_strings_buffer (const ecma_char_t *); -void serializer_dump_literals (); void serializer_set_scope (scopes_tree); -void serializer_merge_scopes_into_bytecode (void); +const opcode_t *serializer_merge_scopes_into_bytecode (void); void serializer_dump_op_meta (op_meta); opcode_counter_t serializer_get_current_opcode_counter (void); opcode_counter_t serializer_count_opcodes_in_subscopes (void); void serializer_set_writing_position (opcode_counter_t); void serializer_rewrite_op_meta (opcode_counter_t, op_meta); -void serializer_print_opcodes (void); void serializer_free (void); #endif // SERIALIZER_H diff --git a/jerry-core/parser/js/syntax-errors.cpp b/jerry-core/parser/js/syntax-errors.cpp index 481aef3508..5089168835 100644 --- a/jerry-core/parser/js/syntax-errors.cpp +++ b/jerry-core/parser/js/syntax-errors.cpp @@ -20,6 +20,15 @@ #include "jrt-libc-includes.h" #include "ecma-helpers.h" +/** + * SyntaxError longjmp label, used to finish parse upon a SyntaxError is raised + * + * See also: + * syntax_get_syntax_error_longjmp_label + * syntax_raise_error + */ +static jmp_buf jsp_syntax_error_label; + typedef struct { prop_type type; @@ -38,6 +47,26 @@ enum }; STATIC_STACK (U8, uint8_t) +/** + * Get buffer for SyntaxError longjmp label + * + * @return pointer to jmp_buf + */ +jmp_buf * +syntax_get_syntax_error_longjmp_label (void) +{ + return &jsp_syntax_error_label; +} /* syntax_get_syntax_error_longjmp_label */ + +/** + * Raise SyntaxError, i.e. perform longjmp to SyntaxError longjmp label + */ +void __attribute__((noreturn)) +syntax_raise_error (void) +{ + longjmp (jsp_syntax_error_label, 1); +} /* syntax_raise_error */ + static prop_literal create_prop_literal (literal_t lit, prop_type type) { diff --git a/jerry-core/parser/js/syntax-errors.h b/jerry-core/parser/js/syntax-errors.h index 62dc228ccc..c075252d97 100644 --- a/jerry-core/parser/js/syntax-errors.h +++ b/jerry-core/parser/js/syntax-errors.h @@ -16,11 +16,12 @@ #ifndef SYNTAX_ERRORS_H #define SYNTAX_ERRORS_H +#include "jrt-libc-includes.h" #include "opcodes-dumper.h" #include "lexer.h" #ifndef JERRY_NDEBUG -#define PARSE_ERROR(MESSAGE, LOCUS) do { \ +#define PARSE_ERROR_PRINT_PLACE(TYPE, LOCUS) do { \ size_t line, column; \ lexer_locus_to_line_and_column ((locus) (LOCUS), &line, &column); \ lexer_dump_line (line); \ @@ -29,49 +30,30 @@ putchar (' '); \ } \ printf ("^\n"); \ - printf ("ERROR: Ln %lu, Col %lu: %s\n", (unsigned long) (line + 1), (unsigned long) (column + 1), MESSAGE); \ - jerry_fatal (ERR_PARSER); \ + printf ("%s: Ln %lu, Col %lu: ", TYPE, (unsigned long) (line + 1), (unsigned long) (column + 1)); \ } while (0) -#define PARSE_WARN(MESSAGE, LOCUS) do { \ - size_t line, column; \ - lexer_locus_to_line_and_column ((locus) (LOCUS), &line, &column); \ - printf ("WARNING: Ln %lu, Col %lu: %s\n", (unsigned long) (line + 1), (unsigned long) (column + 1), MESSAGE); \ +#define PARSE_ERROR(MESSAGE, LOCUS) do { \ + PARSE_ERROR_PRINT_PLACE ("ERROR", LOCUS); \ + printf ("%s\n", MESSAGE); \ + syntax_raise_error (); \ } while (0) #define PARSE_ERROR_VARG(MESSAGE, LOCUS, ...) do { \ - size_t line, column; \ - lexer_locus_to_line_and_column ((locus) (LOCUS), &line, &column); \ - lexer_dump_line (line); \ - printf ("\n"); \ - for (size_t i = 0; i < column; i++) { \ - putchar (' '); \ - } \ - printf ("^\n"); \ - printf ("ERROR: Ln %lu, Col %lu: ", (unsigned long) (line + 1), (unsigned long) (column + 1)); \ + PARSE_ERROR_PRINT_PLACE ("ERROR", LOCUS); \ printf (MESSAGE, __VA_ARGS__); \ printf ("\n"); \ - jerry_fatal (ERR_PARSER); \ + syntax_raise_error (); \ } while (0) #define PARSE_SORRY(MESSAGE, LOCUS) do { \ - size_t line, column; \ - lexer_locus_to_line_and_column ((locus) (LOCUS), &line, &column); \ - lexer_dump_line (line); \ - printf ("\n"); \ - for (size_t i = 0; i < column; i++) { \ - putchar (' '); \ - } \ - printf ("^\n"); \ - printf ("SORRY, Unimplemented: Ln %lu, Col %lu: %s\n", \ - (unsigned long) (line + 1), (unsigned long) (column + 1), MESSAGE); \ + PARSE_ERROR_PRINT_PLACE ("SORRY, Unimplemented", LOCUS); \ + printf ("%s\n", MESSAGE); \ JERRY_UNIMPLEMENTED ("Unimplemented parser feature."); \ } while (0) #else /* JERRY_NDEBUG */ #define PARSE_ERROR(MESSAGE, LOCUS) do { \ - jerry_fatal (ERR_PARSER); \ -} while (0) -#define PARSE_WARN(MESSAGE, LOCUS) do { \ + syntax_raise_error (); \ } while (0) #define PARSE_ERROR_VARG(MESSAGE, LOCUS, ...) do { \ - jerry_fatal (ERR_PARSER); \ + syntax_raise_error (); \ } while (0) #define PARSE_SORRY(MESSAGE, LOCUS) do { \ JERRY_UNIMPLEMENTED ("Unimplemented parser feature."); \ @@ -100,4 +82,7 @@ void syntax_check_for_syntax_errors_in_formal_param_list (bool, locus); void syntax_check_delete (bool, locus); +jmp_buf * syntax_get_syntax_error_longjmp_label (void); +void __attribute__((noreturn)) syntax_raise_error (void); + #endif /* SYNTAX_ERRORS_H */ diff --git a/jerry-libc/include/setjmp.h b/jerry-libc/include/setjmp.h index 89071eb9e3..35ae5ae594 100644 --- a/jerry-libc/include/setjmp.h +++ b/jerry-libc/include/setjmp.h @@ -16,6 +16,8 @@ #ifndef JERRY_LIBC_SETJMP_H #define JERRY_LIBC_SETJMP_H +#include + #ifdef __cplusplus # define EXTERN_C "C" #else /* !__cplusplus */ diff --git a/tests/jerry/eval.js b/tests/jerry/eval.js index 22eb187fd5..f3e6bfb514 100644 --- a/tests/jerry/eval.js +++ b/tests/jerry/eval.js @@ -86,3 +86,14 @@ for (var i = 0; i < 100; i++) r = eval ('if (true) 3; else 5;'); assert (r === 3); } + +// Check SyntaxError handling +try +{ + eval ('var var;'); + assert (false); +} +catch (e) +{ + assert (e instanceof SyntaxError); +} diff --git a/tests/jerry/fail/12/arguments-assignment-strict.js b/tests/jerry/fail/1/arguments-assignment-strict.js similarity index 91% rename from tests/jerry/fail/12/arguments-assignment-strict.js rename to tests/jerry/fail/1/arguments-assignment-strict.js index b581932d89..c39b16eb58 100644 --- a/tests/jerry/fail/12/arguments-assignment-strict.js +++ b/tests/jerry/fail/1/arguments-assignment-strict.js @@ -1,4 +1,4 @@ -// Copyright 2014 Samsung Electronics Co., Ltd. +// Copyright 2014-2015 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. diff --git a/tests/jerry/fail/12/arguments-catch-strict.js b/tests/jerry/fail/1/arguments-catch-strict.js similarity index 91% rename from tests/jerry/fail/12/arguments-catch-strict.js rename to tests/jerry/fail/1/arguments-catch-strict.js index 80b3fa1d4f..433e5a7fa2 100644 --- a/tests/jerry/fail/12/arguments-catch-strict.js +++ b/tests/jerry/fail/1/arguments-catch-strict.js @@ -1,4 +1,4 @@ -// Copyright 2014 Samsung Electronics Co., Ltd. +// Copyright 2014-2015 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. diff --git a/tests/jerry/fail/12/arguments-in-prop-set-param-list-strict.js b/tests/jerry/fail/1/arguments-in-prop-set-param-list-strict.js similarity index 91% rename from tests/jerry/fail/12/arguments-in-prop-set-param-list-strict.js rename to tests/jerry/fail/1/arguments-in-prop-set-param-list-strict.js index ea4383bb49..4ba512f046 100644 --- a/tests/jerry/fail/12/arguments-in-prop-set-param-list-strict.js +++ b/tests/jerry/fail/1/arguments-in-prop-set-param-list-strict.js @@ -1,4 +1,4 @@ -// Copyright 2014 Samsung Electronics Co., Ltd. +// Copyright 2014-2015 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. diff --git a/tests/jerry/fail/12/arguments-in-var-decl-strict.js b/tests/jerry/fail/1/arguments-in-var-decl-strict.js similarity index 91% rename from tests/jerry/fail/12/arguments-in-var-decl-strict.js rename to tests/jerry/fail/1/arguments-in-var-decl-strict.js index 7bd81940ba..276c9b7d06 100644 --- a/tests/jerry/fail/12/arguments-in-var-decl-strict.js +++ b/tests/jerry/fail/1/arguments-in-var-decl-strict.js @@ -1,4 +1,4 @@ -// Copyright 2014 Samsung Electronics Co., Ltd. +// Copyright 2014-2015 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. diff --git a/tests/jerry/fail/12/arguments-param-strict.js b/tests/jerry/fail/1/arguments-param-strict.js similarity index 91% rename from tests/jerry/fail/12/arguments-param-strict.js rename to tests/jerry/fail/1/arguments-param-strict.js index 6aecb72d0e..10e44ba0da 100644 --- a/tests/jerry/fail/12/arguments-param-strict.js +++ b/tests/jerry/fail/1/arguments-param-strict.js @@ -1,4 +1,4 @@ -// Copyright 2014 Samsung Electronics Co., Ltd. +// Copyright 2014-2015 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. diff --git a/tests/jerry/fail/12/arguments-postfix-strict.js b/tests/jerry/fail/1/arguments-postfix-strict.js similarity index 91% rename from tests/jerry/fail/12/arguments-postfix-strict.js rename to tests/jerry/fail/1/arguments-postfix-strict.js index bc319d524f..2498f79c9a 100644 --- a/tests/jerry/fail/12/arguments-postfix-strict.js +++ b/tests/jerry/fail/1/arguments-postfix-strict.js @@ -1,4 +1,4 @@ -// Copyright 2014 Samsung Electronics Co., Ltd. +// Copyright 2014-2015 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. diff --git a/tests/jerry/fail/12/arguments-prefix-strict.js b/tests/jerry/fail/1/arguments-prefix-strict.js similarity index 91% rename from tests/jerry/fail/12/arguments-prefix-strict.js rename to tests/jerry/fail/1/arguments-prefix-strict.js index 217fa508e9..c011369b9e 100644 --- a/tests/jerry/fail/12/arguments-prefix-strict.js +++ b/tests/jerry/fail/1/arguments-prefix-strict.js @@ -1,4 +1,4 @@ -// Copyright 2014 Samsung Electronics Co., Ltd. +// Copyright 2014-2015 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. diff --git a/tests/jerry/fail/12/delete-strict.js b/tests/jerry/fail/1/delete-strict.js similarity index 91% rename from tests/jerry/fail/12/delete-strict.js rename to tests/jerry/fail/1/delete-strict.js index fa82d732a4..1b525aa4ef 100644 --- a/tests/jerry/fail/12/delete-strict.js +++ b/tests/jerry/fail/1/delete-strict.js @@ -1,4 +1,4 @@ -// Copyright 2014 Samsung Electronics Co., Ltd. +// Copyright 2014-2015 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. diff --git a/tests/jerry/fail/12/escape-sequences-invalid-hex.js b/tests/jerry/fail/1/escape-sequences-invalid-hex.js similarity index 100% rename from tests/jerry/fail/12/escape-sequences-invalid-hex.js rename to tests/jerry/fail/1/escape-sequences-invalid-hex.js diff --git a/tests/jerry/fail/12/escape-sequences-invalid-unicode.js b/tests/jerry/fail/1/escape-sequences-invalid-unicode.js similarity index 100% rename from tests/jerry/fail/12/escape-sequences-invalid-unicode.js rename to tests/jerry/fail/1/escape-sequences-invalid-unicode.js diff --git a/tests/jerry/fail/12/escape-sequences-invalid-variable.js b/tests/jerry/fail/1/escape-sequences-invalid-variable.js similarity index 100% rename from tests/jerry/fail/12/escape-sequences-invalid-variable.js rename to tests/jerry/fail/1/escape-sequences-invalid-variable.js diff --git a/tests/jerry/fail/12/eval-assignment-strict.js b/tests/jerry/fail/1/eval-assignment-strict.js similarity index 91% rename from tests/jerry/fail/12/eval-assignment-strict.js rename to tests/jerry/fail/1/eval-assignment-strict.js index aa28ff6d4e..b59b5d3f0c 100644 --- a/tests/jerry/fail/12/eval-assignment-strict.js +++ b/tests/jerry/fail/1/eval-assignment-strict.js @@ -1,4 +1,4 @@ -// Copyright 2014 Samsung Electronics Co., Ltd. +// Copyright 2014-2015 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. diff --git a/tests/jerry/fail/12/eval-catch-strict.js b/tests/jerry/fail/1/eval-catch-strict.js similarity index 91% rename from tests/jerry/fail/12/eval-catch-strict.js rename to tests/jerry/fail/1/eval-catch-strict.js index c48f0a8f69..80d2996bb1 100644 --- a/tests/jerry/fail/12/eval-catch-strict.js +++ b/tests/jerry/fail/1/eval-catch-strict.js @@ -1,4 +1,4 @@ -// Copyright 2014 Samsung Electronics Co., Ltd. +// Copyright 2014-2015 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. diff --git a/tests/jerry/fail/12/eval-in-prop-set-param-list-strict.js b/tests/jerry/fail/1/eval-in-prop-set-param-list-strict.js similarity index 91% rename from tests/jerry/fail/12/eval-in-prop-set-param-list-strict.js rename to tests/jerry/fail/1/eval-in-prop-set-param-list-strict.js index da21ecd8fb..3cd28bad05 100644 --- a/tests/jerry/fail/12/eval-in-prop-set-param-list-strict.js +++ b/tests/jerry/fail/1/eval-in-prop-set-param-list-strict.js @@ -1,4 +1,4 @@ -// Copyright 2014 Samsung Electronics Co., Ltd. +// Copyright 2014-2015 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. diff --git a/tests/jerry/fail/12/eval-in-var-decl-strict.js b/tests/jerry/fail/1/eval-in-var-decl-strict.js similarity index 91% rename from tests/jerry/fail/12/eval-in-var-decl-strict.js rename to tests/jerry/fail/1/eval-in-var-decl-strict.js index 753197c5a6..319635e912 100644 --- a/tests/jerry/fail/12/eval-in-var-decl-strict.js +++ b/tests/jerry/fail/1/eval-in-var-decl-strict.js @@ -1,4 +1,4 @@ -// Copyright 2014 Samsung Electronics Co., Ltd. +// Copyright 2014-2015 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. diff --git a/tests/jerry/fail/12/eval-param-strict.js b/tests/jerry/fail/1/eval-param-strict.js similarity index 91% rename from tests/jerry/fail/12/eval-param-strict.js rename to tests/jerry/fail/1/eval-param-strict.js index 689f4f58d8..893efb539b 100644 --- a/tests/jerry/fail/12/eval-param-strict.js +++ b/tests/jerry/fail/1/eval-param-strict.js @@ -1,4 +1,4 @@ -// Copyright 2014 Samsung Electronics Co., Ltd. +// Copyright 2014-2015 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. diff --git a/tests/jerry/fail/12/eval-postfix-strict.js b/tests/jerry/fail/1/eval-postfix-strict.js similarity index 91% rename from tests/jerry/fail/12/eval-postfix-strict.js rename to tests/jerry/fail/1/eval-postfix-strict.js index e908b5f717..da7d49f301 100644 --- a/tests/jerry/fail/12/eval-postfix-strict.js +++ b/tests/jerry/fail/1/eval-postfix-strict.js @@ -1,4 +1,4 @@ -// Copyright 2014 Samsung Electronics Co., Ltd. +// Copyright 2014-2015 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. diff --git a/tests/jerry/fail/12/eval-prefix-strict.js b/tests/jerry/fail/1/eval-prefix-strict.js similarity index 91% rename from tests/jerry/fail/12/eval-prefix-strict.js rename to tests/jerry/fail/1/eval-prefix-strict.js index 55a0202e1c..d36f8b9508 100644 --- a/tests/jerry/fail/12/eval-prefix-strict.js +++ b/tests/jerry/fail/1/eval-prefix-strict.js @@ -1,4 +1,4 @@ -// Copyright 2014 Samsung Electronics Co., Ltd. +// Copyright 2014-2015 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. diff --git a/tests/jerry/fail/12/labelled-statements-break-across-function.js b/tests/jerry/fail/1/labelled-statements-break-across-function.js similarity index 100% rename from tests/jerry/fail/12/labelled-statements-break-across-function.js rename to tests/jerry/fail/1/labelled-statements-break-across-function.js diff --git a/tests/jerry/fail/12/labelled-statements-duplicate-label.js b/tests/jerry/fail/1/labelled-statements-duplicate-label.js similarity index 100% rename from tests/jerry/fail/12/labelled-statements-duplicate-label.js rename to tests/jerry/fail/1/labelled-statements-duplicate-label.js diff --git a/tests/jerry/fail/12/labelled-statements-no-label.js b/tests/jerry/fail/1/labelled-statements-no-label.js similarity index 100% rename from tests/jerry/fail/12/labelled-statements-no-label.js rename to tests/jerry/fail/1/labelled-statements-no-label.js diff --git a/tests/jerry/fail/12/let-strict.js b/tests/jerry/fail/1/let-strict.js similarity index 91% rename from tests/jerry/fail/12/let-strict.js rename to tests/jerry/fail/1/let-strict.js index e39810412c..4f40cc0fc5 100644 --- a/tests/jerry/fail/12/let-strict.js +++ b/tests/jerry/fail/1/let-strict.js @@ -1,4 +1,4 @@ -// Copyright 2014 Samsung Electronics Co., Ltd. +// Copyright 2014-2015 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. diff --git a/tests/jerry/fail/12/object-get-data.js b/tests/jerry/fail/1/object-get-data.js similarity index 91% rename from tests/jerry/fail/12/object-get-data.js rename to tests/jerry/fail/1/object-get-data.js index 5a2184af0d..f69c4c8267 100644 --- a/tests/jerry/fail/12/object-get-data.js +++ b/tests/jerry/fail/1/object-get-data.js @@ -1,4 +1,4 @@ -// Copyright 2014 Samsung Electronics Co., Ltd. +// Copyright 2014-2015 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. diff --git a/tests/jerry/fail/12/object-get-get.js b/tests/jerry/fail/1/object-get-get.js similarity index 92% rename from tests/jerry/fail/12/object-get-get.js rename to tests/jerry/fail/1/object-get-get.js index fb429f78c4..324ea3187f 100644 --- a/tests/jerry/fail/12/object-get-get.js +++ b/tests/jerry/fail/1/object-get-get.js @@ -1,4 +1,4 @@ -// Copyright 2014 Samsung Electronics Co., Ltd. +// Copyright 2014-2015 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. diff --git a/tests/jerry/fail/12/object-several-prop-names-strict.js b/tests/jerry/fail/1/object-several-prop-names-strict.js similarity index 91% rename from tests/jerry/fail/12/object-several-prop-names-strict.js rename to tests/jerry/fail/1/object-several-prop-names-strict.js index 1426f3ef6f..366bad9876 100644 --- a/tests/jerry/fail/12/object-several-prop-names-strict.js +++ b/tests/jerry/fail/1/object-several-prop-names-strict.js @@ -1,4 +1,4 @@ -// Copyright 2014 Samsung Electronics Co., Ltd. +// Copyright 2014-2015 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. diff --git a/tests/jerry/fail/12/octal-strict.js b/tests/jerry/fail/1/octal-strict.js similarity index 91% rename from tests/jerry/fail/12/octal-strict.js rename to tests/jerry/fail/1/octal-strict.js index 7e51a81293..e271e3721e 100644 --- a/tests/jerry/fail/12/octal-strict.js +++ b/tests/jerry/fail/1/octal-strict.js @@ -1,4 +1,4 @@ -// Copyright 2014 Samsung Electronics Co., Ltd. +// Copyright 2014-2015 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. diff --git a/tests/jerry/fail/12/param-duplication-strict.js b/tests/jerry/fail/1/param-duplication-strict.js similarity index 91% rename from tests/jerry/fail/12/param-duplication-strict.js rename to tests/jerry/fail/1/param-duplication-strict.js index ce645650d9..388b2a24a6 100644 --- a/tests/jerry/fail/12/param-duplication-strict.js +++ b/tests/jerry/fail/1/param-duplication-strict.js @@ -1,4 +1,4 @@ -// Copyright 2014 Samsung Electronics Co., Ltd. +// Copyright 2014-2015 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. diff --git a/tests/jerry/fail/12/with-strict.js b/tests/jerry/fail/1/with-strict.js similarity index 91% rename from tests/jerry/fail/12/with-strict.js rename to tests/jerry/fail/1/with-strict.js index 34aa856d2f..7d51fcc7c9 100644 --- a/tests/jerry/fail/12/with-strict.js +++ b/tests/jerry/fail/1/with-strict.js @@ -1,4 +1,4 @@ -// Copyright 2014 Samsung Electronics Co., Ltd. +// Copyright 2014-2015 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. diff --git a/tests/jerry/function-construct.js b/tests/jerry/function-construct.js index 0a2d70364a..8f221c216c 100644 --- a/tests/jerry/function-construct.js +++ b/tests/jerry/function-construct.js @@ -79,3 +79,14 @@ catch (e) { assert (e instanceof TypeError); } + +// Check SyntaxError handling +try +{ + new Function ('var var;'); + assert (false); +} +catch (e) +{ + assert (e instanceof SyntaxError); +} diff --git a/tests/unit/test-parser.cpp b/tests/unit/test-parser.cpp index e30867a5ea..e1b1604c69 100644 --- a/tests/unit/test-parser.cpp +++ b/tests/unit/test-parser.cpp @@ -71,15 +71,19 @@ main (int __attr_unused___ argc, { TEST_INIT (); - char program[] = "a=1;var a;"; - bool is_ok; + const opcode_t *opcodes_p; + bool is_syntax_correct; mem_init (); + + // #1 + char program1[] = "a=1;var a;"; + serializer_init (); parser_set_show_opcodes (true); - parser_init (); - parser_parse_script (program, strlen (program)); - parser_free (); + is_syntax_correct = parser_parse_script (program1, strlen (program1), &opcodes_p); + + JERRY_ASSERT (is_syntax_correct && opcodes_p != NULL); opcode_t opcodes[] = { @@ -94,17 +98,22 @@ main (int __attr_unused___ argc, getop_exitval (0) // exit 0; }; - if (!opcodes_equal ((const opcode_t *) serializer_get_bytecode (), opcodes, 5)) - { - is_ok = false; - } - else - { - is_ok = true; - } + JERRY_ASSERT (opcodes_equal (opcodes_p, opcodes, 5)); serializer_free (); + + // #2 + char program2[] = "var var;"; + + serializer_init (); + parser_set_show_opcodes (true); + is_syntax_correct = parser_parse_script (program2, strlen (program2), &opcodes_p); + + JERRY_ASSERT (!is_syntax_correct && opcodes_p == NULL); + + serializer_free (); + mem_finalize (false); - return (is_ok ? 0 : 1); + return 0; } /* main */