Replace array of literals with literal storage.

JerryScript-DCO-1.0-Signed-off-by: Evgeny Gavrin e.gavrin@samsung.com
JerryScript-DCO-1.0-Signed-off-by: Andrey Shitov a.shitov@samsung.com
This commit is contained in:
Andrey Shitov
2015-06-10 17:28:53 +03:00
parent 340a9ef002
commit 53801e3b41
36 changed files with 460 additions and 1097 deletions
@@ -15,9 +15,7 @@
#include "linked-list.h"
#include "jrt-libc-includes.h"
#include "jrt.h"
#include "mem-heap.h"
#include "lp-string.h"
typedef struct linked_list_header
{
@@ -15,8 +15,6 @@
#include "lit-id-hash-table.h"
#include "bytecode-data.h"
#include "mem-heap.h"
#include "jrt-libc-includes.h"
lit_id_hash_table *
lit_id_hash_table_init (size_t buckets_count, size_t blocks_count)
@@ -24,11 +22,11 @@ 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 (literal_index_t) * buckets_count);
table->raw_buckets = (literal_index_t *) mem_heap_alloc_block (size, MEM_HEAP_ALLOC_LONG_TERM);
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 (literal_index_t *) * blocks_count);
table->buckets = (literal_index_t **) mem_heap_alloc_block (size, MEM_HEAP_ALLOC_LONG_TERM);
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;
@@ -44,7 +42,7 @@ lit_id_hash_table_free (lit_id_hash_table *table)
}
void
lit_id_hash_table_insert (lit_id_hash_table *table, idx_t uid, opcode_counter_t oc, literal_index_t lit_id)
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;
@@ -52,11 +50,11 @@ lit_id_hash_table_insert (lit_id_hash_table *table, idx_t uid, opcode_counter_t
{
table->buckets[block_id] = table->raw_buckets + table->current_bucket_pos;
}
table->buckets[block_id][uid] = lit_id;
table->buckets[block_id][uid] = lit_cp;
table->current_bucket_pos++;
}
literal_index_t
lit_cpointer_t
lit_id_hash_table_lookup (lit_id_hash_table *table, idx_t uid, opcode_counter_t oc)
{
JERRY_ASSERT (table);
@@ -19,17 +19,18 @@
#include "jrt.h"
#include "ecma-globals.h"
#include "opcodes.h"
#include "lit-literal.h"
typedef struct
{
size_t current_bucket_pos;
literal_index_t *raw_buckets;
literal_index_t **buckets;
lit_cpointer_t *raw_buckets;
lit_cpointer_t **buckets;
} lit_id_hash_table;
lit_id_hash_table *lit_id_hash_table_init (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, literal_index_t);
literal_index_t lit_id_hash_table_lookup (lit_id_hash_table *, idx_t, opcode_counter_t);
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);
#endif /* LIT_ID_HASH_TABLE */
@@ -1,63 +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 "lp-string.h"
#include "jrt-libc-includes.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)
{
return lp_string_equal_zt (lp, (const ecma_char_t *) s);
}
bool
lp_string_equal_zt (lp_string lp, const ecma_char_t *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;
}
-33
View File
@@ -1,33 +0,0 @@
/* 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
{
const ecma_char_t *str;
ecma_length_t length;
ecma_string_hash_t hash;
} lp_string;
bool lp_string_equal (lp_string, lp_string);
bool lp_string_equal_s (lp_string, const char *);
bool lp_string_equal_zt (lp_string, const ecma_char_t *);
#endif /* LP_STRING */
-3
View File
@@ -17,7 +17,6 @@
#define BYTECODE_DATA_H
#include "opcodes.h"
#include "literal.h"
#include "lit-id-hash-table.h"
/*
@@ -38,10 +37,8 @@
typedef struct
{
const ecma_char_t *strings_buffer;
const literal *literals;
const opcode_t *opcodes;
lit_id_hash_table *lit_id_hash;
literal_index_t literals_count;
opcode_counter_t opcodes_count;
} bytecode_data_t;
+33 -198
View File
@@ -16,11 +16,7 @@
#include "mem-allocator.h"
#include "jrt-libc-includes.h"
#include "lexer.h"
#include "parser.h"
#include "stack.h"
#include "opcodes.h"
#include "syntax-errors.h"
#include "parser.h"
#include "ecma-helpers.h"
static token saved_token, prev_token, sent_token, empty_token;
@@ -32,18 +28,9 @@ static size_t buffer_size = 0;
static const char *buffer_start = NULL;
static const char *buffer = NULL;
static const char *token_start;
static ecma_char_t *strings_cache;
static size_t strings_cache_size;
static size_t strings_cache_used_size;
#define LA(I) (get_char (I))
enum
{
literals_global_size
};
STATIC_STACK (literals, literal)
static bool
is_empty (token tok)
{
@@ -93,7 +80,25 @@ dump_current_line (void)
}
static token
create_token (token_type type, literal_index_t uid)
create_token_from_lit (token_type type, literal_t lit)
{
token ret;
ret.type = type;
ret.loc = current_locus () - (type == TOK_STRING ? 1 : 0);
ret.uid = lit_cpointer_t::compress (lit).packed_value;
return ret;
}
/**
* Create token of specified type
*
* @return token descriptor
*/
static token
create_token (token_type type, /**< type of token */
uint16_t uid) /**< uid of token */
{
token ret;
@@ -102,92 +107,7 @@ create_token (token_type type, literal_index_t uid)
ret.uid = uid;
return ret;
}
/**
* Compare specified string to literal
*
* @return true - if the literal contains exactly the specified string,
* false - otherwise.
*/
static bool
string_equals_to_literal (const ecma_char_t *str_p, /**< characters buffer */
ecma_length_t length, /**< string's length */
literal lit) /**< literal */
{
if (lit.type == LIT_STR)
{
if (lit.data.lp.length == length
&& strncmp ((const char *) lit.data.lp.str, (const char*) str_p, length) == 0)
{
return true;
}
}
else if (lit.type == LIT_MAGIC_STR)
{
const char *magic_str_p = (const char *) ecma_get_magic_string_zt (lit.data.magic_str_id);
if (strlen (magic_str_p) == length
&& strncmp (magic_str_p, (const char*) str_p, length) == 0)
{
return true;
}
}
else if (lit.type == LIT_MAGIC_STR_EX)
{
const char *magic_str_p = (const char *) ecma_get_magic_string_ex_zt (lit.data.magic_str_ex_id);
if (strlen (magic_str_p) == length
&& strncmp (magic_str_p, (const char*) str_p, length) == 0)
{
return true;
}
}
return false;
} /* string_equals_to_literal */
static literal
adjust_string_ptrs (literal lit, size_t diff)
{
if (lit.type != LIT_STR)
{
return lit;
}
literal ret;
ret.type = LIT_STR;
ret.data.lp.length = lit.data.lp.length;
ret.data.lp.hash = lit.data.lp.hash;
ret.data.lp.str = lit.data.lp.str + diff;
return ret;
}
static literal
add_string_to_string_cache (const ecma_char_t* str, ecma_length_t length)
{
if (strings_cache_used_size + length * sizeof (ecma_char_t) >= strings_cache_size)
{
strings_cache_size = mem_heap_recommend_allocation_size (strings_cache_used_size
+ ((size_t) length + 1) * sizeof (ecma_char_t));
ecma_char_t *temp = (ecma_char_t *) mem_heap_alloc_block (strings_cache_size,
MEM_HEAP_ALLOC_SHORT_TERM);
if (strings_cache)
{
memcpy (temp, strings_cache, strings_cache_used_size);
STACK_ITERATE_VARG_SET (literals, adjust_string_ptrs, 0, (size_t) (temp - strings_cache));
mem_heap_free_block ((uint8_t *) strings_cache);
}
strings_cache = temp;
}
strncpy ((char *) (strings_cache + strings_cache_used_size), (const char*) str, length);
(strings_cache + strings_cache_used_size)[length] = '\0';
const literal res = create_literal_from_zt (strings_cache + strings_cache_used_size, length);
strings_cache_used_size = (size_t) (((size_t) length + 1) * sizeof (ecma_char_t) + strings_cache_used_size);
return res;
}
} /* create_token */
/**
* Convert string to token of specified type
@@ -201,30 +121,22 @@ convert_string_to_token (token_type tt, /**< token type */
{
JERRY_ASSERT (str_p != NULL);
for (literal_index_t i = 0; i < STACK_SIZE (literals); i++)
literal_t lit = lit_find_literal_by_charset (str_p, length);
if (lit != NULL)
{
const literal lit = STACK_ELEMENT (literals, i);
if ((lit.type == LIT_STR || lit.type == LIT_MAGIC_STR || lit.type == LIT_MAGIC_STR_EX)
&& string_equals_to_literal (str_p, length, lit))
{
return create_token (tt, i);
}
return create_token_from_lit (tt, lit);
}
literal lit = create_literal_from_str (str_p, length);
JERRY_ASSERT (lit.type == LIT_STR || lit.type == LIT_MAGIC_STR || lit.type == LIT_MAGIC_STR_EX);
if (lit.type == LIT_STR)
{
lit = add_string_to_string_cache (str_p, length);
}
lit = lit_create_literal_from_charset (str_p, length);
JERRY_ASSERT (lit->get_type () == LIT_STR_T
|| lit->get_type () == LIT_MAGIC_STR_T
|| lit->get_type () == LIT_MAGIC_STR_EX_T);
STACK_PUSH (literals, lit);
return create_token (tt, (literal_index_t) (STACK_SIZE (literals) - 1));
return create_token_from_lit (tt, lit);
}
/**
* Try to decore specified string as keyword
* Try to decode specified string as keyword
*
* @return if specified string represents a keyword, return corresponding keyword token,
* else if it is 'null' - return TOK_NULL token,
@@ -360,85 +272,13 @@ decode_keyword (const ecma_char_t *str_p, /**< characters buffer */
static token
convert_seen_num_to_token (ecma_number_t num)
{
for (literal_index_t i = 0; i < STACK_SIZE (literals); i++)
literal_t lit = lit_find_literal_by_num (num);
if (lit != NULL)
{
const literal lit = STACK_ELEMENT (literals, i);
if (lit.type != LIT_NUMBER)
{
continue;
}
if (lit.data.num == num)
{
return create_token (TOK_NUMBER, i);
}
return create_token_from_lit (TOK_NUMBER, lit);
}
STACK_PUSH (literals, create_literal_from_num (num));
return create_token (TOK_NUMBER, (literal_index_t) (STACK_SIZE (literals) - 1));
}
const literal *
lexer_get_literals (void)
{
literal *data = NULL;
if (STACK_SIZE (literals) > 0)
{
STACK_CONVERT_TO_RAW_DATA (literals, data);
}
return data;
}
literal_index_t
lexer_get_literals_count (void)
{
return (literal_index_t) STACK_SIZE (literals);
}
literal_index_t
lexer_lookup_literal_uid (literal lit)
{
for (literal_index_t i = 0; i < STACK_SIZE (literals); i++)
{
if (literal_equal_type (STACK_ELEMENT (literals, i), lit))
{
return i;
}
}
return INVALID_VALUE;
}
literal
lexer_get_literal_by_id (literal_index_t id)
{
JERRY_ASSERT (id != INVALID_LITERAL);
JERRY_ASSERT (id < STACK_SIZE (literals));
return STACK_ELEMENT (literals, id);
}
const ecma_char_t *
lexer_get_strings_cache (void)
{
return strings_cache;
}
void
lexer_add_keyword_or_numeric_literal_if_not_present (literal lit)
{
for (literal_index_t i = 0; i < STACK_SIZE (literals); i++)
{
if (literal_equal_type (STACK_ELEMENT (literals, i), lit))
{
return;
}
}
if (lit.type == LIT_STR)
{
lit = add_string_to_string_cache (lit.data.lp.str, lit.data.lp.length);
}
STACK_PUSH (literals, lit);
return create_token_from_lit (TOK_NUMBER, lit_create_literal_from_num (num));
}
static void
@@ -1644,15 +1484,10 @@ lexer_init (const char *source, size_t source_size, bool show_opcodes)
buffer_size = source_size;
lexer_set_source (source);
strings_cache = NULL;
strings_cache_used_size = strings_cache_size = 0;
lexer_set_strict_mode (false);
STACK_INIT (literals);
}
void
lexer_free (void)
{
STACK_FREE (literals);
}
+3 -10
View File
@@ -16,10 +16,10 @@
#ifndef LEXER_H
#define LEXER_H
#include "literal.h"
#include "lit-literal.h"
#define INVALID_VALUE 255
#define INVALID_LITERAL ((uint32_t) -1)
#define INVALID_LITERAL (rcs_cpointer_t::null_cp ())
/* Keywords. */
typedef enum __attr_packed___
@@ -160,7 +160,7 @@ typedef struct
{
locus loc;
token_type type;
literal_index_t uid;
uint16_t uid;
} token;
/**
@@ -175,13 +175,6 @@ token lexer_next_token (void);
void lexer_save_token (token);
token lexer_prev_token (void);
const literal *lexer_get_literals (void);
const ecma_char_t *lexer_get_strings_cache (void);
void lexer_add_keyword_or_numeric_literal_if_not_present (literal);
literal_index_t lexer_get_literals_count (void);
literal lexer_get_literal_by_id (literal_index_t);
literal_index_t lexer_lookup_literal_uid (literal lit);
void lexer_seek (locus);
void lexer_locus_to_line_and_column (locus, size_t *, size_t *);
void lexer_dump_line (size_t);
-275
View File
@@ -1,275 +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 "literal.h"
#include "ecma-helpers.h"
#include "jrt-libc-includes.h"
literal
create_empty_literal (void)
{
literal ret;
ret.type = LIT_UNKNOWN;
ret.data.none = NULL;
return ret;
}
literal
create_literal_from_num (ecma_number_t num)
{
literal ret;
ret.type = LIT_NUMBER;
ret.data.num = num;
return ret;
}
/**
* Create literal from string
*
* @return literal descriptor
*/
literal
create_literal_from_str (const ecma_char_t *s, /**< characters buffer */
ecma_length_t len) /**< string's length */
{
return create_literal_from_zt (s, len);
} /* create_literal_from_str */
literal
create_literal_from_str_compute_len (const char *s)
{
return create_literal_from_zt ((const ecma_char_t *) s, (ecma_length_t) strlen (s));
}
literal
create_literal_from_zt (const ecma_char_t *s, ecma_length_t len)
{
for (ecma_magic_string_id_t msi = (ecma_magic_string_id_t) 0;
msi < ECMA_MAGIC_STRING__COUNT;
msi = (ecma_magic_string_id_t) (msi + 1))
{
if (ecma_zt_string_length (ecma_get_magic_string_zt (msi)) != len)
{
continue;
}
if (!strncmp ((const char *) s, (const char *) ecma_get_magic_string_zt (msi), len))
{
literal ret;
ret.type = LIT_MAGIC_STR;
ret.data.magic_str_id = msi;
return ret;
}
}
uint32_t ex_count = ecma_get_magic_string_ex_count ();
for (ecma_magic_string_ex_id_t msi = (ecma_magic_string_ex_id_t) 0;
msi < ex_count;
msi = (ecma_magic_string_id_t) (msi + 1))
{
const ecma_char_t* ex_string = ecma_get_magic_string_ex_zt (msi);
if (ecma_zt_string_length (ex_string) != len)
{
continue;
}
if (!strncmp ((const char *) s, (const char *) ex_string, len))
{
literal ret;
ret.type = LIT_MAGIC_STR_EX;
ret.data.magic_str_ex_id = msi;
return ret;
}
}
literal ret;
ret.type = LIT_STR;
ret.data.lp.length = len;
ret.data.lp.str = s;
ret.data.lp.hash = ecma_chars_buffer_calc_hash_last_chars (s, len);
return ret;
}
bool
literal_equal_type (literal lit1, literal lit2)
{
if (lit1.type != lit2.type)
{
return false;
}
return literal_equal (lit1, lit2);
}
bool
literal_equal_type_s (literal lit, const char *s)
{
return literal_equal_type_zt (lit, (const ecma_char_t *) s);
}
bool
literal_equal_type_zt (literal lit, const ecma_char_t *s)
{
if (lit.type != LIT_STR && lit.type != LIT_MAGIC_STR && lit.type != LIT_MAGIC_STR_EX)
{
return false;
}
return literal_equal_zt (lit, s);
}
bool
literal_equal_type_num (literal lit, ecma_number_t num)
{
if (lit.type != LIT_NUMBER)
{
return false;
}
return literal_equal_num (lit, num);
}
static bool
literal_equal_lp (literal lit, lp_string lp)
{
switch (lit.type)
{
case LIT_UNKNOWN:
{
return false;
}
case LIT_STR:
{
return lp_string_equal (lit.data.lp, lp);
}
case LIT_MAGIC_STR:
{
return lp_string_equal_zt (lp, ecma_get_magic_string_zt (lit.data.magic_str_id));
}
case LIT_MAGIC_STR_EX:
{
return lp_string_equal_zt (lp, ecma_get_magic_string_ex_zt (lit.data.magic_str_ex_id));
}
case LIT_NUMBER:
{
ecma_char_t buff[ECMA_MAX_CHARS_IN_STRINGIFIED_NUMBER];
ecma_number_to_zt_string (lit.data.num, buff, ECMA_MAX_CHARS_IN_STRINGIFIED_NUMBER);
return lp_string_equal_zt (lp, buff);
}
default:
{
JERRY_UNREACHABLE ();
}
}
}
bool
literal_equal (literal lit1, literal lit2)
{
switch (lit2.type)
{
case LIT_UNKNOWN:
{
return lit2.type == LIT_UNKNOWN;
}
case LIT_STR:
{
return literal_equal_lp (lit1, lit2.data.lp);
}
case LIT_MAGIC_STR:
{
return literal_equal_zt (lit1, ecma_get_magic_string_zt (lit2.data.magic_str_id));
}
case LIT_MAGIC_STR_EX:
{
return literal_equal_zt (lit1, ecma_get_magic_string_ex_zt (lit2.data.magic_str_ex_id));
}
case LIT_NUMBER:
{
return literal_equal_num (lit1, lit2.data.num);
}
default:
{
JERRY_UNREACHABLE ();
}
}
}
bool
literal_equal_s (literal lit, const char *s)
{
return literal_equal_zt (lit, (const ecma_char_t *) s);
}
bool
literal_equal_zt (literal lit, const ecma_char_t *s)
{
switch (lit.type)
{
case LIT_UNKNOWN:
{
return false;
}
case LIT_STR:
{
return lp_string_equal_zt (lit.data.lp, s);
}
case LIT_MAGIC_STR:
{
return ecma_compare_zt_strings (s, ecma_get_magic_string_zt (lit.data.magic_str_id));
}
case LIT_MAGIC_STR_EX:
{
return ecma_compare_zt_strings (s, ecma_get_magic_string_ex_zt (lit.data.magic_str_ex_id));
}
case LIT_NUMBER:
{
ecma_char_t buff[ECMA_MAX_CHARS_IN_STRINGIFIED_NUMBER];
ecma_number_to_zt_string (lit.data.num, buff, ECMA_MAX_CHARS_IN_STRINGIFIED_NUMBER);
return ecma_compare_zt_strings (s, buff);
}
default:
{
JERRY_UNREACHABLE ();
}
}
}
bool
literal_equal_num (literal lit, ecma_number_t num)
{
ecma_char_t buff[ECMA_MAX_CHARS_IN_STRINGIFIED_NUMBER];
ecma_number_to_zt_string (num, buff, ECMA_MAX_CHARS_IN_STRINGIFIED_NUMBER);
return literal_equal_zt (lit, buff);
}
const ecma_char_t *
literal_to_zt (literal lit)
{
JERRY_ASSERT (lit.type == LIT_STR || lit.type == LIT_MAGIC_STR || lit.type == LIT_MAGIC_STR_EX);
switch (lit.type)
{
case LIT_STR: return lit.data.lp.str;
case LIT_MAGIC_STR: return ecma_get_magic_string_zt (lit.data.magic_str_id);
case LIT_MAGIC_STR_EX: return ecma_get_magic_string_ex_zt (lit.data.magic_str_ex_id);
default: JERRY_UNREACHABLE ();
}
}
-61
View File
@@ -1,61 +0,0 @@
/* 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 LITERAL_H
#define LITERAL_H
#include "ecma-globals.h"
#include "lp-string.h"
typedef enum __attr_packed___
{
LIT_UNKNOWN,
LIT_STR,
LIT_MAGIC_STR,
LIT_MAGIC_STR_EX,
LIT_NUMBER
} literal_type;
typedef struct
{
union
{
ecma_magic_string_id_t magic_str_id;
ecma_magic_string_ex_id_t magic_str_ex_id;
ecma_number_t num;
lp_string lp;
void *none;
} data;
literal_type type;
} literal;
#define LITERAL_TO_REWRITE (INVALID_VALUE - 1)
literal create_empty_literal (void);
literal create_literal_from_num (ecma_number_t);
literal create_literal_from_str (const ecma_char_t*, ecma_length_t);
literal create_literal_from_str_compute_len (const char *);
literal create_literal_from_zt (const ecma_char_t *, ecma_length_t);
bool literal_equal (literal, literal);
bool literal_equal_s (literal, const char *);
bool literal_equal_zt (literal, const ecma_char_t *);
bool literal_equal_num (literal, ecma_number_t);
bool literal_equal_type (literal, literal);
bool literal_equal_type_s (literal, const char *);
bool literal_equal_type_zt (literal, const ecma_char_t *);
bool literal_equal_type_num (literal, ecma_number_t);
const ecma_char_t *literal_to_zt (literal);
#endif /* LITERAL_H */
+49 -44
View File
@@ -14,14 +14,11 @@
*/
#include "opcodes-dumper.h"
#include "serializer.h"
#include "jrt.h"
#include "lexer.h"
#include "stack.h"
#include "syntax-errors.h"
#include "jrt-libc-includes.h"
#include "opcodes-native-call.h"
#include "serializer.h"
#define MIN_TEMP_NAME 128
static idx_t temp_name, max_temp_name;
@@ -136,7 +133,7 @@ next_temp_name (void)
}
static op_meta
create_op_meta (opcode_t op, literal_index_t lit_id1, literal_index_t lit_id2, literal_index_t lit_id3)
create_op_meta (opcode_t op, lit_cpointer_t lit_id1, lit_cpointer_t lit_id2, lit_cpointer_t lit_id3)
{
op_meta ret;
@@ -155,43 +152,43 @@ create_op_meta_000 (opcode_t op)
}
static op_meta
create_op_meta_001 (opcode_t op, literal_index_t lit_id)
create_op_meta_001 (opcode_t op, lit_cpointer_t lit_id)
{
return create_op_meta (op, NOT_A_LITERAL, NOT_A_LITERAL, lit_id);
}
static op_meta
create_op_meta_010 (opcode_t op, literal_index_t lit_id)
create_op_meta_010 (opcode_t op, lit_cpointer_t lit_id)
{
return create_op_meta (op, NOT_A_LITERAL, lit_id, NOT_A_LITERAL);
}
static op_meta
create_op_meta_011 (opcode_t op, literal_index_t lit_id2, literal_index_t lit_id3)
create_op_meta_011 (opcode_t op, lit_cpointer_t lit_id2, lit_cpointer_t lit_id3)
{
return create_op_meta (op, NOT_A_LITERAL, lit_id2, lit_id3);
}
static op_meta
create_op_meta_100 (opcode_t op, literal_index_t lit_id)
create_op_meta_100 (opcode_t op, lit_cpointer_t lit_id)
{
return create_op_meta (op, lit_id, NOT_A_LITERAL, NOT_A_LITERAL);
}
static op_meta
create_op_meta_101 (opcode_t op, literal_index_t lit_id1, literal_index_t lit_id3)
create_op_meta_101 (opcode_t op, lit_cpointer_t lit_id1, lit_cpointer_t lit_id3)
{
return create_op_meta (op, lit_id1, NOT_A_LITERAL, lit_id3);
}
static op_meta
create_op_meta_110 (opcode_t op, literal_index_t lit_id1, literal_index_t lit_id2)
create_op_meta_110 (opcode_t op, lit_cpointer_t lit_id1, lit_cpointer_t lit_id2)
{
return create_op_meta (op, lit_id1, lit_id2, NOT_A_LITERAL);
}
static op_meta
create_op_meta_111 (opcode_t op, literal_index_t lit_id1, literal_index_t lit_id2, literal_index_t lit_id3)
create_op_meta_111 (opcode_t op, lit_cpointer_t lit_id1, lit_cpointer_t lit_id2, lit_cpointer_t lit_id3)
{
return create_op_meta (op, lit_id1, lit_id2, lit_id3);
}
@@ -214,27 +211,27 @@ name_to_native_call_id (operand obj)
{
return OPCODE_NATIVE_CALL__COUNT;
}
if (literal_equal_type_s (lexer_get_literal_by_id (obj.data.lit_id), "LEDToggle"))
if (lit_literal_equal_type_zt (lit_get_literal_by_cp (obj.data.lit_id), (const ecma_char_t *) "LEDToggle"))
{
return OPCODE_NATIVE_CALL_LED_TOGGLE;
}
else if (literal_equal_type_s (lexer_get_literal_by_id (obj.data.lit_id), "LEDOn"))
else if (lit_literal_equal_type_zt (lit_get_literal_by_cp (obj.data.lit_id), (const ecma_char_t *) "LEDOn"))
{
return OPCODE_NATIVE_CALL_LED_ON;
}
else if (literal_equal_type_s (lexer_get_literal_by_id (obj.data.lit_id), "LEDOff"))
else if (lit_literal_equal_type_zt (lit_get_literal_by_cp (obj.data.lit_id), (const ecma_char_t *) "LEDOff"))
{
return OPCODE_NATIVE_CALL_LED_OFF;
}
else if (literal_equal_type_s (lexer_get_literal_by_id (obj.data.lit_id), "LEDOnce"))
else if (lit_literal_equal_type_zt (lit_get_literal_by_cp (obj.data.lit_id), (const ecma_char_t *) "LEDOnce"))
{
return OPCODE_NATIVE_CALL_LED_ONCE;
}
else if (literal_equal_type_s (lexer_get_literal_by_id (obj.data.lit_id), "wait"))
else if (lit_literal_equal_type_zt (lit_get_literal_by_cp (obj.data.lit_id), (const ecma_char_t *) "wait"))
{
return OPCODE_NATIVE_CALL_WAIT;
}
else if (literal_equal_type_s (lexer_get_literal_by_id (obj.data.lit_id), "print"))
else if (lit_literal_equal_type_zt (lit_get_literal_by_cp (obj.data.lit_id), (const ecma_char_t *) "print"))
{
return OPCODE_NATIVE_CALL_PRINT;
}
@@ -614,11 +611,11 @@ dump_prop_setter_op_meta (op_meta last, operand op)
}
static operand
create_operand_from_tmp_and_lit (idx_t tmp, literal_index_t lit_id)
create_operand_from_tmp_and_lit (idx_t tmp, lit_cpointer_t lit_id)
{
if (tmp != LITERAL_TO_REWRITE)
{
JERRY_ASSERT (lit_id == NOT_A_LITERAL);
JERRY_ASSERT (lit_id.packed_value == MEM_CP_NULL);
operand ret;
@@ -629,7 +626,7 @@ create_operand_from_tmp_and_lit (idx_t tmp, literal_index_t lit_id)
}
else
{
JERRY_ASSERT (lit_id != NOT_A_LITERAL);
JERRY_ASSERT (lit_id.packed_value != MEM_CP_NULL);
operand ret;
@@ -688,12 +685,12 @@ empty_operand (void)
}
operand
literal_operand (literal_index_t lit_id)
literal_operand (lit_cpointer_t lit_cp)
{
operand ret;
ret.type = OPERAND_LITERAL;
ret.data.lit_id = lit_id;
ret.data.lit_id = lit_cp;
return ret;
}
@@ -733,7 +730,7 @@ dumper_is_intrinsic (operand obj)
{
if (obj.type == OPERAND_LITERAL)
{
if (literal_equal_type_s (lexer_get_literal_by_id (obj.data.lit_id), "assert"))
if (lit_literal_equal_type_zt (lit_get_literal_by_cp (obj.data.lit_id), (const ecma_char_t *) "assert"))
{
return true;
}
@@ -746,7 +743,7 @@ dump_intrinsic (operand obj, operand arg)
{
JERRY_ASSERT (obj.type == OPERAND_LITERAL);
TODO (/* Rewrite when there will be more intrinsics. */)
JERRY_ASSERT (literal_equal_type_s (lexer_get_literal_by_id (obj.data.lit_id), "assert"));
JERRY_ASSERT (lit_literal_equal_type_zt (lit_get_literal_by_cp (obj.data.lit_id), (const ecma_char_t *) "assert"));
dump_assert (arg);
return dump_undefined_assignment_res ();
}
@@ -786,7 +783,7 @@ dump_boolean_assignment_res (bool is_true)
}
void
dump_string_assignment (operand op, literal_index_t lit_id)
dump_string_assignment (operand op, lit_cpointer_t lit_id)
{
switch (op.type)
{
@@ -806,7 +803,7 @@ dump_string_assignment (operand op, literal_index_t lit_id)
}
operand
dump_string_assignment_res (literal_index_t lit_id)
dump_string_assignment_res (lit_cpointer_t lit_id)
{
operand op = tmp_operand ();
dump_string_assignment (op, lit_id);
@@ -814,7 +811,7 @@ dump_string_assignment_res (literal_index_t lit_id)
}
void
dump_number_assignment (operand op, literal_index_t lit_id)
dump_number_assignment (operand op, lit_cpointer_t lit_id)
{
switch (op.type)
{
@@ -834,7 +831,7 @@ dump_number_assignment (operand op, literal_index_t lit_id)
}
operand
dump_number_assignment_res (literal_index_t lit_id)
dump_number_assignment_res (lit_cpointer_t lit_id)
{
operand op = tmp_operand ();
dump_number_assignment (op, lit_id);
@@ -1097,15 +1094,17 @@ void
dump_prop_name_and_value (operand name, operand value)
{
JERRY_ASSERT (name.type == OPERAND_LITERAL);
const literal lit = lexer_get_literal_by_id (name.data.lit_id);
literal_t lit = lit_get_literal_by_cp (name.data.lit_id);
operand tmp;
if (lit.type == LIT_STR || lit.type == LIT_MAGIC_STR || lit.type == LIT_MAGIC_STR_EX)
if (lit->get_type () == LIT_STR_T
|| lit->get_type () == LIT_MAGIC_STR_T
|| lit->get_type () == LIT_MAGIC_STR_EX_T)
{
tmp = dump_string_assignment_res (name.data.lit_id);
}
else
{
JERRY_ASSERT (lit.type == LIT_NUMBER);
JERRY_ASSERT (lit->get_type () == LIT_NUMBER_T);
tmp = dump_number_assignment_res (name.data.lit_id);
}
switch (value.type)
@@ -1130,15 +1129,17 @@ dump_prop_getter_decl (operand name, operand func)
{
JERRY_ASSERT (name.type == OPERAND_LITERAL);
JERRY_ASSERT (func.type == OPERAND_TMP);
const literal lit = lexer_get_literal_by_id (name.data.lit_id);
literal_t lit = lit_get_literal_by_cp (name.data.lit_id);
operand tmp;
if (lit.type == LIT_STR || lit.type == LIT_MAGIC_STR || lit.type == LIT_MAGIC_STR_EX)
if (lit->get_type () == LIT_STR_T
|| lit->get_type () == LIT_MAGIC_STR_T
|| lit->get_type () == LIT_MAGIC_STR_EX_T)
{
tmp = dump_string_assignment_res (name.data.lit_id);
}
else
{
JERRY_ASSERT (lit.type == LIT_NUMBER);
JERRY_ASSERT (lit->get_type () == LIT_NUMBER_T);
tmp = dump_number_assignment_res (name.data.lit_id);
}
const opcode_t opcode = getop_meta (OPCODE_META_TYPE_VARG_PROP_GETTER, tmp.data.uid, func.data.uid);
@@ -1150,15 +1151,17 @@ dump_prop_setter_decl (operand name, operand func)
{
JERRY_ASSERT (name.type == OPERAND_LITERAL);
JERRY_ASSERT (func.type == OPERAND_TMP);
const literal lit = lexer_get_literal_by_id (name.data.lit_id);
literal_t lit = lit_get_literal_by_cp (name.data.lit_id);
operand tmp;
if (lit.type == LIT_STR || lit.type == LIT_MAGIC_STR || lit.type == LIT_MAGIC_STR_EX)
if (lit->get_type () == LIT_STR_T
|| lit->get_type () == LIT_MAGIC_STR_T
|| lit->get_type () == LIT_MAGIC_STR_EX_T)
{
tmp = dump_string_assignment_res (name.data.lit_id);
}
else
{
JERRY_ASSERT (lit.type == LIT_NUMBER);
JERRY_ASSERT (lit->get_type () == LIT_NUMBER_T);
tmp = dump_number_assignment_res (name.data.lit_id);
}
const opcode_t opcode = getop_meta (OPCODE_META_TYPE_VARG_PROP_SETTER, tmp.data.uid, func.data.uid);
@@ -1347,8 +1350,10 @@ dump_delete (operand res, operand op, bool is_strict, locus loc)
{
case OPERAND_LITERAL:
{
const literal lit = lexer_get_literal_by_id (op.data.lit_id);
if (lit.type == LIT_MAGIC_STR || lit.type == LIT_MAGIC_STR_EX || lit.type == LIT_STR)
literal_t lit = lit_get_literal_by_cp (op.data.lit_id);
if (lit->get_type () == LIT_STR_T
|| lit->get_type () == LIT_MAGIC_STR_T
|| lit->get_type () == LIT_MAGIC_STR_EX_T)
{
syntax_check_delete (is_strict, loc);
switch (res.type)
@@ -1368,7 +1373,7 @@ dump_delete (operand res, operand op, bool is_strict, locus loc)
}
break;
}
else if (lit.type == LIT_NUMBER)
else if (lit->get_type () == LIT_NUMBER_T)
{
dump_boolean_assignment (res, true);
}
@@ -2372,7 +2377,7 @@ dump_throw (operand op)
}
bool
dumper_variable_declaration_exists (literal_index_t lit_id)
dumper_variable_declaration_exists (lit_cpointer_t lit_id)
{
for (opcode_counter_t oc = (opcode_counter_t) (serializer_get_current_opcode_counter () - 1);
oc > 0; oc--)
@@ -2382,7 +2387,7 @@ dumper_variable_declaration_exists (literal_index_t lit_id)
{
break;
}
if (var_decl_op_meta.lit_id[0] == lit_id)
if (var_decl_op_meta.lit_id[0].packed_value == lit_id.packed_value)
{
return true;
}
@@ -2391,7 +2396,7 @@ dumper_variable_declaration_exists (literal_index_t lit_id)
}
void
dump_variable_declaration (literal_index_t lit_id)
dump_variable_declaration (lit_cpointer_t lit_id)
{
const opcode_t opcode = getop_var_decl (LITERAL_TO_REWRITE);
serializer_dump_op_meta (create_op_meta_100 (opcode, lit_id));
+8 -8
View File
@@ -32,7 +32,7 @@ typedef struct
union
{
idx_t uid;
literal_index_t lit_id;
lit_cpointer_t lit_id;
} data;
} operand;
@@ -47,7 +47,7 @@ typedef enum __attr_packed___
} varg_list_type;
operand empty_operand (void);
operand literal_operand (literal_index_t);
operand literal_operand (lit_cpointer_t);
bool operand_is_empty (operand);
void dumper_init (void);
@@ -62,10 +62,10 @@ operand dump_intrinsic (operand, operand);
void dump_boolean_assignment (operand, bool);
operand dump_boolean_assignment_res (bool);
void dump_string_assignment (operand, literal_index_t);
operand dump_string_assignment_res (literal_index_t);
void dump_number_assignment (operand, literal_index_t);
operand dump_number_assignment_res (literal_index_t);
void dump_string_assignment (operand, lit_cpointer_t);
operand dump_string_assignment_res (lit_cpointer_t);
void dump_number_assignment (operand, lit_cpointer_t);
operand dump_number_assignment_res (lit_cpointer_t);
void dump_smallint_assignment (operand, idx_t);
operand dump_smallint_assignment_res (idx_t);
void dump_undefined_assignment (operand);
@@ -215,8 +215,8 @@ void rewrite_finally (void);
void dump_end_try_catch_finally (void);
void dump_throw (operand);
bool dumper_variable_declaration_exists (literal_index_t);
void dump_variable_declaration (literal_index_t);
bool dumper_variable_declaration_exists (lit_cpointer_t);
void dump_variable_declaration (lit_cpointer_t);
opcode_counter_t dump_scope_code_flags_for_rewrite (void);
void rewrite_scope_code_flags (opcode_counter_t scope_code_flags_oc,
+55 -45
View File
@@ -59,12 +59,26 @@ token_is (token_type tt)
return tok.type == tt;
}
static literal_index_t
static uint16_t
token_data (void)
{
return tok.uid;
}
/**
* Get token data as `lit_cpointer_t`
*
* @return compressed pointer to token data
*/
static lit_cpointer_t
token_data_as_lit_cp (void)
{
lit_cpointer_t cp;
cp.packed_value = tok.uid;
return cp;
} /* token_data_as_lit_cp */
static void
skip_token (void)
{
@@ -158,21 +172,18 @@ parse_property_name (void)
case TOK_STRING:
case TOK_NUMBER:
{
return literal_operand (token_data ());
return literal_operand (token_data_as_lit_cp ());
}
case TOK_SMALL_INT:
{
const literal lit = create_literal_from_num ((ecma_number_t) token_data ());
lexer_add_keyword_or_numeric_literal_if_not_present (lit);
const literal_index_t lit_id = lexer_lookup_literal_uid (lit);
return literal_operand (lit_id);
literal_t lit = lit_find_or_create_literal_from_num ((ecma_number_t) token_data ());
return literal_operand (lit_cpointer_t::compress (lit));
}
case TOK_KEYWORD:
{
const literal lit = create_literal_from_str_compute_len (lexer_keyword_to_string ((keyword) token_data ()));
lexer_add_keyword_or_numeric_literal_if_not_present (lit);
const literal_index_t lit_id = lexer_lookup_literal_uid (lit);
return literal_operand (lit_id);
const char *s = lexer_keyword_to_string ((keyword) token_data ());
literal_t lit = lit_find_or_create_literal_from_charset ((const ecma_char_t *) s, (ecma_length_t) strlen (s));
return literal_operand (lit_cpointer_t::compress (lit));
}
default:
{
@@ -207,11 +218,11 @@ parse_property_assignment (void)
{
bool is_setter;
if (literal_equal_type_s (lexer_get_literal_by_id (token_data ()), "get"))
if (lit_literal_equal_type_zt (lit_get_literal_by_cp (token_data_as_lit_cp ()), (const ecma_char_t *) "get"))
{
is_setter = false;
}
else if (literal_equal_type_s (lexer_get_literal_by_id (token_data ()), "set"))
else if (lit_literal_equal_type_zt (lit_get_literal_by_cp (token_data_as_lit_cp ()), (const ecma_char_t *) "set"))
{
is_setter = true;
}
@@ -344,7 +355,7 @@ parse_argument_list (varg_list_type vlt, operand obj, uint8_t *args_count, opera
case VARG_FUNC_EXPR:
{
current_token_must_be (TOK_NAME);
op = literal_operand (token_data ());
op = literal_operand (token_data_as_lit_cp ());
syntax_add_varg (op);
syntax_check_for_eval_and_arguments_in_strict_mode (op, is_strict_mode (), tok.loc);
break;
@@ -451,7 +462,7 @@ parse_function_declaration (void)
jsp_label_t *masked_label_set_p = jsp_label_mask_set ();
token_after_newlines_must_be (TOK_NAME);
const operand name = literal_operand (token_data ());
const operand name = literal_operand (token_data_as_lit_cp ());
skip_newlines ();
STACK_PUSH (scopes, scopes_tree_init (STACK_TOP (scopes)));
@@ -495,7 +506,7 @@ parse_function_expression (void)
skip_newlines ();
if (token_is (TOK_NAME))
{
const operand name = literal_operand (token_data ());
const operand name = literal_operand (token_data_as_lit_cp ());
skip_newlines ();
res = parse_argument_list (VARG_FUNC_EXPR, name, NULL, NULL);
}
@@ -556,8 +567,8 @@ parse_literal (void)
{
switch (tok.type)
{
case TOK_NUMBER: return dump_number_assignment_res (token_data ());
case TOK_STRING: return dump_string_assignment_res (token_data ());
case TOK_NUMBER: return dump_number_assignment_res (token_data_as_lit_cp ());
case TOK_STRING: return dump_string_assignment_res (token_data_as_lit_cp ());
case TOK_NULL: return dump_null_assignment_res ();
case TOK_BOOL: return dump_boolean_assignment_res ((bool) token_data ());
case TOK_SMALL_INT: return dump_smallint_assignment_res ((idx_t) token_data ());
@@ -592,7 +603,7 @@ parse_primary_expression (void)
case TOK_SMALL_INT:
case TOK_NUMBER:
case TOK_STRING: return parse_literal ();
case TOK_NAME: return literal_operand (token_data ());
case TOK_NAME: return literal_operand (token_data_as_lit_cp ());
case TOK_OPEN_SQUARE: return parse_array_literal ();
case TOK_OPEN_BRACE: return parse_object_literal ();
case TOK_OPEN_PAREN:
@@ -680,17 +691,17 @@ parse_member_expression (operand *this_arg, operand *prop_gl)
skip_newlines ();
if (token_is (TOK_NAME))
{
prop = dump_string_assignment_res (token_data ());
prop = dump_string_assignment_res (token_data_as_lit_cp ());
}
else if (token_is (TOK_KEYWORD))
{
const literal lit = create_literal_from_str_compute_len (lexer_keyword_to_string ((keyword) token_data ()));
const literal_index_t lit_id = lexer_lookup_literal_uid (lit);
if (lit_id == INVALID_LITERAL)
const char *s = lexer_keyword_to_string ((keyword) token_data ());
literal_t lit = lit_find_literal_by_charset ((const ecma_char_t *) s, (ecma_length_t) strlen (s));
if (lit == NULL)
{
EMIT_ERROR ("Expected identifier");
}
prop = dump_string_assignment_res (lit_id);
prop = dump_string_assignment_res (lit_cpointer_t::compress (lit));
}
else
{
@@ -769,7 +780,7 @@ parse_call_expression (operand *this_arg_gl, operand *prop_gl)
else if (tok.type == TOK_DOT)
{
token_after_newlines_must_be (TOK_NAME);
prop = dump_string_assignment_res (token_data ());
prop = dump_string_assignment_res (token_data_as_lit_cp ());
}
expr = dump_prop_getter_res (expr, prop);
skip_newlines ();
@@ -1557,7 +1568,7 @@ static void
parse_variable_declaration (void)
{
current_token_must_be (TOK_NAME);
const operand name = literal_operand (token_data ());
const operand name = literal_operand (token_data_as_lit_cp ());
skip_newlines ();
if (token_is (TOK_EQ))
@@ -2036,7 +2047,7 @@ parse_catch_clause (void)
token_after_newlines_must_be (TOK_OPEN_PAREN);
token_after_newlines_must_be (TOK_NAME);
const operand exception = literal_operand (token_data ());
const operand exception = literal_operand (token_data_as_lit_cp ());
syntax_check_for_eval_and_arguments_in_strict_mode (exception, is_strict_mode (), tok.loc);
token_after_newlines_must_be (TOK_CLOSE_PAREN);
@@ -2471,8 +2482,8 @@ static void process_keyword_names ()
skip_newlines ();
if (token_is (TOK_COLON))
{
lexer_add_keyword_or_numeric_literal_if_not_present (
create_literal_from_str_compute_len (lexer_keyword_to_string (kw)));
const char *s = lexer_keyword_to_string (kw);
lit_find_or_create_literal_from_charset ((const ecma_char_t *) s, (ecma_length_t) strlen (s));
}
else
{
@@ -2481,8 +2492,8 @@ static void process_keyword_names ()
}
else if (token_is (TOK_NAME))
{
if (literal_equal_type_s (lexer_get_literal_by_id (token_data ()), "get")
|| literal_equal_type_s (lexer_get_literal_by_id (token_data ()), "set"))
if (lit_literal_equal_type_zt (lit_get_literal_by_cp (token_data_as_lit_cp ()), (const ecma_char_t *) "get")
|| lit_literal_equal_type_zt (lit_get_literal_by_cp (token_data_as_lit_cp ()), (const ecma_char_t *) "set"))
{
skip_newlines ();
if (token_is (TOK_KEYWORD))
@@ -2491,8 +2502,8 @@ static void process_keyword_names ()
skip_newlines ();
if (token_is (TOK_OPEN_PAREN))
{
lexer_add_keyword_or_numeric_literal_if_not_present (
create_literal_from_str_compute_len (lexer_keyword_to_string (kw)));
const char *s = lexer_keyword_to_string (kw);
lit_find_or_create_literal_from_charset ((const ecma_char_t *) s, (ecma_length_t) strlen (s));
}
else
{
@@ -2581,9 +2592,9 @@ skip_parens (void)
}
static bool
var_declared (literal_index_t var_id)
var_declared (lit_cpointer_t var_cp)
{
return dumper_variable_declaration_exists (var_id);
return dumper_variable_declaration_exists (var_cp);
}
static void
@@ -2596,12 +2607,12 @@ preparse_var_decls (void)
{
if (token_is (TOK_NAME))
{
if (!var_declared (token_data ()))
if (!var_declared (token_data_as_lit_cp ()))
{
syntax_check_for_eval_and_arguments_in_strict_mode (literal_operand (token_data ()),
syntax_check_for_eval_and_arguments_in_strict_mode (literal_operand (token_data_as_lit_cp ()),
is_strict_mode (),
tok.loc);
dump_variable_declaration (token_data ());
dump_variable_declaration (token_data_as_lit_cp ());
}
skip_token ();
continue;
@@ -2653,7 +2664,8 @@ preparse_scope (bool is_global)
bool is_ref_eval_identifier = false;
bool is_use_strict = false;
if (token_is (TOK_STRING) && literal_equal_s (lexer_get_literal_by_id (token_data ()), "use strict"))
if (token_is (TOK_STRING) && lit_literal_equal_zt (lit_get_literal_by_cp (token_data_as_lit_cp ()),
(const ecma_char_t *) "use strict"))
{
scopes_tree_set_strict_mode (STACK_TOP (scopes), true);
is_use_strict = true;
@@ -2690,14 +2702,13 @@ preparse_scope (bool is_global)
{
if (token_is (TOK_NAME))
{
if (literal_equal_type_s (lexer_get_literal_by_id (token_data ()),
"arguments"))
if (lit_literal_equal_type_zt (lit_get_literal_by_cp (token_data_as_lit_cp ()),
(const ecma_char_t *) "arguments"))
{
is_ref_arguments_identifier = true;
}
if (literal_equal_type_s (lexer_get_literal_by_id (token_data ()),
"eval"))
else if (lit_literal_equal_type_zt (lit_get_literal_by_cp (token_data_as_lit_cp ()),
(const ecma_char_t *) "eval"))
{
is_ref_eval_identifier = true;
}
@@ -2774,10 +2785,9 @@ parser_parse_program (void)
JERRY_ASSERT (token_is (TOK_EOF));
dump_exit ();
serializer_dump_literals (lexer_get_literals (), lexer_get_literals_count ());
serializer_dump_literals ();
serializer_merge_scopes_into_bytecode ();
serializer_set_scope (NULL);
serializer_set_strings_buffer (lexer_get_strings_cache ());
scopes_tree_free (STACK_TOP (scopes));
STACK_DROP (scopes, 1);
+10 -13
View File
@@ -15,9 +15,6 @@
#include "scopes-tree.h"
#include "bytecode-data.h"
#include "mem-heap.h"
#include "jrt-libc-includes.h"
#include "lexer.h"
#define OPCODE(op) (__op__idx_##op)
#define HASH_SIZE 128
@@ -103,7 +100,7 @@ scopes_tree_count_opcodes (scopes_tree t)
static uint16_t
lit_id_hash (void * lit_id)
{
return *(literal_index_t *) lit_id % HASH_SIZE;
return ((lit_cpointer_t *) lit_id)->packed_value % HASH_SIZE;
}
static void
@@ -117,7 +114,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 (literal_index_t), sizeof (idx_t), HASH_SIZE, lit_id_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);
}
}
@@ -157,8 +154,8 @@ change_uid (op_meta *om, lit_id_hash_table *lit_ids, uint16_t mask)
{
if (get_uid (om, i) == LITERAL_TO_REWRITE)
{
JERRY_ASSERT (om->lit_id[i] != NOT_A_LITERAL);
literal_index_t lit_id = om->lit_id[i];
JERRY_ASSERT (om->lit_id[i].packed_value != MEM_CP_NULL);
lit_cpointer_t lit_id = om->lit_id[i];
idx_t *uid = (idx_t *) hash_table_lookup (lit_id_to_uid, &lit_id);
if (uid == NULL)
{
@@ -173,12 +170,12 @@ change_uid (op_meta *om, lit_id_hash_table *lit_ids, uint16_t mask)
}
else
{
JERRY_ASSERT (om->lit_id[i] == NOT_A_LITERAL);
JERRY_ASSERT (om->lit_id[i].packed_value == MEM_CP_NULL);
}
}
else
{
JERRY_ASSERT (om->lit_id[i] == NOT_A_LITERAL);
JERRY_ASSERT (om->lit_id[i].packed_value == MEM_CP_NULL);
}
}
}
@@ -192,8 +189,8 @@ insert_uids_to_lit_id_map (op_meta *om, uint16_t mask)
{
if (get_uid (om, i) == LITERAL_TO_REWRITE)
{
JERRY_ASSERT (om->lit_id[i] != NOT_A_LITERAL);
literal_index_t lit_id = om->lit_id[i];
JERRY_ASSERT (om->lit_id[i].packed_value != MEM_CP_NULL);
lit_cpointer_t lit_id = om->lit_id[i];
idx_t *uid = (idx_t *) hash_table_lookup (lit_id_to_uid, &lit_id);
if (uid == NULL)
{
@@ -206,12 +203,12 @@ insert_uids_to_lit_id_map (op_meta *om, uint16_t mask)
}
else
{
JERRY_ASSERT (om->lit_id[i] == NOT_A_LITERAL);
JERRY_ASSERT (om->lit_id[i].packed_value == MEM_CP_NULL);
}
}
else
{
JERRY_ASSERT (om->lit_id[i] == NOT_A_LITERAL);
JERRY_ASSERT (om->lit_id[i].packed_value == MEM_CP_NULL);
}
}
}
+3 -2
View File
@@ -22,12 +22,13 @@
#include "hash-table.h"
#include "opcodes.h"
#include "lit-id-hash-table.h"
#include "lit-literal.h"
#define NOT_A_LITERAL (INVALID_LITERAL - 1)
#define NOT_A_LITERAL (lit_cpointer_t::null_cp ())
typedef struct
{
literal_index_t lit_id[3];
lit_cpointer_t lit_id[3];
opcode_t op;
} op_meta;
+9 -23
View File
@@ -15,9 +15,6 @@
#include "serializer.h"
#include "bytecode-data.h"
#include "jrt.h"
#include "parser.h"
#include "jrt-libc-includes.h"
#include "pretty-printer.h"
static bytecode_data_t bytecode_data;
@@ -43,16 +40,8 @@ serializer_get_opcode (opcode_counter_t oc)
return bytecode_data.opcodes[oc];
}
literal
serializer_get_literal_by_id (literal_index_t id)
{
JERRY_ASSERT (id != INVALID_LITERAL);
JERRY_ASSERT (id < bytecode_data.literals_count);
return bytecode_data.literals[id];
}
literal_index_t
serializer_get_literal_id_by_uid (uint8_t id, opcode_counter_t oc)
lit_cpointer_t
serializer_get_literal_cp_by_uid (uint8_t id, opcode_counter_t oc)
{
if (bytecode_data.lit_id_hash == null_hash)
{
@@ -91,17 +80,14 @@ serializer_merge_scopes_into_bytecode (void)
}
void
serializer_dump_literals (const literal *literals, literal_index_t literals_count)
serializer_dump_literals (void)
{
#ifdef JERRY_ENABLE_PRETTY_PRINTER
if (print_opcodes)
{
pp_literals (literals, literals_count);
lit_dump_literals ();
}
#endif
bytecode_data.literals_count = literals_count;
bytecode_data.literals = literals;
}
void
@@ -185,9 +171,10 @@ serializer_init ()
print_opcodes = false;
bytecode_data.strings_buffer = NULL;
bytecode_data.literals = NULL;
bytecode_data.opcodes = NULL;
bytecode_data.lit_id_hash = null_hash;
lit_init ();
}
void serializer_set_show_opcodes (bool show_opcodes)
@@ -206,9 +193,8 @@ serializer_free (void)
{
lit_id_hash_table_free (bytecode_data.lit_id_hash);
}
if (bytecode_data.literals != NULL)
{
mem_heap_free_block ((uint8_t *) bytecode_data.literals);
}
mem_heap_free_block ((uint8_t *) bytecode_data.opcodes);
lit_finalize ();
}
+2 -4
View File
@@ -20,18 +20,16 @@
#include "ecma-globals.h"
#include "opcodes.h"
#include "vm.h"
#include "literal.h"
#include "scopes-tree.h"
void serializer_init ();
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);
literal serializer_get_literal_by_id (literal_index_t);
literal_index_t serializer_get_literal_id_by_uid (uint8_t, opcode_counter_t);
lit_cpointer_t serializer_get_literal_cp_by_uid (uint8_t, opcode_counter_t);
const void *serializer_get_bytecode (void);
void serializer_set_strings_buffer (const ecma_char_t *);
void serializer_dump_literals (const literal *, literal_index_t);
void serializer_dump_literals ();
void serializer_set_scope (scopes_tree);
void serializer_merge_scopes_into_bytecode (void);
void serializer_dump_op_meta (op_meta);
+23 -19
View File
@@ -23,7 +23,7 @@
typedef struct
{
prop_type type;
literal lit;
literal_t lit;
} prop_literal;
enum
@@ -39,7 +39,7 @@ enum
STATIC_STACK (U8, uint8_t)
static prop_literal
create_prop_literal (literal lit, prop_type type)
create_prop_literal (literal_t lit, prop_type type)
{
prop_literal ret;
@@ -59,7 +59,7 @@ void
syntax_add_prop_name (operand op, prop_type pt)
{
JERRY_ASSERT (op.type == OPERAND_LITERAL);
STACK_PUSH (props, create_prop_literal (lexer_get_literal_by_id (op.data.lit_id), pt));
STACK_PUSH (props, create_prop_literal (lit_get_literal_by_cp (op.data.lit_id), pt));
}
void
@@ -94,34 +94,34 @@ syntax_check_for_duplication_of_prop_names (bool is_strict, locus loc __attr_unu
JERRY_ASSERT (current.type == PROP_DATA
|| current.type == PROP_GET
|| current.type == PROP_SET);
if (literal_equal (previous.lit, current.lit))
if (lit_literal_equal (previous.lit, current.lit))
{
/*a*/
if (is_strict && previous.type == PROP_DATA && current.type == PROP_DATA)
{
PARSE_ERROR_VARG ("Duplication of parameter name '%s' in ObjectDeclaration is not allowed in strict mode",
loc, (const char *) literal_to_zt (current.lit));
loc, lit_literal_to_str_internal_buf (current.lit));
}
/*b*/
if (previous.type == PROP_DATA
&& (current.type == PROP_SET || current.type == PROP_GET))
{
PARSE_ERROR_VARG ("Parameter name '%s' in ObjectDeclaration may not be both data and accessor",
loc, (const char *) literal_to_zt (current.lit));
loc, lit_literal_to_str_internal_buf (current.lit));
}
/*c*/
if (current.type == PROP_DATA
&& (previous.type == PROP_SET || previous.type == PROP_GET))
{
PARSE_ERROR_VARG ("Parameter name '%s' in ObjectDeclaration may not be both data and accessor",
loc, (const char *) literal_to_zt (current.lit));
loc, lit_literal_to_str_internal_buf (current.lit));
}
/*d*/
if ((previous.type == PROP_SET && current.type == PROP_SET)
|| (previous.type == PROP_GET && current.type == PROP_GET))
{
PARSE_ERROR_VARG ("Parameter name '%s' in ObjectDeclaration may not be accessor of same type",
loc, (const char *) literal_to_zt (current.lit));
loc, lit_literal_to_str_internal_buf (current.lit));
}
}
}
@@ -140,7 +140,7 @@ syntax_start_checking_of_vargs (void)
void syntax_add_varg (operand op)
{
JERRY_ASSERT (op.type == OPERAND_LITERAL);
STACK_PUSH (props, create_prop_literal (lexer_get_literal_by_id (op.data.lit_id), VARG));
STACK_PUSH (props, create_prop_literal (lit_get_literal_by_cp (op.data.lit_id), VARG));
}
static void
@@ -148,10 +148,10 @@ emit_error_on_eval_and_arguments (operand op, locus loc __attr_unused___)
{
if (op.type == OPERAND_LITERAL)
{
if (literal_equal_type_zt (lexer_get_literal_by_id (op.data.lit_id),
ecma_get_magic_string_zt (ECMA_MAGIC_STRING_ARGUMENTS))
|| literal_equal_type_zt (lexer_get_literal_by_id (op.data.lit_id),
ecma_get_magic_string_zt (ECMA_MAGIC_STRING_EVAL)))
if (lit_literal_equal_type_zt (lit_get_literal_by_cp (op.data.lit_id),
ecma_get_magic_string_zt (ECMA_MAGIC_STRING_ARGUMENTS))
|| lit_literal_equal_type_zt (lit_get_literal_by_cp (op.data.lit_id),
ecma_get_magic_string_zt (ECMA_MAGIC_STRING_EVAL)))
{
PARSE_ERROR ("'eval' and 'arguments' are not allowed here in strict mode", loc);
}
@@ -179,17 +179,21 @@ syntax_check_for_syntax_errors_in_formal_param_list (bool is_strict, locus loc _
for (uint8_t i = (uint8_t) (STACK_TOP (U8) + 1); i < STACK_SIZE (props); i = (uint8_t) (i + 1))
{
JERRY_ASSERT (STACK_ELEMENT (props, i).type == VARG);
const literal previous = STACK_ELEMENT (props, i).lit;
JERRY_ASSERT (previous.type == LIT_STR || previous.type == LIT_MAGIC_STR || previous.type == LIT_MAGIC_STR_EX);
literal_t previous = STACK_ELEMENT (props, i).lit;
JERRY_ASSERT (previous->get_type () == LIT_STR_T
|| previous->get_type () == LIT_MAGIC_STR_T
|| previous->get_type () == LIT_MAGIC_STR_EX_T);
for (uint8_t j = STACK_TOP (U8); j < i; j = (uint8_t) (j + 1))
{
JERRY_ASSERT (STACK_ELEMENT (props, j).type == VARG);
const literal current = STACK_ELEMENT (props, j).lit;
JERRY_ASSERT (current.type == LIT_STR || current.type == LIT_MAGIC_STR || current.type == LIT_MAGIC_STR_EX);
if (literal_equal_type (previous, current))
literal_t current = STACK_ELEMENT (props, j).lit;
JERRY_ASSERT (current->get_type () == LIT_STR_T
|| current->get_type () == LIT_MAGIC_STR_T
|| current->get_type () == LIT_MAGIC_STR_EX_T);
if (lit_literal_equal_type (previous, current))
{
PARSE_ERROR_VARG ("Duplication of literal '%s' in FormalParameterList is not allowed in strict mode",
loc, (const char *) literal_to_zt (previous));
loc, lit_literal_to_str_internal_buf (previous));
}
}
}
-1
View File
@@ -16,7 +16,6 @@
#ifndef SYNTAX_ERRORS_H
#define SYNTAX_ERRORS_H
#include "literal.h"
#include "opcodes-dumper.h"
#include "lexer.h"