Create function variables using the data produced by the pre-scanner. (#3199)

The pre-scanner now is able to track all variable declarations and produces a compressed
stream which store this data for each function and catch block. When a function or
catch block is parsed, this information is decoded and the appropriate variables are
created. Furthermore a stack scope is created which contains the currently available
local variables and their register or literal index.

JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
Zoltan Herczeg
2019-10-17 15:20:04 +02:00
committed by GitHub
parent fd1f7eab9f
commit 7df87b7778
20 changed files with 2098 additions and 1219 deletions
+91 -62
View File
@@ -1387,7 +1387,7 @@ lexer_next_token (parser_context_t *context_p) /**< context */
#undef LEXER_TYPE_D_TOKEN
/**
* Checks whether the next token is the specified character.
* Checks whether the next token starts with the specified character.
*
* @return true - if the next is the specified character
* false - otherwise
@@ -1443,6 +1443,12 @@ lexer_process_char_literal (parser_context_t *context_p, /**< context */
parser_list_iterator_t literal_iterator;
lexer_literal_t *literal_p;
uint32_t literal_index = 0;
bool search_scope_stack = (literal_type == LEXER_IDENT_LITERAL);
if (JERRY_UNLIKELY (literal_type == LEXER_NEW_IDENT_LITERAL))
{
literal_type = LEXER_IDENT_LITERAL;
}
JERRY_ASSERT (literal_type == LEXER_IDENT_LITERAL
|| literal_type == LEXER_STRING_LITERAL);
@@ -1460,7 +1466,27 @@ lexer_process_char_literal (parser_context_t *context_p, /**< context */
{
context_p->lit_object.literal_p = literal_p;
context_p->lit_object.index = (uint16_t) literal_index;
literal_p->status_flags = (uint8_t) (literal_p->status_flags & ~LEXER_FLAG_UNUSED_IDENT);
if (search_scope_stack)
{
parser_scope_stack *scope_stack_start_p = context_p->scope_stack_p;
parser_scope_stack *scope_stack_p = scope_stack_start_p + context_p->scope_stack_top;
while (scope_stack_p > scope_stack_start_p)
{
scope_stack_p--;
if (scope_stack_p->map_from == literal_index)
{
JERRY_ASSERT (scope_stack_p->map_to >= PARSER_REGISTER_START
|| (literal_p->status_flags & LEXER_FLAG_USED));
context_p->lit_object.index = scope_stack_p->map_to;
return;
}
}
literal_p->status_flags |= LEXER_FLAG_USED;
}
return;
}
@@ -1482,10 +1508,12 @@ lexer_process_char_literal (parser_context_t *context_p, /**< context */
literal_p = (lexer_literal_t *) parser_list_append (context_p, &context_p->literal_pool);
literal_p->prop.length = (prop_length_t) length;
literal_p->type = literal_type;
literal_p->status_flags = has_escape ? 0 : LEXER_FLAG_SOURCE_PTR;
uint8_t status_flags = LEXER_FLAG_SOURCE_PTR;
if (has_escape)
{
status_flags = 0;
literal_p->u.char_p = (uint8_t *) jmem_heap_alloc_block (length);
memcpy ((uint8_t *) literal_p->u.char_p, char_p, length);
}
@@ -1494,6 +1522,13 @@ lexer_process_char_literal (parser_context_t *context_p, /**< context */
literal_p->u.char_p = char_p;
}
if (search_scope_stack)
{
status_flags |= LEXER_FLAG_USED;
}
literal_p->status_flags = status_flags;
context_p->lit_object.literal_p = literal_p;
context_p->lit_object.index = (uint16_t) literal_index;
context_p->literal_count++;
@@ -1509,7 +1544,7 @@ lexer_process_char_literal (parser_context_t *context_p, /**< context */
*/
void
lexer_construct_literal_object (parser_context_t *context_p, /**< context */
lexer_lit_location_t *literal_p, /**< literal location */
const lexer_lit_location_t *literal_p, /**< literal location */
uint8_t literal_type) /**< final literal type */
{
uint8_t *destination_start_p;
@@ -1518,7 +1553,7 @@ lexer_construct_literal_object (parser_context_t *context_p, /**< context */
JERRY_ASSERT (literal_p->type == LEXER_IDENT_LITERAL
|| literal_p->type == LEXER_STRING_LITERAL);
JERRY_ASSERT (context_p->allocated_buffer_p == NULL);
JERRY_ASSERT (context_p->u.allocated_buffer_p == NULL);
destination_start_p = local_byte_array;
source_p = literal_p->char_p;
@@ -1530,7 +1565,7 @@ lexer_construct_literal_object (parser_context_t *context_p, /**< context */
if (literal_p->length > LEXER_MAX_LITERAL_LOCAL_BUFFER_SIZE)
{
destination_start_p = (uint8_t *) parser_malloc_local (context_p, literal_p->length);
context_p->allocated_buffer_p = destination_start_p;
context_p->u.allocated_buffer_p = destination_start_p;
context_p->allocated_buffer_size = literal_p->length;
}
@@ -1764,16 +1799,8 @@ lexer_construct_literal_object (parser_context_t *context_p, /**< context */
literal_type,
literal_p->has_escape);
JERRY_ASSERT (literal_type == context_p->lit_object.literal_p->type);
context_p->lit_object.type = LEXER_LITERAL_OBJECT_ANY;
if (literal_type == LEXER_IDENT_LITERAL
&& (context_p->status_flags & PARSER_INSIDE_WITH))
{
context_p->lit_object.literal_p->status_flags |= LEXER_FLAG_NO_REG_STORE;
}
if (literal_p->length == 4
&& source_p[0] == LIT_CHAR_LOWERCASE_E
&& source_p[3] == LIT_CHAR_LOWERCASE_L
@@ -1789,24 +1816,18 @@ lexer_construct_literal_object (parser_context_t *context_p, /**< context */
&& memcmp (source_p + 1, "rgument", 7) == 0)
{
context_p->lit_object.type = LEXER_LITERAL_OBJECT_ARGUMENTS;
if (!(context_p->status_flags & PARSER_ARGUMENTS_NOT_NEEDED)
&& literal_type == LEXER_IDENT_LITERAL)
{
context_p->status_flags |= PARSER_ARGUMENTS_NEEDED | PARSER_LEXICAL_ENV_NEEDED;
context_p->lit_object.literal_p->status_flags |= LEXER_FLAG_NO_REG_STORE;
}
}
if (destination_start_p != local_byte_array)
{
JERRY_ASSERT (context_p->allocated_buffer_p == destination_start_p);
JERRY_ASSERT (context_p->u.allocated_buffer_p == destination_start_p);
context_p->allocated_buffer_p = NULL;
context_p->u.allocated_buffer_p = NULL;
parser_free_local (destination_start_p,
context_p->allocated_buffer_size);
}
JERRY_ASSERT (context_p->allocated_buffer_p == NULL);
JERRY_ASSERT (context_p->u.allocated_buffer_p == NULL);
} /* lexer_construct_literal_object */
#undef LEXER_MAX_LITERAL_LOCAL_BUFFER_SIZE
@@ -2251,7 +2272,8 @@ lexer_expect_identifier (parser_context_t *context_p, /**< context */
uint8_t literal_type) /**< literal type */
{
JERRY_ASSERT (literal_type == LEXER_STRING_LITERAL
|| literal_type == LEXER_IDENT_LITERAL);
|| literal_type == LEXER_IDENT_LITERAL
|| literal_type == LEXER_NEW_IDENT_LITERAL);
lexer_skip_spaces (context_p);
context_p->token.line = context_p->line;
@@ -2264,11 +2286,13 @@ lexer_expect_identifier (parser_context_t *context_p, /**< context */
if (context_p->token.type == LEXER_LITERAL)
{
JERRY_ASSERT (context_p->token.lit_location.type == LEXER_IDENT_LITERAL);
lexer_construct_literal_object (context_p,
&context_p->token.lit_location,
literal_type);
if (literal_type == LEXER_IDENT_LITERAL
if (literal_type != LEXER_STRING_LITERAL
&& (context_p->status_flags & PARSER_IS_STRICT)
&& context_p->lit_object.type != LEXER_LITERAL_OBJECT_ANY)
{
@@ -2286,8 +2310,6 @@ lexer_expect_identifier (parser_context_t *context_p, /**< context */
parser_raise_error (context_p, error);
}
context_p->token.lit_location.type = literal_type;
return;
}
}
@@ -2300,9 +2322,7 @@ lexer_expect_identifier (parser_context_t *context_p, /**< context */
context_p->token.literal_is_reserved = false;
context_p->token.lit_location.type = LEXER_IDENT_LITERAL;
context_p->token.lit_location.has_escape = false;
lexer_construct_literal_object (context_p,
(lexer_lit_location_t *) &lexer_default_literal,
lexer_default_literal.type);
lexer_construct_literal_object (context_p, &lexer_default_literal, lexer_default_literal.type);
context_p->status_flags &= (uint32_t) ~(PARSER_MODULE_DEFAULT_CLASS_OR_FUNC);
return;
}
@@ -2519,43 +2539,23 @@ lexer_scan_identifier (parser_context_t *context_p, /**< context */
} /* lexer_scan_identifier */
/**
* Compares the current identifier in the context to the parameter identifier
* Compares two identifiers.
*
* Note:
* Escape sequences are allowed.
* Escape sequences are allowed, size must be the same.
*
* @return true if the input identifiers are the same
* @return true if the two identifiers are the same
*/
bool
lexer_compare_identifier_to_current (parser_context_t *context_p, /**< context */
const lexer_lit_location_t *right_ident_p) /**< identifier */
lexer_compare_identifiers (const uint8_t *left_p, /**< left identifier */
const uint8_t *right_p, /**< right identifier */
size_t size) /**< byte size of the two identifiers */
{
lexer_lit_location_t *left_ident_p = &context_p->token.lit_location;
const uint8_t *left_p;
const uint8_t *right_p;
size_t count;
JERRY_ASSERT (left_ident_p->length > 0 && right_ident_p->length > 0);
if (left_ident_p->length != right_ident_p->length)
{
return 0;
}
if (!left_ident_p->has_escape && !right_ident_p->has_escape)
{
return memcmp (left_ident_p->char_p, right_ident_p->char_p, left_ident_p->length) == 0;
}
left_p = left_ident_p->char_p;
right_p = right_ident_p->char_p;
count = left_ident_p->length;
uint8_t utf8_buf[3];
size_t utf8_len, offset;
do
{
uint8_t utf8_buf[3];
size_t utf8_len, offset;
/* Backslash cannot be part of a multibyte UTF-8 character. */
if (*left_p != LIT_CHAR_BACKSLASH && *right_p != LIT_CHAR_BACKSLASH)
{
@@ -2563,7 +2563,7 @@ lexer_compare_identifier_to_current (parser_context_t *context_p, /**< context *
{
return false;
}
count--;
size--;
continue;
}
@@ -2578,7 +2578,7 @@ lexer_compare_identifier_to_current (parser_context_t *context_p, /**< context *
left_p += 6;
right_p += 6;
count += lit_char_get_utf8_length (left_chr);
size -= lit_char_get_utf8_length (left_chr);
continue;
}
@@ -2593,7 +2593,7 @@ lexer_compare_identifier_to_current (parser_context_t *context_p, /**< context *
utf8_len = lit_char_to_utf8_bytes (utf8_buf, lexer_unchecked_hex_to_character (left_p + 2, 4));
JERRY_ASSERT (utf8_len > 0);
count -= utf8_len;
size -= utf8_len;
offset = 0;
do
@@ -2608,9 +2608,38 @@ lexer_compare_identifier_to_current (parser_context_t *context_p, /**< context *
left_p += 6;
}
while (count > 0);
while (size > 0);
return true;
} /* lexer_compare_identifiers */
/**
* Compares the current identifier in the context to the parameter identifier
*
* Note:
* Escape sequences are allowed.
*
* @return true if the input identifiers are the same
*/
bool
lexer_compare_identifier_to_current (parser_context_t *context_p, /**< context */
const lexer_lit_location_t *right_ident_p) /**< identifier */
{
lexer_lit_location_t *left_ident_p = &context_p->token.lit_location;
JERRY_ASSERT (left_ident_p->length > 0 && right_ident_p->length > 0);
if (left_ident_p->length != right_ident_p->length)
{
return 0;
}
if (!left_ident_p->has_escape && !right_ident_p->has_escape)
{
return memcmp (left_ident_p->char_p, right_ident_p->char_p, left_ident_p->length) == 0;
}
return lexer_compare_identifiers (left_ident_p->char_p, right_ident_p->char_p, left_ident_p->length);
} /* lexer_compare_identifier_to_current */
/**