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:
@@ -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 */
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user