Remove preparser lexer pass and pass for searching of "eval" and "arguments" literals.

JerryScript-DCO-1.0-Signed-off-by: Andrey Shitov a.shitov@samsung.com
This commit is contained in:
Andrey Shitov
2015-08-12 15:50:16 +03:00
parent cc4283b945
commit a870a07972
7 changed files with 352 additions and 344 deletions
+17 -12
View File
@@ -2507,31 +2507,36 @@ dump_throw (operand op)
dump_single_address (getop_throw_value, op); dump_single_address (getop_throw_value, op);
} }
/**
* Checks if variable is already declared
*
* @return true if variable declaration already exists
* false otherwise
*/
bool bool
dumper_variable_declaration_exists (lit_cpointer_t lit_id) dumper_variable_declaration_exists (lit_cpointer_t lit_id) /**< literal which holds variable's name */
{ {
for (vm_instr_counter_t oc = (vm_instr_counter_t) (serializer_get_current_instr_counter () - 1); vm_instr_counter_t var_decls_count = (vm_instr_counter_t) serializer_get_current_var_decls_counter ();
oc > 0; oc--) for (vm_instr_counter_t oc = (vm_instr_counter_t) (0); oc < var_decls_count; oc++)
{ {
const op_meta var_decl_op_meta = serializer_get_op_meta (oc); const op_meta var_decl_op_meta = serializer_get_var_decl (oc);
if (var_decl_op_meta.op.op_idx != VM_OP_VAR_DECL)
{
break;
}
if (var_decl_op_meta.lit_id[0].packed_value == lit_id.packed_value) if (var_decl_op_meta.lit_id[0].packed_value == lit_id.packed_value)
{ {
return true; return true;
} }
} }
return false; return false;
} } /* dumper_variable_declaration_exists */
/**
* Dump instruction designating variable declaration
*/
void void
dump_variable_declaration (lit_cpointer_t lit_id) dump_variable_declaration (lit_cpointer_t lit_id) /**< literal which holds variable's name */
{ {
const vm_instr_t instr = getop_var_decl (LITERAL_TO_REWRITE); const vm_instr_t instr = getop_var_decl (LITERAL_TO_REWRITE);
serializer_dump_op_meta (create_op_meta_100 (instr, lit_id)); serializer_dump_var_decl (create_op_meta_100 (instr, lit_id));
} } /* dump_variable_declaration */
/** /**
* Dump template of 'meta' instruction for scope's code flags. * Dump template of 'meta' instruction for scope's code flags.
+62 -232
View File
@@ -829,7 +829,18 @@ parse_primary_expression (void)
case TOK_NUMBER: case TOK_NUMBER:
case TOK_REGEXP: case TOK_REGEXP:
case TOK_STRING: return parse_literal (); case TOK_STRING: return parse_literal ();
case TOK_NAME: return literal_operand (token_data_as_lit_cp ()); case TOK_NAME:
{
if (lit_literal_equal_type_cstr (lit_get_literal_by_cp (token_data_as_lit_cp ()), "arguments"))
{
scopes_tree_set_arguments_used (STACK_TOP (scopes));
}
if (lit_literal_equal_type_cstr (lit_get_literal_by_cp (token_data_as_lit_cp ()), "eval"))
{
scopes_tree_set_eval_used (STACK_TOP (scopes));
}
return literal_operand (token_data_as_lit_cp ());
}
case TOK_OPEN_SQUARE: return parse_array_literal (); case TOK_OPEN_SQUARE: return parse_array_literal ();
case TOK_OPEN_BRACE: return parse_object_literal (); case TOK_OPEN_BRACE: return parse_object_literal ();
case TOK_OPEN_PAREN: case TOK_OPEN_PAREN:
@@ -1812,6 +1823,15 @@ parse_variable_declaration (void)
current_token_must_be (TOK_NAME); current_token_must_be (TOK_NAME);
const operand name = literal_operand (token_data_as_lit_cp ()); const operand name = literal_operand (token_data_as_lit_cp ());
if (!dumper_variable_declaration_exists (token_data_as_lit_cp ()))
{
jsp_early_error_check_for_eval_and_arguments_in_strict_mode (literal_operand (token_data_as_lit_cp ()),
is_strict_mode (),
tok.loc);
dump_variable_declaration (token_data_as_lit_cp ());
}
skip_newlines (); skip_newlines ();
if (token_is (TOK_EQ)) if (token_is (TOK_EQ))
{ {
@@ -1825,7 +1845,7 @@ parse_variable_declaration (void)
} }
return name; return name;
} } /* parse_variable_declaration */
/* variable_declaration_list /* variable_declaration_list
: variable_declaration : variable_declaration
@@ -2886,65 +2906,12 @@ parse_source_element (void)
} }
/** /**
* Skip function's optional name and parentheses * Check for "use strict" in directive prologue
*
* @return: true, if skipped successfully
* false, if open parentheses wasn't found (this means that keyword 'function' is used as
* a property name)
*/ */
static bool
skip_optional_name_and_parens (void)
{
if (token_is (TOK_NAME))
{
token_after_newlines_must_be (TOK_OPEN_PAREN);
}
if (token_is (TOK_OPEN_PAREN))
{
skip_newlines ();
}
else
{
return false;
}
while (!token_is (TOK_CLOSE_PAREN))
{
skip_newlines ();
}
return true;
} /* skip_optional_name_and_parens */
static void static void
skip_function (void) check_directive_prologue_for_use_strict ()
{
skip_newlines ();
if (skip_optional_name_and_parens ())
{
skip_newlines ();
jsp_skip_braces (TOK_OPEN_BRACE);
}
}
static bool
var_declared (lit_cpointer_t var_cp)
{
return dumper_variable_declaration_exists (var_cp);
}
static void
preparse_scope (bool is_global)
{ {
const locus start_loc = tok.loc; const locus start_loc = tok.loc;
const token_type end_tt = is_global ? TOK_EOF : TOK_CLOSE_BRACE;
vm_instr_counter_t scope_code_flags_oc = dump_scope_code_flags_for_rewrite ();
bool is_use_strict = false;
bool is_ref_arguments_identifier = false;
bool is_ref_eval_identifier = false;
/* /*
* Check Directive Prologue for Use Strict directive (see ECMA-262 5.1 section 14.1) * Check Directive Prologue for Use Strict directive (see ECMA-262 5.1 section 14.1)
@@ -2954,7 +2921,8 @@ preparse_scope (bool is_global)
if (lit_literal_equal_type_cstr (lit_get_literal_by_cp (token_data_as_lit_cp ()), "use strict") if (lit_literal_equal_type_cstr (lit_get_literal_by_cp (token_data_as_lit_cp ()), "use strict")
&& lexer_is_no_escape_sequences_in_token_string (tok)) && lexer_is_no_escape_sequences_in_token_string (tok))
{ {
is_use_strict = true; scopes_tree_set_strict_mode (STACK_TOP (scopes), true);
lexer_set_strict_mode (scopes_tree_strict_mode (STACK_TOP (scopes)));
break; break;
} }
@@ -2966,186 +2934,15 @@ preparse_scope (bool is_global)
} }
} }
size_t nesting_level = 0;
while (nesting_level > 0 || !token_is (end_tt))
{
if (token_is (TOK_OPEN_BRACE))
{
nesting_level++;
}
else if (token_is (TOK_CLOSE_BRACE))
{
nesting_level--;
}
else if (token_is (TOK_NAME))
{
if (lit_literal_equal_type_cstr (lit_get_literal_by_cp (token_data_as_lit_cp ()), "arguments"))
{
is_ref_arguments_identifier = true;
}
else if (lit_literal_equal_type_cstr (lit_get_literal_by_cp (token_data_as_lit_cp ()), "eval"))
{
is_ref_eval_identifier = true;
}
}
skip_newlines ();
}
opcode_scope_code_flags_t scope_flags = OPCODE_SCOPE_CODE_FLAGS__EMPTY;
if (is_use_strict)
{
scopes_tree_set_strict_mode (STACK_TOP (scopes), true);
scope_flags = (opcode_scope_code_flags_t) (scope_flags | OPCODE_SCOPE_CODE_FLAGS_STRICT);
}
if (!is_ref_arguments_identifier)
{
scope_flags = (opcode_scope_code_flags_t) (scope_flags | OPCODE_SCOPE_CODE_FLAGS_NOT_REF_ARGUMENTS_IDENTIFIER);
}
if (!is_ref_eval_identifier)
{
scope_flags = (opcode_scope_code_flags_t) (scope_flags | OPCODE_SCOPE_CODE_FLAGS_NOT_REF_EVAL_IDENTIFIER);
}
rewrite_scope_code_flags (scope_code_flags_oc, scope_flags);
lexer_set_strict_mode (scopes_tree_strict_mode (STACK_TOP (scopes)));
dump_reg_var_decl_for_rewrite ();
if (lit_utf8_iterator_pos_cmp (start_loc, tok.loc) != 0) if (lit_utf8_iterator_pos_cmp (start_loc, tok.loc) != 0)
{ {
lexer_seek (start_loc); lexer_seek (start_loc);
skip_newlines ();
bool is_in_var_declaration_list = false;
size_t nesting_level = 0;
while (nesting_level > 0 || !token_is (end_tt))
{
/*
* FIXME:
* Remove preparse_scope; move variable declaration search to main pass of parser.
* When byte-code and scope storages would be introduced, move variable declarations
* from byte-code to scope descriptor.
*/
if (token_is (TOK_NAME))
{
if (is_in_var_declaration_list)
{
if (!var_declared (token_data_as_lit_cp ()))
{
jsp_early_error_check_for_eval_and_arguments_in_strict_mode (literal_operand (token_data_as_lit_cp ()),
is_strict_mode (),
tok.loc);
dump_variable_declaration (token_data_as_lit_cp ());
}
}
skip_newlines ();
if (!token_is (TOK_COMMA)
&& !token_is (TOK_EQ))
{
is_in_var_declaration_list = false;
}
}
else if (is_in_var_declaration_list)
{
if (token_is (TOK_EQ))
{
skip_newlines ();
while (!token_is (end_tt)
&& !token_is (TOK_COMMA)
&& !token_is (TOK_SEMICOLON))
{
if (is_keyword (KW_FUNCTION))
{
skip_function ();
}
else if (token_is (TOK_OPEN_BRACE))
{
jsp_skip_braces (TOK_OPEN_BRACE);
}
else if (token_is (TOK_OPEN_SQUARE))
{
jsp_skip_braces (TOK_OPEN_SQUARE);
}
else if (token_is (TOK_OPEN_PAREN))
{
jsp_skip_braces (TOK_OPEN_PAREN);
}
else if (token_is (TOK_KEYWORD))
{
if (is_keyword (KW_VAR))
{
is_in_var_declaration_list = false;
}
break;
}
else if (token_is (TOK_CLOSE_BRACE))
{
/* the '}' would be handled during next iteration, reducing nesting level counter */
is_in_var_declaration_list = false;
break;
}
skip_token ();
}
}
else if (token_is (TOK_COMMA))
{
skip_newlines ();
}
else
{
is_in_var_declaration_list = false;
skip_newlines ();
}
}
else
{
if (token_is (TOK_OPEN_BRACE))
{
nesting_level++;
}
else if (token_is (TOK_CLOSE_BRACE))
{
nesting_level--;
}
else if (token_is (TOK_OPEN_SQUARE))
{
jsp_skip_braces (TOK_OPEN_SQUARE);
}
else if (is_keyword (KW_VAR))
{
is_in_var_declaration_list = true;
}
else if (is_keyword (KW_FUNCTION))
{
skip_function ();
}
skip_newlines ();
}
}
lexer_seek (start_loc);
} }
else else
{ {
JERRY_ASSERT (token_is (end_tt));
lexer_save_token (tok); lexer_save_token (tok);
} }
} } /* check_directive_prologue_for_use_strict */
/** /**
* Parse source element list * Parse source element list
@@ -3155,10 +2952,17 @@ preparse_scope (bool is_global)
* ; * ;
*/ */
static void static void
parse_source_element_list (bool is_global) /**< flag indicating if we are parsing the global scope */ parse_source_element_list (bool is_global) /**< flag, indicating that we parsing global context */
{ {
const token_type end_tt = is_global ? TOK_EOF : TOK_CLOSE_BRACE;
dumper_new_scope (); dumper_new_scope ();
preparse_scope (is_global);
vm_instr_counter_t scope_code_flags_oc = dump_scope_code_flags_for_rewrite ();
check_directive_prologue_for_use_strict ();
dump_reg_var_decl_for_rewrite ();
if (inside_eval if (inside_eval
&& !inside_function) && !inside_function)
@@ -3172,7 +2976,33 @@ parse_source_element_list (bool is_global) /**< flag indicating if we are parsin
parse_source_element (); parse_source_element ();
skip_newlines (); skip_newlines ();
} }
if (!token_is (end_tt))
{
PARSE_ERROR (JSP_EARLY_ERROR_SYNTAX, "Unexpected token", tok.loc);
}
lexer_save_token (tok); lexer_save_token (tok);
opcode_scope_code_flags_t scope_flags = OPCODE_SCOPE_CODE_FLAGS__EMPTY;
scopes_tree fe_scope_tree = STACK_TOP (scopes);
if (fe_scope_tree->strict_mode)
{
scope_flags = (opcode_scope_code_flags_t) (scope_flags | OPCODE_SCOPE_CODE_FLAGS_STRICT);
}
if (!fe_scope_tree->ref_arguments)
{
scope_flags = (opcode_scope_code_flags_t) (scope_flags | OPCODE_SCOPE_CODE_FLAGS_NOT_REF_ARGUMENTS_IDENTIFIER);
}
if (!fe_scope_tree->ref_eval)
{
scope_flags = (opcode_scope_code_flags_t) (scope_flags | OPCODE_SCOPE_CODE_FLAGS_NOT_REF_EVAL_IDENTIFIER);
}
rewrite_scope_code_flags (scope_code_flags_oc, scope_flags);
rewrite_reg_var_decl (); rewrite_reg_var_decl ();
dumper_finish_scope (); dumper_finish_scope ();
} /* parse_source_element_list */ } /* parse_source_element_list */
+202 -87
View File
@@ -49,21 +49,44 @@ vm_instr_counter_t
scopes_tree_instrs_num (scopes_tree t) scopes_tree_instrs_num (scopes_tree t)
{ {
assert_tree (t); assert_tree (t);
return t->instrs_num; return t->instrs_count;
} }
/**
* Get number of variable declarations in the scope
*
* @return number of variable declarations
*/
vm_instr_counter_t
scopes_tree_var_decls_num (scopes_tree t) /**< scope */
{
assert_tree (t);
return t->var_decls_cout;
} /* scopes_tree_var_decls_num */
void void
scopes_tree_add_op_meta (scopes_tree tree, op_meta op) scopes_tree_add_op_meta (scopes_tree tree, op_meta op)
{ {
assert_tree (tree); assert_tree (tree);
linked_list_set_element (tree->instrs, tree->instrs_num++, &op); linked_list_set_element (tree->instrs, tree->instrs_count++, &op);
} }
/**
* Add variable declaration to a scope
*/
void
scopes_tree_add_var_decl (scopes_tree tree, /**< scope, to which variable declaration is added */
op_meta op) /**< variable declaration instruction */
{
assert_tree (tree);
linked_list_set_element (tree->var_decls, tree->var_decls_cout++, &op);
} /* scopes_tree_add_var_decl */
void void
scopes_tree_set_op_meta (scopes_tree tree, vm_instr_counter_t oc, op_meta op) scopes_tree_set_op_meta (scopes_tree tree, vm_instr_counter_t oc, op_meta op)
{ {
assert_tree (tree); assert_tree (tree);
JERRY_ASSERT (oc < tree->instrs_num); JERRY_ASSERT (oc < tree->instrs_count);
linked_list_set_element (tree->instrs, oc, &op); linked_list_set_element (tree->instrs, oc, &op);
} }
@@ -71,23 +94,37 @@ void
scopes_tree_set_instrs_num (scopes_tree tree, vm_instr_counter_t oc) scopes_tree_set_instrs_num (scopes_tree tree, vm_instr_counter_t oc)
{ {
assert_tree (tree); assert_tree (tree);
JERRY_ASSERT (oc < tree->instrs_num); JERRY_ASSERT (oc < tree->instrs_count);
tree->instrs_num = oc; tree->instrs_count = oc;
} }
op_meta op_meta
scopes_tree_op_meta (scopes_tree tree, vm_instr_counter_t oc) scopes_tree_op_meta (scopes_tree tree, vm_instr_counter_t oc)
{ {
assert_tree (tree); assert_tree (tree);
JERRY_ASSERT (oc < tree->instrs_num); JERRY_ASSERT (oc < tree->instrs_count);
return *(op_meta *) linked_list_element (tree->instrs, oc); return *(op_meta *) linked_list_element (tree->instrs, oc);
} }
/**
* Get variable declaration for the specified scope
*
* @return instruction, declaring a variable
*/
op_meta
scopes_tree_var_decl (scopes_tree tree, /**< scope, from which variable declaration is retrieved */
vm_instr_counter_t oc) /**< number of variable declaration in the scope */
{
assert_tree (tree);
JERRY_ASSERT (oc < tree->var_decls_cout);
return *(op_meta *) linked_list_element (tree->var_decls, oc);
} /* scopes_tree_var_decl */
vm_instr_counter_t vm_instr_counter_t
scopes_tree_count_instructions (scopes_tree t) scopes_tree_count_instructions (scopes_tree t)
{ {
assert_tree (t); assert_tree (t);
vm_instr_counter_t res = t->instrs_num; vm_instr_counter_t res = (vm_instr_counter_t) (t->instrs_count + t->var_decls_cout);
for (uint8_t i = 0; i < t->t.children_num; i++) for (uint8_t i = 0; i < t->t.children_num; i++)
{ {
res = (vm_instr_counter_t) ( res = (vm_instr_counter_t) (
@@ -212,24 +249,37 @@ insert_uids_to_lit_id_map (op_meta *om, uint16_t mask)
} }
} }
/**
* Get instruction from instruction list
*
* @return instruction at specified position
*/
static op_meta * static op_meta *
extract_op_meta (scopes_tree tree, vm_instr_counter_t instr_pos) extract_op_meta (linked_list instr_list, /**< instruction list */
vm_instr_counter_t instr_pos) /**< position inside the list */
{ {
return (op_meta *) linked_list_element (tree->instrs, instr_pos); return (op_meta *) linked_list_element (instr_list, instr_pos);
} } /* extract_op_meta */
/**
* Add instruction to an instruction list
*
* @return generated instruction
*/
static vm_instr_t static vm_instr_t
generate_instr (scopes_tree tree, vm_instr_counter_t instr_pos, lit_id_hash_table *lit_ids) generate_instr (linked_list instr_list, /**< instruction list */
vm_instr_counter_t instr_pos, /**< position where to generate an instruction */
lit_id_hash_table *lit_ids) /**< hash table binding operand identifiers and literals */
{ {
start_new_block_if_necessary (); start_new_block_if_necessary ();
op_meta *om = extract_op_meta (tree, instr_pos); op_meta *om_p = extract_op_meta (instr_list, instr_pos);
/* Now we should change uids of instructions. /* Now we should change uids of instructions.
Since different instructions has different literals/tmps in different places, Since different instructions has different literals/tmps in different places,
we should change only them. we should change only them.
For each case possible literal positions are shown as 0xYYY literal, For each case possible literal positions are shown as 0xYYY literal,
where Y is set to '1' when there is a possible literal in this position, where Y is set to '1' when there is a possible literal in this position,
and '0' otherwise. */ and '0' otherwise. */
switch (om->op.op_idx) switch (om_p->op.op_idx)
{ {
case VM_OP_PROP_GETTER: case VM_OP_PROP_GETTER:
case VM_OP_PROP_SETTER: case VM_OP_PROP_SETTER:
@@ -256,7 +306,7 @@ generate_instr (scopes_tree tree, vm_instr_counter_t instr_pos, lit_id_hash_tabl
case VM_OP_MULTIPLICATION: case VM_OP_MULTIPLICATION:
case VM_OP_REMAINDER: case VM_OP_REMAINDER:
{ {
change_uid (om, lit_ids, 0x111); change_uid (om_p, lit_ids, 0x111);
break; break;
} }
case VM_OP_CALL_N: case VM_OP_CALL_N:
@@ -273,18 +323,18 @@ generate_instr (scopes_tree tree, vm_instr_counter_t instr_pos, lit_id_hash_tabl
case VM_OP_UNARY_PLUS: case VM_OP_UNARY_PLUS:
case VM_OP_UNARY_MINUS: case VM_OP_UNARY_MINUS:
{ {
change_uid (om, lit_ids, 0x110); change_uid (om_p, lit_ids, 0x110);
break; break;
} }
case VM_OP_ASSIGNMENT: case VM_OP_ASSIGNMENT:
{ {
switch (om->op.data.assignment.type_value_right) switch (om_p->op.data.assignment.type_value_right)
{ {
case OPCODE_ARG_TYPE_SIMPLE: case OPCODE_ARG_TYPE_SIMPLE:
case OPCODE_ARG_TYPE_SMALLINT: case OPCODE_ARG_TYPE_SMALLINT:
case OPCODE_ARG_TYPE_SMALLINT_NEGATE: case OPCODE_ARG_TYPE_SMALLINT_NEGATE:
{ {
change_uid (om, lit_ids, 0x100); change_uid (om_p, lit_ids, 0x100);
break; break;
} }
case OPCODE_ARG_TYPE_NUMBER: case OPCODE_ARG_TYPE_NUMBER:
@@ -293,7 +343,7 @@ generate_instr (scopes_tree tree, vm_instr_counter_t instr_pos, lit_id_hash_tabl
case OPCODE_ARG_TYPE_STRING: case OPCODE_ARG_TYPE_STRING:
case OPCODE_ARG_TYPE_VARIABLE: case OPCODE_ARG_TYPE_VARIABLE:
{ {
change_uid (om, lit_ids, 0x101); change_uid (om_p, lit_ids, 0x101);
break; break;
} }
} }
@@ -313,7 +363,7 @@ generate_instr (scopes_tree tree, vm_instr_counter_t instr_pos, lit_id_hash_tabl
case VM_OP_VAR_DECL: case VM_OP_VAR_DECL:
case VM_OP_RETVAL: case VM_OP_RETVAL:
{ {
change_uid (om, lit_ids, 0x100); change_uid (om_p, lit_ids, 0x100);
break; break;
} }
case VM_OP_RET: case VM_OP_RET:
@@ -322,24 +372,24 @@ generate_instr (scopes_tree tree, vm_instr_counter_t instr_pos, lit_id_hash_tabl
case VM_OP_JMP_DOWN: case VM_OP_JMP_DOWN:
case VM_OP_REG_VAR_DECL: case VM_OP_REG_VAR_DECL:
{ {
change_uid (om, lit_ids, 0x000); change_uid (om_p, lit_ids, 0x000);
break; break;
} }
case VM_OP_META: case VM_OP_META:
{ {
switch (om->op.data.meta.type) switch (om_p->op.data.meta.type)
{ {
case OPCODE_META_TYPE_VARG_PROP_DATA: case OPCODE_META_TYPE_VARG_PROP_DATA:
case OPCODE_META_TYPE_VARG_PROP_GETTER: case OPCODE_META_TYPE_VARG_PROP_GETTER:
case OPCODE_META_TYPE_VARG_PROP_SETTER: case OPCODE_META_TYPE_VARG_PROP_SETTER:
{ {
change_uid (om, lit_ids, 0x011); change_uid (om_p, lit_ids, 0x011);
break; break;
} }
case OPCODE_META_TYPE_VARG: case OPCODE_META_TYPE_VARG:
case OPCODE_META_TYPE_CATCH_EXCEPTION_IDENTIFIER: case OPCODE_META_TYPE_CATCH_EXCEPTION_IDENTIFIER:
{ {
change_uid (om, lit_ids, 0x010); change_uid (om_p, lit_ids, 0x010);
break; break;
} }
case OPCODE_META_TYPE_UNDEFINED: case OPCODE_META_TYPE_UNDEFINED:
@@ -351,23 +401,27 @@ generate_instr (scopes_tree tree, vm_instr_counter_t instr_pos, lit_id_hash_tabl
case OPCODE_META_TYPE_CALL_SITE_INFO: case OPCODE_META_TYPE_CALL_SITE_INFO:
case OPCODE_META_TYPE_SCOPE_CODE_FLAGS: case OPCODE_META_TYPE_SCOPE_CODE_FLAGS:
{ {
change_uid (om, lit_ids, 0x000); change_uid (om_p, lit_ids, 0x000);
break; break;
} }
} }
break; break;
} }
} }
return om->op; return om_p->op;
} } /* generate_instr */
/**
* Count number of literals in instruction which were not seen previously
*
* @return number of new literals
*/
static idx_t static idx_t
count_new_literals_in_instr (scopes_tree tree, vm_instr_counter_t instr_pos) count_new_literals_in_instr (op_meta *om_p) /**< instruction */
{ {
start_new_block_if_necessary (); start_new_block_if_necessary ();
idx_t current_uid = next_uid; idx_t current_uid = next_uid;
op_meta *om = extract_op_meta (tree, instr_pos); switch (om_p->op.op_idx)
switch (om->op.op_idx)
{ {
case VM_OP_PROP_GETTER: case VM_OP_PROP_GETTER:
case VM_OP_PROP_SETTER: case VM_OP_PROP_SETTER:
@@ -394,7 +448,7 @@ count_new_literals_in_instr (scopes_tree tree, vm_instr_counter_t instr_pos)
case VM_OP_MULTIPLICATION: case VM_OP_MULTIPLICATION:
case VM_OP_REMAINDER: case VM_OP_REMAINDER:
{ {
insert_uids_to_lit_id_map (om, 0x111); insert_uids_to_lit_id_map (om_p, 0x111);
break; break;
} }
case VM_OP_CALL_N: case VM_OP_CALL_N:
@@ -411,18 +465,18 @@ count_new_literals_in_instr (scopes_tree tree, vm_instr_counter_t instr_pos)
case VM_OP_UNARY_PLUS: case VM_OP_UNARY_PLUS:
case VM_OP_UNARY_MINUS: case VM_OP_UNARY_MINUS:
{ {
insert_uids_to_lit_id_map (om, 0x110); insert_uids_to_lit_id_map (om_p, 0x110);
break; break;
} }
case VM_OP_ASSIGNMENT: case VM_OP_ASSIGNMENT:
{ {
switch (om->op.data.assignment.type_value_right) switch (om_p->op.data.assignment.type_value_right)
{ {
case OPCODE_ARG_TYPE_SIMPLE: case OPCODE_ARG_TYPE_SIMPLE:
case OPCODE_ARG_TYPE_SMALLINT: case OPCODE_ARG_TYPE_SMALLINT:
case OPCODE_ARG_TYPE_SMALLINT_NEGATE: case OPCODE_ARG_TYPE_SMALLINT_NEGATE:
{ {
insert_uids_to_lit_id_map (om, 0x100); insert_uids_to_lit_id_map (om_p, 0x100);
break; break;
} }
case OPCODE_ARG_TYPE_NUMBER: case OPCODE_ARG_TYPE_NUMBER:
@@ -431,7 +485,7 @@ count_new_literals_in_instr (scopes_tree tree, vm_instr_counter_t instr_pos)
case OPCODE_ARG_TYPE_STRING: case OPCODE_ARG_TYPE_STRING:
case OPCODE_ARG_TYPE_VARIABLE: case OPCODE_ARG_TYPE_VARIABLE:
{ {
insert_uids_to_lit_id_map (om, 0x101); insert_uids_to_lit_id_map (om_p, 0x101);
break; break;
} }
} }
@@ -450,7 +504,7 @@ count_new_literals_in_instr (scopes_tree tree, vm_instr_counter_t instr_pos)
case VM_OP_VAR_DECL: case VM_OP_VAR_DECL:
case VM_OP_RETVAL: case VM_OP_RETVAL:
{ {
insert_uids_to_lit_id_map (om, 0x100); insert_uids_to_lit_id_map (om_p, 0x100);
break; break;
} }
case VM_OP_RET: case VM_OP_RET:
@@ -459,24 +513,24 @@ count_new_literals_in_instr (scopes_tree tree, vm_instr_counter_t instr_pos)
case VM_OP_JMP_DOWN: case VM_OP_JMP_DOWN:
case VM_OP_REG_VAR_DECL: case VM_OP_REG_VAR_DECL:
{ {
insert_uids_to_lit_id_map (om, 0x000); insert_uids_to_lit_id_map (om_p, 0x000);
break; break;
} }
case VM_OP_META: case VM_OP_META:
{ {
switch (om->op.data.meta.type) switch (om_p->op.data.meta.type)
{ {
case OPCODE_META_TYPE_VARG_PROP_DATA: case OPCODE_META_TYPE_VARG_PROP_DATA:
case OPCODE_META_TYPE_VARG_PROP_GETTER: case OPCODE_META_TYPE_VARG_PROP_GETTER:
case OPCODE_META_TYPE_VARG_PROP_SETTER: case OPCODE_META_TYPE_VARG_PROP_SETTER:
{ {
insert_uids_to_lit_id_map (om, 0x011); insert_uids_to_lit_id_map (om_p, 0x011);
break; break;
} }
case OPCODE_META_TYPE_VARG: case OPCODE_META_TYPE_VARG:
case OPCODE_META_TYPE_CATCH_EXCEPTION_IDENTIFIER: case OPCODE_META_TYPE_CATCH_EXCEPTION_IDENTIFIER:
{ {
insert_uids_to_lit_id_map (om, 0x010); insert_uids_to_lit_id_map (om_p, 0x010);
break; break;
} }
case OPCODE_META_TYPE_UNDEFINED: case OPCODE_META_TYPE_UNDEFINED:
@@ -488,7 +542,7 @@ count_new_literals_in_instr (scopes_tree tree, vm_instr_counter_t instr_pos)
case OPCODE_META_TYPE_CALL_SITE_INFO: case OPCODE_META_TYPE_CALL_SITE_INFO:
case OPCODE_META_TYPE_SCOPE_CODE_FLAGS: case OPCODE_META_TYPE_SCOPE_CODE_FLAGS:
{ {
insert_uids_to_lit_id_map (om, 0x000); insert_uids_to_lit_id_map (om_p, 0x000);
break; break;
} }
} }
@@ -496,16 +550,23 @@ count_new_literals_in_instr (scopes_tree tree, vm_instr_counter_t instr_pos)
} }
} }
return (idx_t) (next_uid - current_uid); return (idx_t) (next_uid - current_uid);
} } /* count_new_literals_in_instr */
/* Before filling literal indexes 'hash' table we shall initiate it with number of neccesary literal indexes. /**
Since bytecode is divided into blocks and id of the block is a part of hash key, we shall divide bytecode * Count slots needed for a scope's hash table
into blocks and count unique literal indexes used in each block. */ *
* Before filling literal indexes 'hash' table we shall initiate it with number of neccesary literal indexes.
* Since bytecode is divided into blocks and id of the block is a part of hash key, we shall divide bytecode
* into blocks and count unique literal indexes used in each block.
*
* @return total number of literals in scope
*/
size_t size_t
scopes_tree_count_literals_in_blocks (scopes_tree tree) scopes_tree_count_literals_in_blocks (scopes_tree tree) /**< scope */
{ {
assert_tree (tree); assert_tree (tree);
size_t result = 0; size_t result = 0;
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);
@@ -517,79 +578,99 @@ scopes_tree_count_literals_in_blocks (scopes_tree tree)
assert_tree (tree); assert_tree (tree);
vm_instr_counter_t instr_pos; vm_instr_counter_t instr_pos;
bool header = true; bool header = true;
for (instr_pos = 0; instr_pos < tree->instrs_num; instr_pos++) for (instr_pos = 0; instr_pos < tree->instrs_count; instr_pos++)
{ {
op_meta *om = extract_op_meta (tree, instr_pos); op_meta *om_p = extract_op_meta (tree->instrs, instr_pos);
if (om->op.op_idx != VM_OP_VAR_DECL if (om_p->op.op_idx != VM_OP_META && !header)
&& om->op.op_idx != VM_OP_META && !header)
{ {
break; break;
} }
if (om->op.op_idx == VM_OP_REG_VAR_DECL) if (om_p->op.op_idx == VM_OP_REG_VAR_DECL)
{ {
header = false; header = false;
} }
result += count_new_literals_in_instr (tree, instr_pos); result += count_new_literals_in_instr (om_p);
} }
for (vm_instr_counter_t var_decl_pos = 0; var_decl_pos < tree->var_decls_cout; var_decl_pos++)
{
op_meta *om_p = extract_op_meta (tree->var_decls, var_decl_pos);
result += count_new_literals_in_instr (om_p);
}
for (uint8_t child_id = 0; child_id < tree->t.children_num; child_id++) for (uint8_t child_id = 0; child_id < tree->t.children_num; child_id++)
{ {
result += scopes_tree_count_literals_in_blocks (*(scopes_tree *) linked_list_element (tree->t.children, child_id)); result += scopes_tree_count_literals_in_blocks (*(scopes_tree *) linked_list_element (tree->t.children, child_id));
} }
for (; instr_pos < tree->instrs_num; instr_pos++)
for (; instr_pos < tree->instrs_count; instr_pos++)
{ {
result += count_new_literals_in_instr (tree, instr_pos); op_meta *om_p = extract_op_meta (tree->instrs, instr_pos);
result += count_new_literals_in_instr (om_p);
} }
return result; return result;
} } /* scopes_tree_count_literals_in_blocks */
/* This function performs functions hoisting. /*
* This function performs functions hoisting.
Each scope consists of four parts: *
1) Header with 'use strict' marker and reg_var_decl opcode * Each scope consists of four parts:
2) Variable declarations, dumped by the preparser * 1) Header with 'use strict' marker and reg_var_decl opcode
3) Function declarations * 2) Variable declarations, dumped by the preparser
4) Computational code * 3) Function declarations
* 4) Computational code
Header and var_decls are dumped first, *
then we shall recursively dump function declaration, * Header and var_decls are dumped first,
and finally, other instructions. * then we shall recursively dump function declaration,
* and finally, other instructions.
For each instructions block (size of block is defined in bytecode-data.h) *
literal indexes 'hash' table is filled. */ * For each instructions block (size of block is defined in bytecode-data.h)
* literal indexes 'hash' table is filled.
*/
static void static void
merge_subscopes (scopes_tree tree, vm_instr_t *data, lit_id_hash_table *lit_ids) merge_subscopes (scopes_tree tree, /**< scopes tree to merge */
vm_instr_t *data_p, /**< instruction array, where the scopes are merged to */
lit_id_hash_table *lit_ids_p) /**< literal indexes 'hash' table */
{ {
assert_tree (tree); assert_tree (tree);
JERRY_ASSERT (data); JERRY_ASSERT (data_p);
vm_instr_counter_t instr_pos; vm_instr_counter_t instr_pos;
bool header = true; bool header = true;
for (instr_pos = 0; instr_pos < tree->instrs_num; instr_pos++) for (instr_pos = 0; instr_pos < tree->instrs_count; instr_pos++)
{ {
op_meta *om = extract_op_meta (tree, instr_pos); op_meta *om_p = extract_op_meta (tree->instrs, instr_pos);
if (om->op.op_idx != VM_OP_VAR_DECL if (om_p->op.op_idx != VM_OP_VAR_DECL
&& om->op.op_idx != VM_OP_META && !header) && om_p->op.op_idx != VM_OP_META && !header)
{ {
break; break;
} }
if (om->op.op_idx == VM_OP_REG_VAR_DECL) if (om_p->op.op_idx == VM_OP_REG_VAR_DECL)
{ {
header = false; header = false;
} }
data[global_oc] = generate_instr (tree, instr_pos, lit_ids); data_p[global_oc] = generate_instr (tree->instrs, instr_pos, lit_ids_p);
global_oc++; global_oc++;
} }
for (vm_instr_counter_t var_decl_pos = 0; var_decl_pos < tree->var_decls_cout; var_decl_pos++)
{
data_p[global_oc] = generate_instr (tree->var_decls, var_decl_pos, lit_ids_p);
global_oc++;
}
for (uint8_t child_id = 0; child_id < tree->t.children_num; child_id++) for (uint8_t child_id = 0; child_id < tree->t.children_num; child_id++)
{ {
merge_subscopes (*(scopes_tree *) linked_list_element (tree->t.children, child_id), merge_subscopes (*(scopes_tree *) linked_list_element (tree->t.children, child_id),
data, lit_ids); data_p, lit_ids_p);
} }
for (; instr_pos < tree->instrs_num; instr_pos++)
for (; instr_pos < tree->instrs_count; instr_pos++)
{ {
data[global_oc] = generate_instr (tree, instr_pos, lit_ids); data_p[global_oc] = generate_instr (tree->instrs, instr_pos, lit_ids_p);
global_oc++; global_oc++;
} }
} } /* merge_subscopes */
/* Postparser. /* Postparser.
Init literal indexes 'hash' table. Init literal indexes 'hash' table.
@@ -631,12 +712,36 @@ scopes_tree_raw_data (scopes_tree tree, /**< scopes tree to convert to byte-code
return instrs; return instrs;
} /* scopes_tree_raw_data */ } /* scopes_tree_raw_data */
/**
* Set up a flag, indicating that scope should be executed in strict mode
*/
void void
scopes_tree_set_strict_mode (scopes_tree tree, bool strict_mode) scopes_tree_set_strict_mode (scopes_tree tree, /**< scope */
bool strict_mode) /**< value of the strict mode flag */
{ {
assert_tree (tree); assert_tree (tree);
tree->strict_mode = strict_mode ? 1 : 0; tree->strict_mode = strict_mode;
} } /* scopes_tree_set_strict_mode */
/**
* Set up a flag, indicating that "arguments" is used inside a scope
*/
void
scopes_tree_set_arguments_used (scopes_tree tree) /**< scope */
{
assert_tree (tree);
tree->ref_arguments = true;
} /* merge_subscopes */
/**
* Set up a flag, indicating that "eval" is used inside a scope
*/
void
scopes_tree_set_eval_used (scopes_tree tree) /**< scope */
{
assert_tree (tree);
tree->ref_eval = true;
} /* scopes_tree_set_eval_used */
bool bool
scopes_tree_strict_mode (scopes_tree tree) scopes_tree_strict_mode (scopes_tree tree)
@@ -645,8 +750,13 @@ scopes_tree_strict_mode (scopes_tree tree)
return (bool) tree->strict_mode; return (bool) tree->strict_mode;
} }
/**
* Initialize a scope
*
* @return initialized scope
*/
scopes_tree scopes_tree
scopes_tree_init (scopes_tree parent) scopes_tree_init (scopes_tree parent) /**< parent scope */
{ {
scopes_tree tree = (scopes_tree) jsp_mm_alloc (sizeof (scopes_tree_int)); scopes_tree tree = (scopes_tree) jsp_mm_alloc (sizeof (scopes_tree_int));
memset (tree, 0, sizeof (scopes_tree_int)); memset (tree, 0, sizeof (scopes_tree_int));
@@ -664,11 +774,15 @@ scopes_tree_init (scopes_tree parent)
JERRY_ASSERT (*(scopes_tree *) added == tree); JERRY_ASSERT (*(scopes_tree *) added == tree);
parent->t.children_num++; parent->t.children_num++;
} }
tree->instrs_num = 0; tree->instrs_count = 0;
tree->strict_mode = 0; tree->strict_mode = false;
tree->ref_eval = false;
tree->ref_arguments = false;
tree->instrs = linked_list_init (sizeof (op_meta)); tree->instrs = linked_list_init (sizeof (op_meta));
tree->var_decls_cout = 0;
tree->var_decls = linked_list_init (sizeof (op_meta));
return tree; return tree;
} } /* scopes_tree_init */
void void
scopes_tree_free (scopes_tree tree) scopes_tree_free (scopes_tree tree)
@@ -683,5 +797,6 @@ scopes_tree_free (scopes_tree tree)
linked_list_free (tree->t.children); linked_list_free (tree->t.children);
} }
linked_list_free (tree->instrs); linked_list_free (tree->instrs);
linked_list_free (tree->var_decls);
jsp_mm_free (tree); jsp_mm_free (tree);
} }
+16 -4
View File
@@ -39,12 +39,19 @@ typedef struct tree_header
uint8_t children_num; uint8_t children_num;
} tree_header; } tree_header;
/**
* Structure for holding scope information during parsing
*/
typedef struct typedef struct
{ {
tree_header t; tree_header t; /**< header */
linked_list instrs; linked_list instrs; /**< instructions */
vm_instr_counter_t instrs_num; vm_instr_counter_t instrs_count; /**< count of instructions */
unsigned strict_mode:1; linked_list var_decls; /**< instructions for variable declarations */
uint8_t var_decls_cout; /**< number of instructions for variable declarations */
bool strict_mode: 1; /**< flag, indicating that scope's code should be executed in strict mode */
bool ref_arguments: 1; /**< flag, indicating that "arguments" variable is used inside the scope */
bool ref_eval: 1; /**< flag, indicating that "eval" is used inside the scope */
} scopes_tree_int; } scopes_tree_int;
typedef scopes_tree_int * scopes_tree; typedef scopes_tree_int * scopes_tree;
@@ -52,14 +59,19 @@ typedef scopes_tree_int * scopes_tree;
scopes_tree scopes_tree_init (scopes_tree); scopes_tree scopes_tree_init (scopes_tree);
void scopes_tree_free (scopes_tree); void scopes_tree_free (scopes_tree);
vm_instr_counter_t scopes_tree_instrs_num (scopes_tree); vm_instr_counter_t scopes_tree_instrs_num (scopes_tree);
vm_instr_counter_t scopes_tree_var_decls_num (scopes_tree);
void scopes_tree_add_op_meta (scopes_tree, op_meta); void scopes_tree_add_op_meta (scopes_tree, op_meta);
void scopes_tree_add_var_decl (scopes_tree, op_meta);
void scopes_tree_set_op_meta (scopes_tree, vm_instr_counter_t, op_meta); void scopes_tree_set_op_meta (scopes_tree, vm_instr_counter_t, op_meta);
void scopes_tree_set_instrs_num (scopes_tree, vm_instr_counter_t); void scopes_tree_set_instrs_num (scopes_tree, vm_instr_counter_t);
op_meta scopes_tree_op_meta (scopes_tree, vm_instr_counter_t); op_meta scopes_tree_op_meta (scopes_tree, vm_instr_counter_t);
op_meta scopes_tree_var_decl (scopes_tree, vm_instr_counter_t);
size_t scopes_tree_count_literals_in_blocks (scopes_tree); size_t scopes_tree_count_literals_in_blocks (scopes_tree);
vm_instr_counter_t scopes_tree_count_instructions (scopes_tree); vm_instr_counter_t scopes_tree_count_instructions (scopes_tree);
vm_instr_t *scopes_tree_raw_data (scopes_tree, uint8_t *, size_t, lit_id_hash_table *); vm_instr_t *scopes_tree_raw_data (scopes_tree, uint8_t *, size_t, lit_id_hash_table *);
void scopes_tree_set_strict_mode (scopes_tree, bool); void scopes_tree_set_strict_mode (scopes_tree, bool);
void scopes_tree_set_arguments_used (scopes_tree);
void scopes_tree_set_eval_used (scopes_tree);
bool scopes_tree_strict_mode (scopes_tree); bool scopes_tree_strict_mode (scopes_tree);
#endif /* SCOPES_TREE_H */ #endif /* SCOPES_TREE_H */
+49 -9
View File
@@ -17,6 +17,7 @@
#include "bytecode-data.h" #include "bytecode-data.h"
#include "pretty-printer.h" #include "pretty-printer.h"
#include "array-list.h" #include "array-list.h"
#include "scopes-tree.h"
static bytecode_data_t bytecode_data; static bytecode_data_t bytecode_data;
static scopes_tree current_scope; static scopes_tree current_scope;
@@ -33,6 +34,18 @@ serializer_get_op_meta (vm_instr_counter_t oc)
return scopes_tree_op_meta (current_scope, oc); return scopes_tree_op_meta (current_scope, oc);
} }
/**
* Get variable declaration of the current scope
*
* @return variable declaration instruction
*/
op_meta
serializer_get_var_decl (vm_instr_counter_t oc) /**< index of variable declaration */
{
JERRY_ASSERT (current_scope);
return scopes_tree_var_decl (current_scope, oc);
} /* serializer_get_var_decl */
/** /**
* Get byte-code instruction from current scope, or specified byte-code array * Get byte-code instruction from current scope, or specified byte-code array
* *
@@ -102,28 +115,33 @@ serializer_dump_subscope (scopes_tree tree) /**< scope to dump */
JERRY_ASSERT (tree != NULL); JERRY_ASSERT (tree != NULL);
vm_instr_counter_t instr_pos; vm_instr_counter_t instr_pos;
bool header = true; bool header = true;
for (instr_pos = 0; instr_pos < tree->instrs_num; instr_pos++) for (instr_pos = 0; instr_pos < tree->instrs_count; instr_pos++)
{ {
op_meta *om = (op_meta *) linked_list_element (tree->instrs, instr_pos); op_meta *om_p = (op_meta *) linked_list_element (tree->instrs, instr_pos);
if (om->op.op_idx != VM_OP_VAR_DECL if (om_p->op.op_idx != VM_OP_VAR_DECL
&& om->op.op_idx != VM_OP_META && !header) && om_p->op.op_idx != VM_OP_META && !header)
{ {
break; break;
} }
if (om->op.op_idx == VM_OP_REG_VAR_DECL) if (om_p->op.op_idx == VM_OP_REG_VAR_DECL)
{ {
header = false; header = false;
} }
scopes_tree_add_op_meta (current_scope, *om); scopes_tree_add_op_meta (current_scope, *om_p);
}
for (vm_instr_counter_t var_decl_pos = 0; var_decl_pos < tree->var_decls_cout; var_decl_pos++)
{
op_meta *om_p = (op_meta *) linked_list_element (tree->var_decls, var_decl_pos);
scopes_tree_add_op_meta (current_scope, *om_p);
} }
for (uint8_t child_id = 0; child_id < tree->t.children_num; child_id++) for (uint8_t child_id = 0; child_id < tree->t.children_num; child_id++)
{ {
serializer_dump_subscope (*(scopes_tree *) linked_list_element (tree->t.children, child_id)); serializer_dump_subscope (*(scopes_tree *) linked_list_element (tree->t.children, child_id));
} }
for (; instr_pos < tree->instrs_num; instr_pos++) for (; instr_pos < tree->instrs_count; instr_pos++)
{ {
op_meta *om = (op_meta *) linked_list_element (tree->instrs, instr_pos); op_meta *om_p = (op_meta *) linked_list_element (tree->instrs, instr_pos);
scopes_tree_add_op_meta (current_scope, *om); scopes_tree_add_op_meta (current_scope, *om_p);
} }
} /* serializer_dump_subscope */ } /* serializer_dump_subscope */
@@ -180,12 +198,34 @@ serializer_dump_op_meta (op_meta op)
#endif #endif
} }
/**
* Dump variable declaration into the current scope
*/
void
serializer_dump_var_decl (op_meta op) /**< variable declaration instruction */
{
JERRY_ASSERT (scopes_tree_instrs_num (current_scope) + current_scope->var_decls_cout < MAX_OPCODES);
scopes_tree_add_var_decl (current_scope, op);
} /* serializer_dump_var_decl */
vm_instr_counter_t vm_instr_counter_t
serializer_get_current_instr_counter (void) serializer_get_current_instr_counter (void)
{ {
return scopes_tree_instrs_num (current_scope); return scopes_tree_instrs_num (current_scope);
} }
/**
* Get number of variable declarations in the current scope
*
* @return count of variable declarations
*/
vm_instr_counter_t
serializer_get_current_var_decls_counter (void)
{
return scopes_tree_var_decls_num (current_scope);
} /* serializer_get_current_var_decls_counter */
vm_instr_counter_t vm_instr_counter_t
serializer_count_instrs_in_subscopes (void) serializer_count_instrs_in_subscopes (void)
{ {
+3
View File
@@ -25,6 +25,7 @@
void serializer_init (); void serializer_init ();
void serializer_set_show_instrs (bool show_instrs); void serializer_set_show_instrs (bool show_instrs);
op_meta serializer_get_op_meta (vm_instr_counter_t); op_meta serializer_get_op_meta (vm_instr_counter_t);
op_meta serializer_get_var_decl (vm_instr_counter_t);
vm_instr_t serializer_get_instr (const vm_instr_t*, vm_instr_counter_t); vm_instr_t serializer_get_instr (const vm_instr_t*, vm_instr_counter_t);
lit_cpointer_t serializer_get_literal_cp_by_uid (uint8_t, const vm_instr_t*, vm_instr_counter_t); lit_cpointer_t serializer_get_literal_cp_by_uid (uint8_t, const vm_instr_t*, vm_instr_counter_t);
void serializer_set_strings_buffer (const ecma_char_t *); void serializer_set_strings_buffer (const ecma_char_t *);
@@ -32,7 +33,9 @@ void serializer_set_scope (scopes_tree);
void serializer_dump_subscope (scopes_tree); void serializer_dump_subscope (scopes_tree);
const vm_instr_t *serializer_merge_scopes_into_bytecode (void); const vm_instr_t *serializer_merge_scopes_into_bytecode (void);
void serializer_dump_op_meta (op_meta); void serializer_dump_op_meta (op_meta);
void serializer_dump_var_decl (op_meta);
vm_instr_counter_t serializer_get_current_instr_counter (void); vm_instr_counter_t serializer_get_current_instr_counter (void);
vm_instr_counter_t serializer_get_current_var_decls_counter (void);
vm_instr_counter_t serializer_count_instrs_in_subscopes (void); vm_instr_counter_t serializer_count_instrs_in_subscopes (void);
void serializer_set_writing_position (vm_instr_counter_t); void serializer_set_writing_position (vm_instr_counter_t);
void serializer_rewrite_op_meta (vm_instr_counter_t, op_meta); void serializer_rewrite_op_meta (vm_instr_counter_t, op_meta);
+3
View File
@@ -1810,6 +1810,7 @@ vm_read_instr_counter_from_meta (opcode_meta_type expected_type, /**< expected t
vm_instr_t getop_##opcode_name (void) \ vm_instr_t getop_##opcode_name (void) \
{ \ { \
vm_instr_t instr; \ vm_instr_t instr; \
memset (&instr, 0, sizeof(instr)); \
instr.op_idx = VM_OP_##opcode_name_uppercase; \ instr.op_idx = VM_OP_##opcode_name_uppercase; \
return instr; \ return instr; \
} }
@@ -1817,6 +1818,7 @@ vm_read_instr_counter_from_meta (opcode_meta_type expected_type, /**< expected t
vm_instr_t getop_##opcode_name (idx_t arg1_v) \ vm_instr_t getop_##opcode_name (idx_t arg1_v) \
{ \ { \
vm_instr_t instr; \ vm_instr_t instr; \
memset (&instr, 0, sizeof(instr)); \
instr.op_idx = VM_OP_##opcode_name_uppercase; \ instr.op_idx = VM_OP_##opcode_name_uppercase; \
instr.data.opcode_name.arg1 = arg1_v; \ instr.data.opcode_name.arg1 = arg1_v; \
return instr; \ return instr; \
@@ -1825,6 +1827,7 @@ vm_read_instr_counter_from_meta (opcode_meta_type expected_type, /**< expected t
vm_instr_t getop_##opcode_name (idx_t arg1_v, idx_t arg2_v) \ vm_instr_t getop_##opcode_name (idx_t arg1_v, idx_t arg2_v) \
{ \ { \
vm_instr_t instr; \ vm_instr_t instr; \
memset (&instr, 0, sizeof(instr)); \
instr.op_idx = VM_OP_##opcode_name_uppercase; \ instr.op_idx = VM_OP_##opcode_name_uppercase; \
instr.data.opcode_name.arg1 = arg1_v; \ instr.data.opcode_name.arg1 = arg1_v; \
instr.data.opcode_name.arg2 = arg2_v; \ instr.data.opcode_name.arg2 = arg2_v; \