mirror of
https://github.com/jerryscript-project/jerryscript.git
synced 2025-12-15 16:29:21 +00:00
Remove parser_init / parser_free interfaces (corresponding actions are now performed in parser_parse_program); introduce boolean return value in parser invocation interfaces that would indicate whether SyntaxError was raised during parse.
JerryScript-DCO-1.0-Signed-off-by: Ruben Ayrapetyan r.ayrapetyan@samsung.com
This commit is contained in:
parent
2bf25f10eb
commit
4e563932f1
@ -15,6 +15,7 @@
|
||||
|
||||
#include "ecma-alloc.h"
|
||||
#include "ecma-conversion.h"
|
||||
#include "ecma-exceptions.h"
|
||||
#include "ecma-gc.h"
|
||||
#include "ecma-function-object.h"
|
||||
#include "ecma-lex-env.h"
|
||||
@ -130,52 +131,55 @@ ecma_builtin_function_dispatch_construct (const ecma_value_t *arguments_list_p,
|
||||
zt_string_buffer_pos += sz;
|
||||
}
|
||||
|
||||
parser_init ();
|
||||
const opcode_t* opcodes_p;
|
||||
bool is_syntax_correct;
|
||||
|
||||
/*
|
||||
* FIXME:
|
||||
* Handle syntax errors
|
||||
*/
|
||||
parser_parse_new_function ((const char **) zt_string_params_p, params_count);
|
||||
const opcode_t* opcodes_p = (const opcode_t*) serializer_get_bytecode ();
|
||||
serializer_print_opcodes ();
|
||||
parser_free ();
|
||||
is_syntax_correct = parser_parse_new_function ((const char **) zt_string_params_p,
|
||||
params_count,
|
||||
&opcodes_p);
|
||||
|
||||
bool is_strict = false;
|
||||
bool do_instantiate_arguments_object = true;
|
||||
|
||||
opcode_scope_code_flags_t scope_flags = vm_get_scope_flags (opcodes_p,
|
||||
0);
|
||||
|
||||
if (scope_flags & OPCODE_SCOPE_CODE_FLAGS_STRICT)
|
||||
if (!is_syntax_correct)
|
||||
{
|
||||
is_strict = true;
|
||||
ret_value = ecma_make_throw_obj_completion_value (ecma_new_standard_error (ECMA_ERROR_SYNTAX));
|
||||
}
|
||||
|
||||
if ((scope_flags & OPCODE_SCOPE_CODE_FLAGS_NOT_REF_ARGUMENTS_IDENTIFIER)
|
||||
&& (scope_flags & OPCODE_SCOPE_CODE_FLAGS_NOT_REF_EVAL_IDENTIFIER))
|
||||
else
|
||||
{
|
||||
/* the code doesn't use 'arguments' identifier
|
||||
* and doesn't perform direct call to eval,
|
||||
* so Arguments object can't be referenced */
|
||||
do_instantiate_arguments_object = false;
|
||||
bool is_strict = false;
|
||||
bool do_instantiate_arguments_object = true;
|
||||
|
||||
opcode_scope_code_flags_t scope_flags = vm_get_scope_flags (opcodes_p,
|
||||
0);
|
||||
|
||||
if (scope_flags & OPCODE_SCOPE_CODE_FLAGS_STRICT)
|
||||
{
|
||||
is_strict = true;
|
||||
}
|
||||
|
||||
if ((scope_flags & OPCODE_SCOPE_CODE_FLAGS_NOT_REF_ARGUMENTS_IDENTIFIER)
|
||||
&& (scope_flags & OPCODE_SCOPE_CODE_FLAGS_NOT_REF_EVAL_IDENTIFIER))
|
||||
{
|
||||
/* the code doesn't use 'arguments' identifier
|
||||
* and doesn't perform direct call to eval,
|
||||
* so Arguments object can't be referenced */
|
||||
do_instantiate_arguments_object = false;
|
||||
}
|
||||
|
||||
/* 11. */
|
||||
ecma_object_t *glob_lex_env_p = ecma_get_global_environment ();
|
||||
|
||||
ecma_object_t *func_obj_p = ecma_op_create_function_object (params_count > 1u ? string_params_p : NULL,
|
||||
(ecma_length_t) (params_count - 1u),
|
||||
glob_lex_env_p,
|
||||
is_strict,
|
||||
do_instantiate_arguments_object,
|
||||
opcodes_p,
|
||||
1);
|
||||
|
||||
ecma_deref_object (glob_lex_env_p);
|
||||
|
||||
ret_value = ecma_make_normal_completion_value (ecma_make_object_value (func_obj_p));
|
||||
}
|
||||
|
||||
/* 11. */
|
||||
ecma_object_t *glob_lex_env_p = ecma_get_global_environment ();
|
||||
|
||||
ecma_object_t *func_obj_p = ecma_op_create_function_object (params_count > 1u ? string_params_p : NULL,
|
||||
(ecma_length_t) (params_count - 1u),
|
||||
glob_lex_env_p,
|
||||
is_strict,
|
||||
do_instantiate_arguments_object,
|
||||
opcodes_p,
|
||||
1);
|
||||
|
||||
ecma_deref_object (glob_lex_env_p);
|
||||
|
||||
ret_value = ecma_make_normal_completion_value (ecma_make_object_value (func_obj_p));
|
||||
|
||||
MEM_FINALIZE_LOCAL_ARRAY (zt_string_buffer_p);
|
||||
MEM_FINALIZE_LOCAL_ARRAY (zt_string_params_p);
|
||||
}
|
||||
|
||||
@ -86,22 +86,12 @@ ecma_op_eval_chars_buffer (const ecma_char_t *code_p, /**< code characters buffe
|
||||
|
||||
ecma_completion_value_t completion;
|
||||
|
||||
parser_init ();
|
||||
bool is_syntax_correct = parser_parse_eval ((const char *) code_p, code_buffer_size);
|
||||
const opcode_t* opcodes_p = (const opcode_t*) serializer_get_bytecode ();
|
||||
serializer_print_opcodes ();
|
||||
parser_free ();
|
||||
const opcode_t *opcodes_p;
|
||||
bool is_syntax_correct;
|
||||
|
||||
opcode_counter_t first_opcode_index = 0u;
|
||||
bool is_strict_prologue = false;
|
||||
opcode_scope_code_flags_t scope_flags = vm_get_scope_flags (opcodes_p,
|
||||
first_opcode_index++);
|
||||
if (scope_flags & OPCODE_SCOPE_CODE_FLAGS_STRICT)
|
||||
{
|
||||
is_strict_prologue = true;
|
||||
}
|
||||
|
||||
bool is_strict = (is_strict_prologue || (is_direct && is_called_from_strict_mode_code));
|
||||
is_syntax_correct = parser_parse_eval ((const char *) code_p,
|
||||
code_buffer_size,
|
||||
&opcodes_p);
|
||||
|
||||
if (!is_syntax_correct)
|
||||
{
|
||||
@ -109,6 +99,17 @@ ecma_op_eval_chars_buffer (const ecma_char_t *code_p, /**< code characters buffe
|
||||
}
|
||||
else
|
||||
{
|
||||
opcode_counter_t first_opcode_index = 0u;
|
||||
bool is_strict_prologue = false;
|
||||
opcode_scope_code_flags_t scope_flags = vm_get_scope_flags (opcodes_p,
|
||||
first_opcode_index++);
|
||||
if (scope_flags & OPCODE_SCOPE_CODE_FLAGS_STRICT)
|
||||
{
|
||||
is_strict_prologue = true;
|
||||
}
|
||||
|
||||
bool is_strict = (is_strict_prologue || (is_direct && is_called_from_strict_mode_code));
|
||||
|
||||
ecma_value_t this_binding;
|
||||
ecma_object_t *lex_env_p;
|
||||
|
||||
|
||||
@ -1244,6 +1244,9 @@ jerry_reg_err_callback (jerry_error_callback_t callback) /**< pointer to callbac
|
||||
|
||||
/**
|
||||
* Parse script for specified context
|
||||
*
|
||||
* @return true - if script was parsed successfully,
|
||||
* false - otherwise (SyntaxError was raised).
|
||||
*/
|
||||
bool
|
||||
jerry_parse (const char* source_p, /**< script source */
|
||||
@ -1254,13 +1257,18 @@ jerry_parse (const char* source_p, /**< script source */
|
||||
bool is_show_opcodes = ((jerry_flags & JERRY_FLAG_SHOW_OPCODES) != 0);
|
||||
|
||||
parser_set_show_opcodes (is_show_opcodes);
|
||||
parser_init ();
|
||||
parser_parse_script (source_p, source_size);
|
||||
|
||||
const opcode_t* opcodes = (const opcode_t*) serializer_get_bytecode ();
|
||||
const opcode_t *opcodes_p;
|
||||
bool is_syntax_correct;
|
||||
|
||||
serializer_print_opcodes ();
|
||||
parser_free ();
|
||||
is_syntax_correct = parser_parse_script (source_p,
|
||||
source_size,
|
||||
&opcodes_p);
|
||||
|
||||
if (!is_syntax_correct)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef MEM_STATS
|
||||
if (jerry_flags & JERRY_FLAG_MEM_STATS_SEPARATE)
|
||||
@ -1272,7 +1280,7 @@ jerry_parse (const char* source_p, /**< script source */
|
||||
|
||||
bool is_show_mem_stats_per_opcode = ((jerry_flags & JERRY_FLAG_MEM_STATS_PER_OPCODE) != 0);
|
||||
|
||||
vm_init (opcodes, is_show_mem_stats_per_opcode);
|
||||
vm_init (opcodes_p, is_show_mem_stats_per_opcode);
|
||||
|
||||
return true;
|
||||
} /* jerry_parse */
|
||||
|
||||
@ -2878,25 +2878,44 @@ parse_source_element_list (bool is_global) /**< flag indicating if we are parsin
|
||||
* program
|
||||
* : LT!* source_element_list LT!* EOF!
|
||||
* ;
|
||||
*
|
||||
* @return true - if parse finished successfully (no SyntaxError was raised);
|
||||
* false - otherwise.
|
||||
*/
|
||||
static void
|
||||
parser_parse_program (const char *source, /**< source code buffer */
|
||||
static bool
|
||||
parser_parse_program (const char *source_p, /**< source code buffer */
|
||||
size_t source_size, /**< source code size in bytes */
|
||||
bool in_new_function) /**< flag indicating if we are parsing body of a function */
|
||||
bool in_function, /**< flag indicating if we are parsing body of a function */
|
||||
bool in_eval, /**< flag indicating if we are parsing body of eval code */
|
||||
const opcode_t **out_opcodes_p) /**< out: generated byte-code array
|
||||
* (in case there were no syntax errors) */
|
||||
{
|
||||
lexer_init_source (source, source_size);
|
||||
JERRY_ASSERT (out_opcodes_p != NULL);
|
||||
|
||||
inside_function = in_function;
|
||||
inside_eval = in_eval;
|
||||
|
||||
lexer_init (parser_show_opcodes);
|
||||
lexer_init_source (source_p, source_size);
|
||||
|
||||
serializer_set_show_opcodes (parser_show_opcodes);
|
||||
dumper_init ();
|
||||
syntax_init ();
|
||||
|
||||
STACK_INIT (scopes);
|
||||
STACK_PUSH (scopes, scopes_tree_init (NULL));
|
||||
serializer_set_scope (STACK_TOP (scopes));
|
||||
lexer_set_strict_mode (scopes_tree_strict_mode (STACK_TOP (scopes)));
|
||||
|
||||
jsp_label_init ();
|
||||
|
||||
skip_newlines ();
|
||||
parse_source_element_list (true);
|
||||
|
||||
skip_newlines ();
|
||||
JERRY_ASSERT (token_is (TOK_EOF));
|
||||
|
||||
if (in_new_function)
|
||||
if (in_function)
|
||||
{
|
||||
dump_ret ();
|
||||
}
|
||||
@ -2909,41 +2928,50 @@ parser_parse_program (const char *source, /**< source code buffer */
|
||||
dump_exit ();
|
||||
}
|
||||
|
||||
serializer_dump_literals ();
|
||||
serializer_merge_scopes_into_bytecode ();
|
||||
serializer_set_scope (NULL);
|
||||
jsp_label_finalize ();
|
||||
syntax_free ();
|
||||
lexer_free ();
|
||||
|
||||
*out_opcodes_p = serializer_merge_scopes_into_bytecode ();
|
||||
|
||||
dumper_free ();
|
||||
|
||||
serializer_set_scope (NULL);
|
||||
scopes_tree_free (STACK_TOP (scopes));
|
||||
STACK_DROP (scopes, 1);
|
||||
STACK_FREE (scopes);
|
||||
|
||||
return true;
|
||||
} /* parser_parse_program */
|
||||
|
||||
/**
|
||||
* Parse source script
|
||||
*
|
||||
* @return true - if parse finished successfully (no SyntaxError were raised);
|
||||
* false - otherwise.
|
||||
*/
|
||||
void
|
||||
bool
|
||||
parser_parse_script (const char *source, /**< source script */
|
||||
size_t source_size) /**< source script size it bytes */
|
||||
size_t source_size, /**< source script size it bytes */
|
||||
const opcode_t **opcodes_p) /**< out: generated byte-code array
|
||||
* (in case there were no syntax errors) */
|
||||
{
|
||||
inside_eval = false;
|
||||
inside_function = false;
|
||||
parser_parse_program (source, source_size, false);
|
||||
return parser_parse_program (source, source_size, false, false, opcodes_p);
|
||||
} /* parser_parse_script */
|
||||
|
||||
/**
|
||||
* Parse string passed to eval() call
|
||||
*
|
||||
* @return true if parse succeeds
|
||||
* false otherwise
|
||||
* @return true - if parse finished successfully (no SyntaxError were raised);
|
||||
* false - otherwise.
|
||||
*/
|
||||
bool parser_parse_eval (const char *source, /**< string passed to eval() */
|
||||
size_t source_size) /**< string size in bytes */
|
||||
bool
|
||||
parser_parse_eval (const char *source, /**< string passed to eval() */
|
||||
size_t source_size, /**< string size in bytes */
|
||||
const opcode_t **opcodes_p) /**< out: generated byte-code array
|
||||
* (in case there were no syntax errors) */
|
||||
{
|
||||
TODO (implement syntax error processing);
|
||||
|
||||
inside_eval = true;
|
||||
inside_function = false;
|
||||
parser_parse_program (source, source_size, false);
|
||||
return true;
|
||||
return parser_parse_program (source, source_size, false, true, opcodes_p);
|
||||
} /* parser_parse_eval */
|
||||
|
||||
/**
|
||||
@ -2952,14 +2980,16 @@ bool parser_parse_eval (const char *source, /**< string passed to eval() */
|
||||
* NOTE: Array of arguments should contain at least one element.
|
||||
* In case of new Function() call without parameters, empty string should be passed as argument to this
|
||||
* function.
|
||||
*
|
||||
* @return true - if parse finished successfully (no SyntaxError were raised);
|
||||
* false - otherwise.
|
||||
*/
|
||||
void
|
||||
bool
|
||||
parser_parse_new_function (const char **params, /**< array of arguments of new Function (p1, p2, ..., pn, body) call */
|
||||
size_t params_count) /**< total number of arguments passed to new Function (...) */
|
||||
size_t params_count, /**< total number of arguments passed to new Function (...) */
|
||||
const opcode_t **out_opcodes_p) /**< out: generated byte-code array
|
||||
* (in case there were no syntax errors) */
|
||||
{
|
||||
inside_eval = false;
|
||||
inside_function = true;
|
||||
|
||||
// Process arguments
|
||||
JERRY_ASSERT (params_count > 0);
|
||||
for (size_t i = 0; i < params_count - 1; ++i)
|
||||
@ -2967,22 +2997,9 @@ parser_parse_new_function (const char **params, /**< array of arguments of new F
|
||||
FIXME ("check parameter's name for syntax errors");
|
||||
lit_find_or_create_literal_from_charset ((ecma_char_t *) params[i], (ecma_length_t) strlen (params[i]));
|
||||
}
|
||||
parser_parse_program (params[params_count - 1], strlen (params[params_count - 1]), true);
|
||||
return parser_parse_program (params[params_count - 1], strlen (params[params_count - 1]), true, false, out_opcodes_p);
|
||||
} /* parser_parse_new_function */
|
||||
|
||||
void
|
||||
parser_init ()
|
||||
{
|
||||
lexer_init (parser_show_opcodes);
|
||||
serializer_set_show_opcodes (parser_show_opcodes);
|
||||
dumper_init ();
|
||||
syntax_init ();
|
||||
|
||||
STACK_INIT (scopes);
|
||||
|
||||
jsp_label_init ();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell parser to dump bytecode
|
||||
*/
|
||||
@ -2991,15 +3008,3 @@ parser_set_show_opcodes (bool show_opcodes) /**< flag indicating if to dump byte
|
||||
{
|
||||
parser_show_opcodes = show_opcodes;
|
||||
} /* parser_set_show_opcodes */
|
||||
|
||||
void
|
||||
parser_free (void)
|
||||
{
|
||||
jsp_label_finalize ();
|
||||
|
||||
STACK_FREE (scopes);
|
||||
|
||||
syntax_free ();
|
||||
dumper_free ();
|
||||
lexer_free ();
|
||||
}
|
||||
|
||||
@ -18,11 +18,9 @@
|
||||
|
||||
#include "jrt.h"
|
||||
|
||||
void parser_init ();
|
||||
void parser_set_show_opcodes (bool);
|
||||
void parser_parse_script (const char *, size_t);
|
||||
bool parser_parse_eval (const char *, size_t);
|
||||
void parser_parse_new_function (const char **, size_t);
|
||||
void parser_free (void);
|
||||
bool parser_parse_script (const char *, size_t, const opcode_t **);
|
||||
bool parser_parse_eval (const char *, size_t, const opcode_t **);
|
||||
bool parser_parse_new_function (const char **, size_t, const opcode_t **);
|
||||
|
||||
#endif
|
||||
#endif /* PARSER_H */
|
||||
|
||||
@ -23,6 +23,10 @@ static scopes_tree current_scope;
|
||||
static array_list bytecodes_cache; /**< storage of pointers to byetecodes */
|
||||
static bool print_opcodes;
|
||||
|
||||
static void
|
||||
serializer_print_opcodes (const opcode_t *opcodes_p,
|
||||
size_t opcodes_count);
|
||||
|
||||
op_meta
|
||||
serializer_get_op_meta (opcode_counter_t oc)
|
||||
{
|
||||
@ -63,13 +67,6 @@ serializer_get_literal_cp_by_uid (uint8_t id, /**< literal idx */
|
||||
return lit_id_hash_table_lookup (lit_id_hash, id, oc);
|
||||
} /* serializer_get_literal_cp_by_uid */
|
||||
|
||||
const void *
|
||||
serializer_get_bytecode (void)
|
||||
{
|
||||
JERRY_ASSERT (bytecode_data.opcodes != NULL);
|
||||
return bytecode_data.opcodes;
|
||||
}
|
||||
|
||||
void
|
||||
serializer_set_strings_buffer (const ecma_char_t *s)
|
||||
{
|
||||
@ -82,7 +79,7 @@ serializer_set_scope (scopes_tree new_scope)
|
||||
current_scope = new_scope;
|
||||
}
|
||||
|
||||
void
|
||||
const opcode_t *
|
||||
serializer_merge_scopes_into_bytecode (void)
|
||||
{
|
||||
bytecode_data.opcodes_count = scopes_tree_count_opcodes (current_scope);
|
||||
@ -90,17 +87,14 @@ serializer_merge_scopes_into_bytecode (void)
|
||||
(size_t) bytecode_data.opcodes_count / BLOCK_SIZE + 1);
|
||||
bytecode_data.opcodes = scopes_tree_raw_data (current_scope, lit_id_hash);
|
||||
bytecodes_cache = array_list_append (bytecodes_cache, &bytecode_data.opcodes);
|
||||
}
|
||||
|
||||
void
|
||||
serializer_dump_literals (void)
|
||||
{
|
||||
#ifdef JERRY_ENABLE_PRETTY_PRINTER
|
||||
if (print_opcodes)
|
||||
{
|
||||
lit_dump_literals ();
|
||||
serializer_print_opcodes (bytecode_data.opcodes, bytecode_data.opcodes_count);
|
||||
}
|
||||
#endif
|
||||
|
||||
return bytecode_data.opcodes;
|
||||
}
|
||||
|
||||
void
|
||||
@ -149,24 +143,16 @@ serializer_rewrite_op_meta (const opcode_counter_t loc, op_meta op)
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
serializer_print_opcodes (void)
|
||||
static void
|
||||
serializer_print_opcodes (const opcode_t *opcodes_p,
|
||||
size_t opcodes_count)
|
||||
{
|
||||
#ifdef JERRY_ENABLE_PRETTY_PRINTER
|
||||
opcode_counter_t loc;
|
||||
|
||||
if (!print_opcodes)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
printf ("AFTER OPTIMIZER:\n");
|
||||
|
||||
for (loc = 0; loc < bytecode_data.opcodes_count; loc++)
|
||||
for (opcode_counter_t loc = 0; loc < opcodes_count; loc++)
|
||||
{
|
||||
op_meta opm;
|
||||
|
||||
opm.op = bytecode_data.opcodes[loc];
|
||||
opm.op = opcodes_p[loc];
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
opm.lit_id[i] = NOT_A_LITERAL;
|
||||
@ -174,6 +160,9 @@ serializer_print_opcodes (void)
|
||||
|
||||
pp_op_meta (loc, opm, false);
|
||||
}
|
||||
#else
|
||||
(void) opcodes_p;
|
||||
(void) opcodes_count;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -27,17 +27,14 @@ void serializer_set_show_opcodes (bool show_opcodes);
|
||||
op_meta serializer_get_op_meta (opcode_counter_t);
|
||||
opcode_t serializer_get_opcode (opcode_counter_t);
|
||||
lit_cpointer_t serializer_get_literal_cp_by_uid (uint8_t, const opcode_t*, opcode_counter_t);
|
||||
const void *serializer_get_bytecode (void);
|
||||
void serializer_set_strings_buffer (const ecma_char_t *);
|
||||
void serializer_dump_literals ();
|
||||
void serializer_set_scope (scopes_tree);
|
||||
void serializer_merge_scopes_into_bytecode (void);
|
||||
const opcode_t *serializer_merge_scopes_into_bytecode (void);
|
||||
void serializer_dump_op_meta (op_meta);
|
||||
opcode_counter_t serializer_get_current_opcode_counter (void);
|
||||
opcode_counter_t serializer_count_opcodes_in_subscopes (void);
|
||||
void serializer_set_writing_position (opcode_counter_t);
|
||||
void serializer_rewrite_op_meta (opcode_counter_t, op_meta);
|
||||
void serializer_print_opcodes (void);
|
||||
void serializer_free (void);
|
||||
|
||||
#endif // SERIALIZER_H
|
||||
|
||||
@ -74,12 +74,15 @@ main (int __attr_unused___ argc,
|
||||
char program[] = "a=1;var a;";
|
||||
bool is_ok;
|
||||
|
||||
const opcode_t *opcodes_p;
|
||||
bool is_syntax_correct;
|
||||
|
||||
mem_init ();
|
||||
serializer_init ();
|
||||
parser_set_show_opcodes (true);
|
||||
parser_init ();
|
||||
parser_parse_script (program, strlen (program));
|
||||
parser_free ();
|
||||
is_syntax_correct = parser_parse_script (program, strlen (program), &opcodes_p);
|
||||
|
||||
JERRY_ASSERT (is_syntax_correct);
|
||||
|
||||
opcode_t opcodes[] =
|
||||
{
|
||||
@ -94,7 +97,7 @@ main (int __attr_unused___ argc,
|
||||
getop_exitval (0) // exit 0;
|
||||
};
|
||||
|
||||
if (!opcodes_equal ((const opcode_t *) serializer_get_bytecode (), opcodes, 5))
|
||||
if (!opcodes_equal (opcodes_p, opcodes, 5))
|
||||
{
|
||||
is_ok = false;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user