Add support for eval in parser.
JerryScript-DCO-1.0-Signed-off-by: Andrey Shitov a.shitov@samsung.com
This commit is contained in:
committed by
Ruben Ayrapetyan
parent
57c6c377af
commit
3577261261
@@ -20,6 +20,8 @@
|
|||||||
#include "ecma-globals.h"
|
#include "ecma-globals.h"
|
||||||
#include "ecma-helpers.h"
|
#include "ecma-helpers.h"
|
||||||
#include "ecma-lex-env.h"
|
#include "ecma-lex-env.h"
|
||||||
|
#include "parser.h"
|
||||||
|
#include "serializer.h"
|
||||||
#include "vm.h"
|
#include "vm.h"
|
||||||
|
|
||||||
/** \addtogroup ecma ECMA
|
/** \addtogroup ecma ECMA
|
||||||
@@ -54,15 +56,15 @@ ecma_op_eval (ecma_string_t *code_p, /**< code string */
|
|||||||
buf_size);
|
buf_size);
|
||||||
JERRY_ASSERT (buffer_size_req == buf_size);
|
JERRY_ASSERT (buffer_size_req == buf_size);
|
||||||
|
|
||||||
// FIXME: Get parser feedback about syntax correctness
|
parser_init ();
|
||||||
bool is_syntax_correct = true;
|
bool is_syntax_correct = parser_parse_eval ((const char *) code_p, (size_t) buf_size);
|
||||||
bool is_strict_prologue;
|
const opcode_t* opcodes_p = (const opcode_t*) serializer_get_bytecode ();
|
||||||
|
serializer_print_opcodes ();
|
||||||
// FIXME: Call parser
|
parser_free ();
|
||||||
JERRY_UNIMPLEMENTED ("eval operation is not implemented");
|
|
||||||
|
|
||||||
// FIXME:
|
// FIXME:
|
||||||
is_strict_prologue = false;
|
bool is_strict_prologue = false;
|
||||||
|
(void) is_strict_prologue;
|
||||||
|
|
||||||
if (!is_syntax_correct)
|
if (!is_syntax_correct)
|
||||||
{
|
{
|
||||||
@@ -95,6 +97,7 @@ ecma_op_eval (ecma_string_t *code_p, /**< code string */
|
|||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Call interpreter
|
// FIXME: Call interpreter
|
||||||
|
(void) opcodes_p;
|
||||||
completion = ecma_make_return_completion_value (ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED));
|
completion = ecma_make_return_completion_value (ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED));
|
||||||
JERRY_UNIMPLEMENTED ("eval operation is not implemented");
|
JERRY_UNIMPLEMENTED ("eval operation is not implemented");
|
||||||
|
|
||||||
|
|||||||
@@ -1215,8 +1215,9 @@ jerry_parse (const char* source_p, /**< script source */
|
|||||||
|
|
||||||
bool is_show_opcodes = ((jerry_flags & JERRY_FLAG_SHOW_OPCODES) != 0);
|
bool is_show_opcodes = ((jerry_flags & JERRY_FLAG_SHOW_OPCODES) != 0);
|
||||||
|
|
||||||
parser_init (source_p, source_size, is_show_opcodes);
|
parser_set_show_opcodes (is_show_opcodes);
|
||||||
parser_parse_program ();
|
parser_init ();
|
||||||
|
parser_parse_script (source_p, source_size);
|
||||||
|
|
||||||
const opcode_t* opcodes = (const opcode_t*) serializer_get_bytecode ();
|
const opcode_t* opcodes = (const opcode_t*) serializer_get_bytecode ();
|
||||||
|
|
||||||
|
|||||||
@@ -34,12 +34,30 @@
|
|||||||
*/
|
*/
|
||||||
#define BLOCK_SIZE 64
|
#define BLOCK_SIZE 64
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pointer to lit_id_hash_table precedes every independent bytecode region
|
||||||
|
*/
|
||||||
|
typedef struct __attribute__ ((aligned (MEM_ALIGNMENT)))
|
||||||
|
{
|
||||||
|
lit_id_hash_table *lit_id_hash;
|
||||||
|
} opcodes_header_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
const ecma_char_t *strings_buffer;
|
const ecma_char_t *strings_buffer;
|
||||||
const opcode_t *opcodes;
|
const opcode_t *opcodes;
|
||||||
lit_id_hash_table *lit_id_hash;
|
|
||||||
opcode_counter_t opcodes_count;
|
opcode_counter_t opcodes_count;
|
||||||
} bytecode_data_t;
|
} bytecode_data_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Macros to get a hash table corresponding to a bytecode region
|
||||||
|
*/
|
||||||
|
#define GET_HASH_TABLE_FOR_BYTECODE(opcodes) (((opcodes_header_t *) (((uint8_t *) (opcodes)) - \
|
||||||
|
sizeof (opcodes_header_t)))->lit_id_hash)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Macros to get a pointer to bytecode header by pointer to opcodes start
|
||||||
|
*/
|
||||||
|
#define GET_BYTECODE_HEADER(opcodes) ((opcodes_header_t *) (((uint8_t *) (opcodes)) - sizeof (opcodes_header_t)))
|
||||||
|
|
||||||
#endif // BYTECODE_DATA_H
|
#endif // BYTECODE_DATA_H
|
||||||
|
|||||||
@@ -1466,26 +1466,37 @@ lexer_are_tokens_with_same_identifier (token id1, /**< identifier token (TOK_NAM
|
|||||||
return (id1.uid == id2.uid);
|
return (id1.uid == id2.uid);
|
||||||
} /* lexer_are_tokens_with_same_identifier */
|
} /* lexer_are_tokens_with_same_identifier */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize lexer to start parsing of a new source
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
lexer_init (const char *source, size_t source_size, bool show_opcodes)
|
lexer_init_source (const char *source, /**< script source */
|
||||||
|
size_t source_size) /**< script source size in bytes */
|
||||||
|
{
|
||||||
|
saved_token = prev_token = sent_token = empty_token;
|
||||||
|
|
||||||
|
buffer_size = source_size;
|
||||||
|
lexer_set_source (source);
|
||||||
|
lexer_set_strict_mode (false);
|
||||||
|
} /* lexer_init_source */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Intitialize lexer
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
lexer_init (bool show_opcodes) /**< flag indicating if to dump opcodes */
|
||||||
{
|
{
|
||||||
empty_token.type = TOK_EMPTY;
|
empty_token.type = TOK_EMPTY;
|
||||||
empty_token.uid = 0;
|
empty_token.uid = 0;
|
||||||
empty_token.loc = 0;
|
empty_token.loc = 0;
|
||||||
|
|
||||||
saved_token = prev_token = sent_token = empty_token;
|
|
||||||
|
|
||||||
#ifndef JERRY_NDEBUG
|
#ifndef JERRY_NDEBUG
|
||||||
allow_dump_lines = show_opcodes;
|
allow_dump_lines = show_opcodes;
|
||||||
#else /* JERRY_NDEBUG */
|
#else /* JERRY_NDEBUG */
|
||||||
(void) show_opcodes;
|
(void) show_opcodes;
|
||||||
allow_dump_lines = false;
|
allow_dump_lines = false;
|
||||||
#endif /* JERRY_NDEBUG */
|
#endif /* JERRY_NDEBUG */
|
||||||
|
} /* lexer_init */
|
||||||
buffer_size = source_size;
|
|
||||||
lexer_set_source (source);
|
|
||||||
lexer_set_strict_mode (false);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
lexer_free (void)
|
lexer_free (void)
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
#include "lit-literal.h"
|
#include "lit-literal.h"
|
||||||
|
|
||||||
#define INVALID_VALUE 255
|
#define INVALID_VALUE 255
|
||||||
|
#define EVAL_RET_VALUE 128
|
||||||
#define INVALID_LITERAL (rcs_cpointer_t::null_cp ())
|
#define INVALID_LITERAL (rcs_cpointer_t::null_cp ())
|
||||||
|
|
||||||
/* Keywords. */
|
/* Keywords. */
|
||||||
@@ -168,7 +169,8 @@ typedef struct
|
|||||||
*/
|
*/
|
||||||
#define TOKEN_EMPTY_INITIALIZER {0, TOK_EMPTY, 0}
|
#define TOKEN_EMPTY_INITIALIZER {0, TOK_EMPTY, 0}
|
||||||
|
|
||||||
void lexer_init (const char *, size_t, bool);
|
void lexer_init (bool);
|
||||||
|
void lexer_init_source (const char *, size_t);
|
||||||
void lexer_free (void);
|
void lexer_free (void);
|
||||||
|
|
||||||
token lexer_next_token (void);
|
token lexer_next_token (void);
|
||||||
|
|||||||
@@ -695,6 +695,22 @@ literal_operand (lit_cpointer_t lit_cp)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates operand for eval's return value
|
||||||
|
*
|
||||||
|
* @return constructed operand
|
||||||
|
*/
|
||||||
|
operand
|
||||||
|
eval_ret_operand (void)
|
||||||
|
{
|
||||||
|
operand ret;
|
||||||
|
|
||||||
|
ret.type = OPERAND_TMP;
|
||||||
|
ret.data.uid = EVAL_RET_VALUE;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
} /* eval_ret_operand */
|
||||||
|
|
||||||
bool
|
bool
|
||||||
operand_is_empty (operand op)
|
operand_is_empty (operand op)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ typedef enum __attr_packed___
|
|||||||
|
|
||||||
operand empty_operand (void);
|
operand empty_operand (void);
|
||||||
operand literal_operand (lit_cpointer_t);
|
operand literal_operand (lit_cpointer_t);
|
||||||
|
operand eval_ret_operand (void);
|
||||||
bool operand_is_empty (operand);
|
bool operand_is_empty (operand);
|
||||||
|
|
||||||
void dumper_init (void);
|
void dumper_init (void);
|
||||||
|
|||||||
+176
-34
@@ -30,7 +30,27 @@
|
|||||||
#include "opcodes-dumper.h"
|
#include "opcodes-dumper.h"
|
||||||
#include "serializer.h"
|
#include "serializer.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flag, indicating whether result of expression
|
||||||
|
* evaluation should be stored to 'eval result'
|
||||||
|
* temporary variable.
|
||||||
|
*
|
||||||
|
* In other words, the flag indicates whether
|
||||||
|
* 'eval result' store code should be dumped.
|
||||||
|
*
|
||||||
|
* See also:
|
||||||
|
* parse_expression
|
||||||
|
*/
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
JSP_EVAL_RET_STORE_NOT_DUMP, /**< do not dump */
|
||||||
|
JSP_EVAL_RET_STORE_DUMP, /**< dump */
|
||||||
|
} jsp_eval_ret_store_t;
|
||||||
|
|
||||||
static token tok;
|
static token tok;
|
||||||
|
static bool inside_eval = false;
|
||||||
|
static bool inside_function = false;
|
||||||
|
static bool parser_show_opcodes = false;
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
@@ -44,7 +64,7 @@ STATIC_STACK (scopes, scopes_tree)
|
|||||||
|
|
||||||
#define OPCODE_IS(OP, ID) (OP.op_idx == __op__idx_##ID)
|
#define OPCODE_IS(OP, ID) (OP.op_idx == __op__idx_##ID)
|
||||||
|
|
||||||
static operand parse_expression (bool);
|
static operand parse_expression (bool, jsp_eval_ret_store_t);
|
||||||
static void parse_statement (jsp_label_t *outermost_stmt_label_p);
|
static void parse_statement (jsp_label_t *outermost_stmt_label_p);
|
||||||
static operand parse_assignment_expression (bool);
|
static operand parse_assignment_expression (bool);
|
||||||
static void parse_source_element_list (bool);
|
static void parse_source_element_list (bool);
|
||||||
@@ -259,6 +279,9 @@ parse_property_assignment (void)
|
|||||||
token_after_newlines_must_be (TOK_OPEN_BRACE);
|
token_after_newlines_must_be (TOK_OPEN_BRACE);
|
||||||
skip_newlines ();
|
skip_newlines ();
|
||||||
|
|
||||||
|
bool was_in_function = inside_function;
|
||||||
|
inside_function = true;
|
||||||
|
|
||||||
jsp_label_t *masked_label_set_p = jsp_label_mask_set ();
|
jsp_label_t *masked_label_set_p = jsp_label_mask_set ();
|
||||||
|
|
||||||
parse_source_element_list (false);
|
parse_source_element_list (false);
|
||||||
@@ -271,6 +294,9 @@ parse_property_assignment (void)
|
|||||||
|
|
||||||
dump_ret ();
|
dump_ret ();
|
||||||
rewrite_function_end (VARG_FUNC_EXPR);
|
rewrite_function_end (VARG_FUNC_EXPR);
|
||||||
|
|
||||||
|
inside_function = was_in_function;
|
||||||
|
|
||||||
if (is_setter)
|
if (is_setter)
|
||||||
{
|
{
|
||||||
dump_prop_setter_decl (name, func);
|
dump_prop_setter_decl (name, func);
|
||||||
@@ -474,9 +500,11 @@ parse_function_declaration (void)
|
|||||||
dump_function_end_for_rewrite ();
|
dump_function_end_for_rewrite ();
|
||||||
|
|
||||||
token_after_newlines_must_be (TOK_OPEN_BRACE);
|
token_after_newlines_must_be (TOK_OPEN_BRACE);
|
||||||
|
|
||||||
skip_newlines ();
|
skip_newlines ();
|
||||||
|
|
||||||
|
bool was_in_function = inside_function;
|
||||||
|
inside_function = true;
|
||||||
|
|
||||||
parse_source_element_list (false);
|
parse_source_element_list (false);
|
||||||
|
|
||||||
next_token_must_be (TOK_CLOSE_BRACE);
|
next_token_must_be (TOK_CLOSE_BRACE);
|
||||||
@@ -484,6 +512,8 @@ parse_function_declaration (void)
|
|||||||
dump_ret ();
|
dump_ret ();
|
||||||
rewrite_function_end (VARG_FUNC_DECL);
|
rewrite_function_end (VARG_FUNC_DECL);
|
||||||
|
|
||||||
|
inside_function = was_in_function;
|
||||||
|
|
||||||
STACK_DROP (scopes, 1);
|
STACK_DROP (scopes, 1);
|
||||||
serializer_set_scope (STACK_TOP (scopes));
|
serializer_set_scope (STACK_TOP (scopes));
|
||||||
lexer_set_strict_mode (scopes_tree_strict_mode (STACK_TOP (scopes)));
|
lexer_set_strict_mode (scopes_tree_strict_mode (STACK_TOP (scopes)));
|
||||||
@@ -522,6 +552,9 @@ parse_function_expression (void)
|
|||||||
token_after_newlines_must_be (TOK_OPEN_BRACE);
|
token_after_newlines_must_be (TOK_OPEN_BRACE);
|
||||||
skip_newlines ();
|
skip_newlines ();
|
||||||
|
|
||||||
|
bool was_in_function = inside_function;
|
||||||
|
inside_function = true;
|
||||||
|
|
||||||
jsp_label_t *masked_label_set_p = jsp_label_mask_set ();
|
jsp_label_t *masked_label_set_p = jsp_label_mask_set ();
|
||||||
|
|
||||||
parse_source_element_list (false);
|
parse_source_element_list (false);
|
||||||
@@ -534,6 +567,8 @@ parse_function_expression (void)
|
|||||||
dump_ret ();
|
dump_ret ();
|
||||||
rewrite_function_end (VARG_FUNC_EXPR);
|
rewrite_function_end (VARG_FUNC_EXPR);
|
||||||
|
|
||||||
|
inside_function = was_in_function;
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -611,7 +646,7 @@ parse_primary_expression (void)
|
|||||||
skip_newlines ();
|
skip_newlines ();
|
||||||
if (!token_is (TOK_CLOSE_PAREN))
|
if (!token_is (TOK_CLOSE_PAREN))
|
||||||
{
|
{
|
||||||
operand res = parse_expression (true);
|
operand res = parse_expression (true, JSP_EVAL_RET_STORE_NOT_DUMP);
|
||||||
token_after_newlines_must_be (TOK_CLOSE_PAREN);
|
token_after_newlines_must_be (TOK_CLOSE_PAREN);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -683,7 +718,7 @@ parse_member_expression (operand *this_arg, operand *prop_gl)
|
|||||||
if (token_is (TOK_OPEN_SQUARE))
|
if (token_is (TOK_OPEN_SQUARE))
|
||||||
{
|
{
|
||||||
skip_newlines ();
|
skip_newlines ();
|
||||||
prop = parse_expression (true);
|
prop = parse_expression (true, JSP_EVAL_RET_STORE_NOT_DUMP);
|
||||||
next_token_must_be (TOK_CLOSE_SQUARE);
|
next_token_must_be (TOK_CLOSE_SQUARE);
|
||||||
}
|
}
|
||||||
else if (token_is (TOK_DOT))
|
else if (token_is (TOK_DOT))
|
||||||
@@ -774,7 +809,7 @@ parse_call_expression (operand *this_arg_gl, operand *prop_gl)
|
|||||||
if (tok.type == TOK_OPEN_SQUARE)
|
if (tok.type == TOK_OPEN_SQUARE)
|
||||||
{
|
{
|
||||||
skip_newlines ();
|
skip_newlines ();
|
||||||
prop = parse_expression (true);
|
prop = parse_expression (true, JSP_EVAL_RET_STORE_NOT_DUMP);
|
||||||
next_token_must_be (TOK_CLOSE_SQUARE);
|
next_token_must_be (TOK_CLOSE_SQUARE);
|
||||||
}
|
}
|
||||||
else if (tok.type == TOK_DOT)
|
else if (tok.type == TOK_DOT)
|
||||||
@@ -1532,12 +1567,19 @@ parse_assignment_expression (bool in_allowed)
|
|||||||
return expr;
|
return expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* expression
|
/**
|
||||||
: assignment_expression (LT!* ',' LT!* assignment_expression)*
|
* Parse an expression
|
||||||
;
|
*
|
||||||
|
* expression
|
||||||
|
* : assignment_expression (LT!* ',' LT!* assignment_expression)*
|
||||||
|
* ;
|
||||||
|
*
|
||||||
|
* @return operand which holds result of expression
|
||||||
*/
|
*/
|
||||||
static operand
|
static operand
|
||||||
parse_expression (bool in_allowed)
|
parse_expression (bool in_allowed, /**< flag indicating if 'in' is allowed inside expression to parse */
|
||||||
|
jsp_eval_ret_store_t dump_eval_ret_store) /**< flag indicating if 'eval'
|
||||||
|
* result code store should be dumped */
|
||||||
{
|
{
|
||||||
operand expr = parse_assignment_expression (in_allowed);
|
operand expr = parse_assignment_expression (in_allowed);
|
||||||
|
|
||||||
@@ -1555,8 +1597,16 @@ parse_expression (bool in_allowed)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (inside_eval
|
||||||
|
&& dump_eval_ret_store == JSP_EVAL_RET_STORE_DUMP
|
||||||
|
&& !inside_function)
|
||||||
|
{
|
||||||
|
dump_variable_assignment (eval_ret_operand () , expr);
|
||||||
|
}
|
||||||
|
|
||||||
return expr;
|
return expr;
|
||||||
}
|
} /* parse_expression */
|
||||||
|
|
||||||
/* variable_declaration
|
/* variable_declaration
|
||||||
: Identifier LT!* initialiser?
|
: Identifier LT!* initialiser?
|
||||||
@@ -1646,7 +1696,7 @@ parse_plain_for (jsp_label_t *outermost_stmt_label_p) /**< outermost (first) lab
|
|||||||
skip_token ();
|
skip_token ();
|
||||||
if (!token_is (TOK_CLOSE_PAREN))
|
if (!token_is (TOK_CLOSE_PAREN))
|
||||||
{
|
{
|
||||||
parse_expression (true);
|
parse_expression (true, JSP_EVAL_RET_STORE_NOT_DUMP);
|
||||||
}
|
}
|
||||||
|
|
||||||
rewrite_jump_to_end ();
|
rewrite_jump_to_end ();
|
||||||
@@ -1659,7 +1709,7 @@ parse_plain_for (jsp_label_t *outermost_stmt_label_p) /**< outermost (first) lab
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const operand cond = parse_expression (true);
|
const operand cond = parse_expression (true, JSP_EVAL_RET_STORE_NOT_DUMP);
|
||||||
dump_continue_iterations_check (cond);
|
dump_continue_iterations_check (cond);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1749,7 +1799,7 @@ parse_for_or_for_in_statement (jsp_label_t *outermost_stmt_label_p) /**< outermo
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* expression contains left_hand_side_expression. */
|
/* expression contains left_hand_side_expression. */
|
||||||
parse_expression (false);
|
parse_expression (false, JSP_EVAL_RET_STORE_NOT_DUMP);
|
||||||
|
|
||||||
skip_newlines ();
|
skip_newlines ();
|
||||||
if (token_is (TOK_SEMICOLON))
|
if (token_is (TOK_SEMICOLON))
|
||||||
@@ -1773,7 +1823,7 @@ parse_expression_inside_parens (void)
|
|||||||
{
|
{
|
||||||
token_after_newlines_must_be (TOK_OPEN_PAREN);
|
token_after_newlines_must_be (TOK_OPEN_PAREN);
|
||||||
skip_newlines ();
|
skip_newlines ();
|
||||||
const operand res = parse_expression (true);
|
const operand res = parse_expression (true, JSP_EVAL_RET_STORE_NOT_DUMP);
|
||||||
token_after_newlines_must_be (TOK_CLOSE_PAREN);
|
token_after_newlines_must_be (TOK_CLOSE_PAREN);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -1963,7 +2013,7 @@ parse_switch_statement (void)
|
|||||||
if (is_keyword (KW_CASE))
|
if (is_keyword (KW_CASE))
|
||||||
{
|
{
|
||||||
skip_newlines ();
|
skip_newlines ();
|
||||||
const operand case_expr = parse_expression (true);
|
const operand case_expr = parse_expression (true, JSP_EVAL_RET_STORE_NOT_DUMP);
|
||||||
next_token_must_be (TOK_COLON);
|
next_token_must_be (TOK_COLON);
|
||||||
dump_case_clause_check_for_rewrite (switch_expr, case_expr);
|
dump_case_clause_check_for_rewrite (switch_expr, case_expr);
|
||||||
skip_newlines ();
|
skip_newlines ();
|
||||||
@@ -2358,7 +2408,7 @@ parse_statement (jsp_label_t *outermost_stmt_label_p) /**< outermost (first) lab
|
|||||||
skip_token ();
|
skip_token ();
|
||||||
if (!token_is (TOK_SEMICOLON) && !token_is (TOK_NEWLINE))
|
if (!token_is (TOK_SEMICOLON) && !token_is (TOK_NEWLINE))
|
||||||
{
|
{
|
||||||
const operand op = parse_expression (true);
|
const operand op = parse_expression (true, JSP_EVAL_RET_STORE_NOT_DUMP);
|
||||||
dump_retval (op);
|
dump_retval (op);
|
||||||
insert_semicolon ();
|
insert_semicolon ();
|
||||||
return;
|
return;
|
||||||
@@ -2382,7 +2432,7 @@ parse_statement (jsp_label_t *outermost_stmt_label_p) /**< outermost (first) lab
|
|||||||
if (is_keyword (KW_THROW))
|
if (is_keyword (KW_THROW))
|
||||||
{
|
{
|
||||||
skip_token ();
|
skip_token ();
|
||||||
const operand op = parse_expression (true);
|
const operand op = parse_expression (true, JSP_EVAL_RET_STORE_NOT_DUMP);
|
||||||
insert_semicolon ();
|
insert_semicolon ();
|
||||||
dump_throw (op);
|
dump_throw (op);
|
||||||
return;
|
return;
|
||||||
@@ -2418,7 +2468,7 @@ parse_statement (jsp_label_t *outermost_stmt_label_p) /**< outermost (first) lab
|
|||||||
{
|
{
|
||||||
lexer_save_token (tok);
|
lexer_save_token (tok);
|
||||||
tok = temp;
|
tok = temp;
|
||||||
parse_expression (true);
|
parse_expression (true, JSP_EVAL_RET_STORE_DUMP);
|
||||||
skip_newlines ();
|
skip_newlines ();
|
||||||
if (!token_is (TOK_SEMICOLON))
|
if (!token_is (TOK_SEMICOLON))
|
||||||
{
|
{
|
||||||
@@ -2429,7 +2479,7 @@ parse_statement (jsp_label_t *outermost_stmt_label_p) /**< outermost (first) lab
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
parse_expression (true);
|
parse_expression (true, JSP_EVAL_RET_STORE_DUMP);
|
||||||
skip_newlines ();
|
skip_newlines ();
|
||||||
if (!token_is (TOK_SEMICOLON))
|
if (!token_is (TOK_SEMICOLON))
|
||||||
{
|
{
|
||||||
@@ -2748,15 +2798,25 @@ preparse_scope (bool is_global)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* source_element_list
|
/**
|
||||||
: source_element (LT!* source_element)*
|
* Parse source element list
|
||||||
; */
|
*
|
||||||
|
* source_element_list
|
||||||
|
* : source_element (LT!* source_element)*
|
||||||
|
* ;
|
||||||
|
*/
|
||||||
static void
|
static void
|
||||||
parse_source_element_list (bool is_global)
|
parse_source_element_list (bool is_global) /**< flag indicating if we are parsing the global scope */
|
||||||
{
|
{
|
||||||
dumper_new_scope ();
|
dumper_new_scope ();
|
||||||
preparse_scope (is_global);
|
preparse_scope (is_global);
|
||||||
|
|
||||||
|
if (inside_eval
|
||||||
|
&& !inside_function)
|
||||||
|
{
|
||||||
|
dump_undefined_assignment (eval_ret_operand ());
|
||||||
|
}
|
||||||
|
|
||||||
skip_newlines ();
|
skip_newlines ();
|
||||||
while (!token_is (TOK_EOF) && !token_is (TOK_CLOSE_BRACE))
|
while (!token_is (TOK_EOF) && !token_is (TOK_CLOSE_BRACE))
|
||||||
{
|
{
|
||||||
@@ -2766,14 +2826,22 @@ parse_source_element_list (bool is_global)
|
|||||||
lexer_save_token (tok);
|
lexer_save_token (tok);
|
||||||
rewrite_reg_var_decl ();
|
rewrite_reg_var_decl ();
|
||||||
dumper_finish_scope ();
|
dumper_finish_scope ();
|
||||||
}
|
} /* parse_source_element_list */
|
||||||
|
|
||||||
/* program
|
/**
|
||||||
: LT!* source_element_list LT!* EOF!
|
* Parse program
|
||||||
; */
|
*
|
||||||
void
|
* program
|
||||||
parser_parse_program (void)
|
* : LT!* source_element_list LT!* EOF!
|
||||||
|
* ;
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
parser_parse_program (const char *source, /**< 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 */
|
||||||
{
|
{
|
||||||
|
lexer_init_source (source, source_size);
|
||||||
|
|
||||||
STACK_PUSH (scopes, scopes_tree_init (NULL));
|
STACK_PUSH (scopes, scopes_tree_init (NULL));
|
||||||
serializer_set_scope (STACK_TOP (scopes));
|
serializer_set_scope (STACK_TOP (scopes));
|
||||||
lexer_set_strict_mode (scopes_tree_strict_mode (STACK_TOP (scopes)));
|
lexer_set_strict_mode (scopes_tree_strict_mode (STACK_TOP (scopes)));
|
||||||
@@ -2783,7 +2851,19 @@ parser_parse_program (void)
|
|||||||
|
|
||||||
skip_newlines ();
|
skip_newlines ();
|
||||||
JERRY_ASSERT (token_is (TOK_EOF));
|
JERRY_ASSERT (token_is (TOK_EOF));
|
||||||
dump_exit ();
|
|
||||||
|
if (in_new_function)
|
||||||
|
{
|
||||||
|
dump_ret ();
|
||||||
|
}
|
||||||
|
else if (inside_eval)
|
||||||
|
{
|
||||||
|
dump_retval (eval_ret_operand ());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dump_exit ();
|
||||||
|
}
|
||||||
|
|
||||||
serializer_dump_literals ();
|
serializer_dump_literals ();
|
||||||
serializer_merge_scopes_into_bytecode ();
|
serializer_merge_scopes_into_bytecode ();
|
||||||
@@ -2791,13 +2871,66 @@ parser_parse_program (void)
|
|||||||
|
|
||||||
scopes_tree_free (STACK_TOP (scopes));
|
scopes_tree_free (STACK_TOP (scopes));
|
||||||
STACK_DROP (scopes, 1);
|
STACK_DROP (scopes, 1);
|
||||||
}
|
} /* parser_parse_program */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse source script
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
parser_parse_script (const char *source, /**< source script */
|
||||||
|
size_t source_size) /**< source script size it bytes */
|
||||||
|
{
|
||||||
|
inside_eval = false;
|
||||||
|
inside_function = false;
|
||||||
|
parser_parse_program (source, source_size, false);
|
||||||
|
} /* parser_parse_script */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse string passed to eval() call
|
||||||
|
*
|
||||||
|
* @return true if parse succeeds
|
||||||
|
* false otherwise
|
||||||
|
*/
|
||||||
|
bool parser_parse_eval (const char *source, /**< string passed to eval() */
|
||||||
|
size_t source_size) /**< string size in bytes */
|
||||||
|
{
|
||||||
|
TODO (implement syntax error processing);
|
||||||
|
|
||||||
|
inside_eval = true;
|
||||||
|
inside_function = false;
|
||||||
|
parser_parse_program (source, source_size, false);
|
||||||
|
return true;
|
||||||
|
} /* parser_parse_eval */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse a function created via new Function call
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
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 (...) */
|
||||||
|
{
|
||||||
|
inside_eval = false;
|
||||||
|
inside_function = true;
|
||||||
|
|
||||||
|
// Process arguments
|
||||||
|
JERRY_ASSERT (params_count > 0);
|
||||||
|
for (size_t i = 0; i < params_count - 1; ++i)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
} /* parser_parse_new_function */
|
||||||
|
|
||||||
void
|
void
|
||||||
parser_init (const char *source, size_t source_size, bool show_opcodes)
|
parser_init ()
|
||||||
{
|
{
|
||||||
lexer_init (source, source_size, show_opcodes);
|
lexer_init (parser_show_opcodes);
|
||||||
serializer_set_show_opcodes (show_opcodes);
|
serializer_set_show_opcodes (parser_show_opcodes);
|
||||||
dumper_init ();
|
dumper_init ();
|
||||||
syntax_init ();
|
syntax_init ();
|
||||||
|
|
||||||
@@ -2806,6 +2939,15 @@ parser_init (const char *source, size_t source_size, bool show_opcodes)
|
|||||||
jsp_label_init ();
|
jsp_label_init ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tell parser to dump bytecode
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
parser_set_show_opcodes (bool show_opcodes) /**< flag indicating if to dump bytecode */
|
||||||
|
{
|
||||||
|
parser_show_opcodes = show_opcodes;
|
||||||
|
} /* parser_set_show_opcodes */
|
||||||
|
|
||||||
void
|
void
|
||||||
parser_free (void)
|
parser_free (void)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -18,8 +18,11 @@
|
|||||||
|
|
||||||
#include "jrt.h"
|
#include "jrt.h"
|
||||||
|
|
||||||
void parser_init (const char *, size_t, bool);
|
void parser_init ();
|
||||||
void parser_parse_program (void);
|
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);
|
void parser_free (void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -613,15 +613,18 @@ scopes_tree_raw_data (scopes_tree tree, lit_id_hash_table *lit_ids)
|
|||||||
global_oc = 0;
|
global_oc = 0;
|
||||||
|
|
||||||
/* Dump bytecode and fill literal indexes 'hash' table. */
|
/* Dump bytecode and fill literal indexes 'hash' table. */
|
||||||
size_t size = ((size_t) (scopes_tree_count_opcodes (tree) + 1) * sizeof (opcode_t)); // +1 for valgrind
|
// +1 for valgrind
|
||||||
opcode_t *opcodes = (opcode_t *) mem_heap_alloc_block (size, MEM_HEAP_ALLOC_LONG_TERM);
|
size_t size = sizeof (opcodes_header_t) + (size_t) (scopes_tree_count_opcodes (tree) + 1) * sizeof (opcode_t);
|
||||||
memset (opcodes, 0, size);
|
opcodes_header_t *opcodes_data = (opcodes_header_t *) mem_heap_alloc_block (size, MEM_HEAP_ALLOC_LONG_TERM);
|
||||||
|
memset (opcodes_data, 0, size);
|
||||||
|
opcode_t *opcodes = (opcode_t *)(((uint8_t*) opcodes_data) + sizeof (opcodes_header_t));
|
||||||
merge_subscopes (tree, opcodes, lit_ids);
|
merge_subscopes (tree, opcodes, lit_ids);
|
||||||
if (lit_id_to_uid != null_hash)
|
if (lit_id_to_uid != null_hash)
|
||||||
{
|
{
|
||||||
hash_table_free (lit_id_to_uid);
|
hash_table_free (lit_id_to_uid);
|
||||||
lit_id_to_uid = null_hash;
|
lit_id_to_uid = null_hash;
|
||||||
}
|
}
|
||||||
|
opcodes_data->lit_id_hash = lit_ids;
|
||||||
return opcodes;
|
return opcodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,10 +16,11 @@
|
|||||||
#include "serializer.h"
|
#include "serializer.h"
|
||||||
#include "bytecode-data.h"
|
#include "bytecode-data.h"
|
||||||
#include "pretty-printer.h"
|
#include "pretty-printer.h"
|
||||||
|
#include "array-list.h"
|
||||||
|
|
||||||
static bytecode_data_t bytecode_data;
|
static bytecode_data_t bytecode_data;
|
||||||
static scopes_tree current_scope;
|
static scopes_tree current_scope;
|
||||||
|
static array_list bytecodes_cache; /**< storage of pointers to byetecodes */
|
||||||
static bool print_opcodes;
|
static bool print_opcodes;
|
||||||
|
|
||||||
op_meta
|
op_meta
|
||||||
@@ -40,15 +41,27 @@ serializer_get_opcode (opcode_counter_t oc)
|
|||||||
return bytecode_data.opcodes[oc];
|
return bytecode_data.opcodes[oc];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert literal id (operand value of instruction) to compressed pointer to literal
|
||||||
|
*
|
||||||
|
* Bytecode is divided into blocks of fixed size and each block has independent encoding of variable names,
|
||||||
|
* which are represented by 8 bit numbers - ids.
|
||||||
|
* This function performs conversion from id to literal.
|
||||||
|
*
|
||||||
|
* @return compressed pointer to literal
|
||||||
|
*/
|
||||||
lit_cpointer_t
|
lit_cpointer_t
|
||||||
serializer_get_literal_cp_by_uid (uint8_t id, opcode_counter_t oc)
|
serializer_get_literal_cp_by_uid (uint8_t id, /**< literal idx */
|
||||||
|
const opcode_t *opcodes_p, /**< pointer to bytecode */
|
||||||
|
opcode_counter_t oc) /**< position in the bytecode */
|
||||||
{
|
{
|
||||||
if (bytecode_data.lit_id_hash == null_hash)
|
lit_id_hash_table *lit_id_hash = GET_HASH_TABLE_FOR_BYTECODE (opcodes_p == NULL ? bytecode_data.opcodes : opcodes_p);
|
||||||
|
if (lit_id_hash == null_hash)
|
||||||
{
|
{
|
||||||
return INVALID_LITERAL;
|
return INVALID_LITERAL;
|
||||||
}
|
}
|
||||||
return lit_id_hash_table_lookup (bytecode_data.lit_id_hash, id, oc);
|
return lit_id_hash_table_lookup (lit_id_hash, id, oc);
|
||||||
}
|
} /* serializer_get_literal_cp_by_uid */
|
||||||
|
|
||||||
const void *
|
const void *
|
||||||
serializer_get_bytecode (void)
|
serializer_get_bytecode (void)
|
||||||
@@ -72,11 +85,11 @@ serializer_set_scope (scopes_tree new_scope)
|
|||||||
void
|
void
|
||||||
serializer_merge_scopes_into_bytecode (void)
|
serializer_merge_scopes_into_bytecode (void)
|
||||||
{
|
{
|
||||||
JERRY_ASSERT (bytecode_data.lit_id_hash == null_hash);
|
|
||||||
bytecode_data.opcodes_count = scopes_tree_count_opcodes (current_scope);
|
bytecode_data.opcodes_count = scopes_tree_count_opcodes (current_scope);
|
||||||
bytecode_data.lit_id_hash = lit_id_hash_table_init (scopes_tree_count_literals_in_blocks (current_scope),
|
lit_id_hash_table *lit_id_hash = lit_id_hash_table_init (scopes_tree_count_literals_in_blocks (current_scope),
|
||||||
bytecode_data.opcodes_count);
|
(size_t) bytecode_data.opcodes_count / BLOCK_SIZE + 1);
|
||||||
bytecode_data.opcodes = scopes_tree_raw_data (current_scope, bytecode_data.lit_id_hash);
|
bytecode_data.opcodes = scopes_tree_raw_data (current_scope, lit_id_hash);
|
||||||
|
bytecodes_cache = array_list_append (bytecodes_cache, &bytecode_data.opcodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -172,9 +185,10 @@ serializer_init ()
|
|||||||
|
|
||||||
bytecode_data.strings_buffer = NULL;
|
bytecode_data.strings_buffer = NULL;
|
||||||
bytecode_data.opcodes = NULL;
|
bytecode_data.opcodes = NULL;
|
||||||
bytecode_data.lit_id_hash = null_hash;
|
|
||||||
|
|
||||||
lit_init ();
|
lit_init ();
|
||||||
|
|
||||||
|
bytecodes_cache = array_list_init (sizeof (opcode_t *));
|
||||||
}
|
}
|
||||||
|
|
||||||
void serializer_set_show_opcodes (bool show_opcodes)
|
void serializer_set_show_opcodes (bool show_opcodes)
|
||||||
@@ -189,12 +203,13 @@ serializer_free (void)
|
|||||||
{
|
{
|
||||||
mem_heap_free_block ((uint8_t *) bytecode_data.strings_buffer);
|
mem_heap_free_block ((uint8_t *) bytecode_data.strings_buffer);
|
||||||
}
|
}
|
||||||
if (bytecode_data.lit_id_hash != null_hash)
|
|
||||||
{
|
|
||||||
lit_id_hash_table_free (bytecode_data.lit_id_hash);
|
|
||||||
}
|
|
||||||
|
|
||||||
mem_heap_free_block ((uint8_t *) bytecode_data.opcodes);
|
|
||||||
|
|
||||||
lit_finalize ();
|
lit_finalize ();
|
||||||
|
|
||||||
|
for (size_t i = 0; i < array_list_len (bytecodes_cache); ++i)
|
||||||
|
{
|
||||||
|
lit_id_hash_table_free (GET_BYTECODE_HEADER (*(opcode_t **) array_list_element (bytecodes_cache, i))->lit_id_hash);
|
||||||
|
mem_heap_free_block (GET_BYTECODE_HEADER (*(opcode_t **) array_list_element (bytecodes_cache, i)));
|
||||||
|
}
|
||||||
|
array_list_free (bytecodes_cache);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ void serializer_init ();
|
|||||||
void serializer_set_show_opcodes (bool show_opcodes);
|
void serializer_set_show_opcodes (bool show_opcodes);
|
||||||
op_meta serializer_get_op_meta (opcode_counter_t);
|
op_meta serializer_get_op_meta (opcode_counter_t);
|
||||||
opcode_t serializer_get_opcode (opcode_counter_t);
|
opcode_t serializer_get_opcode (opcode_counter_t);
|
||||||
lit_cpointer_t serializer_get_literal_cp_by_uid (uint8_t, 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);
|
const void *serializer_get_bytecode (void);
|
||||||
void serializer_set_strings_buffer (const ecma_char_t *);
|
void serializer_set_strings_buffer (const ecma_char_t *);
|
||||||
void serializer_dump_literals ();
|
void serializer_dump_literals ();
|
||||||
|
|||||||
@@ -63,9 +63,9 @@ opfunc_try_block (opcode_t opdata, /**< operation data */
|
|||||||
JERRY_ASSERT (next_opcode.op_idx == __op__idx_meta);
|
JERRY_ASSERT (next_opcode.op_idx == __op__idx_meta);
|
||||||
JERRY_ASSERT (next_opcode.data.meta.type == OPCODE_META_TYPE_CATCH_EXCEPTION_IDENTIFIER);
|
JERRY_ASSERT (next_opcode.data.meta.type == OPCODE_META_TYPE_CATCH_EXCEPTION_IDENTIFIER);
|
||||||
|
|
||||||
lit_cpointer_t catch_exc_val_var_name_lit_cp = serializer_get_literal_cp_by_uid (
|
lit_cpointer_t catch_exc_val_var_name_lit_cp = serializer_get_literal_cp_by_uid (next_opcode.data.meta.data_1,
|
||||||
next_opcode.data.meta.data_1,
|
int_data->opcodes_p,
|
||||||
int_data->pos);
|
int_data->pos);
|
||||||
int_data->pos++;
|
int_data->pos++;
|
||||||
|
|
||||||
ecma_string_t *catch_exc_var_name_str_p = ecma_new_ecma_string_from_lit_cp (catch_exc_val_var_name_lit_cp);
|
ecma_string_t *catch_exc_var_name_str_p = ecma_new_ecma_string_from_lit_cp (catch_exc_val_var_name_lit_cp);
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ get_variable_value (int_data_t *int_data, /**< interpreter context */
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
ecma_string_t var_name_string;
|
ecma_string_t var_name_string;
|
||||||
lit_cpointer_t lit_cp = serializer_get_literal_cp_by_uid (var_idx, int_data->pos);
|
lit_cpointer_t lit_cp = serializer_get_literal_cp_by_uid (var_idx, int_data->opcodes_p, int_data->pos);
|
||||||
JERRY_ASSERT (lit_cp.packed_value != MEM_CP_NULL);
|
JERRY_ASSERT (lit_cp.packed_value != MEM_CP_NULL);
|
||||||
ecma_new_ecma_string_on_stack_from_lit_cp (&var_name_string, lit_cp);
|
ecma_new_ecma_string_on_stack_from_lit_cp (&var_name_string, lit_cp);
|
||||||
|
|
||||||
@@ -158,7 +158,7 @@ set_variable_value (int_data_t *int_data, /**< interpreter context */
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
ecma_string_t var_name_string;
|
ecma_string_t var_name_string;
|
||||||
lit_cpointer_t lit_cp = serializer_get_literal_cp_by_uid (var_idx, lit_oc);
|
lit_cpointer_t lit_cp = serializer_get_literal_cp_by_uid (var_idx, int_data->opcodes_p, lit_oc);
|
||||||
JERRY_ASSERT (lit_cp.packed_value != MEM_CP_NULL);
|
JERRY_ASSERT (lit_cp.packed_value != MEM_CP_NULL);
|
||||||
ecma_new_ecma_string_on_stack_from_lit_cp (&var_name_string, lit_cp);
|
ecma_new_ecma_string_on_stack_from_lit_cp (&var_name_string, lit_cp);
|
||||||
|
|
||||||
|
|||||||
@@ -97,6 +97,7 @@ fill_params_list (int_data_t *int_data, /**< interpreter context */
|
|||||||
JERRY_ASSERT (next_opcode.data.meta.type == OPCODE_META_TYPE_VARG);
|
JERRY_ASSERT (next_opcode.data.meta.type == OPCODE_META_TYPE_VARG);
|
||||||
|
|
||||||
const lit_cpointer_t param_name_lit_idx = serializer_get_literal_cp_by_uid (next_opcode.data.meta.data_1,
|
const lit_cpointer_t param_name_lit_idx = serializer_get_literal_cp_by_uid (next_opcode.data.meta.data_1,
|
||||||
|
int_data->opcodes_p,
|
||||||
int_data->pos);
|
int_data->pos);
|
||||||
|
|
||||||
params_names[param_index] = ecma_new_ecma_string_from_lit_cp (param_name_lit_idx);
|
params_names[param_index] = ecma_new_ecma_string_from_lit_cp (param_name_lit_idx);
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ opfunc_assignment (opcode_t opdata, /**< operation data */
|
|||||||
}
|
}
|
||||||
else if (type_value_right == OPCODE_ARG_TYPE_STRING)
|
else if (type_value_right == OPCODE_ARG_TYPE_STRING)
|
||||||
{
|
{
|
||||||
lit_cpointer_t lit_cp = serializer_get_literal_cp_by_uid (src_val_descr, int_data->pos);
|
lit_cpointer_t lit_cp = serializer_get_literal_cp_by_uid (src_val_descr, int_data->opcodes_p, int_data->pos);
|
||||||
ecma_string_t *string_p = ecma_new_ecma_string_from_lit_cp (lit_cp);
|
ecma_string_t *string_p = ecma_new_ecma_string_from_lit_cp (lit_cp);
|
||||||
|
|
||||||
ret_value = set_variable_value (int_data,
|
ret_value = set_variable_value (int_data,
|
||||||
@@ -125,7 +125,7 @@ opfunc_assignment (opcode_t opdata, /**< operation data */
|
|||||||
{
|
{
|
||||||
ecma_number_t *num_p = int_data->tmp_num_p;
|
ecma_number_t *num_p = int_data->tmp_num_p;
|
||||||
|
|
||||||
lit_cpointer_t lit_cp = serializer_get_literal_cp_by_uid (src_val_descr, int_data->pos);
|
lit_cpointer_t lit_cp = serializer_get_literal_cp_by_uid (src_val_descr, int_data->opcodes_p, int_data->pos);
|
||||||
literal_t lit = lit_get_literal_by_cp (lit_cp);
|
literal_t lit = lit_get_literal_by_cp (lit_cp);
|
||||||
JERRY_ASSERT (lit->get_type () == LIT_NUMBER_T);
|
JERRY_ASSERT (lit->get_type () == LIT_NUMBER_T);
|
||||||
|
|
||||||
@@ -140,7 +140,7 @@ opfunc_assignment (opcode_t opdata, /**< operation data */
|
|||||||
{
|
{
|
||||||
ecma_number_t *num_p = int_data->tmp_num_p;
|
ecma_number_t *num_p = int_data->tmp_num_p;
|
||||||
|
|
||||||
lit_cpointer_t lit_cp = serializer_get_literal_cp_by_uid (src_val_descr, int_data->pos);
|
lit_cpointer_t lit_cp = serializer_get_literal_cp_by_uid (src_val_descr, int_data->opcodes_p, int_data->pos);
|
||||||
literal_t lit = lit_get_literal_by_cp (lit_cp);
|
literal_t lit = lit_get_literal_by_cp (lit_cp);
|
||||||
JERRY_ASSERT (lit->get_type () == LIT_NUMBER_T);
|
JERRY_ASSERT (lit->get_type () == LIT_NUMBER_T);
|
||||||
|
|
||||||
@@ -395,7 +395,9 @@ ecma_completion_value_t
|
|||||||
opfunc_var_decl (opcode_t opdata, /**< operation data */
|
opfunc_var_decl (opcode_t opdata, /**< operation data */
|
||||||
int_data_t *int_data) /**< interpreter context */
|
int_data_t *int_data) /**< interpreter context */
|
||||||
{
|
{
|
||||||
lit_cpointer_t lit_cp = serializer_get_literal_cp_by_uid (opdata.data.var_decl.variable_name, int_data->pos);
|
lit_cpointer_t lit_cp = serializer_get_literal_cp_by_uid (opdata.data.var_decl.variable_name,
|
||||||
|
int_data->opcodes_p,
|
||||||
|
int_data->pos);
|
||||||
JERRY_ASSERT (lit_cp.packed_value != MEM_CP_NULL);
|
JERRY_ASSERT (lit_cp.packed_value != MEM_CP_NULL);
|
||||||
|
|
||||||
ecma_string_t *var_name_string_p = ecma_new_ecma_string_from_lit_cp (lit_cp);
|
ecma_string_t *var_name_string_p = ecma_new_ecma_string_from_lit_cp (lit_cp);
|
||||||
@@ -491,7 +493,9 @@ opfunc_func_decl_n (opcode_t opdata, /**< operation data */
|
|||||||
const idx_t function_name_idx = opdata.data.func_decl_n.name_lit_idx;
|
const idx_t function_name_idx = opdata.data.func_decl_n.name_lit_idx;
|
||||||
const ecma_length_t params_number = opdata.data.func_decl_n.arg_list;
|
const ecma_length_t params_number = opdata.data.func_decl_n.arg_list;
|
||||||
|
|
||||||
lit_cpointer_t function_name_lit_cp = serializer_get_literal_cp_by_uid (function_name_idx, int_data->pos);
|
lit_cpointer_t function_name_lit_cp = serializer_get_literal_cp_by_uid (function_name_idx,
|
||||||
|
int_data->opcodes_p,
|
||||||
|
int_data->pos);
|
||||||
|
|
||||||
int_data->pos++;
|
int_data->pos++;
|
||||||
|
|
||||||
@@ -573,7 +577,9 @@ opfunc_func_expr_n (opcode_t opdata, /**< operation data */
|
|||||||
{
|
{
|
||||||
scope_p = ecma_create_decl_lex_env (int_data->lex_env_p);
|
scope_p = ecma_create_decl_lex_env (int_data->lex_env_p);
|
||||||
|
|
||||||
lit_cpointer_t lit_cp = serializer_get_literal_cp_by_uid (function_name_lit_idx, lit_oc);
|
lit_cpointer_t lit_cp = serializer_get_literal_cp_by_uid (function_name_lit_idx,
|
||||||
|
int_data->opcodes_p,
|
||||||
|
lit_oc);
|
||||||
JERRY_ASSERT (lit_cp.packed_value != MEM_CP_NULL);
|
JERRY_ASSERT (lit_cp.packed_value != MEM_CP_NULL);
|
||||||
|
|
||||||
function_name_string_p = ecma_new_ecma_string_from_lit_cp (lit_cp);
|
function_name_string_p = ecma_new_ecma_string_from_lit_cp (lit_cp);
|
||||||
@@ -1407,7 +1413,7 @@ evaluate_arg_for_typeof (int_data_t *int_data, /**< interpreter context */
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
lit_cpointer_t lit_cp = serializer_get_literal_cp_by_uid (var_idx, int_data->pos);
|
lit_cpointer_t lit_cp = serializer_get_literal_cp_by_uid (var_idx, int_data->opcodes_p, int_data->pos);
|
||||||
JERRY_ASSERT (lit_cp.packed_value != MEM_CP_NULL);
|
JERRY_ASSERT (lit_cp.packed_value != MEM_CP_NULL);
|
||||||
|
|
||||||
ecma_string_t *var_name_string_p = ecma_new_ecma_string_from_lit_cp (lit_cp);
|
ecma_string_t *var_name_string_p = ecma_new_ecma_string_from_lit_cp (lit_cp);
|
||||||
@@ -1523,7 +1529,7 @@ opfunc_delete_var (opcode_t opdata, /**< operation data */
|
|||||||
|
|
||||||
ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();
|
ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();
|
||||||
|
|
||||||
lit_cpointer_t lit_cp = serializer_get_literal_cp_by_uid (name_lit_idx, lit_oc);
|
lit_cpointer_t lit_cp = serializer_get_literal_cp_by_uid (name_lit_idx, int_data->opcodes_p, lit_oc);
|
||||||
JERRY_ASSERT (lit_cp.packed_value != MEM_CP_NULL);
|
JERRY_ASSERT (lit_cp.packed_value != MEM_CP_NULL);
|
||||||
|
|
||||||
ecma_string_t *name_string_p = ecma_new_ecma_string_from_lit_cp (lit_cp);
|
ecma_string_t *name_string_p = ecma_new_ecma_string_from_lit_cp (lit_cp);
|
||||||
|
|||||||
@@ -87,11 +87,17 @@ typedef enum : idx_t
|
|||||||
* 'eval' identifier */
|
* 'eval' identifier */
|
||||||
} opcode_scope_code_flags_t;
|
} opcode_scope_code_flags_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Forward declaration of opcode structure
|
||||||
|
*/
|
||||||
|
struct opcode_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interpreter context
|
* Interpreter context
|
||||||
*/
|
*/
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
const opcode_t *opcodes_p; /**< pointer to array containing currently executed bytecode */
|
||||||
opcode_counter_t pos; /**< current opcode to execute */
|
opcode_counter_t pos; /**< current opcode to execute */
|
||||||
ecma_value_t this_binding; /**< this binding for current context */
|
ecma_value_t this_binding; /**< this binding for current context */
|
||||||
ecma_object_t *lex_env_p; /**< current lexical environment */
|
ecma_object_t *lex_env_p; /**< current lexical environment */
|
||||||
@@ -257,7 +263,7 @@ opcode_counter_t read_meta_opcode_counter (opcode_meta_type expected_type, int_d
|
|||||||
OP_ARGS_LIST (OP_DATA)
|
OP_ARGS_LIST (OP_DATA)
|
||||||
|
|
||||||
#define __OP_STRUCT_FIELD(name, arg1, arg2, arg3) __op_##name name;
|
#define __OP_STRUCT_FIELD(name, arg1, arg2, arg3) __op_##name name;
|
||||||
typedef struct
|
typedef struct opcode_t
|
||||||
{
|
{
|
||||||
idx_t op_idx;
|
idx_t op_idx;
|
||||||
union
|
union
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ var_to_str (opcode_t opcode, lit_cpointer_t lit_ids[], opcode_counter_t oc, uint
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return lit_cp_to_str (serializer_get_literal_cp_by_uid (raw.uids[current_arg], oc));
|
return lit_cp_to_str (serializer_get_literal_cp_by_uid (raw.uids[current_arg], NULL, oc));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -534,6 +534,7 @@ vm_run_from_pos (opcode_counter_t start_pos, /**< identifier of starting opcode
|
|||||||
MEM_DEFINE_LOCAL_ARRAY (regs, regs_num, ecma_value_t);
|
MEM_DEFINE_LOCAL_ARRAY (regs, regs_num, ecma_value_t);
|
||||||
|
|
||||||
int_data_t int_data;
|
int_data_t int_data;
|
||||||
|
int_data.opcodes_p = __program;
|
||||||
int_data.pos = (opcode_counter_t) (start_pos + 1);
|
int_data.pos = (opcode_counter_t) (start_pos + 1);
|
||||||
int_data.this_binding = this_binding_value;
|
int_data.this_binding = this_binding_value;
|
||||||
int_data.lex_env_p = lex_env_p;
|
int_data.lex_env_p = lex_env_p;
|
||||||
|
|||||||
@@ -74,8 +74,9 @@ main (int __attr_unused___ argc,
|
|||||||
|
|
||||||
mem_init ();
|
mem_init ();
|
||||||
serializer_init ();
|
serializer_init ();
|
||||||
parser_init (program, strlen (program), true);
|
parser_set_show_opcodes (true);
|
||||||
parser_parse_program ();
|
parser_init ();
|
||||||
|
parser_parse_script (program, strlen (program));
|
||||||
parser_free ();
|
parser_free ();
|
||||||
|
|
||||||
opcode_t opcodes[] =
|
opcode_t opcodes[] =
|
||||||
|
|||||||
Reference in New Issue
Block a user