Add literals - replacements of strings and numbers in parser.

This commit is contained in:
Ilmir Usmanov
2014-10-31 21:22:52 +04:00
parent 05cf2dbe04
commit 8c7dc08d93
26 changed files with 822 additions and 568 deletions
+3 -1
View File
@@ -116,7 +116,9 @@ opfunc_assignment (opcode_t opdata, /**< operation data */
case OPCODE_ARG_TYPE_NUMBER: case OPCODE_ARG_TYPE_NUMBER:
{ {
ecma_number_t *num_p = ecma_alloc_number (); ecma_number_t *num_p = ecma_alloc_number ();
*num_p = deserialize_num_by_id (src_val_descr); const literal lit = deserialize_literal_by_id (src_val_descr);
JERRY_ASSERT (lit.type == LIT_NUMBER);
*num_p = lit.data.num;
get_value_completion = ecma_make_normal_completion_value (ecma_make_number_value (num_p)); get_value_completion = ecma_make_normal_completion_value (ecma_make_number_value (num_p));
break; break;
+24 -11
View File
@@ -218,15 +218,18 @@ ecma_new_ecma_string_from_number (ecma_number_t num) /**< ecma-number */
ecma_string_t* ecma_string_t*
ecma_new_ecma_string_from_lit_index (literal_index_t lit_index) /**< ecma-number */ ecma_new_ecma_string_from_lit_index (literal_index_t lit_index) /**< ecma-number */
{ {
const literal lit = deserialize_literal_by_id ((idx_t) lit_index);
if (lit.type == LIT_MAGIC_STR)
{
return ecma_get_magic_string (lit.data.magic_str_id);
}
JERRY_ASSERT (lit.type == LIT_STR);
ecma_string_t* string_desc_p = ecma_alloc_string (); ecma_string_t* string_desc_p = ecma_alloc_string ();
string_desc_p->refs = 1; string_desc_p->refs = 1;
FIXME (/* Interface for getting literal's length without string's characters iteration */); string_desc_p->length = lit.data.lp.length;
const ecma_char_t *str_p = deserialize_string_by_id ((idx_t) lit_index);
JERRY_ASSERT (str_p != NULL);
ecma_length_t length = (ecma_length_t) __strlen ((const char*)str_p);
string_desc_p->length = length;
string_desc_p->container = ECMA_STRING_CONTAINER_LIT_TABLE; string_desc_p->container = ECMA_STRING_CONTAINER_LIT_TABLE;
string_desc_p->u.lit_index = lit_index; string_desc_p->u.lit_index = lit_index;
@@ -611,7 +614,9 @@ ecma_string_to_zt_string (const ecma_string_t *string_desc_p, /**< ecma-string d
} }
case ECMA_STRING_CONTAINER_LIT_TABLE: case ECMA_STRING_CONTAINER_LIT_TABLE:
{ {
const ecma_char_t *str_p = deserialize_string_by_id ((idx_t) string_desc_p->u.lit_index); const literal lit = deserialize_literal_by_id ((idx_t) string_desc_p->u.lit_index);
JERRY_ASSERT (lit.type == LIT_STR || lit.type == LIT_MAGIC_STR);
const ecma_char_t *str_p = literal_to_zt (lit);
JERRY_ASSERT (str_p != NULL); JERRY_ASSERT (str_p != NULL);
ecma_copy_zt_string_to_buffer (str_p, buffer_p, required_buffer_size); ecma_copy_zt_string_to_buffer (str_p, buffer_p, required_buffer_size);
@@ -799,7 +804,9 @@ ecma_compare_ecma_strings_longpath (const ecma_string_t *string1_p, /* ecma-stri
if (string1_p->container == ECMA_STRING_CONTAINER_LIT_TABLE) if (string1_p->container == ECMA_STRING_CONTAINER_LIT_TABLE)
{ {
FIXME (uint8_t -> literal_index_t); FIXME (uint8_t -> literal_index_t);
zt_string1_p = deserialize_string_by_id ((uint8_t) string1_p->u.lit_index); const literal lit = deserialize_literal_by_id ((uint8_t) string1_p->u.lit_index);
JERRY_ASSERT (lit.type == LIT_STR || lit.type == LIT_MAGIC_STR);
zt_string1_p = literal_to_zt (lit);
} }
else else
{ {
@@ -845,7 +852,9 @@ ecma_compare_ecma_strings_longpath (const ecma_string_t *string1_p, /* ecma-stri
if (string2_p->container == ECMA_STRING_CONTAINER_LIT_TABLE) if (string2_p->container == ECMA_STRING_CONTAINER_LIT_TABLE)
{ {
FIXME (uint8_t -> literal_index_t); FIXME (uint8_t -> literal_index_t);
zt_string2_p = deserialize_string_by_id ((uint8_t) string2_p->u.lit_index); const literal lit = deserialize_literal_by_id ((uint8_t) string2_p->u.lit_index);
JERRY_ASSERT (lit.type == LIT_STR || lit.type == LIT_MAGIC_STR);
zt_string2_p = literal_to_zt (lit);
} }
else else
{ {
@@ -1000,7 +1009,9 @@ ecma_compare_ecma_strings_relational (const ecma_string_t *string1_p, /**< ecma-
if (string1_p->container == ECMA_STRING_CONTAINER_LIT_TABLE) if (string1_p->container == ECMA_STRING_CONTAINER_LIT_TABLE)
{ {
FIXME (uint8_t -> literal_index_t); FIXME (uint8_t -> literal_index_t);
zt_string1_p = deserialize_string_by_id ((uint8_t) string1_p->u.lit_index); const literal lit = deserialize_literal_by_id ((uint8_t) string1_p->u.lit_index);
JERRY_ASSERT (lit.type == LIT_STR || lit.type == LIT_MAGIC_STR);
zt_string1_p = literal_to_zt (lit);
} }
else else
{ {
@@ -1034,7 +1045,9 @@ ecma_compare_ecma_strings_relational (const ecma_string_t *string1_p, /**< ecma-
if (string2_p->container == ECMA_STRING_CONTAINER_LIT_TABLE) if (string2_p->container == ECMA_STRING_CONTAINER_LIT_TABLE)
{ {
FIXME (uint8_t -> literal_index_t); FIXME (uint8_t -> literal_index_t);
zt_string2_p = deserialize_string_by_id ((uint8_t) string2_p->u.lit_index); const literal lit = deserialize_literal_by_id ((uint8_t) string2_p->u.lit_index);
JERRY_ASSERT (lit.type == LIT_STR || lit.type == LIT_MAGIC_STR);
zt_string2_p = literal_to_zt (lit);
} }
else else
{ {
+232
View File
@@ -0,0 +1,232 @@
/* 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 "literal.h"
#include "ecma-helpers.h"
#include "jerry-libc.h"
literal
create_empty_literal (void)
{
return (literal)
{
.type = LIT_UNKNOWN,
.data.none = NULL
};
}
literal
create_literal_from_num (ecma_number_t num)
{
return (literal)
{
.type = LIT_NUMBER,
.data.num = num
};
}
literal
create_literal_from_str (const char *s, ecma_length_t len)
{
return create_literal_from_zt ((const ecma_char_t *) s, len);
}
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 = 0; msi < ECMA_MAGIC_STRING__COUNT; msi++)
{
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))
{
return (literal)
{
.type = LIT_MAGIC_STR,
.data.magic_str_id = msi
};
}
}
return (literal)
{
.type = LIT_STR,
.data.lp = (lp_string)
{
.length = len,
.str = s
}
};
}
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)
{
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_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_NUMBER:
{
ecma_char_t buff[ECMA_MAX_CHARS_IN_STRINGIFIED_NUMBER];
ecma_number_to_zt_string (lit2.data.num, buff, ECMA_MAX_CHARS_IN_STRINGIFIED_NUMBER);
return literal_equal_zt (lit1, buff);
}
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_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);
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);
default: JERRY_UNREACHABLE ();
}
}
+60
View File
@@ -0,0 +1,60 @@
/* 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 LITERAL_H
#define LITERAL_H
#include "ecma-globals.h"
#include "lp-string.h"
typedef enum
{
LIT_UNKNOWN,
LIT_STR,
LIT_MAGIC_STR,
LIT_NUMBER
}
literal_type;
typedef struct
{
union
{
ecma_magic_string_id_t magic_str_id;
ecma_number_t num;
lp_string lp;
void *none;
}
data;
literal_type type;
}
literal;
literal create_empty_literal (void);
literal create_literal_from_num (ecma_number_t);
literal create_literal_from_str (const char *, 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 */
+151 -147
View File
@@ -46,21 +46,9 @@ static size_t strings_cache_used_size;
enum enum
{ {
strings_global_size literals_global_size
}; };
STATIC_STACK (strings, uint8_t, lp_string) STATIC_STACK (literals, uint8_t, literal)
enum
{
numbers_global_size
};
STATIC_STACK (numbers, uint8_t, ecma_number_t)
enum
{
num_ids_global_size
};
STATIC_STACK (num_ids, uint8_t, idx_t)
static bool static bool
is_empty (token tok) is_empty (token tok)
@@ -116,7 +104,7 @@ create_token (token_type type, uint8_t uid)
return (token) return (token)
{ {
.type = type, .type = type,
.loc = current_locus (), .loc = current_locus () - (type == TOK_STRING ? 1 : 0),
.uid = uid .uid = uid
}; };
} }
@@ -136,49 +124,74 @@ current_token_equals_to (const char *str)
} }
static bool static bool
current_token_equals_to_lp (lp_string str) current_token_equals_to_literal (literal lit)
{ {
if (str.length != (ecma_length_t) (buffer - token_start)) if (lit.type == LIT_STR)
{ {
return false; if (lit.data.lp.length != (ecma_length_t) (buffer - token_start))
{
return false;
}
if (!__strncmp ((const char *) lit.data.lp.str, token_start, lit.data.lp.length))
{
return true;
}
} }
if (!__strncmp ((const char *) str.str, token_start, str.length)) else if (lit.type == LIT_MAGIC_STR)
{ {
return true; const char *str = (const char *) ecma_get_magic_string_zt (lit.data.magic_str_id);
if (__strlen (str) != /* Fucking [-Werror=sign-compare] */ (size_t) (buffer - token_start))
{
return false;
}
if (!__strncmp (str, token_start, __strlen (str)))
{
return true;
}
} }
return false; return false;
} }
static lp_string static literal
adjust_string_ptrs (lp_string lp, size_t diff) adjust_string_ptrs (literal lit, size_t diff)
{ {
return (lp_string) if (lit.type != LIT_STR)
{ {
.length = lp.length, return lit;
.str = lp.str + diff }
return (literal)
{
.type = LIT_STR,
.data.lp = (lp_string)
{
.length = lit.data.lp.length,
.str = lit.data.lp.str + diff
}
}; };
} }
static lp_string static literal
add_current_token_to_string_cache (void) add_current_token_to_string_cache (void)
{ {
lp_string res; const ecma_length_t length = (ecma_length_t) (buffer - token_start);
res.length = (ecma_length_t) (buffer - token_start); if (strings_cache_used_size + length * sizeof (ecma_char_t) >= strings_cache_size)
if (strings_cache_used_size + res.length * sizeof (ecma_char_t) >= strings_cache_size)
{ {
strings_cache_size = mem_heap_recommend_allocation_size (strings_cache_used_size strings_cache_size = mem_heap_recommend_allocation_size (strings_cache_used_size
+ ((size_t) res.length + 1) * sizeof (ecma_char_t)); + ((size_t) length + 1) * sizeof (ecma_char_t));
ecma_char_t *temp = (ecma_char_t *) mem_heap_alloc_block (strings_cache_size, ecma_char_t *temp = (ecma_char_t *) mem_heap_alloc_block (strings_cache_size,
MEM_HEAP_ALLOC_SHORT_TERM); MEM_HEAP_ALLOC_SHORT_TERM);
__memcpy (temp, strings_cache, strings_cache_used_size); __memcpy (temp, strings_cache, strings_cache_used_size);
mem_heap_free_block ((uint8_t *) strings_cache); STACK_ITERATE_VARG_SET (literals, adjust_string_ptrs, 0, (size_t) (temp - strings_cache));
STACK_ITERATE_VARG_SET (strings, adjust_string_ptrs, 0, (size_t) (temp - strings_cache)); if (strings_cache)
{
mem_heap_free_block ((uint8_t *) strings_cache);
}
strings_cache = temp; strings_cache = temp;
} }
__strncpy ((char *) (strings_cache + strings_cache_used_size), token_start, res.length); __strncpy ((char *) (strings_cache + strings_cache_used_size), token_start, length);
res.str = strings_cache + strings_cache_used_size; (strings_cache + strings_cache_used_size)[length] = '\0';
(strings_cache + strings_cache_used_size)[res.length] = '\0'; const literal res = create_literal_from_zt (strings_cache + strings_cache_used_size, length);
strings_cache_used_size = (size_t) (((size_t) res.length + 1) * sizeof (ecma_char_t) + strings_cache_used_size); strings_cache_used_size = (size_t) (((size_t) length + 1) * sizeof (ecma_char_t) + strings_cache_used_size);
return res; return res;
} }
@@ -187,9 +200,11 @@ convert_current_token_to_token (token_type tt)
{ {
JERRY_ASSERT (token_start); JERRY_ASSERT (token_start);
for (uint8_t i = 0; i < STACK_SIZE (strings); i++) for (uint8_t i = 0; i < STACK_SIZE (literals); i++)
{ {
if (current_token_equals_to_lp (STACK_ELEMENT (strings, i))) const literal lit = STACK_ELEMENT (literals, i);
if ((lit.type == LIT_STR || lit.type == LIT_MAGIC_STR)
&& current_token_equals_to_literal (lit))
{ {
if (tt == TOK_STRING) if (tt == TOK_STRING)
{ {
@@ -208,11 +223,16 @@ convert_current_token_to_token (token_type tt)
} }
} }
const lp_string str = add_current_token_to_string_cache (); literal lit = create_literal_from_str (token_start, (ecma_length_t) (buffer - token_start));
JERRY_ASSERT (lit.type == LIT_STR || lit.type == LIT_MAGIC_STR);
if (lit.type == LIT_STR)
{
lit = add_current_token_to_string_cache ();
}
STACK_PUSH (strings, str); STACK_PUSH (literals, lit);
return create_token (tt, (idx_t) (STACK_SIZE (strings) - 1)); return create_token (tt, (idx_t) (STACK_SIZE (literals) - 1));
} }
/* If TOKEN represents a keyword, return decoded keyword, /* If TOKEN represents a keyword, return decoded keyword,
@@ -235,11 +255,11 @@ decode_keyword (void)
} }
if (current_token_equals_to ("class")) if (current_token_equals_to ("class"))
{ {
PARSE_SORRY ("'class' is reseved keyword and not supported yet", current_locus ()); return create_token (TOK_KEYWORD, KW_CLASS);
} }
if (current_token_equals_to ("const")) if (current_token_equals_to ("const"))
{ {
PARSE_SORRY ("'const' is reseved keyword and not supported yet", current_locus ()); return create_token (TOK_KEYWORD, KW_CONST);
} }
if (current_token_equals_to ("continue")) if (current_token_equals_to ("continue"))
{ {
@@ -267,15 +287,15 @@ decode_keyword (void)
} }
if (current_token_equals_to ("enum")) if (current_token_equals_to ("enum"))
{ {
PARSE_SORRY ("'enum' is reseved keyword and not supported yet", current_locus ()); return create_token (TOK_KEYWORD, KW_ENUM);
} }
if (current_token_equals_to ("export")) if (current_token_equals_to ("export"))
{ {
PARSE_SORRY ("'export' is reseved keyword and not supported yet", current_locus ()); return create_token (TOK_KEYWORD, KW_EXPORT);
} }
if (current_token_equals_to ("extends")) if (current_token_equals_to ("extends"))
{ {
PARSE_SORRY ("'extends' is reseved keyword and not supported yet", current_locus ()); return create_token (TOK_KEYWORD, KW_EXTENDS);
} }
if (current_token_equals_to ("false")) if (current_token_equals_to ("false"))
{ {
@@ -297,6 +317,10 @@ decode_keyword (void)
{ {
return create_token (TOK_KEYWORD, KW_IF); return create_token (TOK_KEYWORD, KW_IF);
} }
if (current_token_equals_to ("in"))
{
return create_token (TOK_KEYWORD, KW_IN);
}
if (current_token_equals_to ("instanceof")) if (current_token_equals_to ("instanceof"))
{ {
return create_token (TOK_KEYWORD, KW_INSTANCEOF); return create_token (TOK_KEYWORD, KW_INSTANCEOF);
@@ -305,26 +329,22 @@ decode_keyword (void)
{ {
if (parser_strict_mode ()) if (parser_strict_mode ())
{ {
PARSE_ERROR ("'interface' is reseved keyword and not allowed in strict mode", current_locus ()); return create_token (TOK_KEYWORD, KW_INTERFACE);
} }
else else
{ {
return convert_current_token_to_token (TOK_NAME); return convert_current_token_to_token (TOK_NAME);
} }
} }
if (current_token_equals_to ("in"))
{
return create_token (TOK_KEYWORD, KW_IN);
}
if (current_token_equals_to ("import")) if (current_token_equals_to ("import"))
{ {
PARSE_SORRY ("'import' is reseved keyword and not supported yet", current_locus ()); return create_token (TOK_KEYWORD, KW_IMPORT);
} }
if (current_token_equals_to ("implements")) if (current_token_equals_to ("implements"))
{ {
if (parser_strict_mode ()) if (parser_strict_mode ())
{ {
PARSE_ERROR ("'implements' is reseved keyword and not allowed in strict mode", current_locus ()); return create_token (TOK_KEYWORD, KW_IMPLEMENTS);
} }
else else
{ {
@@ -335,7 +355,7 @@ decode_keyword (void)
{ {
if (parser_strict_mode ()) if (parser_strict_mode ())
{ {
PARSE_ERROR ("'let' is reseved keyword and not allowed in strict mode", current_locus ()); return create_token (TOK_KEYWORD, KW_LET);
} }
else else
{ {
@@ -354,7 +374,7 @@ decode_keyword (void)
{ {
if (parser_strict_mode ()) if (parser_strict_mode ())
{ {
PARSE_ERROR ("'package' is reseved keyword and not allowed in strict mode", current_locus ()); return create_token (TOK_KEYWORD, KW_PACKAGE);
} }
else else
{ {
@@ -365,7 +385,7 @@ decode_keyword (void)
{ {
if (parser_strict_mode ()) if (parser_strict_mode ())
{ {
PARSE_ERROR ("'private' is reseved keyword and not allowed in strict mode", current_locus ()); return create_token (TOK_KEYWORD, KW_PRIVATE);
} }
else else
{ {
@@ -376,7 +396,7 @@ decode_keyword (void)
{ {
if (parser_strict_mode ()) if (parser_strict_mode ())
{ {
PARSE_ERROR ("'protected' is reseved keyword and not allowed in strict mode", current_locus ()); return create_token (TOK_KEYWORD, KW_PROTECTED);
} }
else else
{ {
@@ -387,7 +407,7 @@ decode_keyword (void)
{ {
if (parser_strict_mode ()) if (parser_strict_mode ())
{ {
PARSE_ERROR ("'public' is reseved keyword and not allowed in strict mode", current_locus ()); return create_token (TOK_KEYWORD, KW_PUBLIC);
} }
else else
{ {
@@ -402,7 +422,7 @@ decode_keyword (void)
{ {
if (parser_strict_mode ()) if (parser_strict_mode ())
{ {
PARSE_ERROR ("'static' is reseved keyword and not allowed in strict mode", current_locus ()); return create_token (TOK_KEYWORD, KW_STATIC);
} }
else else
{ {
@@ -411,7 +431,7 @@ decode_keyword (void)
} }
if (current_token_equals_to ("super")) if (current_token_equals_to ("super"))
{ {
PARSE_SORRY ("'super' is reseved keyword and not supported yet", current_locus ()); return create_token (TOK_KEYWORD, KW_SUPER);
} }
if (current_token_equals_to ("switch")) if (current_token_equals_to ("switch"))
{ {
@@ -457,7 +477,7 @@ decode_keyword (void)
{ {
if (parser_strict_mode ()) if (parser_strict_mode ())
{ {
PARSE_ERROR ("'yield' is reseved keyword and not allowed in strict mode", current_locus ()); return create_token (TOK_KEYWORD, KW_YIELD);
} }
else else
{ {
@@ -470,81 +490,75 @@ decode_keyword (void)
static token static token
convert_seen_num_to_token (ecma_number_t num) convert_seen_num_to_token (ecma_number_t num)
{ {
uint8_t num_id; for (uint8_t i = 0; i < STACK_SIZE (literals); i++)
JERRY_ASSERT (STACK_SIZE (num_ids) == STACK_SIZE (numbers));
for (uint8_t i = 0; i < STACK_SIZE (numbers); i++)
{ {
if (STACK_ELEMENT (numbers, i) == num) const literal lit = STACK_ELEMENT (literals, i);
if (lit.type != LIT_NUMBER)
{ {
return create_token (TOK_NUMBER, STACK_ELEMENT (num_ids, i)); continue;
}
if (lit.data.num == num)
{
return create_token (TOK_NUMBER, i);
} }
} }
num_id = STACK_SIZE (num_ids); STACK_PUSH (literals, create_literal_from_num (num));
STACK_PUSH (num_ids, num_id);
STACK_PUSH (numbers, num);
return create_token (TOK_NUMBER, num_id); return create_token (TOK_NUMBER, (idx_t) (STACK_SIZE (literals) - 1));
} }
const lp_string * const literal *
lexer_get_strings (void) lexer_get_literals (void)
{ {
lp_string *data = NULL; literal *data = NULL;
STACK_CONVERT_TO_RAW_DATA (strings, data); STACK_CONVERT_TO_RAW_DATA (literals, data);
return data; return data;
} }
uint8_t uint8_t
lexer_get_strings_count (void) lexer_get_literals_count (void)
{ {
return STACK_SIZE (strings); return STACK_SIZE (literals);
} }
uint8_t idx_t
lexer_get_reserved_ids_count (void) lexer_lookup_literal_uid (literal lit)
{ {
return (uint8_t) (STACK_SIZE (strings) + STACK_SIZE (numbers)); for (uint8_t i = 0; i < STACK_SIZE (literals); i++)
{
if (literal_equal_type (STACK_ELEMENT (literals, i), lit))
{
return i;
}
}
return INVALID_VALUE;
} }
lp_string literal
lexer_get_string_by_id (uint8_t id) lexer_get_literal_by_id (uint8_t id)
{ {
JERRY_ASSERT (id < STACK_SIZE (strings)); JERRY_ASSERT (id < STACK_SIZE (literals));
return STACK_ELEMENT (strings, id); return STACK_ELEMENT (literals, id);
} }
const ecma_number_t * const ecma_char_t *
lexer_get_nums (void) lexer_get_strings_cache (void)
{ {
ecma_number_t *data = NULL; return strings_cache;
STACK_CONVERT_TO_RAW_DATA (numbers, data);
return data;
}
uint8_t
lexer_get_nums_count (void)
{
return STACK_SIZE (numbers);
} }
void void
lexer_adjust_num_ids (void) lexer_add_literal_if_not_present (literal lit)
{ {
JERRY_ASSERT (STACK_SIZE (numbers) == STACK_SIZE (num_ids)); for (uint8_t i = 0; i < STACK_SIZE (literals); i++)
for (uint8_t i = 0; i < STACK_SIZE (numbers); i++)
{ {
STACK_SET_ELEMENT (num_ids, i, (uint8_t) (STACK_ELEMENT (num_ids, i) + STACK_SIZE (strings))); if (literal_equal_type (STACK_ELEMENT (literals, i), lit))
{
return;
}
} }
} STACK_PUSH (literals, lit);
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 static void
@@ -989,14 +1003,6 @@ lexer_set_source (const char * source)
buffer = buffer_start; buffer = buffer_start;
} }
static void
lexer_rewind (void)
{
JERRY_ASSERT (buffer_start != NULL);
buffer = buffer_start;
}
static bool static bool
replace_comment_by_newline (void) replace_comment_by_newline (void)
{ {
@@ -1229,18 +1235,6 @@ lexer_prev_token (void)
return prev_token; return prev_token;
} }
void
lexer_run_first_pass (void)
{
token tok = lexer_next_token ();
while (tok.type != TOK_EOF)
{
tok = lexer_next_token ();
}
lexer_rewind ();
}
void void
lexer_seek (size_t locus) lexer_seek (size_t locus)
{ {
@@ -1307,34 +1301,53 @@ lexer_keyword_to_string (keyword kw)
case KW_BREAK: return "break"; case KW_BREAK: return "break";
case KW_CASE: return "case"; case KW_CASE: return "case";
case KW_CATCH: return "catch"; case KW_CATCH: return "catch";
case KW_CLASS: return "class";
case KW_CONST: return "const";
case KW_CONTINUE: return "continue"; case KW_CONTINUE: return "continue";
case KW_DEBUGGER: return "debugger"; case KW_DEBUGGER: return "debugger";
case KW_DEFAULT: return "default"; case KW_DEFAULT: return "default";
case KW_DELETE: return "delete"; case KW_DELETE: return "delete";
case KW_DO: return "do";
case KW_DO: return "do";
case KW_ELSE: return "else"; case KW_ELSE: return "else";
case KW_ENUM: return "enum";
case KW_EXPORT: return "export";
case KW_EXTENDS: return "extends";
case KW_FINALLY: return "finally"; case KW_FINALLY: return "finally";
case KW_FOR: return "for"; case KW_FOR: return "for";
case KW_FUNCTION: return "function"; case KW_FUNCTION: return "function";
case KW_IF: return "if"; case KW_IF: return "if";
case KW_IN: return "in"; case KW_IN: return "in";
case KW_INSTANCEOF: return "instanceof";
case KW_NEW: return "new";
case KW_RETURN: return "return";
case KW_SWITCH: return "switch";
case KW_INSTANCEOF: return "instanceof";
case KW_INTERFACE: return "interface";
case KW_IMPORT: return "import";
case KW_IMPLEMENTS: return "implements";
case KW_LET: return "let";
case KW_NEW: return "new";
case KW_PACKAGE: return "package";
case KW_PRIVATE: return "private";
case KW_PROTECTED: return "protected";
case KW_PUBLIC: return "public";
case KW_RETURN: return "return";
case KW_STATIC: return "static";
case KW_SUPER: return "super";
case KW_SWITCH: return "switch";
case KW_THIS: return "this"; case KW_THIS: return "this";
case KW_THROW: return "throw"; case KW_THROW: return "throw";
case KW_TRY: return "try"; case KW_TRY: return "try";
case KW_TYPEOF: return "typeof"; case KW_TYPEOF: return "typeof";
case KW_VAR: return "var"; case KW_VAR: return "var";
case KW_VOID: return "void"; case KW_VOID: return "void";
case KW_WHILE: return "while"; case KW_WHILE: return "while";
case KW_WITH: return "with"; case KW_WITH: return "with";
case KW_YIELD: return "yield";
default: JERRY_UNREACHABLE (); default: JERRY_UNREACHABLE ();
} }
} }
@@ -1423,23 +1436,14 @@ lexer_init (const char *source, size_t source_size, bool show_opcodes)
allow_dump_lines = show_opcodes; allow_dump_lines = show_opcodes;
buffer_size = source_size; buffer_size = source_size;
lexer_set_source (source); lexer_set_source (source);
strings_cache_size = mem_heap_recommend_allocation_size (sizeof (ecma_char_t)); strings_cache = NULL;
strings_cache = (ecma_char_t *) mem_heap_alloc_block (strings_cache_size, MEM_HEAP_ALLOC_SHORT_TERM); strings_cache_used_size = strings_cache_size = 0;
strings_cache_used_size = 0;
STACK_INIT (strings); STACK_INIT (literals);
STACK_INIT (numbers);
STACK_INIT (num_ids);
} }
void void
lexer_free (void) lexer_free (void)
{ {
if (STACK_SIZE (strings) == 0) STACK_FREE (literals);
{
mem_heap_free_block (strings_cache);
}
STACK_FREE (strings);
STACK_FREE (numbers);
STACK_FREE (num_ids);
} }
+30 -16
View File
@@ -18,8 +18,10 @@
#include "globals.h" #include "globals.h"
#include "ecma-globals.h" #include "ecma-globals.h"
#include "lp-string.h" #include "literal.h"
#include "opcodes.h"
#define INVALID_VALUE 255
/* Keywords. */ /* Keywords. */
typedef enum typedef enum
{ {
@@ -28,13 +30,19 @@ typedef enum
KW_BREAK, KW_BREAK,
KW_CASE, KW_CASE,
KW_CATCH, KW_CATCH,
KW_CONTINUE, KW_CLASS,
KW_CONST,
KW_CONTINUE,
KW_DEBUGGER, KW_DEBUGGER,
KW_DEFAULT, KW_DEFAULT,
KW_DELETE, KW_DELETE,
KW_DO, KW_DO,
KW_ELSE, KW_ELSE,
KW_ENUM,
KW_EXPORT,
KW_EXTENDS,
KW_FINALLY, KW_FINALLY,
KW_FOR, KW_FOR,
@@ -43,8 +51,20 @@ typedef enum
KW_IN, KW_IN,
KW_INSTANCEOF, KW_INSTANCEOF,
KW_INTERFACE,
KW_IMPORT,
KW_IMPLEMENTS,
KW_LET,
KW_NEW, KW_NEW,
KW_PACKAGE,
KW_PRIVATE,
KW_PROTECTED,
KW_PUBLIC,
KW_RETURN, KW_RETURN,
KW_STATIC,
KW_SUPER,
KW_SWITCH, KW_SWITCH,
KW_THIS, KW_THIS,
@@ -56,6 +76,7 @@ typedef enum
KW_WHILE, KW_WHILE,
KW_WITH, KW_WITH,
KW_YIELD
} }
keyword; keyword;
@@ -142,30 +163,23 @@ typedef struct
{ {
locus loc; locus loc;
token_type type; token_type type;
uint8_t uid; idx_t uid;
} }
token; token;
void lexer_init (const char *, size_t, bool); void lexer_init (const char *, size_t, bool);
void lexer_free (void); void lexer_free (void);
void lexer_run_first_pass (void);
token lexer_next_token (void); token lexer_next_token (void);
void lexer_save_token (token); void lexer_save_token (token);
token lexer_prev_token (void); token lexer_prev_token (void);
uint8_t lexer_get_reserved_ids_count (void); const literal *lexer_get_literals (void);
const ecma_char_t *lexer_get_strings_cache (void);
const lp_string *lexer_get_strings (void); void lexer_add_literal_if_not_present (literal);
uint8_t lexer_get_strings_count (void); uint8_t lexer_get_literals_count (void);
lp_string lexer_get_string_by_id (uint8_t); literal lexer_get_literal_by_id (uint8_t);
idx_t lexer_lookup_literal_uid (literal lit);
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);
void lexer_seek (locus); void lexer_seek (locus);
void lexer_locus_to_line_and_column (locus, size_t *, size_t *); void lexer_locus_to_line_and_column (locus, size_t *, size_t *);
+202 -268
View File
@@ -28,7 +28,6 @@
#include "scopes-tree.h" #include "scopes-tree.h"
#include "ecma-helpers.h" #include "ecma-helpers.h"
#define INVALID_VALUE 255
#define INTRINSICS_COUNT 1 #define INTRINSICS_COUNT 1
typedef enum typedef enum
@@ -39,17 +38,6 @@ typedef enum
} }
rewritable_opcode_type; rewritable_opcode_type;
typedef struct
{
union
{
void (*fun1) (idx_t);
}
funs;
uint8_t args_count;
}
intrinsic_dumper;
typedef enum typedef enum
{ {
PROP_DATA, PROP_DATA,
@@ -59,19 +47,12 @@ typedef enum
} }
prop_type; prop_type;
typedef struct
{
lp_string str;
bool was_num;
}
allocatable_string;
typedef struct typedef struct
{ {
prop_type type; prop_type type;
allocatable_string str; literal lit;
} }
prop_as_str_or_varg; prop_literal;
#define NESTING_ITERATIONAL 1 #define NESTING_ITERATIONAL 1
#define NESTING_SWITCH 2 #define NESTING_SWITCH 2
@@ -88,7 +69,6 @@ STATIC_STACK (U8, uint8_t, uint8_t)
enum enum
{ {
native_calls = OPCODE_NATIVE_CALL__COUNT,
this_arg, this_arg,
prop, prop,
IDX_global_size IDX_global_size
@@ -199,15 +179,15 @@ STATIC_STACK (rewritable_break, uint8_t, uint16_t)
enum enum
{ {
strings_global_size literals_global_size
}; };
STATIC_STACK (strings, uint8_t, allocatable_string) STATIC_STACK (literals, uint8_t, literal)
enum enum
{ {
props_global_size props_global_size
}; };
STATIC_STACK (props, uint8_t, prop_as_str_or_varg) STATIC_STACK (props, uint8_t, prop_literal)
#ifndef JERRY_NDEBUG #ifndef JERRY_NDEBUG
#define STACK_CHECK_USAGE_LHS() \ #define STACK_CHECK_USAGE_LHS() \
@@ -216,9 +196,6 @@ JERRY_ASSERT (IDX.current == IDX_current + 1);
#define STACK_CHECK_USAGE_LHS() ; #define STACK_CHECK_USAGE_LHS() ;
#endif #endif
static uint8_t lp_string_hash (lp_string);
STATIC_HASH_TABLE (intrinsics, lp_string, intrinsic_dumper)
#define LAST_OPCODE_IS(OP) (deserialize_opcode((opcode_counter_t)(OPCODE_COUNTER()-1)).op_idx == __op__idx_##OP) #define LAST_OPCODE_IS(OP) (deserialize_opcode((opcode_counter_t)(OPCODE_COUNTER()-1)).op_idx == __op__idx_##OP)
JERRY_STATIC_ASSERT (sizeof (idx_t) == sizeof (uint8_t)); JERRY_STATIC_ASSERT (sizeof (idx_t) == sizeof (uint8_t));
@@ -356,12 +333,6 @@ static uint8_t parse_argument_list (argument_list_type, idx_t);
static void skip_braces (void); static void skip_braces (void);
static void parse_logical_expression (bool); static void parse_logical_expression (bool);
static uint8_t
lp_string_hash (lp_string str)
{
return str.length % INTRINSICS_COUNT;
}
static idx_t static idx_t
next_temp_name (void) next_temp_name (void)
{ {
@@ -622,22 +593,6 @@ dump_assert (idx_t arg)
DUMP_OPCODE_1 (exitval, 1); DUMP_OPCODE_1 (exitval, 1);
} }
static void
fill_intrinsics (void)
{
lp_string str = (lp_string)
{
.length = 6,
.str = (ecma_char_t *) "assert"
};
intrinsic_dumper dumper = (intrinsic_dumper)
{
.args_count = 1,
.funs.fun1 = dump_assert
};
HASH_INSERT (intrinsics, str, dumper);
}
static bool static bool
is_intrinsic (idx_t obj) is_intrinsic (idx_t obj)
{ {
@@ -649,10 +604,10 @@ is_intrinsic (idx_t obj)
STACK_DECLARE_USAGE (U8) STACK_DECLARE_USAGE (U8)
STACK_PUSH (U8, lexer_get_strings_count ()); STACK_PUSH (U8, lexer_get_literals_count ());
if (obj < STACK_TOP (U8)) if (obj < STACK_TOP (U8))
{ {
if (HASH_LOOKUP (intrinsics, lexer_get_string_by_id (obj)) != NULL) if (literal_equal_type_s (lexer_get_literal_by_id (obj), "assert"))
{ {
result = true; result = true;
goto cleanup; goto cleanup;
@@ -669,131 +624,65 @@ cleanup:
static void static void
dump_intrinsic (idx_t obj, idx_t arg) dump_intrinsic (idx_t obj, idx_t arg)
{ {
if (obj < lexer_get_strings_count ()) if (obj < lexer_get_literals_count ())
{ {
intrinsic_dumper *dumper = HASH_LOOKUP (intrinsics, lexer_get_string_by_id (obj)); if (literal_equal_type_s (lexer_get_literal_by_id (obj), "assert"))
JERRY_ASSERT (dumper);
switch (dumper->args_count)
{ {
case 1: dumper->funs.fun1 (arg); return; dump_assert (arg);
default: JERRY_UNREACHABLE (); return;
} }
} }
JERRY_UNREACHABLE (); JERRY_UNREACHABLE ();
} }
static bool
is_native_call (idx_t obj)
{
if (obj >= lexer_get_strings_count ())
{
return false;
}
for (uint8_t i = 0; i < OPCODE_NATIVE_CALL__COUNT; i++)
{
if (STACK_ELEMENT (IDX, i) == obj)
{
return true;
}
}
return false;
}
static idx_t static idx_t
name_to_native_call_id (idx_t obj) name_to_native_call_id (idx_t obj)
{ {
JERRY_ASSERT (obj < lexer_get_strings_count ()); if (obj >= lexer_get_literals_count ())
for (uint8_t i = 0; i < OPCODE_NATIVE_CALL__COUNT; i++)
{ {
if (STACK_ELEMENT (IDX, i) == obj) return OPCODE_NATIVE_CALL__COUNT;
{
return i;
}
} }
if (literal_equal_type_s (lexer_get_literal_by_id (obj), "LEDToggle"))
JERRY_UNREACHABLE ();
}
static void
free_allocatable_string (prop_as_str_or_varg p)
{
if (p.str.was_num)
{ {
mem_heap_free_block ((uint8_t *) p.str.str.str); return OPCODE_NATIVE_CALL_LED_TOGGLE;
} }
} else if (literal_equal_type_s (lexer_get_literal_by_id (obj), "LEDOn"))
static allocatable_string
create_allocatable_string_from_num_uid (idx_t uid)
{
ecma_char_t *str = mem_heap_alloc_block (ECMA_MAX_CHARS_IN_STRINGIFIED_NUMBER * sizeof (ecma_char_t),
MEM_HEAP_ALLOC_SHORT_TERM);
ecma_number_to_zt_string (lexer_get_num_by_id (uid), str,
ECMA_MAX_CHARS_IN_STRINGIFIED_NUMBER * sizeof (ecma_char_t));
return (allocatable_string)
{ {
.was_num = true, return OPCODE_NATIVE_CALL_LED_ON;
.str = (lp_string)
{
.length = ecma_zt_string_length (str),
.str = str
}
};
}
static allocatable_string
create_allocatable_string_from_literal (idx_t uid)
{
return (allocatable_string)
{
.was_num = false,
.str = lexer_get_string_by_id (uid)
};
}
static allocatable_string
create_allocatable_string_from_small_int (idx_t uid)
{
const uint8_t chars_need = 4; /* Max is 255. */
uint8_t index = 0;
ecma_char_t *str = mem_heap_alloc_block (chars_need * sizeof (ecma_char_t),
MEM_HEAP_ALLOC_SHORT_TERM);
if (uid >= 100)
{
str[index++] = (ecma_char_t) (uid/100 + '0');
uid %= 100;
} }
if (uid >= 10) else if (literal_equal_type_s (lexer_get_literal_by_id (obj), "LEDOff"))
{ {
str[index++] = (ecma_char_t) (uid/10 + '0'); return OPCODE_NATIVE_CALL_LED_OFF;
} }
str[index++] = (ecma_char_t) (uid%10 + '0'); else if (literal_equal_type_s (lexer_get_literal_by_id (obj), "LEDOnce"))
str[index] = ECMA_CHAR_NULL;
return (allocatable_string)
{ {
.was_num = true, return OPCODE_NATIVE_CALL_LED_ONCE;
.str = (lp_string) }
{ else if (literal_equal_type_s (lexer_get_literal_by_id (obj), "wait"))
.length = index, {
.str = str return OPCODE_NATIVE_CALL_WAIT;
} }
}; else if (literal_equal_type_s (lexer_get_literal_by_id (obj), "print"))
{
return OPCODE_NATIVE_CALL_PRINT;
}
return OPCODE_NATIVE_CALL__COUNT;
} }
static prop_as_str_or_varg static bool
create_prop_as_str_or_varg (allocatable_string str, prop_type type) is_native_call (idx_t obj)
{ {
return (prop_as_str_or_varg) return name_to_native_call_id (obj) < OPCODE_NATIVE_CALL__COUNT;
}
static prop_literal
create_prop_literal (literal lit, prop_type type)
{
return (prop_literal)
{ {
.type = type, .type = type,
.str = str .lit = lit
}; };
} }
@@ -814,21 +703,30 @@ parse_property_name (void)
{ {
STACK_PUSH (IDX, next_temp_name ()); STACK_PUSH (IDX, next_temp_name ());
DUMP_OPCODE_3 (assignment, ID(1), OPCODE_ARG_TYPE_STRING, token_data ()); DUMP_OPCODE_3 (assignment, ID(1), OPCODE_ARG_TYPE_STRING, token_data ());
STACK_PUSH (strings, create_allocatable_string_from_literal (token_data ())); STACK_PUSH (literals, lexer_get_literal_by_id (token_data ()));
break; break;
} }
case TOK_NUMBER: case TOK_NUMBER:
{ {
STACK_PUSH (IDX, next_temp_name ()); STACK_PUSH (IDX, next_temp_name ());
DUMP_OPCODE_3 (assignment, ID(1), OPCODE_ARG_TYPE_NUMBER, token_data ()); DUMP_OPCODE_3 (assignment, ID(1), OPCODE_ARG_TYPE_NUMBER, token_data ());
STACK_PUSH (strings, create_allocatable_string_from_num_uid (token_data ())); STACK_PUSH (literals, lexer_get_literal_by_id (token_data ()));
break; break;
} }
case TOK_SMALL_INT: case TOK_SMALL_INT:
{ {
STACK_PUSH (IDX, next_temp_name ()); STACK_PUSH (IDX, next_temp_name ());
DUMP_OPCODE_3 (assignment, ID(1), OPCODE_ARG_TYPE_SMALLINT, token_data ()); DUMP_OPCODE_3 (assignment, ID(1), OPCODE_ARG_TYPE_SMALLINT, token_data ());
STACK_PUSH (strings, create_allocatable_string_from_small_int (token_data ())); STACK_PUSH (literals, create_literal_from_num ((ecma_number_t) token_data ()));
break;
}
case TOK_KEYWORD:
{
literal lit = create_literal_from_str_compute_len (lexer_keyword_to_string (token_data ()));
STACK_PUSH (IDX, next_temp_name ());
DUMP_OPCODE_3 (assignment, ID(1), OPCODE_ARG_TYPE_STRING,
lexer_lookup_literal_uid (lit));
STACK_PUSH (literals, lit);
break; break;
} }
default: default:
@@ -856,8 +754,8 @@ parse_property_name_and_value (void)
DUMP_OPCODE_3 (meta, OPCODE_META_TYPE_VARG_PROP_DATA, STACK_HEAD(IDX, 2), STACK_HEAD(IDX, 1)); DUMP_OPCODE_3 (meta, OPCODE_META_TYPE_VARG_PROP_DATA, STACK_HEAD(IDX, 2), STACK_HEAD(IDX, 1));
STACK_PUSH (props, create_prop_as_str_or_varg (STACK_TOP (strings), PROP_DATA)); STACK_PUSH (props, create_prop_literal (STACK_TOP (literals), PROP_DATA));
STACK_DROP (strings, 1); STACK_DROP (literals, 1);
STACK_DROP (IDX, 2); STACK_DROP (IDX, 2);
STACK_CHECK_USAGE (IDX); STACK_CHECK_USAGE (IDX);
@@ -912,7 +810,7 @@ parse_property_assignment (void)
STACK_DECLARE_USAGE (U16) STACK_DECLARE_USAGE (U16)
STACK_DECLARE_USAGE (toks) STACK_DECLARE_USAGE (toks)
STACK_DECLARE_USAGE (U8) STACK_DECLARE_USAGE (U8)
STACK_DECLARE_USAGE (strings) STACK_DECLARE_USAGE (literals)
if (!token_is (TOK_NAME)) if (!token_is (TOK_NAME))
{ {
@@ -920,7 +818,7 @@ parse_property_assignment (void)
goto cleanup; goto cleanup;
} }
if (lp_string_equal_s (lexer_get_string_by_id (token_data ()), "get")) if (literal_equal_type_s (lexer_get_literal_by_id (token_data ()), "get"))
{ {
STACK_PUSH (toks, TOK ()); STACK_PUSH (toks, TOK ());
skip_newlines (); skip_newlines ();
@@ -934,8 +832,8 @@ parse_property_assignment (void)
STACK_DROP (toks, 1); STACK_DROP (toks, 1);
// name, lhs // name, lhs
parse_property_name (); // push name parse_property_name (); // push name
STACK_PUSH (props, create_prop_as_str_or_varg (STACK_TOP (strings), PROP_GET)); STACK_PUSH (props, create_prop_literal (STACK_TOP (literals), PROP_GET));
STACK_DROP (strings, 1); STACK_DROP (literals, 1);
skip_newlines (); skip_newlines ();
parse_argument_list (AL_FUNC_EXPR, next_temp_name ()); // push lhs parse_argument_list (AL_FUNC_EXPR, next_temp_name ()); // push lhs
@@ -967,7 +865,7 @@ parse_property_assignment (void)
goto cleanup; goto cleanup;
} }
else if (lp_string_equal_s (lexer_get_string_by_id (token_data ()), "set")) else if (literal_equal_type_s (lexer_get_literal_by_id (token_data ()), "set"))
{ {
STACK_PUSH (toks, TOK ()); STACK_PUSH (toks, TOK ());
skip_newlines (); skip_newlines ();
@@ -981,8 +879,8 @@ parse_property_assignment (void)
STACK_DROP (toks, 1); STACK_DROP (toks, 1);
// name, lhs // name, lhs
parse_property_name (); // push name parse_property_name (); // push name
STACK_PUSH (props, create_prop_as_str_or_varg (STACK_TOP (strings), PROP_SET)); STACK_PUSH (props, create_prop_literal (STACK_TOP (literals), PROP_SET));
STACK_DROP (strings, 1); STACK_DROP (literals, 1);
skip_newlines (); skip_newlines ();
parse_argument_list (AL_FUNC_EXPR, next_temp_name ()); // push lhs parse_argument_list (AL_FUNC_EXPR, next_temp_name ()); // push lhs
@@ -1019,7 +917,7 @@ simple_prop:
parse_property_name_and_value (); parse_property_name_and_value ();
cleanup: cleanup:
STACK_CHECK_USAGE (strings); STACK_CHECK_USAGE (literals);
STACK_CHECK_USAGE (U8); STACK_CHECK_USAGE (U8);
STACK_CHECK_USAGE (toks); STACK_CHECK_USAGE (toks);
STACK_CHECK_USAGE (U16); STACK_CHECK_USAGE (U16);
@@ -1029,12 +927,12 @@ cleanup:
static void static void
emit_error_on_eval_and_arguments (idx_t id) emit_error_on_eval_and_arguments (idx_t id)
{ {
if (id < lexer_get_strings_count ()) if (id < lexer_get_literals_count ())
{ {
if (lp_string_equal_zt (lexer_get_string_by_id (id), if (literal_equal_type_zt (lexer_get_literal_by_id (id),
ecma_get_magic_string_zt (ECMA_MAGIC_STRING_ARGUMENTS)) ecma_get_magic_string_zt (ECMA_MAGIC_STRING_ARGUMENTS))
|| lp_string_equal_zt (lexer_get_string_by_id (id), || literal_equal_type_zt (lexer_get_literal_by_id (id),
ecma_get_magic_string_zt (ECMA_MAGIC_STRING_EVAL))) ecma_get_magic_string_zt (ECMA_MAGIC_STRING_EVAL)))
{ {
EMIT_ERROR ("'eval' and 'arguments' are not allowed here in strict mode"); EMIT_ERROR ("'eval' and 'arguments' are not allowed here in strict mode");
} }
@@ -1061,12 +959,17 @@ check_for_syntax_errors_in_formal_param_list (uint8_t from)
for (uint8_t i = (uint8_t) (from + 1); i < STACK_SIZE (props); i = (uint8_t) (i + 1)) for (uint8_t i = (uint8_t) (from + 1); i < STACK_SIZE (props); i = (uint8_t) (i + 1))
{ {
JERRY_ASSERT (STACK_ELEMENT (props, i).type == VARG); 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);
for (uint8_t j = from; j < i; j = (uint8_t) (j + 1)) for (uint8_t j = from; j < i; j = (uint8_t) (j + 1))
{ {
if (lp_string_equal (STACK_ELEMENT (props, i).str.str, STACK_ELEMENT (props, j).str.str)) 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);
if (literal_equal_type (previous, current))
{ {
EMIT_ERROR_VARG ("Duplication of literal '%s' in FormalParameterList is not allowed in strict mode", EMIT_ERROR_VARG ("Duplication of literal '%s' in FormalParameterList is not allowed in strict mode",
STACK_ELEMENT (props, j).str.str.str); (const char *) literal_to_zt (previous));
} }
} }
} }
@@ -1083,44 +986,45 @@ check_for_syntax_errors_in_obj_decl (uint8_t from)
for (uint8_t i = (uint8_t) (from + 1); i < STACK_SIZE (props); i = (uint8_t) (i + 1)) for (uint8_t i = (uint8_t) (from + 1); i < STACK_SIZE (props); i = (uint8_t) (i + 1))
{ {
JERRY_ASSERT (STACK_ELEMENT (props, i).type == PROP_DATA const prop_literal previous = STACK_ELEMENT (props, i);
|| STACK_ELEMENT (props, i).type == PROP_GET JERRY_ASSERT (previous.type == PROP_DATA
|| STACK_ELEMENT (props, i).type == PROP_SET); || previous.type == PROP_GET
|| previous.type == PROP_SET);
for (uint8_t j = from; j < i; j = (uint8_t) (j + 1)) for (uint8_t j = from; j < i; j = (uint8_t) (j + 1))
{ {
/*4*/ /*4*/
const lp_string previous = STACK_ELEMENT (props, j).str.str; const prop_literal current = STACK_ELEMENT (props, j);
const prop_type prop_type_previous = STACK_ELEMENT (props, j).type; JERRY_ASSERT (current.type == PROP_DATA
const lp_string prop_id_desc = STACK_ELEMENT (props, i).str.str; || current.type == PROP_GET
const prop_type prop_type_prop_id_desc = STACK_ELEMENT (props, i).type; || current.type == PROP_SET);
if (lp_string_equal (previous, prop_id_desc)) if (literal_equal (previous.lit, current.lit))
{ {
/*a*/ /*a*/
if (parser_strict_mode () && prop_type_previous == PROP_DATA && prop_type_prop_id_desc == PROP_DATA) if (parser_strict_mode () && previous.type == PROP_DATA && current.type == PROP_DATA)
{ {
EMIT_ERROR_VARG ("Duplication of parameter name '%s' in ObjectDeclaration is not allowed in strict mode", EMIT_ERROR_VARG ("Duplication of parameter name '%s' in ObjectDeclaration is not allowed in strict mode",
previous.str); (const char *) literal_to_zt (current.lit));
} }
/*b*/ /*b*/
if (prop_type_previous == PROP_DATA if (previous.type == PROP_DATA
&& (prop_type_prop_id_desc == PROP_SET || prop_type_prop_id_desc == PROP_GET)) && (current.type == PROP_SET || current.type == PROP_GET))
{ {
EMIT_ERROR_VARG ("Parameter name '%s' in ObjectDeclaration may not be both data and accessor", EMIT_ERROR_VARG ("Parameter name '%s' in ObjectDeclaration may not be both data and accessor",
previous.str); (const char *) literal_to_zt (current.lit));
} }
/*c*/ /*c*/
if (prop_type_prop_id_desc == PROP_DATA if (current.type == PROP_DATA
&& (prop_type_previous == PROP_SET || prop_type_previous == PROP_GET)) && (previous.type == PROP_SET || previous.type == PROP_GET))
{ {
EMIT_ERROR_VARG ("Parameter name '%s' in ObjectDeclaration may not be both data and accessor", EMIT_ERROR_VARG ("Parameter name '%s' in ObjectDeclaration may not be both data and accessor",
previous.str); (const char *) literal_to_zt (current.lit));
} }
/*d*/ /*d*/
if ((prop_type_previous == PROP_SET && prop_type_prop_id_desc == PROP_SET) if ((previous.type == PROP_SET && current.type == PROP_SET)
|| (prop_type_previous == PROP_GET && prop_type_prop_id_desc == PROP_GET)) || (previous.type == PROP_GET && current.type == PROP_GET))
{ {
EMIT_ERROR_VARG ("Parameter name '%s' in ObjectDeclaration may not be accessor of same type", EMIT_ERROR_VARG ("Parameter name '%s' in ObjectDeclaration may not be accessor of same type",
previous.str); (const char *) literal_to_zt (current.lit));
} }
} }
} }
@@ -1238,8 +1142,8 @@ parse_argument_list (argument_list_type alt, idx_t obj)
current_token_must_be (TOK_NAME); current_token_must_be (TOK_NAME);
STACK_PUSH (IDX, token_data ()); STACK_PUSH (IDX, token_data ());
STACK_PUSH (props, STACK_PUSH (props,
create_prop_as_str_or_varg (create_allocatable_string_from_literal (token_data ()), create_prop_literal (lexer_get_literal_by_id (token_data ()),
VARG)); VARG));
check_for_eval_and_arguments_in_strict_mode (STACK_TOP (IDX)); check_for_eval_and_arguments_in_strict_mode (STACK_TOP (IDX));
break; break;
} }
@@ -1358,8 +1262,6 @@ next:
const uint8_t args_num = STACK_TOP (U8); const uint8_t args_num = STACK_TOP (U8);
STACK_ITERATE (props, free_allocatable_string, STACK_HEAD (U8, 4));
STACK_DROP (props, (uint8_t) (STACK_SIZE (props) - STACK_HEAD (U8, 4))); STACK_DROP (props, (uint8_t) (STACK_SIZE (props) - STACK_HEAD (U8, 4)));
STACK_DROP (U8, 4); STACK_DROP (U8, 4);
STACK_DROP (U16, 1); STACK_DROP (U16, 1);
@@ -1722,13 +1624,28 @@ parse_member_expression (void)
else if (token_is (TOK_DOT)) else if (token_is (TOK_DOT))
{ {
skip_newlines (); skip_newlines ();
if (!token_is (TOK_NAME)) if (token_is (TOK_NAME))
{
STACK_PUSH (IDX, next_temp_name ());
SET_PROP (ID (1));
DUMP_OPCODE_3 (assignment, ID(1), OPCODE_ARG_TYPE_STRING, token_data ());
}
else if (token_is (TOK_KEYWORD))
{
const literal lit = create_literal_from_str_compute_len (lexer_keyword_to_string (token_data ()));
const idx_t uid = lexer_lookup_literal_uid (lit);
if (uid == INVALID_VALUE)
{
EMIT_ERROR ("Expected identifier");
}
STACK_PUSH (IDX, next_temp_name ());
SET_PROP (ID (1));
DUMP_OPCODE_3 (assignment, ID(1), OPCODE_ARG_TYPE_STRING, uid);
}
else
{ {
EMIT_ERROR ("Expected identifier"); EMIT_ERROR ("Expected identifier");
} }
STACK_PUSH (IDX, next_temp_name ());
SET_PROP (ID (1));
DUMP_OPCODE_3 (assignment, ID(1), OPCODE_ARG_TYPE_STRING, token_data ());
} }
else else
{ {
@@ -1778,7 +1695,7 @@ parse_call_expression (void)
goto cleanup; goto cleanup;
} }
if (THIS_ARG () < lexer_get_reserved_ids_count ()) if (THIS_ARG () < lexer_get_literals_count ())
{ {
STACK_PUSH (IDX, next_temp_name ()); STACK_PUSH (IDX, next_temp_name ());
DUMP_OPCODE_3 (assignment, ID(1), OPCODE_ARG_TYPE_VARIABLE, THIS_ARG ()); DUMP_OPCODE_3 (assignment, ID(1), OPCODE_ARG_TYPE_VARIABLE, THIS_ARG ());
@@ -1899,6 +1816,15 @@ cleanup:
STACK_CHECK_USAGE_LHS (); STACK_CHECK_USAGE_LHS ();
} }
static void
dump_boolean_true (void)
{
STACK_DECLARE_USAGE (IDX);
STACK_PUSH (IDX, next_temp_name ());
DUMP_OPCODE_3 (assignment, ID (1), OPCODE_ARG_TYPE_SIMPLE, ECMA_SIMPLE_VALUE_TRUE);
STACK_CHECK_USAGE_LHS ();
}
/* unary_expression /* unary_expression
: postfix_expression : postfix_expression
| ('delete' | 'void' | 'typeof' | '++' | '--' | '+' | '-' | '~' | '!') unary_expression | ('delete' | 'void' | 'typeof' | '++' | '--' | '+' | '-' | '~' | '!') unary_expression
@@ -1971,17 +1897,31 @@ parse_unary_expression (void)
if (is_keyword (KW_DELETE)) if (is_keyword (KW_DELETE))
{ {
NEXT (unary_expression); NEXT (unary_expression);
if (ID (1) < lexer_get_strings_count ()) if (ID (1) < lexer_get_literals_count ())
{ {
if (parser_strict_mode ()) literal lit = lexer_get_literal_by_id (ID (1));
if (lit.type == LIT_MAGIC_STR || lit.type == LIT_STR)
{ {
EMIT_ERROR ("'delete' operator shall not apply on identifier in strict mode."); if (parser_strict_mode ())
{
EMIT_ERROR ("'delete' operator shall not apply on identifier in strict mode.");
}
STACK_PUSH (IDX, next_temp_name ());
DUMP_OPCODE_2 (delete_var, ID (1), ID (2));
STACK_SWAP (IDX);
STACK_DROP (IDX, 1);
break;
}
else if (lit.type == LIT_NUMBER)
{
dump_boolean_true ();
STACK_SWAP (IDX);
STACK_DROP (IDX, 1);
}
else
{
JERRY_UNREACHABLE ();
} }
STACK_PUSH (IDX, next_temp_name ());
DUMP_OPCODE_2 (delete_var, ID (1), ID (2));
STACK_SWAP (IDX);
STACK_DROP (IDX, 1);
break;
} }
STACK_PUSH (ops, deserialize_opcode ((opcode_counter_t) (OPCODE_COUNTER () - 1))); STACK_PUSH (ops, deserialize_opcode ((opcode_counter_t) (OPCODE_COUNTER () - 1)));
if (LAST_OPCODE_IS (assignment) if (LAST_OPCODE_IS (assignment)
@@ -2002,8 +1942,7 @@ parse_unary_expression (void)
} }
else else
{ {
STACK_PUSH (IDX, next_temp_name ()); dump_boolean_true ();
DUMP_OPCODE_3 (assignment, ID (1), OPCODE_ARG_TYPE_SIMPLE, ECMA_SIMPLE_VALUE_TRUE);
STACK_SWAP (IDX); STACK_SWAP (IDX);
STACK_DROP (IDX, 1); STACK_DROP (IDX, 1);
} }
@@ -3769,6 +3708,44 @@ skip_braces (void)
{ {
STACK_DECR_HEAD (U8, 1); STACK_DECR_HEAD (U8, 1);
} }
else if (token_is (TOK_KEYWORD))
{
keyword kw = (keyword) token_data ();
skip_newlines ();
if (token_is (TOK_COLON))
{
lexer_add_literal_if_not_present (create_literal_from_str_compute_len (lexer_keyword_to_string (kw)));
}
else
{
lexer_save_token (TOK ());
}
}
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"))
{
skip_newlines ();
if (token_is (TOK_KEYWORD))
{
keyword kw = (keyword) token_data ();
skip_newlines ();
if (token_is (TOK_OPEN_PAREN))
{
lexer_add_literal_if_not_present (create_literal_from_str_compute_len (lexer_keyword_to_string (kw)));
}
else
{
lexer_save_token (TOK ());
}
}
else
{
lexer_save_token (TOK ());
}
}
}
} }
STACK_DROP (U8,1); STACK_DROP (U8,1);
@@ -3953,7 +3930,7 @@ preparse_scope (bool is_global)
STACK_PUSH (locs, TOK ().loc); STACK_PUSH (locs, TOK ().loc);
STACK_PUSH (U8, is_global ? TOK_EOF : TOK_CLOSE_BRACE); STACK_PUSH (U8, is_global ? TOK_EOF : TOK_CLOSE_BRACE);
if (token_is (TOK_STRING) && lp_string_equal_s (lexer_get_string_by_id (token_data ()), "use strict")) if (token_is (TOK_STRING) && literal_equal_s (lexer_get_literal_by_id (token_data ()), "use strict"))
{ {
scopes_tree_set_strict_mode (STACK_TOP (scopes), true); scopes_tree_set_strict_mode (STACK_TOP (scopes), true);
DUMP_OPCODE_3 (meta, OPCODE_META_TYPE_STRICT_CODE, INVALID_VALUE, INVALID_VALUE); DUMP_OPCODE_3 (meta, OPCODE_META_TYPE_STRICT_CODE, INVALID_VALUE, INVALID_VALUE);
@@ -4011,9 +3988,16 @@ parse_source_element_list (bool is_global)
STACK_DECLARE_USAGE (IDX) STACK_DECLARE_USAGE (IDX)
STACK_DECLARE_USAGE (temp_names) STACK_DECLARE_USAGE (temp_names)
start_new_scope ();
preparse_scope (is_global);
preparse_scope (is_global);
if (is_global)
{
SET_MAX_TEMP_NAME (lexer_get_literals_count ());
SET_TEMP_NAME (lexer_get_literals_count ());
SET_MIN_TEMP_NAME (lexer_get_literals_count ());
}
start_new_scope ();
skip_newlines (); skip_newlines ();
while (!token_is (TOK_EOF) && !token_is (TOK_CLOSE_BRACE)) while (!token_is (TOK_EOF) && !token_is (TOK_CLOSE_BRACE))
{ {
@@ -4050,10 +4034,12 @@ parser_parse_program (void)
JERRY_ASSERT (token_is (TOK_EOF)); JERRY_ASSERT (token_is (TOK_EOF));
DUMP_OPCODE_1 (exitval, 0); DUMP_OPCODE_1 (exitval, 0);
serializer_dump_literals (lexer_get_literals (), lexer_get_literals_count ());
serializer_merge_scopes_into_bytecode (); serializer_merge_scopes_into_bytecode ();
serializer_set_scope (NULL);
deserializer_set_strings_buffer (lexer_get_strings_cache ());
scopes_tree_free (STACK_TOP (scopes)); scopes_tree_free (STACK_TOP (scopes));
serializer_set_scope (NULL);
STACK_DROP (scopes, 1); STACK_DROP (scopes, 1);
STACK_CHECK_USAGE (IDX); STACK_CHECK_USAGE (IDX);
@@ -4079,15 +4065,6 @@ parser_init (const char *source, size_t source_size, bool show_opcodes)
lexer_init (source, source_size, show_opcodes); lexer_init (source, source_size, show_opcodes);
serializer_init (show_opcodes); serializer_init (show_opcodes);
lexer_run_first_pass ();
lexer_adjust_num_ids ();
const lp_string *identifiers = lexer_get_strings ();
serializer_dump_strings_and_nums (identifiers, lexer_get_strings_count (),
lexer_get_nums (), lexer_get_nums_count ());
STACK_INIT (U8); STACK_INIT (U8);
STACK_INIT (IDX); STACK_INIT (IDX);
STACK_INIT (nestings); STACK_INIT (nestings);
@@ -4100,51 +4077,10 @@ parser_init (const char *source, size_t source_size, bool show_opcodes)
STACK_INIT (locs); STACK_INIT (locs);
STACK_INIT (scopes); STACK_INIT (scopes);
STACK_INIT (props); STACK_INIT (props);
STACK_INIT (strings); STACK_INIT (literals);
HASH_INIT (intrinsics, 1);
fill_intrinsics ();
SET_MAX_TEMP_NAME (lexer_get_reserved_ids_count ());
SET_TEMP_NAME (lexer_get_reserved_ids_count ());
SET_MIN_TEMP_NAME (lexer_get_reserved_ids_count ());
SET_OPCODE_COUNTER (0); SET_OPCODE_COUNTER (0);
STACK_SET_ELEMENT (U8, no_in, 0); STACK_SET_ELEMENT (U8, no_in, 0);
TODO (/* Rewrite using hash when number of natives reaches 20 */)
for (uint8_t i = 0; i < OPCODE_NATIVE_CALL__COUNT; i++)
{
STACK_SET_ELEMENT (IDX, i, INVALID_VALUE);
}
for (uint8_t i = 0, strs_count = lexer_get_strings_count (); i < strs_count; i++)
{
if (lp_string_equal_s (identifiers[i], "LEDToggle"))
{
STACK_SET_ELEMENT (IDX, OPCODE_NATIVE_CALL_LED_TOGGLE, i);
}
else if (lp_string_equal_s (identifiers[i], "LEDOn"))
{
STACK_SET_ELEMENT (IDX, OPCODE_NATIVE_CALL_LED_ON, i);
}
else if (lp_string_equal_s (identifiers[i], "LEDOff"))
{
STACK_SET_ELEMENT (IDX, OPCODE_NATIVE_CALL_LED_OFF, i);
}
else if (lp_string_equal_s (identifiers[i], "LEDOnce"))
{
STACK_SET_ELEMENT (IDX, OPCODE_NATIVE_CALL_LED_ONCE, i);
}
else if (lp_string_equal_s (identifiers[i], "wait"))
{
STACK_SET_ELEMENT (IDX, OPCODE_NATIVE_CALL_WAIT, i);
}
else if (lp_string_equal_s (identifiers[i], "print"))
{
STACK_SET_ELEMENT (IDX, OPCODE_NATIVE_CALL_PRINT, i);
}
}
} }
void void
@@ -4162,9 +4098,7 @@ parser_free (void)
STACK_FREE (locs); STACK_FREE (locs);
STACK_FREE (scopes); STACK_FREE (scopes);
STACK_FREE (props); STACK_FREE (props);
STACK_FREE (strings); STACK_FREE (literals);
HASH_FREE (intrinsics);
serializer_free (); serializer_free ();
lexer_free (); lexer_free ();
+3 -5
View File
@@ -19,7 +19,7 @@
#include "opcodes.h" #include "opcodes.h"
#include "stack.h" #include "stack.h"
#include "jerry-libc.h" #include "jerry-libc.h"
#include "lp-string.h" #include "literal.h"
#include "scopes-tree.h" #include "scopes-tree.h"
/* bytecode_data contains identifiers, string and num literals. /* bytecode_data contains identifiers, string and num literals.
@@ -35,11 +35,9 @@
} */ } */
struct struct
{ {
const lp_string *strings; const literal *literals;
const ecma_number_t *nums;
const opcode_t *opcodes; const opcode_t *opcodes;
uint8_t strs_count; uint8_t literals_count;
uint8_t nums_count;
opcode_counter_t opcodes_count; opcode_counter_t opcodes_count;
} }
bytecode_data; bytecode_data;
+16 -22
View File
@@ -15,26 +15,21 @@
#include "deserializer.h" #include "deserializer.h"
#include "bytecode-data.h" #include "bytecode-data.h"
#include "ecma-helpers.h"
const ecma_char_t * const ecma_char_t *strings_buffer;
deserialize_string_by_id (uint8_t id)
void
deserializer_set_strings_buffer (const ecma_char_t *s)
{ {
JERRY_ASSERT (id < bytecode_data.strs_count); strings_buffer = s;
JERRY_ASSERT (bytecode_data.strings[id].str[bytecode_data.strings[id].length] == '\0');
return ((const ecma_char_t *) bytecode_data.strings[id].str);
} }
ecma_number_t literal
deserialize_num_by_id (uint8_t id) deserialize_literal_by_id (uint8_t id)
{ {
JERRY_ASSERT (id >= bytecode_data.strs_count); JERRY_ASSERT (id < bytecode_data.literals_count);
return bytecode_data.literals[id];
id = (uint8_t) (id - bytecode_data.strs_count);
JERRY_ASSERT (id < bytecode_data.nums_count);
return bytecode_data.nums[id];
} }
const void * const void *
@@ -58,25 +53,24 @@ deserialize_opcode (opcode_counter_t oc)
uint8_t uint8_t
deserialize_min_temp (void) deserialize_min_temp (void)
{ {
return (uint8_t) (bytecode_data.strs_count + bytecode_data.nums_count); return bytecode_data.literals_count;
} }
void void
deserializer_init (void) deserializer_init (void)
{ {
bytecode_data.strings = NULL; bytecode_data.literals = NULL;
bytecode_data.nums = NULL; strings_buffer = NULL;
bytecode_data.opcodes = NULL; bytecode_data.opcodes = NULL;
} }
void void
deserializer_free (void) deserializer_free (void)
{ {
if (bytecode_data.strs_count > 0) if (strings_buffer)
{ {
mem_heap_free_block ((uint8_t *) bytecode_data.strings[0].str); mem_heap_free_block ((uint8_t *) strings_buffer);
} }
mem_heap_free_block ((uint8_t *) bytecode_data.strings); mem_heap_free_block ((uint8_t *) bytecode_data.literals);
mem_heap_free_block ((uint8_t *) bytecode_data.nums);
mem_heap_free_block ((uint8_t *) bytecode_data.opcodes); mem_heap_free_block ((uint8_t *) bytecode_data.opcodes);
} }
+3 -2
View File
@@ -19,10 +19,11 @@
#include "globals.h" #include "globals.h"
#include "ecma-globals.h" #include "ecma-globals.h"
#include "opcodes.h" #include "opcodes.h"
#include "literal.h"
void deserializer_init (void); void deserializer_init (void);
const ecma_char_t *deserialize_string_by_id (uint8_t); void deserializer_set_strings_buffer (const ecma_char_t *);
ecma_number_t deserialize_num_by_id (uint8_t); literal deserialize_literal_by_id (uint8_t);
const void *deserialize_bytecode (void); const void *deserialize_bytecode (void);
opcode_t deserialize_opcode (opcode_counter_t); opcode_t deserialize_opcode (opcode_counter_t);
uint8_t deserialize_min_temp (void); uint8_t deserialize_min_temp (void);
+35 -38
View File
@@ -20,6 +20,7 @@
#include "lexer.h" #include "lexer.h"
#include "deserializer.h" #include "deserializer.h"
#include "opcodes-native-call.h" #include "opcodes-native-call.h"
#include "ecma-helpers.h"
#include <stdarg.h> #include <stdarg.h>
#define NAME_TO_ID(op) (__op__idx_##op) #define NAME_TO_ID(op) (__op__idx_##op)
@@ -45,43 +46,48 @@ static uint8_t opcode_sizes[] =
}; };
static void static void
dump_lp (lp_string lp) dump_literal (literal lit)
{ {
for (ecma_length_t i = 0; i < lp.length; i++) switch (lit.type)
{ {
__putchar (lp.str[i]); case LIT_NUMBER:
{
__printf ("%d : NUMBER", lit.data.num);
break;
}
case LIT_MAGIC_STR:
{
__printf ("%s : MAGIC STRING", (const char *) ecma_get_magic_string_zt (lit.data.magic_str_id));
break;
}
case LIT_STR:
{
__printf ("%s : STRING", (const char *) (lit.data.lp.str));
break;
}
default:
{
JERRY_UNREACHABLE ();
}
} }
} }
void void
pp_strings (const lp_string strings[], uint8_t size) pp_literals (const literal lits[], uint8_t size)
{ {
__printf ("STRINGS %d:\n", size); __printf ("LITERALS %d:\n", size);
for (uint8_t i = 0; i < size; i++) for (uint8_t i = 0; i < size; i++)
{ {
__printf ("%3d ", i); __printf ("%3d ", i);
dump_lp (strings[i]); dump_literal (lits[i]);
__putchar ('\n'); __putchar ('\n');
} }
} }
void
pp_nums (const ecma_number_t nums[], uint8_t size, uint8_t strings_num)
{
uint8_t i;
__printf ("NUMS %d:\n", size);
for (i = 0; i < size; i++)
{
__printf ("%3d %7d\n", i + strings_num, (int) nums[i]);
}
__printf ("\n");
}
static const char * static const char *
var_id_to_string (char *res, idx_t id) var_id_to_string (char *res, idx_t id)
{ {
if (id >= lexer_get_reserved_ids_count ()) if (id >= lexer_get_literals_count ())
{ {
__strncpy (res, "tmp", 3); __strncpy (res, "tmp", 3);
if (id / 100 != 0) if (id / 100 != 0)
@@ -103,28 +109,19 @@ var_id_to_string (char *res, idx_t id)
return res; return res;
} }
} }
else if (id < lexer_get_strings_count ()) literal lit = lexer_get_literal_by_id (id);
if (lit.type == LIT_STR || lit.type == LIT_MAGIC_STR)
{ {
lp_string str = lexer_get_string_by_id (id); return (char *) literal_to_zt (lit);
__strncpy (res, (char *) str.str, str.length); }
else if (lit.type == LIT_NUMBER)
{
ecma_number_to_zt_string (lit.data.num, (ecma_char_t *) res, ECMA_MAX_CHARS_IN_STRINGIFIED_NUMBER);
return res; return res;
} }
else else
{ {
int i = 0; JERRY_UNREACHABLE ();
int num = (int) lexer_get_num_by_id (id);
int temp = num;
for (; temp != 0; i++)
{
temp /= 10;
}
do
{
res[i--] = (char) (num % 10 + '0');
num /= 10;
}
while (i >= 0);
return res;
} }
} }
@@ -152,7 +149,7 @@ pp_printf (const char *format, ...)
} }
case 's': case 's':
{ {
char res[32] = {'\0'}; char res[ECMA_MAX_CHARS_IN_STRINGIFIED_NUMBER] = {'\0'};
__printf ("%s", var_id_to_string (res, (idx_t) va_arg (args, int))); __printf ("%s", var_id_to_string (res, (idx_t) va_arg (args, int)));
break; break;
} }
+2 -3
View File
@@ -19,11 +19,10 @@
#include "globals.h" #include "globals.h"
#ifdef JERRY_ENABLE_PP #ifdef JERRY_ENABLE_PP
#include "interpreter.h" #include "interpreter.h"
#include "lp-string.h" #include "literal.h"
void pp_opcode (opcode_counter_t, opcode_t, bool); void pp_opcode (opcode_counter_t, opcode_t, bool);
void pp_strings (const lp_string *, uint8_t); void pp_literals (const literal *, uint8_t);
void pp_nums (const ecma_number_t *, uint8_t, uint8_t);
#endif // JERRY_ENABLE_PP #endif // JERRY_ENABLE_PP
#endif // PRETTY_PRINTER #endif // PRETTY_PRINTER
+4 -8
View File
@@ -37,21 +37,17 @@ serializer_merge_scopes_into_bytecode (void)
void void
serializer_dump_strings_and_nums (const lp_string strings[], uint8_t strs_count, serializer_dump_literals (const literal literals[], uint8_t literals_count)
const ecma_number_t nums[], uint8_t nums_count)
{ {
#ifdef JERRY_ENABLE_PP #ifdef JERRY_ENABLE_PP
if (print_opcodes) if (print_opcodes)
{ {
pp_strings (strings, strs_count); pp_literals (literals, literals_count);
pp_nums (nums, nums_count, strs_count);
} }
#endif #endif
bytecode_data.strs_count = strs_count; bytecode_data.literals_count = literals_count;
bytecode_data.nums_count = nums_count; bytecode_data.literals = literals;
bytecode_data.strings = strings;
bytecode_data.nums = nums;
} }
void void
+2 -3
View File
@@ -19,12 +19,11 @@
#include "globals.h" #include "globals.h"
#include "opcodes.h" #include "opcodes.h"
#include "interpreter.h" #include "interpreter.h"
#include "lp-string.h" #include "literal.h"
#include "scopes-tree.h" #include "scopes-tree.h"
void serializer_init (bool show_opcodes); void serializer_init (bool show_opcodes);
void serializer_dump_strings_and_nums (const lp_string *, uint8_t, void serializer_dump_literals (const literal *, uint8_t);
const ecma_number_t *, uint8_t);
void serializer_set_scope (scopes_tree); void serializer_set_scope (scopes_tree);
void serializer_merge_scopes_into_bytecode (void); void serializer_merge_scopes_into_bytecode (void);
void serializer_dump_opcode (opcode_t); void serializer_dump_opcode (opcode_t);
+10 -1
View File
@@ -14,4 +14,13 @@
var a = {get a(){return undefined}, set a(b){}} var a = {get a(){return undefined}, set a(b){}}
// var b = {if:0, else:1, try:2, catch:3, finally:4} var b = {if:0, else:1, try:2, catch:3, finally:4, let:5}
assert (b.if + b.else + b.try + b.catch + b.finally + b.let === 15)
function c() {
"use strict"
var b = {let:15, enum:10}
assert (b.let + b.enum === 25)
}
c();
+3 -1
View File
@@ -17,13 +17,15 @@
#define COMMON_H #define COMMON_H
#include "jerry-libc.h" #include "jerry-libc.h"
#include "literal.h"
#define NAME_TO_ID(op) (__op__idx_##op) #define NAME_TO_ID(op) (__op__idx_##op)
#define __OPCODE_SIZE(name, arg1, arg2, arg3) \ #define __OPCODE_SIZE(name, arg1, arg2, arg3) \
sizeof (__op_##name) + 1, sizeof (__op_##name) + 1,
#define LP(s) (lp_string) { .length = (uint8_t) __strlen(s), .str = (ecma_char_t *) s } #define LP(s) create_literal_from_str_compute_len (s)
#define NUM(s) create_literal_from_num (s)
static uint8_t opcode_sizes[] = { static uint8_t opcode_sizes[] = {
OP_LIST (OPCODE_SIZE) OP_LIST (OPCODE_SIZE)
@@ -40,10 +40,10 @@ main( int __unused argc,
mem_init(); mem_init();
serializer_init (false); serializer_init (false);
const lp_string strings[] = { LP("a"), const literal lits[] = { LP("a"),
LP("b") }; LP("b"),
ecma_number_t nums [] = { 2.0 }; NUM(2.0) };
serializer_dump_strings_and_nums (strings, 2, nums, 1); serializer_dump_literals (lits, 3);
init_int( test_program, false); init_int( test_program, false);
+8 -8
View File
@@ -172,14 +172,14 @@ main( int __unused argc,
mem_init(); mem_init();
serializer_init (false); serializer_init (false);
const lp_string strings[] = { LP("a"), const literal literals[] = { LP("a"),
LP("b"), LP("b"),
LP("length"), LP("length"),
LP("1") }; LP("1"),
ecma_number_t nums [] = { 2.0, NUM(2.0),
12.0, NUM(12.0),
2.5 }; NUM(2.5) };
serializer_dump_strings_and_nums (strings, 4, nums, 3); serializer_dump_literals (literals, 7);
init_int( test_program, false); init_int( test_program, false);
+4 -4
View File
@@ -45,10 +45,10 @@ main( int __unused argc,
mem_init(); mem_init();
serializer_init (false); serializer_init (false);
const lp_string strings[] = { LP("a"), const literal lits[] = { LP("a"),
LP("b") }; LP("b"),
ecma_number_t nums [] = { 2.0 }; NUM(2.0) };
serializer_dump_strings_and_nums (strings, 2, nums, 1); serializer_dump_literals (lits, 3);
init_int( test_program, false); init_int( test_program, false);
+4 -4
View File
@@ -40,10 +40,10 @@ main( int __unused argc,
mem_init(); mem_init();
serializer_init (false); serializer_init (false);
const lp_string strings[] = { LP("a"), const literal lits[] = { LP("a"),
LP("b") }; LP("b"),
ecma_number_t nums [] = { 2.0 }; NUM(2.0) };
serializer_dump_strings_and_nums (strings, 2, nums, 1); serializer_dump_literals (lits, 3);
init_int( test_program, false); init_int( test_program, false);
+4 -4
View File
@@ -40,10 +40,10 @@ main( int __unused argc,
mem_init(); mem_init();
serializer_init (false); serializer_init (false);
const lp_string strings[] = { LP("a"), const literal lits[] = { LP("a"),
LP("b") }; LP("b"),
ecma_number_t nums [] = { 2.0 }; NUM(2.0) };
serializer_dump_strings_and_nums (strings, 2, nums, 1); serializer_dump_literals (lits, 3);
init_int( test_program, false); init_int( test_program, false);
+1 -1
View File
@@ -33,7 +33,7 @@ main( int __unused argc,
mem_init(); mem_init();
deserializer_init (); deserializer_init ();
parser_init (program, __strlen (program), false); parser_init (program, __strlen (program), true);
parser_parse_program (); parser_parse_program ();
parser_free (); parser_free ();
+4 -4
View File
@@ -40,10 +40,10 @@ main( int __unused argc,
mem_init(); mem_init();
serializer_init (false); serializer_init (false);
const lp_string strings[] = { LP("a"), const literal lits[] = { LP("a"),
LP("b") }; LP("b"),
ecma_number_t nums [] = { 2.0 }; NUM(2.0) };
serializer_dump_strings_and_nums (strings, 2, nums, 1); serializer_dump_literals (lits, 3);
init_int( test_program, false); init_int( test_program, false);
+4 -4
View File
@@ -40,10 +40,10 @@ main( int __unused argc,
mem_init(); mem_init();
serializer_init (false); serializer_init (false);
const lp_string strings[] = { LP("a"), const literal lits[] = { LP("a"),
LP("b") }; LP("b"),
ecma_number_t nums [] = { 2.0 }; NUM(2.0) };
serializer_dump_strings_and_nums (strings, 2, nums, 1); serializer_dump_literals (lits, 3);
init_int( test_program, false); init_int( test_program, false);
+5 -5
View File
@@ -53,11 +53,11 @@ main( int __unused argc,
mem_init(); mem_init();
serializer_init (false); serializer_init (false);
const lp_string strings[] = { LP("a"), const literal lits[] = { LP("a"),
LP("b"), LP("b"),
LP("c") }; LP("c"),
ecma_number_t nums [] = { 2.0 }; NUM(2.0) };
serializer_dump_strings_and_nums (strings, 3, nums, 1); serializer_dump_literals (lits, 4);
init_int( test_program, false); init_int( test_program, false);
@@ -38,10 +38,10 @@ main( int __unused argc,
mem_init(); mem_init();
serializer_init (false); serializer_init (false);
const lp_string strings[] = { LP("a"), const literal lits[] = { LP("a"),
LP("b") }; LP("b"),
ecma_number_t nums [] = { 2.0 }; NUM(2.0) };
serializer_dump_strings_and_nums (strings, 2, nums, 1); serializer_dump_literals (lits, 3);
init_int( test_program, false); init_int( test_program, false);