Simplify serializer/deserializer. Reduce memory usage in lexer. Create HashTable data structure. Finish preparations for introducing new strings addressation.
This commit is contained in:
+3
-2
@@ -273,8 +273,9 @@ SOURCES_JERRY_C = \
|
||||
$(wildcard ./src/libecmabuiltins/*.c) \
|
||||
$(wildcard ./src/liballocator/*.c) \
|
||||
$(wildcard ./src/libcoreint/*.c) \
|
||||
$(wildcard ./src/liboptimizer/*.c) ) \
|
||||
$(wildcard ./src/libruntime/target/$(TARGET_SYSTEM)/*.c)
|
||||
$(wildcard ./src/libintstructs/*.c) \
|
||||
$(wildcard ./src/liboptimizer/*.c ) \
|
||||
$(wildcard ./src/libruntime/target/$(TARGET_SYSTEM)/*.c) )
|
||||
|
||||
SOURCES_JERRY_H = \
|
||||
$(sort \
|
||||
|
||||
+1
-1
@@ -55,7 +55,7 @@
|
||||
/**
|
||||
* Size of heap
|
||||
*/
|
||||
#define CONFIG_MEM_HEAP_AREA_SIZE (4 * 1024 + 512)
|
||||
#define CONFIG_MEM_HEAP_AREA_SIZE (5 * 1024 + 512)
|
||||
|
||||
/**
|
||||
* Log2 of maximum possible offset in the heap
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
#include "lp-string.h"
|
||||
|
||||
bool
|
||||
lp_string_equal (lp_string s1, lp_string s2)
|
||||
{
|
||||
if (s1.length != s2.length)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (ecma_length_t i = 0; i < s1.length; i++)
|
||||
{
|
||||
JERRY_ASSERT (s1.str[i] != '\0' && s1.str[i] != '\0');
|
||||
if (s1.str[i] != s2.str[i])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
lp_string_equal_s (lp_string lp, const char *s)
|
||||
{
|
||||
for (ecma_length_t i = 0; i < lp.length; i++)
|
||||
{
|
||||
JERRY_ASSERT (lp.str[i] != '\0');
|
||||
if (lp.str[i] != s[i])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (s[lp.length] != '\0')
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
#ifndef LP_STRING
|
||||
#define LP_STRING
|
||||
|
||||
#include "ecma-globals.h"
|
||||
|
||||
/* Length-prefixed or "pascal" string. */
|
||||
typedef struct
|
||||
{
|
||||
ecma_length_t length;
|
||||
const ecma_char_t *str;
|
||||
}
|
||||
__packed
|
||||
lp_string;
|
||||
|
||||
bool lp_string_equal (lp_string, lp_string);
|
||||
bool lp_string_equal_s (lp_string, const char *);
|
||||
|
||||
#endif /* LP_STRING */
|
||||
+64
-50
@@ -15,22 +15,16 @@
|
||||
|
||||
/**
|
||||
This file contains macros to define and use stacks.
|
||||
Do define stack type use macro DEFINE_STACK_TYPE.
|
||||
After definition of type use macro STACK to create stack variable and define all necessaty routines.
|
||||
Use macro STACK or STATIC_STACK to create stack variable and define all necessaty routines.
|
||||
Also, define variable with name NAME##_global_size. If the variable more than 0,
|
||||
first NAME##_global_size element will remain untouched during PUSH and POP operations.
|
||||
Before using the stack, init it by calling INIT_STACK macro.
|
||||
Use macros PUSH, POP, DROP, CLEAN and HEAD to manipulate the stack.
|
||||
DO NOT FORGET to free stack memory by calling FREE_STACK macro.
|
||||
For check usage of stack during a function, use DECLARE_USAGE and CHECK_USAGE macros.
|
||||
first NAME##_global_size element will remain untouched during STACK_PUSH and STACK_POP operations.
|
||||
Before using the stack, init it by calling STACK_INIT macro.
|
||||
Use macros STACK_PUSH, STACK_POP, STACK_DROP, STACK_CLEAN and STACK_HEAD to manipulate the stack.
|
||||
DO NOT FORGET to free stack memory by calling STACK_FREE macro.
|
||||
For check usage of stack during a function, use STACK_DECLARE_USAGE and STACK_CHECK_USAGE macros.
|
||||
|
||||
Example (parser.c):
|
||||
|
||||
#ifndef UINT8_T_STACK_DEFINED
|
||||
#define UINT8_T_STACK_DEFINED
|
||||
DEFINE_STACK_TYPE (uint8_t)
|
||||
#endif
|
||||
|
||||
enum
|
||||
{
|
||||
temp_name,
|
||||
@@ -38,7 +32,7 @@
|
||||
max_temp_name,
|
||||
temp_names_global_size
|
||||
};
|
||||
STACK(uint8_t, temp_names)
|
||||
STACK(temp_names, uint8_t, uint8_t)
|
||||
|
||||
#define GLOBAL(NAME, VAR) \
|
||||
NAME.data[VAR]
|
||||
@@ -55,19 +49,19 @@
|
||||
void
|
||||
parser_init (void)
|
||||
{
|
||||
INIT_STACK(uint8_t, temp_names)
|
||||
STACK_INIT(uint8_t, temp_names)
|
||||
}
|
||||
|
||||
void
|
||||
parser_free (void)
|
||||
{
|
||||
FREE_STACK(temp_names)
|
||||
STACK_FREE(temp_names)
|
||||
}
|
||||
*/
|
||||
#ifndef STACK_H
|
||||
#define STACK_H
|
||||
|
||||
#define DEFINE_STACK_TYPE(DATA_TYPE, TYPE) \
|
||||
#define DEFINE_STACK_TYPE(NAME, DATA_TYPE, TYPE) \
|
||||
typedef struct \
|
||||
{ \
|
||||
DATA_TYPE length; \
|
||||
@@ -75,20 +69,20 @@ typedef struct \
|
||||
TYPE *data; \
|
||||
} \
|
||||
__packed \
|
||||
TYPE##_stack;
|
||||
NAME##_stack;
|
||||
|
||||
#define INIT_STACK(TYPE, NAME) \
|
||||
#define STACK_INIT(TYPE, NAME) \
|
||||
do { \
|
||||
size_t NAME##_size = mem_heap_recommend_allocation_size (sizeof (TYPE) * NAME##_global_size); \
|
||||
NAME.data = (TYPE *) mem_heap_alloc_block (NAME##_size, MEM_HEAP_ALLOC_SHORT_TERM); \
|
||||
NAME.current = NAME##_global_size; \
|
||||
NAME.length = (__typeof__ (NAME.length)) (NAME##_size / sizeof (TYPE)); \
|
||||
size_t stack_size = mem_heap_recommend_allocation_size (sizeof (TYPE) * NAME##_global_size); \
|
||||
NAME.data = (TYPE *) mem_heap_alloc_block (stack_size, MEM_HEAP_ALLOC_SHORT_TERM); \
|
||||
NAME.current = NAME##_global_size; \
|
||||
NAME.length = (__typeof__ (NAME.length)) (stack_size / sizeof (TYPE)); \
|
||||
} while (0)
|
||||
|
||||
#define FREE_STACK(NAME) \
|
||||
#define STACK_FREE(NAME) \
|
||||
do { \
|
||||
mem_heap_free_block ((uint8_t *) NAME.data); \
|
||||
NAME.length = NAME.current = 0; \
|
||||
mem_heap_free_block ((uint8_t *) NAME.data); \
|
||||
NAME.length = NAME.current = 0; \
|
||||
} while (0)
|
||||
|
||||
/* In most cases (for example, in parser) default size of stack is enough.
|
||||
@@ -100,7 +94,7 @@ NAME.length = NAME.current = 0; \
|
||||
4) Allocate new memory. (It must point to the memory before increasing).
|
||||
5) Copy data back.
|
||||
6) Free temp buffer. */
|
||||
#define DEFINE_INCREASE_STACK_SIZE(TYPE, NAME) \
|
||||
#define DEFINE_INCREASE_STACK_SIZE(NAME, TYPE) \
|
||||
static void increase_##NAME##_stack_size (__typeof__ (NAME.length)) __unused; \
|
||||
static void \
|
||||
increase_##NAME##_stack_size (__typeof__ (NAME.length) elements_count) { \
|
||||
@@ -122,6 +116,12 @@ increase_##NAME##_stack_size (__typeof__ (NAME.length) elements_count) { \
|
||||
mem_heap_free_block ((uint8_t *) NAME.data); \
|
||||
mem_heap_free_block ((uint8_t *) temp1); \
|
||||
NAME.data = (TYPE *) mem_heap_alloc_block (new_size, MEM_HEAP_ALLOC_SHORT_TERM); \
|
||||
if (NAME.data == NULL) \
|
||||
{ \
|
||||
__printf ("old_size: %d\ntemp1_size: %d\nnew_size: %d\n", old_size, temp1_size, new_size); \
|
||||
mem_heap_print (true, false, true); \
|
||||
JERRY_UNREACHABLE (); \
|
||||
} \
|
||||
__memcpy (NAME.data, temp2, old_size); \
|
||||
mem_heap_free_block ((uint8_t *) temp2); \
|
||||
NAME.length = (__typeof__ (NAME.length)) (new_size / sizeof (TYPE)); \
|
||||
@@ -137,44 +137,58 @@ decrease_##NAME##_stack_size (uint8_t elements_count) { \
|
||||
NAME.current = (__typeof__ (NAME.current)) (NAME.current - elements_count); \
|
||||
}
|
||||
|
||||
#define PUSH(NAME, VALUE) \
|
||||
increase_##NAME##_stack_size (1); \
|
||||
NAME.data[NAME.current - 1] = VALUE;
|
||||
#define STACK_PUSH(NAME, VALUE) \
|
||||
do { \
|
||||
increase_##NAME##_stack_size (1); \
|
||||
NAME.data[NAME.current - 1] = VALUE; \
|
||||
} while (0)
|
||||
|
||||
#define POP(VALUE, NAME) \
|
||||
decrease_##NAME##_stack_size (1); \
|
||||
VALUE = NAME.data[NAME.current];
|
||||
#define STACK_POP(NAME, VALUE) \
|
||||
do { \
|
||||
decrease_##NAME##_stack_size (1); \
|
||||
VALUE = NAME.data[NAME.current]; \
|
||||
} while (0)
|
||||
|
||||
#define DROP(NAME, I) \
|
||||
decrease_##NAME##_stack_size (I);
|
||||
#define STACK_DROP(NAME, I) \
|
||||
do { decrease_##NAME##_stack_size (I); } while (0)
|
||||
|
||||
#define CLEAN(NAME) \
|
||||
DROP (NAME, NAME.current - NAME##_global_size);
|
||||
#define STACK_CLEAN(NAME) \
|
||||
STACK_DROP (NAME, NAME.current - NAME##_global_size);
|
||||
|
||||
#define HEAD(NAME, I) \
|
||||
#define STACK_HEAD(NAME, I) \
|
||||
NAME.data[NAME.current - I]
|
||||
|
||||
#define STACK_SIZE(NAME) \
|
||||
NAME.current
|
||||
|
||||
#define STACK(TYPE, NAME) \
|
||||
TYPE##_stack NAME; \
|
||||
DEFINE_DECREASE_STACE_SIZE (NAME) \
|
||||
DEFINE_INCREASE_STACK_SIZE (TYPE, NAME)
|
||||
#define STACK_ELEMENT(NAME, I) \
|
||||
NAME.data[I]
|
||||
|
||||
#define STATIC_STACK(TYPE, NAME) \
|
||||
static TYPE##_stack NAME; \
|
||||
#define STACK_RAW_DATA(NAME) \
|
||||
NAME.data
|
||||
|
||||
#define STACK(NAME, DATA_TYPE, TYPE) \
|
||||
DEFINE_STACK_TYPE(NAME, DATA_TYPE, TYPE) \
|
||||
NAME##_stack NAME; \
|
||||
DEFINE_DECREASE_STACE_SIZE (NAME) \
|
||||
DEFINE_INCREASE_STACK_SIZE (TYPE, NAME)
|
||||
DEFINE_INCREASE_STACK_SIZE (NAME, TYPE)
|
||||
|
||||
#define STATIC_STACK(NAME, DATA_TYPE, TYPE) \
|
||||
DEFINE_STACK_TYPE(NAME, DATA_TYPE, TYPE) \
|
||||
static NAME##_stack NAME; \
|
||||
DEFINE_DECREASE_STACE_SIZE (NAME) \
|
||||
DEFINE_INCREASE_STACK_SIZE (NAME, TYPE)
|
||||
|
||||
#ifndef JERRY_NDEBUG
|
||||
#define DECLARE_USAGE(NAME) \
|
||||
uint8_t NAME##_current = NAME.current;
|
||||
#define CHECK_USAGE(NAME) \
|
||||
JERRY_ASSERT (NAME.current == NAME##_current);
|
||||
#define STACK_DECLARE_USAGE(NAME) \
|
||||
__typeof__(NAME.current) NAME##_current = NAME.current;
|
||||
#define STACK_CHECK_USAGE(NAME) \
|
||||
do { \
|
||||
JERRY_ASSERT (NAME.current == NAME##_current); \
|
||||
} while (0);
|
||||
#else
|
||||
#define DECLARE_USAGE(NAME) ;
|
||||
#define CHECK_USAGE(NAME) ;
|
||||
#define STACK_DECLARE_USAGE(NAME) ;
|
||||
#define STACK_CHECK_USAGE(NAME) ;
|
||||
#endif /* JERRY_NDEBUG */
|
||||
|
||||
#endif /* STACK_H */
|
||||
|
||||
+122
-288
@@ -17,31 +17,43 @@
|
||||
#include "jerry-libc.h"
|
||||
#include "lexer.h"
|
||||
#include "parser.h"
|
||||
#include "stack.h"
|
||||
#include "opcodes.h"
|
||||
|
||||
static token saved_token;
|
||||
static token empty_token =
|
||||
{
|
||||
.type =
|
||||
TOK_EMPTY,
|
||||
.type = TOK_EMPTY,
|
||||
.uid = 0
|
||||
};
|
||||
|
||||
static bool allow_dump_lines = false;
|
||||
static size_t buffer_size = 0;
|
||||
|
||||
typedef struct
|
||||
/* Represents the contents of a script. */
|
||||
static const char *buffer_start = NULL;
|
||||
static const char *buffer = NULL;
|
||||
static const char *token_start;
|
||||
|
||||
#define LA(I) (get_char (I))
|
||||
|
||||
enum
|
||||
{
|
||||
ecma_number_t num;
|
||||
token tok;
|
||||
}
|
||||
num_and_token;
|
||||
strings_global_size
|
||||
};
|
||||
STATIC_STACK (strings, uint8_t, lp_string)
|
||||
|
||||
#define MAX_NUMS 25
|
||||
enum
|
||||
{
|
||||
numbers_global_size
|
||||
};
|
||||
STATIC_STACK (numbers, uint8_t, ecma_number_t)
|
||||
|
||||
static uint8_t seen_names_count = 0;
|
||||
|
||||
static num_and_token seen_nums[MAX_NUMS];
|
||||
static uint8_t seen_nums_count = 0;
|
||||
enum
|
||||
{
|
||||
num_ids_global_size
|
||||
};
|
||||
STATIC_STACK (num_ids, uint8_t, idx_t)
|
||||
|
||||
static bool
|
||||
is_empty (token tok)
|
||||
@@ -49,11 +61,6 @@ is_empty (token tok)
|
||||
return tok.type == TOK_EMPTY;
|
||||
}
|
||||
|
||||
/* Represents the contents of a script. */
|
||||
static const char *buffer_start = NULL;
|
||||
static const char *buffer = NULL;
|
||||
static const char *token_start;
|
||||
|
||||
static char
|
||||
get_char (size_t i)
|
||||
{
|
||||
@@ -64,44 +71,6 @@ get_char (size_t i)
|
||||
return *(buffer + i);
|
||||
}
|
||||
|
||||
#define LA(I) (get_char (I))
|
||||
|
||||
/* Continuous array of NULL-terminated strings. */
|
||||
static char *strings_cache = NULL;
|
||||
static size_t strings_cache_size = 0;
|
||||
|
||||
static void
|
||||
increase_strings_cache (void)
|
||||
{
|
||||
char *new_cache;
|
||||
size_t new_cache_size;
|
||||
|
||||
// if strings_cache_size == 0, allocator recommends minimum size that is more than 0
|
||||
new_cache_size = mem_heap_recommend_allocation_size (strings_cache_size * 2);
|
||||
new_cache = (char *) mem_heap_alloc_block (new_cache_size, MEM_HEAP_ALLOC_SHORT_TERM);
|
||||
|
||||
if (!new_cache)
|
||||
{
|
||||
// Allocator alligns recommended memory size
|
||||
new_cache_size = mem_heap_recommend_allocation_size (strings_cache_size + 1);
|
||||
new_cache = (char *) mem_heap_alloc_block (new_cache_size, MEM_HEAP_ALLOC_SHORT_TERM);
|
||||
|
||||
if (!new_cache)
|
||||
{
|
||||
parser_fatal (ERR_MEMORY);
|
||||
}
|
||||
}
|
||||
|
||||
if (strings_cache)
|
||||
{
|
||||
__memcpy (new_cache, strings_cache, strings_cache_size);
|
||||
mem_heap_free_block ((uint8_t *) strings_cache);
|
||||
}
|
||||
|
||||
strings_cache = new_cache;
|
||||
strings_cache_size = new_cache_size;
|
||||
}
|
||||
|
||||
#ifdef __TARGET_HOST_x64
|
||||
static void
|
||||
dump_current_line (void)
|
||||
@@ -137,6 +106,20 @@ current_token_equals_to (const char *str)
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool
|
||||
current_token_equals_to_lp (lp_string str)
|
||||
{
|
||||
if (str.length != (ecma_length_t) (buffer - token_start))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!__strncmp ((const char *) str.str, token_start, str.length))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* If TOKEN represents a keyword, return decoded keyword,
|
||||
if TOKEN represents a Future Reserved Word, return KW_RESERVED,
|
||||
otherwise return KW_NONE. */
|
||||
@@ -507,171 +490,121 @@ decode_keyword (void)
|
||||
}
|
||||
|
||||
static token
|
||||
convert_seen_name_to_token (token_type tt, const char *string)
|
||||
convert_current_token_to_token (token_type tt)
|
||||
{
|
||||
uint8_t i;
|
||||
char *current_string = strings_cache;
|
||||
JERRY_ASSERT (strings_cache);
|
||||
token ret_val = empty_token;
|
||||
JERRY_ASSERT (token_start);
|
||||
|
||||
for (i = 0; i < seen_names_count; i++)
|
||||
for (uint8_t i = 0; i < STACK_SIZE (strings); i++)
|
||||
{
|
||||
if ((string == NULL && current_token_equals_to (current_string))
|
||||
|| (string != NULL && !__strcmp (current_string, string)))
|
||||
if (current_token_equals_to_lp (strings.data[i]))
|
||||
{
|
||||
ret_val = (token)
|
||||
return (token)
|
||||
{
|
||||
.type = tt,
|
||||
.uid = i
|
||||
};
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
current_string += __strlen (current_string) + 1;
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
static token
|
||||
add_token_to_seen_names (token_type tt, const char *string)
|
||||
{
|
||||
size_t i;
|
||||
char *current_string = strings_cache;
|
||||
size_t required_size;
|
||||
size_t len = (string == NULL ? (size_t) (buffer - token_start) : __strlen (string));
|
||||
token ret_val = empty_token;
|
||||
|
||||
// Go to unused memory of cache
|
||||
for (i = 0; i < seen_names_count; i++)
|
||||
const lp_string str = (lp_string)
|
||||
{
|
||||
current_string += __strlen (current_string) + 1;
|
||||
}
|
||||
|
||||
required_size = (size_t) (current_string - strings_cache) + len + 1;
|
||||
if (required_size > strings_cache_size)
|
||||
{
|
||||
size_t offset = (size_t) (current_string - strings_cache);
|
||||
increase_strings_cache ();
|
||||
|
||||
// Now our pointer are invalid, adjust it
|
||||
current_string = strings_cache + offset;
|
||||
}
|
||||
|
||||
if (string == NULL)
|
||||
{
|
||||
// Copy current token with terminating NULL
|
||||
__strncpy (current_string, token_start, (size_t) (buffer - token_start));
|
||||
current_string += buffer - token_start;
|
||||
*current_string = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
__memcpy (current_string, string, __strlen (string) + 1);
|
||||
}
|
||||
|
||||
ret_val = (token)
|
||||
{
|
||||
.type = tt,
|
||||
.uid = seen_names_count++
|
||||
.length = (uint8_t) (buffer - token_start),
|
||||
.str = (const ecma_char_t *) token_start
|
||||
};
|
||||
|
||||
return ret_val;
|
||||
STACK_PUSH (strings, str);
|
||||
|
||||
return (token)
|
||||
{
|
||||
.type = tt,
|
||||
.uid = (idx_t) (STACK_SIZE (strings) - 1)
|
||||
};
|
||||
}
|
||||
|
||||
static token
|
||||
convert_seen_num_to_token (ecma_number_t num)
|
||||
{
|
||||
size_t i;
|
||||
uint8_t num_id;
|
||||
|
||||
for (i = 0; i < seen_nums_count; i++)
|
||||
JERRY_ASSERT (STACK_SIZE (num_ids) == STACK_SIZE (numbers));
|
||||
for (uint8_t i = 0; i < STACK_SIZE (numbers); i++)
|
||||
{
|
||||
// token must be exactly the same as seen
|
||||
if (seen_nums[i].num == num)
|
||||
if (numbers.data[i] == num)
|
||||
{
|
||||
return seen_nums[i].tok;
|
||||
return (token)
|
||||
{
|
||||
.type = TOK_NUMBER,
|
||||
.uid = num_ids.data[i]
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return empty_token;
|
||||
num_id = STACK_SIZE (num_ids);
|
||||
STACK_PUSH (num_ids, num_id);
|
||||
STACK_PUSH (numbers, num);
|
||||
|
||||
return (token)
|
||||
{
|
||||
.type = TOK_NUMBER,
|
||||
.uid = num_id
|
||||
};
|
||||
}
|
||||
|
||||
static void
|
||||
add_num_to_seen_tokens (num_and_token nat)
|
||||
const lp_string *
|
||||
lexer_get_strings (void)
|
||||
{
|
||||
JERRY_ASSERT (seen_nums_count < MAX_NUMS);
|
||||
|
||||
seen_nums[seen_nums_count++] = nat;
|
||||
return STACK_RAW_DATA (strings);
|
||||
}
|
||||
|
||||
uint8_t
|
||||
lexer_get_strings (const char **strings)
|
||||
lexer_get_strings_count (void)
|
||||
{
|
||||
if (strings)
|
||||
{
|
||||
char *current_string = strings_cache;
|
||||
int i;
|
||||
for (i = 0; i < seen_names_count; i++)
|
||||
{
|
||||
strings[i] = current_string;
|
||||
current_string += __strlen (current_string) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return seen_names_count;
|
||||
return STACK_SIZE (strings);
|
||||
}
|
||||
|
||||
uint8_t
|
||||
lexer_get_reserved_ids_count (void)
|
||||
{
|
||||
return (uint8_t) (seen_names_count + seen_nums_count);
|
||||
return (uint8_t) (STACK_SIZE (strings) + STACK_SIZE (numbers));
|
||||
}
|
||||
|
||||
const char *
|
||||
lp_string
|
||||
lexer_get_string_by_id (uint8_t id)
|
||||
{
|
||||
int i;
|
||||
char *current_string = strings_cache;
|
||||
JERRY_ASSERT (id < seen_names_count);
|
||||
JERRY_ASSERT (id < STACK_SIZE (strings));
|
||||
return STACK_ELEMENT (strings, id);
|
||||
}
|
||||
|
||||
for (i = 0 ; i < id; i++)
|
||||
{
|
||||
current_string += __strlen (current_string) + 1;
|
||||
}
|
||||
|
||||
return current_string;
|
||||
const ecma_number_t *
|
||||
lexer_get_nums (void)
|
||||
{
|
||||
return STACK_RAW_DATA (numbers);
|
||||
}
|
||||
|
||||
uint8_t
|
||||
lexer_get_nums (ecma_number_t *nums)
|
||||
lexer_get_nums_count (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!nums)
|
||||
{
|
||||
return seen_nums_count;
|
||||
}
|
||||
|
||||
for (i = 0; i < seen_nums_count; i++)
|
||||
{
|
||||
nums[i] = seen_nums[i].num;
|
||||
}
|
||||
|
||||
return seen_nums_count;
|
||||
return STACK_SIZE (numbers);
|
||||
}
|
||||
|
||||
void
|
||||
lexer_adjust_num_ids (void)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < seen_nums_count; i++)
|
||||
JERRY_ASSERT (STACK_SIZE (numbers) == STACK_SIZE (num_ids));
|
||||
for (uint8_t i = 0; i < STACK_SIZE (numbers); i++)
|
||||
{
|
||||
seen_nums[i].tok.uid = (uint8_t) (seen_nums[i].tok.uid + seen_names_count);
|
||||
STACK_ELEMENT (num_ids, i) = (uint8_t) (STACK_ELEMENT (num_ids, i) + STACK_SIZE (strings));
|
||||
}
|
||||
}
|
||||
|
||||
ecma_number_t
|
||||
lexer_get_num_by_id (uint8_t id)
|
||||
{
|
||||
JERRY_ASSERT (id >= lexer_get_strings_count () && id < lexer_get_reserved_ids_count ());
|
||||
JERRY_ASSERT (STACK_ELEMENT (num_ids, id - lexer_get_strings_count ()) == id);
|
||||
return STACK_ELEMENT (numbers, id - lexer_get_strings_count ());
|
||||
}
|
||||
|
||||
static void
|
||||
new_token (void)
|
||||
{
|
||||
@@ -773,20 +706,14 @@ parse_name (void)
|
||||
}
|
||||
}
|
||||
|
||||
known_token = convert_seen_name_to_token (TOK_NAME, NULL);
|
||||
if (!is_empty (known_token))
|
||||
{
|
||||
goto end;
|
||||
}
|
||||
|
||||
known_token = add_token_to_seen_names (TOK_NAME, NULL);
|
||||
known_token = convert_current_token_to_token (TOK_NAME);
|
||||
|
||||
end:
|
||||
token_start = NULL;
|
||||
return known_token;
|
||||
}
|
||||
|
||||
static int32_t
|
||||
static uint32_t
|
||||
hex_to_int (char hex)
|
||||
{
|
||||
switch (hex)
|
||||
@@ -827,7 +754,7 @@ parse_number (void)
|
||||
bool is_fp = false;
|
||||
bool is_exp = false;
|
||||
size_t tok_length = 0, i;
|
||||
int32_t res = 0;
|
||||
uint32_t res = 0;
|
||||
token known_token;
|
||||
|
||||
JERRY_ASSERT (__isdigit (c) || c == '.');
|
||||
@@ -868,10 +795,17 @@ parse_number (void)
|
||||
}
|
||||
|
||||
tok_length = (size_t) (buffer - token_start);
|
||||
// OK, I know that integer overflow can occur here
|
||||
|
||||
for (i = 0; i < tok_length; i++)
|
||||
{
|
||||
#ifndef JERRY_NDEBUG
|
||||
uint32_t old_res = res;
|
||||
#endif
|
||||
res = (res << 4) + hex_to_int (token_start[i]);
|
||||
FIXME (Replace with conversion to ecma_number_t)
|
||||
#ifndef JERRY_NDEBUG
|
||||
JERRY_ASSERT (old_res <= res);
|
||||
#endif
|
||||
}
|
||||
|
||||
token_start = NULL;
|
||||
@@ -886,23 +820,8 @@ parse_number (void)
|
||||
}
|
||||
|
||||
known_token = convert_seen_num_to_token ((ecma_number_t) res);
|
||||
if (!is_empty (known_token))
|
||||
{
|
||||
return known_token;
|
||||
}
|
||||
JERRY_ASSERT (!is_empty (known_token));
|
||||
|
||||
known_token = (token)
|
||||
{
|
||||
.type = TOK_NUMBER,
|
||||
.uid = seen_nums_count
|
||||
};
|
||||
add_num_to_seen_tokens (
|
||||
(num_and_token)
|
||||
{
|
||||
.num = (ecma_number_t) res,
|
||||
.tok = known_token
|
||||
}
|
||||
);
|
||||
return known_token;
|
||||
}
|
||||
|
||||
@@ -973,23 +892,7 @@ parse_number (void)
|
||||
token_start = NULL;
|
||||
|
||||
known_token = convert_seen_num_to_token (res);
|
||||
if (!is_empty (known_token))
|
||||
{
|
||||
return known_token;
|
||||
}
|
||||
|
||||
known_token = (token)
|
||||
{
|
||||
.type = TOK_NUMBER,
|
||||
.uid = seen_nums_count
|
||||
};
|
||||
add_num_to_seen_tokens (
|
||||
(num_and_token)
|
||||
{
|
||||
.num = res,
|
||||
.tok = known_token
|
||||
}
|
||||
);
|
||||
return known_token;
|
||||
}
|
||||
|
||||
@@ -1011,54 +914,15 @@ parse_number (void)
|
||||
}
|
||||
|
||||
known_token = convert_seen_num_to_token ((ecma_number_t) res);
|
||||
if (!is_empty (known_token))
|
||||
{
|
||||
return known_token;
|
||||
}
|
||||
|
||||
known_token = (token)
|
||||
{
|
||||
.type = TOK_NUMBER,
|
||||
.uid = seen_nums_count
|
||||
};
|
||||
add_num_to_seen_tokens (
|
||||
(num_and_token)
|
||||
{
|
||||
.num = (ecma_number_t) res,
|
||||
.tok = known_token
|
||||
}
|
||||
);
|
||||
return known_token;
|
||||
}
|
||||
|
||||
static char
|
||||
escape_char (char c)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case 'b': return '\b';
|
||||
case 'f': return '\f';
|
||||
case 'n': return '\n';
|
||||
case 'r': return '\r';
|
||||
case 't': return '\t';
|
||||
case 'v': return '\v';
|
||||
case '\'':
|
||||
case '"':
|
||||
case '\\':
|
||||
default: return c;
|
||||
}
|
||||
}
|
||||
|
||||
static token
|
||||
parse_string (void)
|
||||
{
|
||||
char c = LA (0);
|
||||
bool is_double_quoted;
|
||||
char *tok = NULL;
|
||||
char *index = NULL;
|
||||
const char *i;
|
||||
size_t length;
|
||||
token known_token = empty_token;
|
||||
token result;
|
||||
|
||||
JERRY_ASSERT (c == '\'' || c == '"');
|
||||
|
||||
@@ -1104,46 +968,13 @@ parse_string (void)
|
||||
consume_char ();
|
||||
}
|
||||
|
||||
length = (size_t) (buffer - token_start);
|
||||
tok = (char *) mem_heap_alloc_block (length + 1, MEM_HEAP_ALLOC_SHORT_TERM);
|
||||
__memset (tok, '\0', length + 1);
|
||||
index = tok;
|
||||
|
||||
// Copy current token to TOK and replace escape sequences by there meanings
|
||||
for (i = token_start; i < buffer; i++)
|
||||
{
|
||||
if (*i == '\\')
|
||||
{
|
||||
if (*(i+1) == '\n')
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
*index = escape_char (*(i+1));
|
||||
index++;
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
*index = *i;
|
||||
index++;
|
||||
}
|
||||
|
||||
// Eat up '"'
|
||||
result = convert_current_token_to_token (TOK_STRING);
|
||||
|
||||
consume_char ();
|
||||
|
||||
known_token = convert_seen_name_to_token (TOK_STRING, tok);
|
||||
if (!is_empty (known_token))
|
||||
{
|
||||
goto end;
|
||||
}
|
||||
|
||||
known_token = add_token_to_seen_names (TOK_STRING, tok);
|
||||
|
||||
end:
|
||||
mem_heap_free_block ((uint8_t *) tok);
|
||||
token_start = NULL;
|
||||
return known_token;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1421,7 +1252,10 @@ lexer_init (const char *source, size_t source_size, bool show_opcodes)
|
||||
allow_dump_lines = show_opcodes;
|
||||
buffer_size = source_size;
|
||||
lexer_set_source (source);
|
||||
increase_strings_cache ();
|
||||
|
||||
STACK_INIT (lp_string, strings);
|
||||
STACK_INIT (ecma_number_t, numbers);
|
||||
STACK_INIT (idx_t, num_ids);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1439,7 +1273,7 @@ lexer_run_first_pass (void)
|
||||
void
|
||||
lexer_free (void)
|
||||
{
|
||||
mem_heap_free_block ((uint8_t *) strings_cache);
|
||||
strings_cache = NULL;
|
||||
strings_cache_size = 0;
|
||||
STACK_FREE (strings);
|
||||
STACK_FREE (numbers);
|
||||
STACK_FREE (num_ids);
|
||||
}
|
||||
|
||||
+14
-3
@@ -18,6 +18,7 @@
|
||||
|
||||
#include "globals.h"
|
||||
#include "ecma-globals.h"
|
||||
#include "lp-string.h"
|
||||
|
||||
/* Keywords. */
|
||||
typedef uint8_t keyword;
|
||||
@@ -145,14 +146,24 @@ token;
|
||||
|
||||
void lexer_init (const char *, size_t, bool);
|
||||
void lexer_free (void);
|
||||
|
||||
void lexer_run_first_pass (void);
|
||||
|
||||
token lexer_next_token (void);
|
||||
void lexer_save_token (token);
|
||||
|
||||
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 (ecma_number_t *);
|
||||
|
||||
const lp_string *lexer_get_strings (void);
|
||||
uint8_t lexer_get_strings_count (void);
|
||||
lp_string lexer_get_string_by_id (uint8_t);
|
||||
|
||||
const ecma_number_t *lexer_get_nums (void);
|
||||
ecma_number_t lexer_get_num_by_id (uint8_t);
|
||||
uint8_t lexer_get_nums_count (void);
|
||||
|
||||
void lexer_adjust_num_ids (void);
|
||||
|
||||
#endif
|
||||
|
||||
+699
-549
File diff suppressed because it is too large
Load Diff
@@ -18,7 +18,7 @@
|
||||
|
||||
#include "globals.h"
|
||||
|
||||
void parser_init (void);
|
||||
void parser_init (const char *, size_t, bool);
|
||||
void parser_parse_program (void);
|
||||
void parser_free (void);
|
||||
|
||||
|
||||
@@ -19,11 +19,7 @@
|
||||
#include "opcodes.h"
|
||||
#include "stack.h"
|
||||
#include "jerry-libc.h"
|
||||
|
||||
#ifndef OPCODE_T_STACK_DEFINED
|
||||
DEFINE_STACK_TYPE (opcode_counter_t, opcode_t)
|
||||
#define OPCODE_T_STACK_DEFINED
|
||||
#endif
|
||||
#include "lp-string.h"
|
||||
|
||||
/* bytecode_data contains identifiers, string and num literals.
|
||||
Memory map if the following.
|
||||
@@ -36,12 +32,21 @@ DEFINE_STACK_TYPE (opcode_counter_t, opcode_t)
|
||||
U8 nums_count;
|
||||
U32 nums[nums_count];
|
||||
} */
|
||||
extern uint8_t *bytecode_data;
|
||||
struct
|
||||
{
|
||||
uint8_t strs_count;
|
||||
uint8_t nums_count;
|
||||
|
||||
const lp_string *strings;
|
||||
const ecma_number_t *nums;
|
||||
}
|
||||
__packed
|
||||
bytecode_data;
|
||||
|
||||
enum
|
||||
{
|
||||
bytecode_opcodes_global_size
|
||||
};
|
||||
STACK (opcode_t, bytecode_opcodes)
|
||||
STACK (bytecode_opcodes, opcode_counter_t, opcode_t)
|
||||
|
||||
#endif // BYTECODE_DATA_H
|
||||
|
||||
@@ -16,70 +16,34 @@
|
||||
#include "deserializer.h"
|
||||
#include "bytecode-data.h"
|
||||
|
||||
ecma_number_t *num_data = NULL;
|
||||
uint8_t num_size = 0;
|
||||
|
||||
const ecma_char_t *
|
||||
deserialize_string_by_id (uint8_t id)
|
||||
{
|
||||
uint8_t size, *data;
|
||||
uint16_t offset;
|
||||
JERRY_ASSERT (bytecode_data.strings[id].str[bytecode_data.strings[id].length] == '\0');
|
||||
|
||||
if (bytecode_data == NULL)
|
||||
if (id >= bytecode_data.strs_count)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size = *bytecode_data;
|
||||
|
||||
if (id >= size)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
data = bytecode_data;
|
||||
|
||||
data += id * 2 + 1;
|
||||
|
||||
offset = *((uint16_t *) data);
|
||||
|
||||
return ((const ecma_char_t *) bytecode_data + offset);
|
||||
return ((const ecma_char_t *) bytecode_data.strings[id].str);
|
||||
}
|
||||
|
||||
ecma_number_t
|
||||
deserialize_num_by_id (uint8_t id)
|
||||
{
|
||||
uint16_t str_size;
|
||||
|
||||
str_size = *bytecode_data;
|
||||
if (id < str_size)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
id = (uint8_t) (id - str_size);
|
||||
|
||||
if (num_data == NULL)
|
||||
{
|
||||
// Go to last string's offset
|
||||
uint8_t *data = (uint8_t *) (bytecode_data + str_size * 2 - 1);
|
||||
uint16_t str_offset = *((uint16_t *) data);
|
||||
data = bytecode_data + str_offset;
|
||||
|
||||
while (*data)
|
||||
{
|
||||
data++;
|
||||
}
|
||||
|
||||
num_size = *(++data);
|
||||
num_data = (ecma_number_t *) ++data;
|
||||
}
|
||||
|
||||
if (id >= num_size)
|
||||
if (id < bytecode_data.strs_count)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return num_data[id];
|
||||
id = (uint8_t) (id - bytecode_data.strs_count);
|
||||
|
||||
if (id >= bytecode_data.nums_count)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return bytecode_data.nums[id];
|
||||
}
|
||||
|
||||
const void *
|
||||
@@ -92,12 +56,5 @@ deserialize_bytecode (void)
|
||||
uint8_t
|
||||
deserialize_min_temp (void)
|
||||
{
|
||||
uint8_t str_size = *bytecode_data;
|
||||
|
||||
if (num_size == 0)
|
||||
{
|
||||
deserialize_num_by_id (str_size); // Init num_data and num_size
|
||||
}
|
||||
|
||||
return (uint8_t) (str_size + num_size);
|
||||
return (uint8_t) (bytecode_data.strs_count + bytecode_data.nums_count);
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
#include "pretty-printer.h"
|
||||
#include "jerry-libc.h"
|
||||
#include "deserializer.h"
|
||||
#include "lexer.h"
|
||||
|
||||
#define NAME_TO_ID(op) (__op__idx_##op)
|
||||
|
||||
@@ -39,17 +39,24 @@ static uint8_t opcode_sizes[] =
|
||||
0
|
||||
};
|
||||
|
||||
void
|
||||
pp_strings (const char *strings[], uint8_t size)
|
||||
static void
|
||||
dump_lp (lp_string lp)
|
||||
{
|
||||
uint8_t i;
|
||||
uint16_t offset = (uint16_t) (size * 2 + 1);
|
||||
|
||||
__printf ("STRINGS %d:\n", size);
|
||||
for (i = 0; i < size; i++)
|
||||
for (ecma_length_t i = 0; i < lp.length; i++)
|
||||
{
|
||||
__printf ("%3d %5d %20s\n", i, offset, strings[i]);
|
||||
offset = (uint16_t) (offset + __strlen (strings[i]) + 1);
|
||||
__putchar (lp.str[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
pp_strings (const lp_string strings[], uint8_t size)
|
||||
{
|
||||
__printf ("STRINGS %d:\n", size);
|
||||
for (uint8_t i = 0; i < size; i++)
|
||||
{
|
||||
__printf ("%3d ", i);
|
||||
dump_lp (strings[i]);
|
||||
__putchar ('\n');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,17 +84,17 @@ dump_arg_list (idx_t id)
|
||||
static void
|
||||
dump_variable (idx_t id)
|
||||
{
|
||||
if (id >= deserialize_min_temp ())
|
||||
if (id >= lexer_get_reserved_ids_count ())
|
||||
{
|
||||
__printf ("tmp%d", id);
|
||||
}
|
||||
else if (deserialize_string_by_id (id))
|
||||
else if (id < lexer_get_strings_count ())
|
||||
{
|
||||
__printf ("%s", deserialize_string_by_id (id));
|
||||
dump_lp (lexer_get_string_by_id (id));
|
||||
}
|
||||
else
|
||||
{
|
||||
__printf ("%d", (int) deserialize_num_by_id (id));
|
||||
__printf ("%d", (int) lexer_get_num_by_id (id));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -154,14 +161,14 @@ dump_variable (idx_t id)
|
||||
} \
|
||||
__printf (": SIMPLE"); \
|
||||
} else if (opcode.data.op.type_value_right == OPCODE_ARG_TYPE_STRING) { \
|
||||
__printf ("'%s'", deserialize_string_by_id (opcode.data.op.op2)); \
|
||||
dump_lp (lexer_get_string_by_id (opcode.data.op.op2)); \
|
||||
__printf (": STRING"); \
|
||||
} else if (opcode.data.op.type_value_right == OPCODE_ARG_TYPE_NUMBER) {\
|
||||
__printf ("%d", (int) deserialize_num_by_id (opcode.data.op.op2)); \
|
||||
__printf ("%d", (int) lexer_get_num_by_id (opcode.data.op.op2)); \
|
||||
__printf (": NUMBER"); \
|
||||
} else if (opcode.data.op.type_value_right == OPCODE_ARG_TYPE_SMALLINT) {\
|
||||
__printf ("%d", opcode.data.op.op2); \
|
||||
__printf (": NUMBER"); \
|
||||
__printf (": SMALLINT"); \
|
||||
} else if (opcode.data.op.type_value_right == OPCODE_ARG_TYPE_VARIABLE) {\
|
||||
dump_variable (opcode.data.op.op2); \
|
||||
__printf (": TYPEOF("); \
|
||||
|
||||
@@ -17,9 +17,10 @@
|
||||
#define PRETTY_PRINTER
|
||||
|
||||
#include "interpreter.h"
|
||||
#include "lp-string.h"
|
||||
|
||||
void pp_opcode (opcode_counter_t, opcode_t, bool);
|
||||
void pp_strings (const char **, uint8_t);
|
||||
void pp_strings (const lp_string *, uint8_t);
|
||||
void pp_nums (const ecma_number_t *, uint8_t, uint8_t);
|
||||
|
||||
#endif // PRETTY_PRINTER
|
||||
|
||||
@@ -22,94 +22,19 @@
|
||||
|
||||
static bool print_opcodes;
|
||||
|
||||
uint8_t *bytecode_data = NULL;
|
||||
|
||||
void
|
||||
serializer_init (bool show_opcodes)
|
||||
serializer_dump_strings_and_nums (const lp_string strings[], uint8_t strs_count,
|
||||
const ecma_number_t nums[], uint8_t nums_count)
|
||||
{
|
||||
print_opcodes = show_opcodes;
|
||||
INIT_STACK (opcode_t, bytecode_opcodes);
|
||||
}
|
||||
|
||||
uint16_t
|
||||
serializer_dump_strings (const char *strings[], uint8_t size)
|
||||
{
|
||||
uint8_t i;
|
||||
uint16_t offset = (uint16_t) (size * 2 + 1), res;
|
||||
|
||||
if (print_opcodes)
|
||||
{
|
||||
pp_strings (strings, size);
|
||||
pp_strings (strings, strs_count);
|
||||
}
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
offset = (uint16_t) (offset + __strlen (strings[i]) + 1);
|
||||
}
|
||||
|
||||
bytecode_data = mem_heap_alloc_block (offset, MEM_HEAP_ALLOC_SHORT_TERM);
|
||||
res = offset;
|
||||
|
||||
bytecode_data[0] = size;
|
||||
offset = (uint16_t) (size * 2 + 1);
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
*((uint16_t *) (bytecode_data + i * 2 + 1)) = offset;
|
||||
offset = (uint16_t) (offset + __strlen (strings[i]) + 1);
|
||||
}
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
offset = *((uint16_t *) (bytecode_data + i * 2 + 1));
|
||||
__strncpy ((char *) (bytecode_data + offset), strings[i], __strlen (strings[i]) + 1);
|
||||
}
|
||||
|
||||
#ifndef JERRY_NDEBUG
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
JERRY_ASSERT (!__strcmp (strings[i], (const char *) deserialize_string_by_id (i)));
|
||||
}
|
||||
#endif
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void
|
||||
serializer_dump_nums (const ecma_number_t nums[], uint8_t size, uint16_t offset, uint8_t strings_num)
|
||||
{
|
||||
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 * type_size + 1), MEM_HEAP_ALLOC_LONG_TERM);
|
||||
if (!data)
|
||||
{
|
||||
parser_fatal (ERR_MEMORY);
|
||||
}
|
||||
|
||||
__memcpy (data, bytecode_data, offset);
|
||||
mem_heap_free_block (bytecode_data);
|
||||
bytecode_data = data;
|
||||
data += offset;
|
||||
data[0] = size;
|
||||
data++;
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
__memcpy (data, nums + i, type_size);
|
||||
data += type_size;
|
||||
}
|
||||
|
||||
#ifndef JERRY_NDEBUG
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
JERRY_ASSERT (nums[i] == deserialize_num_by_id ((uint8_t) (i + strings_num)));
|
||||
}
|
||||
|
||||
JERRY_ASSERT (deserialize_min_temp () == (uint8_t) (size + strings_num));
|
||||
#endif
|
||||
bytecode_data.strs_count = strs_count;
|
||||
bytecode_data.nums_count = nums_count;
|
||||
bytecode_data.strings = strings;
|
||||
bytecode_data.nums = nums;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -122,14 +47,14 @@ serializer_dump_opcode (opcode_t opcode)
|
||||
pp_opcode (STACK_SIZE (bytecode_opcodes), opcode, false);
|
||||
}
|
||||
|
||||
PUSH (bytecode_opcodes, opcode)
|
||||
STACK_PUSH (bytecode_opcodes, opcode);
|
||||
}
|
||||
|
||||
void
|
||||
serializer_rewrite_opcode (const opcode_counter_t loc, opcode_t opcode)
|
||||
{
|
||||
JERRY_ASSERT (loc < STACK_SIZE (bytecode_opcodes));
|
||||
bytecode_opcodes.data[loc] = opcode;
|
||||
STACK_ELEMENT (bytecode_opcodes, loc) = opcode;
|
||||
|
||||
if (print_opcodes)
|
||||
{
|
||||
@@ -151,18 +76,30 @@ serializer_print_opcodes (void)
|
||||
|
||||
for (loc = 0; loc < STACK_SIZE (bytecode_opcodes); loc++)
|
||||
{
|
||||
pp_opcode (loc, bytecode_opcodes.data[loc], false);
|
||||
pp_opcode (loc, STACK_ELEMENT (bytecode_opcodes, loc), false);
|
||||
}
|
||||
}
|
||||
|
||||
/* Make lp_strings also zero-terminated. */
|
||||
void
|
||||
serializer_adjust_strings (void)
|
||||
{
|
||||
for (uint8_t i = 0; i < bytecode_data.strs_count; i++)
|
||||
{
|
||||
const ecma_length_t len = bytecode_data.strings[i].length;
|
||||
((ecma_char_t *) (bytecode_data.strings[i]).str)[len] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
serializer_init (bool show_opcodes)
|
||||
{
|
||||
print_opcodes = show_opcodes;
|
||||
STACK_INIT (opcode_t, bytecode_opcodes);
|
||||
}
|
||||
|
||||
void
|
||||
serializer_free (void)
|
||||
{
|
||||
mem_heap_free_block (bytecode_data);
|
||||
bytecode_data = NULL;
|
||||
|
||||
if (bytecode_opcodes.data)
|
||||
{
|
||||
FREE_STACK (bytecode_opcodes);
|
||||
}
|
||||
STACK_FREE (bytecode_opcodes);
|
||||
}
|
||||
|
||||
@@ -19,12 +19,12 @@
|
||||
#include "globals.h"
|
||||
#include "opcodes.h"
|
||||
#include "interpreter.h"
|
||||
#include "lp-string.h"
|
||||
|
||||
void serializer_init (bool show_opcodes);
|
||||
|
||||
uint16_t serializer_dump_strings (const char **, uint8_t);
|
||||
|
||||
void serializer_dump_nums (const ecma_number_t *, uint8_t, uint16_t, uint8_t);
|
||||
void serializer_dump_strings_and_nums (const lp_string *, uint8_t,
|
||||
const ecma_number_t *, uint8_t);
|
||||
|
||||
void serializer_dump_opcode (opcode_t);
|
||||
|
||||
@@ -32,6 +32,8 @@ void serializer_rewrite_opcode (const opcode_counter_t, opcode_t);
|
||||
|
||||
void serializer_print_opcodes (void);
|
||||
|
||||
void serializer_adjust_strings (void);
|
||||
|
||||
void serializer_free (void);
|
||||
|
||||
#endif // SERIALIZER_H
|
||||
|
||||
+8
-36
@@ -32,32 +32,17 @@
|
||||
#define MAX_STRINGS 100
|
||||
#define MAX_NUMS 25
|
||||
|
||||
static const opcode_t *
|
||||
parser_run (const char *script_source, size_t script_source_size, bool is_show_opcodes)
|
||||
static bool
|
||||
jerry_run (const char *script_source, size_t script_source_size,
|
||||
bool is_parse_only, bool is_show_opcodes, bool is_show_mem_stats)
|
||||
{
|
||||
const char *strings[MAX_STRINGS];
|
||||
ecma_number_t nums[MAX_NUMS];
|
||||
uint8_t strings_num, nums_count;
|
||||
uint16_t offset;
|
||||
const opcode_t *opcodes;
|
||||
|
||||
lexer_init (script_source, script_source_size, is_show_opcodes);
|
||||
mem_init ();
|
||||
|
||||
lexer_run_first_pass ();
|
||||
|
||||
strings_num = lexer_get_strings (strings);
|
||||
nums_count = lexer_get_nums (nums);
|
||||
lexer_adjust_num_ids ();
|
||||
|
||||
offset = serializer_dump_strings (strings, strings_num);
|
||||
serializer_dump_nums (nums, nums_count, offset, strings_num);
|
||||
|
||||
parser_init ();
|
||||
parser_init (script_source, script_source_size, is_show_opcodes);
|
||||
parser_parse_program ();
|
||||
|
||||
lexer_free ();
|
||||
parser_free ();
|
||||
|
||||
opcodes = deserialize_bytecode ();
|
||||
|
||||
optimizer_run_passes ((opcode_t *) opcodes);
|
||||
@@ -66,23 +51,10 @@ parser_run (const char *script_source, size_t script_source_size, bool is_show_o
|
||||
serializer_print_opcodes ();
|
||||
#endif
|
||||
|
||||
return opcodes;
|
||||
}
|
||||
|
||||
static bool
|
||||
jerry_run (const char *script_source, size_t script_source_size,
|
||||
bool is_parse_only, bool is_show_opcodes, bool is_show_mem_stats)
|
||||
{
|
||||
const opcode_t *opcodes;
|
||||
|
||||
mem_init ();
|
||||
|
||||
serializer_init (is_show_opcodes);
|
||||
|
||||
opcodes = parser_run (script_source, script_source_size, is_show_opcodes);
|
||||
|
||||
if (is_parse_only)
|
||||
{
|
||||
parser_free ();
|
||||
mem_finalize (is_show_mem_stats);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -90,7 +62,7 @@ jerry_run (const char *script_source, size_t script_source_size,
|
||||
|
||||
bool is_success = run_int ();
|
||||
|
||||
serializer_free ();
|
||||
parser_free ();
|
||||
|
||||
mem_finalize (is_show_mem_stats);
|
||||
|
||||
|
||||
@@ -16,16 +16,22 @@
|
||||
#ifndef COMMON_H
|
||||
#define COMMON_H
|
||||
|
||||
#include "jerry-libc.h"
|
||||
|
||||
#define NAME_TO_ID(op) (__op__idx_##op)
|
||||
|
||||
#define __OPCODE_SIZE(name, arg1, arg2, arg3) \
|
||||
sizeof (__op_##name) + 1,
|
||||
|
||||
#define LP(s) (lp_string) { .length = (uint8_t) __strlen(s), .str = (ecma_char_t *) s }
|
||||
|
||||
static uint8_t opcode_sizes[] = {
|
||||
OP_LIST (OPCODE_SIZE)
|
||||
0
|
||||
};
|
||||
|
||||
static bool opcodes_equal (const opcode_t *, opcode_t *, uint16_t) __unused;
|
||||
|
||||
static bool
|
||||
opcodes_equal (const opcode_t *opcodes1, opcode_t *opcodes2, uint16_t size)
|
||||
{
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "mem-allocator.h"
|
||||
#include "opcodes.h"
|
||||
#include "serializer.h"
|
||||
#include "common.h"
|
||||
|
||||
/**
|
||||
* Unit test's main function.
|
||||
@@ -39,11 +40,10 @@ main( int __unused argc,
|
||||
mem_init();
|
||||
serializer_init (false);
|
||||
|
||||
const char *strings[] = { "a",
|
||||
"b" };
|
||||
const lp_string strings[] = { LP("a"),
|
||||
LP("b") };
|
||||
ecma_number_t nums [] = { 2.0 };
|
||||
uint16_t offset = serializer_dump_strings( strings, 2);
|
||||
serializer_dump_nums( nums, 1, offset, 2);
|
||||
serializer_dump_strings_and_nums (strings, 2, nums, 1);
|
||||
|
||||
init_int( test_program, false);
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "mem-allocator.h"
|
||||
#include "opcodes.h"
|
||||
#include "serializer.h"
|
||||
#include "common.h"
|
||||
|
||||
/**
|
||||
* Unit test's main function.
|
||||
@@ -171,15 +172,14 @@ main( int __unused argc,
|
||||
mem_init();
|
||||
serializer_init (false);
|
||||
|
||||
const char *strings[] = { "a",
|
||||
"b",
|
||||
"length",
|
||||
"1" };
|
||||
const lp_string strings[] = { LP("a"),
|
||||
LP("b"),
|
||||
LP("length"),
|
||||
LP("1") };
|
||||
ecma_number_t nums [] = { 2.0,
|
||||
12.0,
|
||||
2.5 };
|
||||
uint16_t offset = serializer_dump_strings( strings, 4);
|
||||
serializer_dump_nums( nums, 3, offset, 4);
|
||||
serializer_dump_strings_and_nums (strings, 4, nums, 3);
|
||||
|
||||
init_int( test_program, false);
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "mem-allocator.h"
|
||||
#include "opcodes.h"
|
||||
#include "serializer.h"
|
||||
#include "common.h"
|
||||
|
||||
/**
|
||||
* Unit test's main function.
|
||||
@@ -42,12 +43,12 @@ main( int __unused argc,
|
||||
};
|
||||
|
||||
mem_init();
|
||||
serializer_init (false);
|
||||
|
||||
const char *strings[] = { "a",
|
||||
"b" };
|
||||
const lp_string strings[] = { LP("a"),
|
||||
LP("b") };
|
||||
ecma_number_t nums [] = { 2.0 };
|
||||
uint16_t offset = serializer_dump_strings( strings, 2);
|
||||
serializer_dump_nums( nums, 1, offset, 2);
|
||||
serializer_dump_strings_and_nums (strings, 2, nums, 1);
|
||||
|
||||
init_int( test_program, false);
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "mem-allocator.h"
|
||||
#include "opcodes.h"
|
||||
#include "serializer.h"
|
||||
#include "common.h"
|
||||
|
||||
/**
|
||||
* Unit test's main function.
|
||||
@@ -37,12 +38,12 @@ main( int __unused argc,
|
||||
};
|
||||
|
||||
mem_init();
|
||||
serializer_init (false);
|
||||
|
||||
const char *strings[] = { "a",
|
||||
"b" };
|
||||
ecma_number_t nums [] = { 2 };
|
||||
uint16_t offset = serializer_dump_strings( strings, 2);
|
||||
serializer_dump_nums( nums, 1, offset, 2);
|
||||
const lp_string strings[] = { LP("a"),
|
||||
LP("b") };
|
||||
ecma_number_t nums [] = { 2.0 };
|
||||
serializer_dump_strings_and_nums (strings, 2, nums, 1);
|
||||
|
||||
init_int( test_program, false);
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "mem-allocator.h"
|
||||
#include "opcodes.h"
|
||||
#include "serializer.h"
|
||||
#include "common.h"
|
||||
|
||||
/**
|
||||
* Unit test's main function.
|
||||
@@ -37,12 +38,12 @@ main( int __unused argc,
|
||||
};
|
||||
|
||||
mem_init();
|
||||
serializer_init (false);
|
||||
|
||||
const char *strings[] = { "a",
|
||||
"b" };
|
||||
ecma_number_t nums [] = { 2 };
|
||||
uint16_t offset = serializer_dump_strings( strings, 2);
|
||||
serializer_dump_nums( nums, 1, offset, 2);
|
||||
const lp_string strings[] = { LP("a"),
|
||||
LP("b") };
|
||||
ecma_number_t nums [] = { 2.0 };
|
||||
serializer_dump_strings_and_nums (strings, 2, nums, 1);
|
||||
|
||||
init_int( test_program, false);
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "mem-allocator.h"
|
||||
#include "opcodes.h"
|
||||
#include "serializer.h"
|
||||
#include "common.h"
|
||||
|
||||
/**
|
||||
* Unit test's main function.
|
||||
@@ -136,16 +137,15 @@ main( int __unused argc,
|
||||
mem_init();
|
||||
serializer_init (false);
|
||||
|
||||
const char *strings[] = { "a",
|
||||
"b",
|
||||
"property1",
|
||||
"property2",
|
||||
"property3",
|
||||
"value1",
|
||||
"value2" };
|
||||
const lp_string strings[] = { LP("a"),
|
||||
LP("b"),
|
||||
LP("property1"),
|
||||
LP("property2"),
|
||||
LP("property3"),
|
||||
LP("value1"),
|
||||
LP("value2") };
|
||||
ecma_number_t nums [] = { 2.5 };
|
||||
uint16_t offset = serializer_dump_strings( strings, 7);
|
||||
serializer_dump_nums( nums, 1, offset, 7);
|
||||
serializer_dump_strings_and_nums (strings, 7, nums, 1);
|
||||
|
||||
init_int( test_program, false);
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "mem-allocator.h"
|
||||
#include "opcodes.h"
|
||||
#include "serializer.h"
|
||||
#include "common.h"
|
||||
|
||||
/**
|
||||
* Unit test's main function.
|
||||
@@ -37,12 +38,12 @@ main( int __unused argc,
|
||||
};
|
||||
|
||||
mem_init();
|
||||
serializer_init (false);
|
||||
|
||||
const char *strings[] = { "a",
|
||||
"b" };
|
||||
ecma_number_t nums [] = { 2 };
|
||||
uint16_t offset = serializer_dump_strings( strings, 2);
|
||||
serializer_dump_nums( nums, 1, offset, 2);
|
||||
const lp_string strings[] = { LP("a"),
|
||||
LP("b") };
|
||||
ecma_number_t nums [] = { 2.0 };
|
||||
serializer_dump_strings_and_nums (strings, 2, nums, 1);
|
||||
|
||||
init_int( test_program, false);
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "mem-allocator.h"
|
||||
#include "opcodes.h"
|
||||
#include "serializer.h"
|
||||
#include "common.h"
|
||||
|
||||
/**
|
||||
* Unit test's main function.
|
||||
@@ -37,12 +38,12 @@ main( int __unused argc,
|
||||
};
|
||||
|
||||
mem_init();
|
||||
serializer_init (false);
|
||||
|
||||
const char *strings[] = { "a",
|
||||
"b" };
|
||||
ecma_number_t nums [] = { 2 };
|
||||
uint16_t offset = serializer_dump_strings( strings, 2);
|
||||
serializer_dump_nums( nums, 1, offset, 2);
|
||||
const lp_string strings[] = { LP("a"),
|
||||
LP("b") };
|
||||
ecma_number_t nums [] = { 2.0 };
|
||||
serializer_dump_strings_and_nums (strings, 2, nums, 1);
|
||||
|
||||
init_int( test_program, false);
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "mem-allocator.h"
|
||||
#include "opcodes.h"
|
||||
#include "serializer.h"
|
||||
#include "common.h"
|
||||
|
||||
/**
|
||||
* Unit test's main function.
|
||||
@@ -50,13 +51,13 @@ main( int __unused argc,
|
||||
};
|
||||
|
||||
mem_init();
|
||||
serializer_init (false);
|
||||
|
||||
const char *strings[] = { "a",
|
||||
"b",
|
||||
"c" };
|
||||
const lp_string strings[] = { LP("a"),
|
||||
LP("b"),
|
||||
LP("c") };
|
||||
ecma_number_t nums [] = { 2.0 };
|
||||
uint16_t offset = serializer_dump_strings( strings, 3);
|
||||
serializer_dump_nums( nums, 1, offset, 3);
|
||||
serializer_dump_strings_and_nums (strings, 3, nums, 1);
|
||||
|
||||
init_int( test_program, false);
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "mem-allocator.h"
|
||||
#include "opcodes.h"
|
||||
#include "serializer.h"
|
||||
#include "common.h"
|
||||
|
||||
/**
|
||||
* Unit test's main function.
|
||||
@@ -35,12 +36,12 @@ main( int __unused argc,
|
||||
};
|
||||
|
||||
mem_init();
|
||||
serializer_init (false);
|
||||
|
||||
const char *strings[] = { "a",
|
||||
"b" };
|
||||
ecma_number_t nums [] = { 2 };
|
||||
uint16_t offset = serializer_dump_strings( strings, 2);
|
||||
serializer_dump_nums( nums, 1, offset, 2);
|
||||
const lp_string strings[] = { LP("a"),
|
||||
LP("b") };
|
||||
ecma_number_t nums [] = { 2.0 };
|
||||
serializer_dump_strings_and_nums (strings, 2, nums, 1);
|
||||
|
||||
init_int( test_program, false);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user