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:
{
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));
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_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 ();
string_desc_p->refs = 1;
FIXME (/* Interface for getting literal's length without string's characters iteration */);
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->length = lit.data.lp.length;
string_desc_p->container = ECMA_STRING_CONTAINER_LIT_TABLE;
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:
{
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);
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)
{
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
{
@@ -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)
{
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
{
@@ -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)
{
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
{
@@ -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)
{
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
{
+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
{
strings_global_size
literals_global_size
};
STATIC_STACK (strings, uint8_t, lp_string)
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_STACK (literals, uint8_t, literal)
static bool
is_empty (token tok)
@@ -116,7 +104,7 @@ create_token (token_type type, uint8_t uid)
return (token)
{
.type = type,
.loc = current_locus (),
.loc = current_locus () - (type == TOK_STRING ? 1 : 0),
.uid = uid
};
}
@@ -136,49 +124,74 @@ current_token_equals_to (const char *str)
}
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;
}
static lp_string
adjust_string_ptrs (lp_string lp, size_t diff)
static literal
adjust_string_ptrs (literal lit, size_t diff)
{
return (lp_string)
if (lit.type != LIT_STR)
{
.length = lp.length,
.str = lp.str + diff
return lit;
}
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)
{
lp_string res;
res.length = (ecma_length_t) (buffer - token_start);
if (strings_cache_used_size + res.length * sizeof (ecma_char_t) >= strings_cache_size)
const ecma_length_t length = (ecma_length_t) (buffer - token_start);
if (strings_cache_used_size + length * sizeof (ecma_char_t) >= strings_cache_size)
{
strings_cache_size = mem_heap_recommend_allocation_size (strings_cache_used_size
+ ((size_t) 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,
MEM_HEAP_ALLOC_SHORT_TERM);
__memcpy (temp, strings_cache, strings_cache_used_size);
mem_heap_free_block ((uint8_t *) strings_cache);
STACK_ITERATE_VARG_SET (strings, adjust_string_ptrs, 0, (size_t) (temp - strings_cache));
STACK_ITERATE_VARG_SET (literals, adjust_string_ptrs, 0, (size_t) (temp - strings_cache));
if (strings_cache)
{
mem_heap_free_block ((uint8_t *) strings_cache);
}
strings_cache = temp;
}
__strncpy ((char *) (strings_cache + strings_cache_used_size), token_start, res.length);
res.str = strings_cache + strings_cache_used_size;
(strings_cache + strings_cache_used_size)[res.length] = '\0';
strings_cache_used_size = (size_t) (((size_t) res.length + 1) * sizeof (ecma_char_t) + strings_cache_used_size);
__strncpy ((char *) (strings_cache + strings_cache_used_size), token_start, length);
(strings_cache + strings_cache_used_size)[length] = '\0';
const literal res = create_literal_from_zt (strings_cache + strings_cache_used_size, length);
strings_cache_used_size = (size_t) (((size_t) length + 1) * sizeof (ecma_char_t) + strings_cache_used_size);
return res;
}
@@ -187,9 +200,11 @@ convert_current_token_to_token (token_type tt)
{
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)
{
@@ -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,
@@ -235,11 +255,11 @@ decode_keyword (void)
}
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"))
{
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"))
{
@@ -267,15 +287,15 @@ decode_keyword (void)
}
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"))
{
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"))
{
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"))
{
@@ -297,6 +317,10 @@ decode_keyword (void)
{
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"))
{
return create_token (TOK_KEYWORD, KW_INSTANCEOF);
@@ -305,26 +329,22 @@ decode_keyword (void)
{
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
{
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"))
{
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 (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
{
@@ -335,7 +355,7 @@ decode_keyword (void)
{
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
{
@@ -354,7 +374,7 @@ decode_keyword (void)
{
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
{
@@ -365,7 +385,7 @@ decode_keyword (void)
{
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
{
@@ -376,7 +396,7 @@ decode_keyword (void)
{
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
{
@@ -387,7 +407,7 @@ decode_keyword (void)
{
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
{
@@ -402,7 +422,7 @@ decode_keyword (void)
{
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
{
@@ -411,7 +431,7 @@ decode_keyword (void)
}
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"))
{
@@ -457,7 +477,7 @@ decode_keyword (void)
{
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
{
@@ -470,81 +490,75 @@ decode_keyword (void)
static token
convert_seen_num_to_token (ecma_number_t num)
{
uint8_t num_id;
JERRY_ASSERT (STACK_SIZE (num_ids) == STACK_SIZE (numbers));
for (uint8_t i = 0; i < STACK_SIZE (numbers); i++)
for (uint8_t i = 0; i < STACK_SIZE (literals); 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 (num_ids, num_id);
STACK_PUSH (numbers, num);
STACK_PUSH (literals, create_literal_from_num (num));
return create_token (TOK_NUMBER, num_id);
return create_token (TOK_NUMBER, (idx_t) (STACK_SIZE (literals) - 1));
}
const lp_string *
lexer_get_strings (void)
const literal *
lexer_get_literals (void)
{
lp_string *data = NULL;
STACK_CONVERT_TO_RAW_DATA (strings, data);
literal *data = NULL;
STACK_CONVERT_TO_RAW_DATA (literals, data);
return data;
}
uint8_t
lexer_get_strings_count (void)
lexer_get_literals_count (void)
{
return STACK_SIZE (strings);
return STACK_SIZE (literals);
}
uint8_t
lexer_get_reserved_ids_count (void)
idx_t
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
lexer_get_string_by_id (uint8_t id)
literal
lexer_get_literal_by_id (uint8_t id)
{
JERRY_ASSERT (id < STACK_SIZE (strings));
return STACK_ELEMENT (strings, id);
JERRY_ASSERT (id < STACK_SIZE (literals));
return STACK_ELEMENT (literals, id);
}
const ecma_number_t *
lexer_get_nums (void)
const ecma_char_t *
lexer_get_strings_cache (void)
{
ecma_number_t *data = NULL;
STACK_CONVERT_TO_RAW_DATA (numbers, data);
return data;
}
uint8_t
lexer_get_nums_count (void)
{
return STACK_SIZE (numbers);
return strings_cache;
}
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 (numbers); i++)
for (uint8_t i = 0; i < STACK_SIZE (literals); 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;
}
}
}
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 ());
STACK_PUSH (literals, lit);
}
static void
@@ -989,14 +1003,6 @@ lexer_set_source (const char * source)
buffer = buffer_start;
}
static void
lexer_rewind (void)
{
JERRY_ASSERT (buffer_start != NULL);
buffer = buffer_start;
}
static bool
replace_comment_by_newline (void)
{
@@ -1229,18 +1235,6 @@ lexer_prev_token (void)
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
lexer_seek (size_t locus)
{
@@ -1307,34 +1301,53 @@ lexer_keyword_to_string (keyword kw)
case KW_BREAK: return "break";
case KW_CASE: return "case";
case KW_CATCH: return "catch";
case KW_CLASS: return "class";
case KW_CONST: return "const";
case KW_CONTINUE: return "continue";
case KW_DEBUGGER: return "debugger";
case KW_DEFAULT: return "default";
case KW_DELETE: return "delete";
case KW_DO: return "do";
case KW_DO: return "do";
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_FOR: return "for";
case KW_FUNCTION: return "function";
case KW_IF: return "if";
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_THROW: return "throw";
case KW_TRY: return "try";
case KW_TYPEOF: return "typeof";
case KW_VAR: return "var";
case KW_VOID: return "void";
case KW_WHILE: return "while";
case KW_WITH: return "with";
case KW_YIELD: return "yield";
default: JERRY_UNREACHABLE ();
}
}
@@ -1423,23 +1436,14 @@ lexer_init (const char *source, size_t source_size, bool show_opcodes)
allow_dump_lines = show_opcodes;
buffer_size = source_size;
lexer_set_source (source);
strings_cache_size = mem_heap_recommend_allocation_size (sizeof (ecma_char_t));
strings_cache = (ecma_char_t *) mem_heap_alloc_block (strings_cache_size, MEM_HEAP_ALLOC_SHORT_TERM);
strings_cache_used_size = 0;
strings_cache = NULL;
strings_cache_used_size = strings_cache_size = 0;
STACK_INIT (strings);
STACK_INIT (numbers);
STACK_INIT (num_ids);
STACK_INIT (literals);
}
void
lexer_free (void)
{
if (STACK_SIZE (strings) == 0)
{
mem_heap_free_block (strings_cache);
}
STACK_FREE (strings);
STACK_FREE (numbers);
STACK_FREE (num_ids);
STACK_FREE (literals);
}
+30 -16
View File
@@ -18,8 +18,10 @@
#include "globals.h"
#include "ecma-globals.h"
#include "lp-string.h"
#include "literal.h"
#include "opcodes.h"
#define INVALID_VALUE 255
/* Keywords. */
typedef enum
{
@@ -28,13 +30,19 @@ typedef enum
KW_BREAK,
KW_CASE,
KW_CATCH,
KW_CONTINUE,
KW_CLASS,
KW_CONST,
KW_CONTINUE,
KW_DEBUGGER,
KW_DEFAULT,
KW_DELETE,
KW_DO,
KW_ELSE,
KW_ENUM,
KW_EXPORT,
KW_EXTENDS,
KW_FINALLY,
KW_FOR,
@@ -43,8 +51,20 @@ typedef enum
KW_IN,
KW_INSTANCEOF,
KW_INTERFACE,
KW_IMPORT,
KW_IMPLEMENTS,
KW_LET,
KW_NEW,
KW_PACKAGE,
KW_PRIVATE,
KW_PROTECTED,
KW_PUBLIC,
KW_RETURN,
KW_STATIC,
KW_SUPER,
KW_SWITCH,
KW_THIS,
@@ -56,6 +76,7 @@ typedef enum
KW_WHILE,
KW_WITH,
KW_YIELD
}
keyword;
@@ -142,30 +163,23 @@ typedef struct
{
locus loc;
token_type type;
uint8_t uid;
idx_t uid;
}
token;
void lexer_init (const char *, size_t, bool);
void lexer_free (void);
void lexer_run_first_pass (void);
token lexer_next_token (void);
void lexer_save_token (token);
token lexer_prev_token (void);
uint8_t lexer_get_reserved_ids_count (void);
const lp_string *lexer_get_strings (void);
uint8_t lexer_get_strings_count (void);
lp_string lexer_get_string_by_id (uint8_t);
const ecma_number_t *lexer_get_nums (void);
ecma_number_t lexer_get_num_by_id (uint8_t);
uint8_t lexer_get_nums_count (void);
void lexer_adjust_num_ids (void);
const literal *lexer_get_literals (void);
const ecma_char_t *lexer_get_strings_cache (void);
void lexer_add_literal_if_not_present (literal);
uint8_t lexer_get_literals_count (void);
literal lexer_get_literal_by_id (uint8_t);
idx_t lexer_lookup_literal_uid (literal lit);
void lexer_seek (locus);
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 "ecma-helpers.h"
#define INVALID_VALUE 255
#define INTRINSICS_COUNT 1
typedef enum
@@ -39,17 +38,6 @@ typedef enum
}
rewritable_opcode_type;
typedef struct
{
union
{
void (*fun1) (idx_t);
}
funs;
uint8_t args_count;
}
intrinsic_dumper;
typedef enum
{
PROP_DATA,
@@ -59,19 +47,12 @@ typedef enum
}
prop_type;
typedef struct
{
lp_string str;
bool was_num;
}
allocatable_string;
typedef struct
{
prop_type type;
allocatable_string str;
literal lit;
}
prop_as_str_or_varg;
prop_literal;
#define NESTING_ITERATIONAL 1
#define NESTING_SWITCH 2
@@ -88,7 +69,6 @@ STATIC_STACK (U8, uint8_t, uint8_t)
enum
{
native_calls = OPCODE_NATIVE_CALL__COUNT,
this_arg,
prop,
IDX_global_size
@@ -199,15 +179,15 @@ STATIC_STACK (rewritable_break, uint8_t, uint16_t)
enum
{
strings_global_size
literals_global_size
};
STATIC_STACK (strings, uint8_t, allocatable_string)
STATIC_STACK (literals, uint8_t, literal)
enum
{
props_global_size
};
STATIC_STACK (props, uint8_t, prop_as_str_or_varg)
STATIC_STACK (props, uint8_t, prop_literal)
#ifndef JERRY_NDEBUG
#define STACK_CHECK_USAGE_LHS() \
@@ -216,9 +196,6 @@ JERRY_ASSERT (IDX.current == IDX_current + 1);
#define STACK_CHECK_USAGE_LHS() ;
#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)
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 parse_logical_expression (bool);
static uint8_t
lp_string_hash (lp_string str)
{
return str.length % INTRINSICS_COUNT;
}
static idx_t
next_temp_name (void)
{
@@ -622,22 +593,6 @@ dump_assert (idx_t arg)
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
is_intrinsic (idx_t obj)
{
@@ -649,10 +604,10 @@ is_intrinsic (idx_t obj)
STACK_DECLARE_USAGE (U8)
STACK_PUSH (U8, lexer_get_strings_count ());
STACK_PUSH (U8, lexer_get_literals_count ());
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;
goto cleanup;
@@ -669,131 +624,65 @@ cleanup:
static void
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));
JERRY_ASSERT (dumper);
switch (dumper->args_count)
if (literal_equal_type_s (lexer_get_literal_by_id (obj), "assert"))
{
case 1: dumper->funs.fun1 (arg); return;
default: JERRY_UNREACHABLE ();
dump_assert (arg);
return;
}
}
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
name_to_native_call_id (idx_t obj)
{
JERRY_ASSERT (obj < lexer_get_strings_count ());
for (uint8_t i = 0; i < OPCODE_NATIVE_CALL__COUNT; i++)
if (obj >= lexer_get_literals_count ())
{
if (STACK_ELEMENT (IDX, i) == obj)
{
return i;
}
return OPCODE_NATIVE_CALL__COUNT;
}
JERRY_UNREACHABLE ();
}
static void
free_allocatable_string (prop_as_str_or_varg p)
{
if (p.str.was_num)
if (literal_equal_type_s (lexer_get_literal_by_id (obj), "LEDToggle"))
{
mem_heap_free_block ((uint8_t *) p.str.str.str);
return OPCODE_NATIVE_CALL_LED_TOGGLE;
}
}
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)
else if (literal_equal_type_s (lexer_get_literal_by_id (obj), "LEDOn"))
{
.was_num = true,
.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;
return OPCODE_NATIVE_CALL_LED_ON;
}
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');
str[index] = ECMA_CHAR_NULL;
return (allocatable_string)
else if (literal_equal_type_s (lexer_get_literal_by_id (obj), "LEDOnce"))
{
.was_num = true,
.str = (lp_string)
{
.length = index,
.str = str
}
};
return OPCODE_NATIVE_CALL_LED_ONCE;
}
else if (literal_equal_type_s (lexer_get_literal_by_id (obj), "wait"))
{
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
create_prop_as_str_or_varg (allocatable_string str, prop_type type)
static bool
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,
.str = str
.lit = lit
};
}
@@ -814,21 +703,30 @@ parse_property_name (void)
{
STACK_PUSH (IDX, next_temp_name ());
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;
}
case TOK_NUMBER:
{
STACK_PUSH (IDX, next_temp_name ());
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;
}
case TOK_SMALL_INT:
{
STACK_PUSH (IDX, next_temp_name ());
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;
}
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));
STACK_PUSH (props, create_prop_as_str_or_varg (STACK_TOP (strings), PROP_DATA));
STACK_DROP (strings, 1);
STACK_PUSH (props, create_prop_literal (STACK_TOP (literals), PROP_DATA));
STACK_DROP (literals, 1);
STACK_DROP (IDX, 2);
STACK_CHECK_USAGE (IDX);
@@ -912,7 +810,7 @@ parse_property_assignment (void)
STACK_DECLARE_USAGE (U16)
STACK_DECLARE_USAGE (toks)
STACK_DECLARE_USAGE (U8)
STACK_DECLARE_USAGE (strings)
STACK_DECLARE_USAGE (literals)
if (!token_is (TOK_NAME))
{
@@ -920,7 +818,7 @@ parse_property_assignment (void)
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 ());
skip_newlines ();
@@ -934,8 +832,8 @@ parse_property_assignment (void)
STACK_DROP (toks, 1);
// name, lhs
parse_property_name (); // push name
STACK_PUSH (props, create_prop_as_str_or_varg (STACK_TOP (strings), PROP_GET));
STACK_DROP (strings, 1);
STACK_PUSH (props, create_prop_literal (STACK_TOP (literals), PROP_GET));
STACK_DROP (literals, 1);
skip_newlines ();
parse_argument_list (AL_FUNC_EXPR, next_temp_name ()); // push lhs
@@ -967,7 +865,7 @@ parse_property_assignment (void)
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 ());
skip_newlines ();
@@ -981,8 +879,8 @@ parse_property_assignment (void)
STACK_DROP (toks, 1);
// name, lhs
parse_property_name (); // push name
STACK_PUSH (props, create_prop_as_str_or_varg (STACK_TOP (strings), PROP_SET));
STACK_DROP (strings, 1);
STACK_PUSH (props, create_prop_literal (STACK_TOP (literals), PROP_SET));
STACK_DROP (literals, 1);
skip_newlines ();
parse_argument_list (AL_FUNC_EXPR, next_temp_name ()); // push lhs
@@ -1019,7 +917,7 @@ simple_prop:
parse_property_name_and_value ();
cleanup:
STACK_CHECK_USAGE (strings);
STACK_CHECK_USAGE (literals);
STACK_CHECK_USAGE (U8);
STACK_CHECK_USAGE (toks);
STACK_CHECK_USAGE (U16);
@@ -1029,12 +927,12 @@ cleanup:
static void
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),
ecma_get_magic_string_zt (ECMA_MAGIC_STRING_ARGUMENTS))
|| lp_string_equal_zt (lexer_get_string_by_id (id),
ecma_get_magic_string_zt (ECMA_MAGIC_STRING_EVAL)))
if (literal_equal_type_zt (lexer_get_literal_by_id (id),
ecma_get_magic_string_zt (ECMA_MAGIC_STRING_ARGUMENTS))
|| literal_equal_type_zt (lexer_get_literal_by_id (id),
ecma_get_magic_string_zt (ECMA_MAGIC_STRING_EVAL)))
{
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))
{
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))
{
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",
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))
{
JERRY_ASSERT (STACK_ELEMENT (props, i).type == PROP_DATA
|| STACK_ELEMENT (props, i).type == PROP_GET
|| STACK_ELEMENT (props, i).type == PROP_SET);
const prop_literal previous = STACK_ELEMENT (props, i);
JERRY_ASSERT (previous.type == PROP_DATA
|| previous.type == PROP_GET
|| previous.type == PROP_SET);
for (uint8_t j = from; j < i; j = (uint8_t) (j + 1))
{
/*4*/
const lp_string previous = STACK_ELEMENT (props, j).str.str;
const prop_type prop_type_previous = STACK_ELEMENT (props, j).type;
const lp_string prop_id_desc = STACK_ELEMENT (props, i).str.str;
const prop_type prop_type_prop_id_desc = STACK_ELEMENT (props, i).type;
if (lp_string_equal (previous, prop_id_desc))
const prop_literal current = STACK_ELEMENT (props, j);
JERRY_ASSERT (current.type == PROP_DATA
|| current.type == PROP_GET
|| current.type == PROP_SET);
if (literal_equal (previous.lit, current.lit))
{
/*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",
previous.str);
(const char *) literal_to_zt (current.lit));
}
/*b*/
if (prop_type_previous == PROP_DATA
&& (prop_type_prop_id_desc == PROP_SET || prop_type_prop_id_desc == PROP_GET))
if (previous.type == PROP_DATA
&& (current.type == PROP_SET || current.type == PROP_GET))
{
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*/
if (prop_type_prop_id_desc == PROP_DATA
&& (prop_type_previous == PROP_SET || prop_type_previous == PROP_GET))
if (current.type == PROP_DATA
&& (previous.type == PROP_SET || previous.type == PROP_GET))
{
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*/
if ((prop_type_previous == PROP_SET && prop_type_prop_id_desc == PROP_SET)
|| (prop_type_previous == PROP_GET && prop_type_prop_id_desc == PROP_GET))
if ((previous.type == PROP_SET && current.type == PROP_SET)
|| (previous.type == PROP_GET && current.type == PROP_GET))
{
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);
STACK_PUSH (IDX, token_data ());
STACK_PUSH (props,
create_prop_as_str_or_varg (create_allocatable_string_from_literal (token_data ()),
VARG));
create_prop_literal (lexer_get_literal_by_id (token_data ()),
VARG));
check_for_eval_and_arguments_in_strict_mode (STACK_TOP (IDX));
break;
}
@@ -1358,8 +1262,6 @@ next:
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 (U8, 4);
STACK_DROP (U16, 1);
@@ -1722,13 +1624,28 @@ parse_member_expression (void)
else if (token_is (TOK_DOT))
{
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");
}
STACK_PUSH (IDX, next_temp_name ());
SET_PROP (ID (1));
DUMP_OPCODE_3 (assignment, ID(1), OPCODE_ARG_TYPE_STRING, token_data ());
}
else
{
@@ -1778,7 +1695,7 @@ parse_call_expression (void)
goto cleanup;
}
if (THIS_ARG () < lexer_get_reserved_ids_count ())
if (THIS_ARG () < lexer_get_literals_count ())
{
STACK_PUSH (IDX, next_temp_name ());
DUMP_OPCODE_3 (assignment, ID(1), OPCODE_ARG_TYPE_VARIABLE, THIS_ARG ());
@@ -1899,6 +1816,15 @@ cleanup:
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
: postfix_expression
| ('delete' | 'void' | 'typeof' | '++' | '--' | '+' | '-' | '~' | '!') unary_expression
@@ -1971,17 +1897,31 @@ parse_unary_expression (void)
if (is_keyword (KW_DELETE))
{
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)));
if (LAST_OPCODE_IS (assignment)
@@ -2002,8 +1942,7 @@ parse_unary_expression (void)
}
else
{
STACK_PUSH (IDX, next_temp_name ());
DUMP_OPCODE_3 (assignment, ID (1), OPCODE_ARG_TYPE_SIMPLE, ECMA_SIMPLE_VALUE_TRUE);
dump_boolean_true ();
STACK_SWAP (IDX);
STACK_DROP (IDX, 1);
}
@@ -3769,6 +3708,44 @@ skip_braces (void)
{
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);
@@ -3953,7 +3930,7 @@ preparse_scope (bool is_global)
STACK_PUSH (locs, TOK ().loc);
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);
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 (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 ();
while (!token_is (TOK_EOF) && !token_is (TOK_CLOSE_BRACE))
{
@@ -4050,10 +4034,12 @@ parser_parse_program (void)
JERRY_ASSERT (token_is (TOK_EOF));
DUMP_OPCODE_1 (exitval, 0);
serializer_dump_literals (lexer_get_literals (), lexer_get_literals_count ());
serializer_merge_scopes_into_bytecode ();
serializer_set_scope (NULL);
deserializer_set_strings_buffer (lexer_get_strings_cache ());
scopes_tree_free (STACK_TOP (scopes));
serializer_set_scope (NULL);
STACK_DROP (scopes, 1);
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);
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 (IDX);
STACK_INIT (nestings);
@@ -4100,51 +4077,10 @@ parser_init (const char *source, size_t source_size, bool show_opcodes)
STACK_INIT (locs);
STACK_INIT (scopes);
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);
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
@@ -4162,9 +4098,7 @@ parser_free (void)
STACK_FREE (locs);
STACK_FREE (scopes);
STACK_FREE (props);
STACK_FREE (strings);
HASH_FREE (intrinsics);
STACK_FREE (literals);
serializer_free ();
lexer_free ();
+3 -5
View File
@@ -19,7 +19,7 @@
#include "opcodes.h"
#include "stack.h"
#include "jerry-libc.h"
#include "lp-string.h"
#include "literal.h"
#include "scopes-tree.h"
/* bytecode_data contains identifiers, string and num literals.
@@ -35,11 +35,9 @@
} */
struct
{
const lp_string *strings;
const ecma_number_t *nums;
const literal *literals;
const opcode_t *opcodes;
uint8_t strs_count;
uint8_t nums_count;
uint8_t literals_count;
opcode_counter_t opcodes_count;
}
bytecode_data;
+16 -22
View File
@@ -15,26 +15,21 @@
#include "deserializer.h"
#include "bytecode-data.h"
#include "ecma-helpers.h"
const ecma_char_t *
deserialize_string_by_id (uint8_t id)
const ecma_char_t *strings_buffer;
void
deserializer_set_strings_buffer (const ecma_char_t *s)
{
JERRY_ASSERT (id < bytecode_data.strs_count);
JERRY_ASSERT (bytecode_data.strings[id].str[bytecode_data.strings[id].length] == '\0');
return ((const ecma_char_t *) bytecode_data.strings[id].str);
strings_buffer = s;
}
ecma_number_t
deserialize_num_by_id (uint8_t id)
literal
deserialize_literal_by_id (uint8_t id)
{
JERRY_ASSERT (id >= bytecode_data.strs_count);
id = (uint8_t) (id - bytecode_data.strs_count);
JERRY_ASSERT (id < bytecode_data.nums_count);
return bytecode_data.nums[id];
JERRY_ASSERT (id < bytecode_data.literals_count);
return bytecode_data.literals[id];
}
const void *
@@ -58,25 +53,24 @@ deserialize_opcode (opcode_counter_t oc)
uint8_t
deserialize_min_temp (void)
{
return (uint8_t) (bytecode_data.strs_count + bytecode_data.nums_count);
return bytecode_data.literals_count;
}
void
deserializer_init (void)
{
bytecode_data.strings = NULL;
bytecode_data.nums = NULL;
bytecode_data.literals = NULL;
strings_buffer = NULL;
bytecode_data.opcodes = NULL;
}
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.nums);
mem_heap_free_block ((uint8_t *) bytecode_data.literals);
mem_heap_free_block ((uint8_t *) bytecode_data.opcodes);
}
+3 -2
View File
@@ -19,10 +19,11 @@
#include "globals.h"
#include "ecma-globals.h"
#include "opcodes.h"
#include "literal.h"
void deserializer_init (void);
const ecma_char_t *deserialize_string_by_id (uint8_t);
ecma_number_t deserialize_num_by_id (uint8_t);
void deserializer_set_strings_buffer (const ecma_char_t *);
literal deserialize_literal_by_id (uint8_t);
const void *deserialize_bytecode (void);
opcode_t deserialize_opcode (opcode_counter_t);
uint8_t deserialize_min_temp (void);
+35 -38
View File
@@ -20,6 +20,7 @@
#include "lexer.h"
#include "deserializer.h"
#include "opcodes-native-call.h"
#include "ecma-helpers.h"
#include <stdarg.h>
#define NAME_TO_ID(op) (__op__idx_##op)
@@ -45,43 +46,48 @@ static uint8_t opcode_sizes[] =
};
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
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++)
{
__printf ("%3d ", i);
dump_lp (strings[i]);
dump_literal (lits[i]);
__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 *
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);
if (id / 100 != 0)
@@ -103,28 +109,19 @@ var_id_to_string (char *res, idx_t id)
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);
__strncpy (res, (char *) str.str, str.length);
return (char *) literal_to_zt (lit);
}
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;
}
else
{
int i = 0;
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;
JERRY_UNREACHABLE ();
}
}
@@ -152,7 +149,7 @@ pp_printf (const char *format, ...)
}
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)));
break;
}
+2 -3
View File
@@ -19,11 +19,10 @@
#include "globals.h"
#ifdef JERRY_ENABLE_PP
#include "interpreter.h"
#include "lp-string.h"
#include "literal.h"
void pp_opcode (opcode_counter_t, opcode_t, bool);
void pp_strings (const lp_string *, uint8_t);
void pp_nums (const ecma_number_t *, uint8_t, uint8_t);
void pp_literals (const literal *, uint8_t);
#endif // JERRY_ENABLE_PP
#endif // PRETTY_PRINTER
+4 -8
View File
@@ -37,21 +37,17 @@ serializer_merge_scopes_into_bytecode (void)
void
serializer_dump_strings_and_nums (const lp_string strings[], uint8_t strs_count,
const ecma_number_t nums[], uint8_t nums_count)
serializer_dump_literals (const literal literals[], uint8_t literals_count)
{
#ifdef JERRY_ENABLE_PP
if (print_opcodes)
{
pp_strings (strings, strs_count);
pp_nums (nums, nums_count, strs_count);
pp_literals (literals, literals_count);
}
#endif
bytecode_data.strs_count = strs_count;
bytecode_data.nums_count = nums_count;
bytecode_data.strings = strings;
bytecode_data.nums = nums;
bytecode_data.literals_count = literals_count;
bytecode_data.literals = literals;
}
void
+2 -3
View File
@@ -19,12 +19,11 @@
#include "globals.h"
#include "opcodes.h"
#include "interpreter.h"
#include "lp-string.h"
#include "literal.h"
#include "scopes-tree.h"
void serializer_init (bool show_opcodes);
void serializer_dump_strings_and_nums (const lp_string *, uint8_t,
const ecma_number_t *, uint8_t);
void serializer_dump_literals (const literal *, uint8_t);
void serializer_set_scope (scopes_tree);
void serializer_merge_scopes_into_bytecode (void);
void serializer_dump_opcode (opcode_t);
+10 -1
View File
@@ -14,4 +14,13 @@
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
#include "jerry-libc.h"
#include "literal.h"
#define NAME_TO_ID(op) (__op__idx_##op)
#define __OPCODE_SIZE(name, arg1, arg2, arg3) \
sizeof (__op_##name) + 1,
#define LP(s) (lp_string) { .length = (uint8_t) __strlen(s), .str = (ecma_char_t *) s }
#define LP(s) create_literal_from_str_compute_len (s)
#define NUM(s) create_literal_from_num (s)
static uint8_t opcode_sizes[] = {
OP_LIST (OPCODE_SIZE)
@@ -40,10 +40,10 @@ main( int __unused argc,
mem_init();
serializer_init (false);
const lp_string strings[] = { LP("a"),
LP("b") };
ecma_number_t nums [] = { 2.0 };
serializer_dump_strings_and_nums (strings, 2, nums, 1);
const literal lits[] = { LP("a"),
LP("b"),
NUM(2.0) };
serializer_dump_literals (lits, 3);
init_int( test_program, false);
+8 -8
View File
@@ -172,14 +172,14 @@ main( int __unused argc,
mem_init();
serializer_init (false);
const lp_string strings[] = { LP("a"),
LP("b"),
LP("length"),
LP("1") };
ecma_number_t nums [] = { 2.0,
12.0,
2.5 };
serializer_dump_strings_and_nums (strings, 4, nums, 3);
const literal literals[] = { LP("a"),
LP("b"),
LP("length"),
LP("1"),
NUM(2.0),
NUM(12.0),
NUM(2.5) };
serializer_dump_literals (literals, 7);
init_int( test_program, false);
+4 -4
View File
@@ -45,10 +45,10 @@ main( int __unused argc,
mem_init();
serializer_init (false);
const lp_string strings[] = { LP("a"),
LP("b") };
ecma_number_t nums [] = { 2.0 };
serializer_dump_strings_and_nums (strings, 2, nums, 1);
const literal lits[] = { LP("a"),
LP("b"),
NUM(2.0) };
serializer_dump_literals (lits, 3);
init_int( test_program, false);
+4 -4
View File
@@ -40,10 +40,10 @@ main( int __unused argc,
mem_init();
serializer_init (false);
const lp_string strings[] = { LP("a"),
LP("b") };
ecma_number_t nums [] = { 2.0 };
serializer_dump_strings_and_nums (strings, 2, nums, 1);
const literal lits[] = { LP("a"),
LP("b"),
NUM(2.0) };
serializer_dump_literals (lits, 3);
init_int( test_program, false);
+4 -4
View File
@@ -40,10 +40,10 @@ main( int __unused argc,
mem_init();
serializer_init (false);
const lp_string strings[] = { LP("a"),
LP("b") };
ecma_number_t nums [] = { 2.0 };
serializer_dump_strings_and_nums (strings, 2, nums, 1);
const literal lits[] = { LP("a"),
LP("b"),
NUM(2.0) };
serializer_dump_literals (lits, 3);
init_int( test_program, false);
+1 -1
View File
@@ -33,7 +33,7 @@ main( int __unused argc,
mem_init();
deserializer_init ();
parser_init (program, __strlen (program), false);
parser_init (program, __strlen (program), true);
parser_parse_program ();
parser_free ();
+4 -4
View File
@@ -40,10 +40,10 @@ main( int __unused argc,
mem_init();
serializer_init (false);
const lp_string strings[] = { LP("a"),
LP("b") };
ecma_number_t nums [] = { 2.0 };
serializer_dump_strings_and_nums (strings, 2, nums, 1);
const literal lits[] = { LP("a"),
LP("b"),
NUM(2.0) };
serializer_dump_literals (lits, 3);
init_int( test_program, false);
+4 -4
View File
@@ -40,10 +40,10 @@ main( int __unused argc,
mem_init();
serializer_init (false);
const lp_string strings[] = { LP("a"),
LP("b") };
ecma_number_t nums [] = { 2.0 };
serializer_dump_strings_and_nums (strings, 2, nums, 1);
const literal lits[] = { LP("a"),
LP("b"),
NUM(2.0) };
serializer_dump_literals (lits, 3);
init_int( test_program, false);
+5 -5
View File
@@ -53,11 +53,11 @@ main( int __unused argc,
mem_init();
serializer_init (false);
const lp_string strings[] = { LP("a"),
LP("b"),
LP("c") };
ecma_number_t nums [] = { 2.0 };
serializer_dump_strings_and_nums (strings, 3, nums, 1);
const literal lits[] = { LP("a"),
LP("b"),
LP("c"),
NUM(2.0) };
serializer_dump_literals (lits, 4);
init_int( test_program, false);
@@ -38,10 +38,10 @@ main( int __unused argc,
mem_init();
serializer_init (false);
const lp_string strings[] = { LP("a"),
LP("b") };
ecma_number_t nums [] = { 2.0 };
serializer_dump_strings_and_nums (strings, 2, nums, 1);
const literal lits[] = { LP("a"),
LP("b"),
NUM(2.0) };
serializer_dump_literals (lits, 3);
init_int( test_program, false);