Freaking FINALLY: postparser
This commit is contained in:
@@ -32,8 +32,8 @@ opfunc_try (opcode_t opdata, /**< operation data */
|
|||||||
{
|
{
|
||||||
const idx_t block_end_oc_idx_1 = opdata.data.try.oc_idx_1;
|
const idx_t block_end_oc_idx_1 = opdata.data.try.oc_idx_1;
|
||||||
const idx_t block_end_oc_idx_2 = opdata.data.try.oc_idx_2;
|
const idx_t block_end_oc_idx_2 = opdata.data.try.oc_idx_2;
|
||||||
const opcode_counter_t try_end_oc = calc_opcode_counter_from_idx_idx (block_end_oc_idx_1,
|
const opcode_counter_t try_end_oc = (opcode_counter_t) (
|
||||||
block_end_oc_idx_2);
|
calc_opcode_counter_from_idx_idx (block_end_oc_idx_1, block_end_oc_idx_2) + int_data->pos);
|
||||||
|
|
||||||
int_data->pos++;
|
int_data->pos++;
|
||||||
|
|
||||||
@@ -52,8 +52,8 @@ opfunc_try (opcode_t opdata, /**< operation data */
|
|||||||
|
|
||||||
if (next_opcode.data.meta.type == OPCODE_META_TYPE_CATCH)
|
if (next_opcode.data.meta.type == OPCODE_META_TYPE_CATCH)
|
||||||
{
|
{
|
||||||
const opcode_counter_t catch_end_oc = read_meta_opcode_counter (OPCODE_META_TYPE_CATCH,
|
const opcode_counter_t catch_end_oc = (opcode_counter_t) (
|
||||||
int_data);
|
read_meta_opcode_counter (OPCODE_META_TYPE_CATCH, int_data) + int_data->pos);
|
||||||
int_data->pos++;
|
int_data->pos++;
|
||||||
|
|
||||||
if (ecma_is_completion_value_throw (try_completion))
|
if (ecma_is_completion_value_throw (try_completion))
|
||||||
@@ -105,8 +105,8 @@ opfunc_try (opcode_t opdata, /**< operation data */
|
|||||||
|
|
||||||
if (next_opcode.data.meta.type == OPCODE_META_TYPE_FINALLY)
|
if (next_opcode.data.meta.type == OPCODE_META_TYPE_FINALLY)
|
||||||
{
|
{
|
||||||
const opcode_counter_t finally_end_oc = read_meta_opcode_counter (OPCODE_META_TYPE_FINALLY,
|
const opcode_counter_t finally_end_oc = (opcode_counter_t) (
|
||||||
int_data);
|
read_meta_opcode_counter (OPCODE_META_TYPE_FINALLY, int_data) + int_data->pos);
|
||||||
int_data->pos++;
|
int_data->pos++;
|
||||||
|
|
||||||
ecma_completion_value_t finally_completion = run_int_loop (int_data);
|
ecma_completion_value_t finally_completion = run_int_loop (int_data);
|
||||||
|
|||||||
@@ -414,7 +414,8 @@ function_declaration (int_data_t *int_data, /**< interpreter context */
|
|||||||
bool is_strict = int_data->is_strict;
|
bool is_strict = int_data->is_strict;
|
||||||
const bool is_configurable_bindings = int_data->is_eval_code;
|
const bool is_configurable_bindings = int_data->is_eval_code;
|
||||||
|
|
||||||
const opcode_counter_t function_code_end_oc = read_meta_opcode_counter (OPCODE_META_TYPE_FUNCTION_END, int_data);
|
const opcode_counter_t function_code_end_oc = (opcode_counter_t) (
|
||||||
|
read_meta_opcode_counter (OPCODE_META_TYPE_FUNCTION_END, int_data) + int_data->pos);
|
||||||
int_data->pos++;
|
int_data->pos++;
|
||||||
|
|
||||||
opcode_t next_opcode = read_opcode (int_data->pos);
|
opcode_t next_opcode = read_opcode (int_data->pos);
|
||||||
@@ -497,7 +498,8 @@ opfunc_func_expr_n (opcode_t opdata, /**< operation data */
|
|||||||
|
|
||||||
bool is_strict = int_data->is_strict;
|
bool is_strict = int_data->is_strict;
|
||||||
|
|
||||||
const opcode_counter_t function_code_end_oc = read_meta_opcode_counter (OPCODE_META_TYPE_FUNCTION_END, int_data);
|
const opcode_counter_t function_code_end_oc = (opcode_counter_t) (
|
||||||
|
read_meta_opcode_counter (OPCODE_META_TYPE_FUNCTION_END, int_data) + int_data->pos);
|
||||||
int_data->pos++;
|
int_data->pos++;
|
||||||
|
|
||||||
opcode_t next_opcode = read_opcode (int_data->pos);
|
opcode_t next_opcode = read_opcode (int_data->pos);
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ typedef enum
|
|||||||
OPCODE_META_TYPE_VARG_PROP_GETTER, /**< name (lit_idx) and getter (var_idx) for an accessor property descriptor */
|
OPCODE_META_TYPE_VARG_PROP_GETTER, /**< name (lit_idx) and getter (var_idx) for an accessor property descriptor */
|
||||||
OPCODE_META_TYPE_VARG_PROP_SETTER, /**< name (lit_idx) and setter (var_idx) for an accessor property descriptor */
|
OPCODE_META_TYPE_VARG_PROP_SETTER, /**< name (lit_idx) and setter (var_idx) for an accessor property descriptor */
|
||||||
OPCODE_META_TYPE_END_WITH, /**< end of with statement */
|
OPCODE_META_TYPE_END_WITH, /**< end of with statement */
|
||||||
OPCODE_META_TYPE_FUNCTION_END, /**< opcode counter */
|
OPCODE_META_TYPE_FUNCTION_END, /**< offset to function end */
|
||||||
OPCODE_META_TYPE_CATCH, /**< mark of beginning of catch block containing pointer to end of catch block */
|
OPCODE_META_TYPE_CATCH, /**< mark of beginning of catch block containing pointer to end of catch block */
|
||||||
OPCODE_META_TYPE_CATCH_EXCEPTION_IDENTIFIER, /**< literal index containing name of variable with exception object */
|
OPCODE_META_TYPE_CATCH_EXCEPTION_IDENTIFIER, /**< literal index containing name of variable with exception object */
|
||||||
OPCODE_META_TYPE_FINALLY, /**< mark of beginning of finally block containing pointer to end of finally block */
|
OPCODE_META_TYPE_FINALLY, /**< mark of beginning of finally block containing pointer to end of finally block */
|
||||||
|
|||||||
+44
-14
@@ -77,13 +77,11 @@ enum
|
|||||||
};
|
};
|
||||||
STATIC_STACK (nestings, uint8_t, uint8_t)
|
STATIC_STACK (nestings, uint8_t, uint8_t)
|
||||||
|
|
||||||
typedef scopes_tree* scopes_tree_p;
|
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
scopes_global_size
|
scopes_global_size
|
||||||
};
|
};
|
||||||
STATIC_STACK (scopes, uint8_t, scopes_tree_p)
|
STATIC_STACK (scopes, uint8_t, scopes_tree)
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
@@ -274,9 +272,9 @@ do { \
|
|||||||
do { \
|
do { \
|
||||||
STACK_DECLARE_USAGE (IDX) \
|
STACK_DECLARE_USAGE (IDX) \
|
||||||
JERRY_STATIC_ASSERT (sizeof (idx_t) == 1); \
|
JERRY_STATIC_ASSERT (sizeof (idx_t) == 1); \
|
||||||
STACK_PUSH (IDX, (idx_t) ((OPCODE_COUNTER ()) >> JERRY_BITSINBYTE)); \
|
STACK_PUSH (IDX, (idx_t) ((OPCODE_COUNTER () - OC) >> JERRY_BITSINBYTE)); \
|
||||||
STACK_PUSH (IDX, (idx_t) ((OPCODE_COUNTER ()) & ((1 << JERRY_BITSINBYTE) - 1))); \
|
STACK_PUSH (IDX, (idx_t) ((OPCODE_COUNTER () - OC) & ((1 << JERRY_BITSINBYTE) - 1))); \
|
||||||
JERRY_ASSERT ((OPCODE_COUNTER ()) \
|
JERRY_ASSERT ((OPCODE_COUNTER () - OC) \
|
||||||
== calc_opcode_counter_from_idx_idx (ID(2), ID(1))); \
|
== calc_opcode_counter_from_idx_idx (ID(2), ID(1))); \
|
||||||
serializer_rewrite_opcode ((OC), getop_try (ID(2), ID(1))); \
|
serializer_rewrite_opcode ((OC), getop_try (ID(2), ID(1))); \
|
||||||
STACK_DROP (IDX, 2); \
|
STACK_DROP (IDX, 2); \
|
||||||
@@ -311,7 +309,7 @@ static void parse_expression (void);
|
|||||||
static void parse_statement (void);
|
static void parse_statement (void);
|
||||||
static void parse_assignment_expression (void);
|
static void parse_assignment_expression (void);
|
||||||
static void parse_source_element_list (bool);
|
static void parse_source_element_list (bool);
|
||||||
static void parse_argument_list (argument_list_type, idx_t, idx_t);
|
static uint8_t parse_argument_list (argument_list_type, idx_t, idx_t);
|
||||||
|
|
||||||
static uint8_t
|
static uint8_t
|
||||||
lp_string_hash (lp_string str)
|
lp_string_hash (lp_string str)
|
||||||
@@ -742,17 +740,17 @@ parse_property_name_and_value (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
rewrite_meta_opcode_counter (opcode_counter_t meta_oc, opcode_meta_type type)
|
rewrite_meta_opcode_counter_set_oc (opcode_counter_t meta_oc, opcode_meta_type type, opcode_counter_t oc)
|
||||||
{
|
{
|
||||||
// IDX oc_idx_1, oc_idx_2
|
// IDX oc_idx_1, oc_idx_2
|
||||||
STACK_DECLARE_USAGE (IDX)
|
STACK_DECLARE_USAGE (IDX)
|
||||||
|
|
||||||
JERRY_STATIC_ASSERT (sizeof (idx_t) == 1);
|
JERRY_STATIC_ASSERT (sizeof (idx_t) == 1);
|
||||||
|
|
||||||
STACK_PUSH (IDX, (idx_t) (OPCODE_COUNTER () >> JERRY_BITSINBYTE));
|
STACK_PUSH (IDX, (idx_t) (oc >> JERRY_BITSINBYTE));
|
||||||
STACK_PUSH (IDX, (idx_t) (OPCODE_COUNTER () & ((1 << JERRY_BITSINBYTE) - 1)));
|
STACK_PUSH (IDX, (idx_t) (oc & ((1 << JERRY_BITSINBYTE) - 1)));
|
||||||
|
|
||||||
JERRY_ASSERT (OPCODE_COUNTER () == calc_opcode_counter_from_idx_idx (ID(2), ID(1)));
|
JERRY_ASSERT (oc == calc_opcode_counter_from_idx_idx (ID(2), ID(1)));
|
||||||
|
|
||||||
REWRITE_OPCODE_3 (meta_oc, meta, type, ID(2), ID(1));
|
REWRITE_OPCODE_3 (meta_oc, meta, type, ID(2), ID(1));
|
||||||
|
|
||||||
@@ -761,6 +759,12 @@ rewrite_meta_opcode_counter (opcode_counter_t meta_oc, opcode_meta_type type)
|
|||||||
STACK_CHECK_USAGE (IDX);
|
STACK_CHECK_USAGE (IDX);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
rewrite_meta_opcode_counter (opcode_counter_t meta_oc, opcode_meta_type type)
|
||||||
|
{
|
||||||
|
rewrite_meta_opcode_counter_set_oc (meta_oc, type, (opcode_counter_t) (OPCODE_COUNTER () - meta_oc));
|
||||||
|
}
|
||||||
|
|
||||||
/* property_assignment
|
/* property_assignment
|
||||||
: property_name_and_value
|
: property_name_and_value
|
||||||
| get LT!* property_name LT!* '(' LT!* ')' LT!* '{' LT!* function_body LT!* '}'
|
| get LT!* property_name LT!* '(' LT!* ')' LT!* '{' LT!* function_body LT!* '}'
|
||||||
@@ -862,7 +866,7 @@ cleanup:
|
|||||||
/** Parse list of identifiers, assigment expressions or properties, splitted by comma.
|
/** Parse list of identifiers, assigment expressions or properties, splitted by comma.
|
||||||
For each ALT dumps appropriate bytecode. Uses OBJ during dump if neccesary.
|
For each ALT dumps appropriate bytecode. Uses OBJ during dump if neccesary.
|
||||||
Returns temp var if expression has lhs, or 0 otherwise. */
|
Returns temp var if expression has lhs, or 0 otherwise. */
|
||||||
static void
|
static uint8_t
|
||||||
parse_argument_list (argument_list_type alt, idx_t obj, idx_t this_arg)
|
parse_argument_list (argument_list_type alt, idx_t obj, idx_t this_arg)
|
||||||
{
|
{
|
||||||
// U8 open_tt, close_tt, args_count
|
// U8 open_tt, close_tt, args_count
|
||||||
@@ -872,6 +876,7 @@ parse_argument_list (argument_list_type alt, idx_t obj, idx_t this_arg)
|
|||||||
STACK_DECLARE_USAGE (U16)
|
STACK_DECLARE_USAGE (U16)
|
||||||
STACK_DECLARE_USAGE (IDX)
|
STACK_DECLARE_USAGE (IDX)
|
||||||
STACK_DECLARE_USAGE (temp_names)
|
STACK_DECLARE_USAGE (temp_names)
|
||||||
|
uint8_t args_num = 0;
|
||||||
|
|
||||||
STACK_PUSH (U16, OPCODE_COUNTER ());
|
STACK_PUSH (U16, OPCODE_COUNTER ());
|
||||||
switch (alt)
|
switch (alt)
|
||||||
@@ -1077,6 +1082,8 @@ next:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
args_num = STACK_TOP (U8);
|
||||||
|
|
||||||
STACK_DROP (U8, 3);
|
STACK_DROP (U8, 3);
|
||||||
STACK_DROP (U16, 1);
|
STACK_DROP (U16, 1);
|
||||||
|
|
||||||
@@ -1094,6 +1101,8 @@ next:
|
|||||||
STACK_CHECK_USAGE_LHS ();
|
STACK_CHECK_USAGE_LHS ();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
return args_num;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* function_declaration
|
/* function_declaration
|
||||||
@@ -1111,6 +1120,12 @@ parse_function_declaration (void)
|
|||||||
STACK_DECLARE_USAGE (IDX)
|
STACK_DECLARE_USAGE (IDX)
|
||||||
STACK_DECLARE_USAGE (U16)
|
STACK_DECLARE_USAGE (U16)
|
||||||
STACK_DECLARE_USAGE (nestings)
|
STACK_DECLARE_USAGE (nestings)
|
||||||
|
STACK_DECLARE_USAGE (scopes)
|
||||||
|
STACK_DECLARE_USAGE (U8)
|
||||||
|
|
||||||
|
SET_OPCODE_COUNTER (0);
|
||||||
|
STACK_PUSH (scopes, scopes_tree_init (STACK_TOP (scopes)));
|
||||||
|
serializer_set_scope (STACK_TOP (scopes));
|
||||||
|
|
||||||
assert_keyword (KW_FUNCTION);
|
assert_keyword (KW_FUNCTION);
|
||||||
|
|
||||||
@@ -1119,7 +1134,7 @@ parse_function_declaration (void)
|
|||||||
STACK_PUSH (IDX, token_data ());
|
STACK_PUSH (IDX, token_data ());
|
||||||
|
|
||||||
skip_newlines ();
|
skip_newlines ();
|
||||||
parse_argument_list (AL_FUNC_DECL, ID(1), INVALID_VALUE);
|
STACK_PUSH (U8, parse_argument_list (AL_FUNC_DECL, ID(1), INVALID_VALUE));
|
||||||
|
|
||||||
STACK_PUSH (U16, OPCODE_COUNTER ());
|
STACK_PUSH (U16, OPCODE_COUNTER ());
|
||||||
DUMP_OPCODE_3 (meta, OPCODE_META_TYPE_UNDEFINED, INVALID_VALUE, INVALID_VALUE);
|
DUMP_OPCODE_3 (meta, OPCODE_META_TYPE_UNDEFINED, INVALID_VALUE, INVALID_VALUE);
|
||||||
@@ -1135,14 +1150,22 @@ parse_function_declaration (void)
|
|||||||
|
|
||||||
DUMP_VOID_OPCODE (ret);
|
DUMP_VOID_OPCODE (ret);
|
||||||
|
|
||||||
rewrite_meta_opcode_counter (STACK_TOP (U16), OPCODE_META_TYPE_FUNCTION_END);
|
rewrite_meta_opcode_counter_set_oc (STACK_TOP (U16), OPCODE_META_TYPE_FUNCTION_END,
|
||||||
|
(opcode_counter_t) (
|
||||||
|
scopes_tree_count_opcodes (STACK_TOP (scopes)) - (STACK_TOP (U8) + 1)));
|
||||||
|
|
||||||
STACK_DROP (U16, 1);
|
STACK_DROP (U16, 1);
|
||||||
|
STACK_DROP (U8, 1);
|
||||||
STACK_DROP (IDX, 1);
|
STACK_DROP (IDX, 1);
|
||||||
|
STACK_DROP (scopes, 1);
|
||||||
|
SET_OPCODE_COUNTER (scopes_tree_opcodes_num (STACK_TOP (scopes)));
|
||||||
|
serializer_set_scope (STACK_TOP (scopes));
|
||||||
|
|
||||||
|
STACK_CHECK_USAGE (U8);
|
||||||
STACK_CHECK_USAGE (IDX);
|
STACK_CHECK_USAGE (IDX);
|
||||||
STACK_CHECK_USAGE (U16);
|
STACK_CHECK_USAGE (U16);
|
||||||
STACK_CHECK_USAGE (nestings);
|
STACK_CHECK_USAGE (nestings);
|
||||||
|
STACK_CHECK_USAGE (scopes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* function_expression
|
/* function_expression
|
||||||
@@ -3547,6 +3570,13 @@ preparse_scope (bool is_global)
|
|||||||
{
|
{
|
||||||
preparse_var_decls ();
|
preparse_var_decls ();
|
||||||
}
|
}
|
||||||
|
else if (is_keyword (KW_FUNCTION))
|
||||||
|
{
|
||||||
|
skip_newlines ();
|
||||||
|
skip_optional_name_and_parens ();
|
||||||
|
skip_newlines ();
|
||||||
|
skip_braces ();
|
||||||
|
}
|
||||||
skip_newlines ();
|
skip_newlines ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,28 +20,28 @@
|
|||||||
#define NAME_TO_ID(op) (__op__idx_##op)
|
#define NAME_TO_ID(op) (__op__idx_##op)
|
||||||
|
|
||||||
static void
|
static void
|
||||||
assert_tree (scopes_tree *t)
|
assert_tree (scopes_tree t)
|
||||||
{
|
{
|
||||||
JERRY_ASSERT (t != NULL);
|
JERRY_ASSERT (t != NULL);
|
||||||
JERRY_ASSERT (t->t.magic == TREE_MAGIC);
|
JERRY_ASSERT (t->t.magic == TREE_MAGIC);
|
||||||
}
|
}
|
||||||
|
|
||||||
opcode_counter_t
|
opcode_counter_t
|
||||||
scopes_tree_opcodes_num (scopes_tree *t)
|
scopes_tree_opcodes_num (scopes_tree t)
|
||||||
{
|
{
|
||||||
assert_tree (t);
|
assert_tree (t);
|
||||||
return t->opcodes_num;
|
return t->opcodes_num;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
scopes_tree_add_opcode (scopes_tree *tree, opcode_t op)
|
scopes_tree_add_opcode (scopes_tree tree, opcode_t op)
|
||||||
{
|
{
|
||||||
assert_tree (tree);
|
assert_tree (tree);
|
||||||
linked_list_set_element (tree->opcodes, sizeof (opcode_t), tree->opcodes_num++, &op);
|
linked_list_set_element (tree->opcodes, sizeof (opcode_t), tree->opcodes_num++, &op);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
scopes_tree_set_opcode (scopes_tree *tree, opcode_counter_t oc, opcode_t op)
|
scopes_tree_set_opcode (scopes_tree tree, opcode_counter_t oc, opcode_t op)
|
||||||
{
|
{
|
||||||
assert_tree (tree);
|
assert_tree (tree);
|
||||||
JERRY_ASSERT (oc < tree->opcodes_num);
|
JERRY_ASSERT (oc < tree->opcodes_num);
|
||||||
@@ -49,7 +49,7 @@ scopes_tree_set_opcode (scopes_tree *tree, opcode_counter_t oc, opcode_t op)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
scopes_tree_set_opcodes_num (scopes_tree *tree, opcode_counter_t oc)
|
scopes_tree_set_opcodes_num (scopes_tree tree, opcode_counter_t oc)
|
||||||
{
|
{
|
||||||
assert_tree (tree);
|
assert_tree (tree);
|
||||||
JERRY_ASSERT (oc < tree->opcodes_num);
|
JERRY_ASSERT (oc < tree->opcodes_num);
|
||||||
@@ -57,76 +57,57 @@ scopes_tree_set_opcodes_num (scopes_tree *tree, opcode_counter_t oc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
opcode_t
|
opcode_t
|
||||||
scopes_tree_opcode (scopes_tree *tree, opcode_counter_t oc)
|
scopes_tree_opcode (scopes_tree tree, opcode_counter_t oc)
|
||||||
{
|
{
|
||||||
assert_tree (tree);
|
assert_tree (tree);
|
||||||
JERRY_ASSERT (oc < tree->opcodes_num);
|
JERRY_ASSERT (oc < tree->opcodes_num);
|
||||||
return *(opcode_t *) linked_list_element (tree->opcodes, sizeof (opcode_t), oc);
|
return *(opcode_t *) linked_list_element (tree->opcodes, sizeof (opcode_t), oc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static opcode_counter_t
|
opcode_counter_t
|
||||||
count_opcodes_in_tree (scopes_tree *t)
|
scopes_tree_count_opcodes (scopes_tree t)
|
||||||
{
|
{
|
||||||
assert_tree (t);
|
assert_tree (t);
|
||||||
opcode_counter_t res = t->opcodes_num;
|
opcode_counter_t res = t->opcodes_num;
|
||||||
for (uint8_t i = 0; i < t->t.children_num; i++)
|
for (uint8_t i = 0; i < t->t.children_num; i++)
|
||||||
{
|
{
|
||||||
res = (opcode_counter_t) (res
|
res = (opcode_counter_t) (res
|
||||||
+ count_opcodes_in_tree ((scopes_tree *) linked_list_element (t->t.children,
|
+ scopes_tree_count_opcodes (*(scopes_tree *) linked_list_element (t->t.children,
|
||||||
sizeof (scopes_tree *),
|
sizeof (scopes_tree),
|
||||||
i)));
|
i)));
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static opcode_counter_t
|
static opcode_counter_t
|
||||||
merge_subscopes (scopes_tree *tree, opcode_t *data)
|
merge_subscopes (scopes_tree tree, opcode_t *data)
|
||||||
{
|
{
|
||||||
assert_tree (tree);
|
assert_tree (tree);
|
||||||
JERRY_ASSERT (data);
|
JERRY_ASSERT (data);
|
||||||
bool header = true;
|
|
||||||
opcode_counter_t opc_index, data_index;
|
opcode_counter_t opc_index, data_index;
|
||||||
|
bool header = true;
|
||||||
for (opc_index = 0, data_index = 0; opc_index < tree->opcodes_num; opc_index++, data_index++)
|
for (opc_index = 0, data_index = 0; opc_index < tree->opcodes_num; opc_index++, data_index++)
|
||||||
{
|
{
|
||||||
opcode_t *op = (opcode_t *) linked_list_element (tree->opcodes, sizeof (opcode_t), opc_index);
|
opcode_t *op = (opcode_t *) linked_list_element (tree->opcodes, sizeof (opcode_t), opc_index);
|
||||||
JERRY_ASSERT (op);
|
JERRY_ASSERT (op);
|
||||||
switch (opc_index)
|
if (op->op_idx != NAME_TO_ID (var_decl)
|
||||||
{
|
&& op->op_idx != NAME_TO_ID (nop)
|
||||||
case 0:
|
&& op->op_idx != NAME_TO_ID (meta) && !header)
|
||||||
{
|
|
||||||
JERRY_ASSERT (op->op_idx == NAME_TO_ID (reg_var_decl));
|
|
||||||
data[data_index] = *op;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 1:
|
|
||||||
{
|
|
||||||
JERRY_ASSERT (op->op_idx == NAME_TO_ID (nop) || op->op_idx == NAME_TO_ID (meta));
|
|
||||||
data[data_index] = *op;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
if (op->op_idx == NAME_TO_ID (var_decl))
|
|
||||||
{
|
|
||||||
data[data_index] = *op;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
header = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!header)
|
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (op->op_idx == NAME_TO_ID (reg_var_decl))
|
||||||
|
{
|
||||||
|
header = false;
|
||||||
|
}
|
||||||
|
data[data_index] = *op;
|
||||||
}
|
}
|
||||||
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++)
|
||||||
{
|
{
|
||||||
data_index = (opcode_counter_t) (data_index
|
data_index = (opcode_counter_t) (data_index
|
||||||
+ merge_subscopes ((scopes_tree *) linked_list_element (tree->t.children,
|
+ merge_subscopes (*(scopes_tree *) linked_list_element (tree->t.children,
|
||||||
sizeof (scopes_tree *),
|
sizeof (scopes_tree),
|
||||||
child_id),
|
child_id),
|
||||||
data + data_index));
|
data + data_index));
|
||||||
}
|
}
|
||||||
for (; opc_index < tree->opcodes_num; opc_index++, data_index++)
|
for (; opc_index < tree->opcodes_num; opc_index++, data_index++)
|
||||||
@@ -138,10 +119,10 @@ merge_subscopes (scopes_tree *tree, opcode_t *data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
opcode_t *
|
opcode_t *
|
||||||
scopes_tree_raw_data (scopes_tree *tree, opcode_counter_t *num)
|
scopes_tree_raw_data (scopes_tree tree, opcode_counter_t *num)
|
||||||
{
|
{
|
||||||
assert_tree (tree);
|
assert_tree (tree);
|
||||||
opcode_counter_t res = count_opcodes_in_tree (tree);
|
opcode_counter_t res = scopes_tree_count_opcodes (tree);
|
||||||
size_t size = ((size_t) (res + 1) * sizeof (opcode_t)); // +1 for valgrind
|
size_t size = ((size_t) (res + 1) * sizeof (opcode_t)); // +1 for valgrind
|
||||||
opcode_t *opcodes = (opcode_t *) mem_heap_alloc_block (size, MEM_HEAP_ALLOC_LONG_TERM);
|
opcode_t *opcodes = (opcode_t *) mem_heap_alloc_block (size, MEM_HEAP_ALLOC_LONG_TERM);
|
||||||
__memset (opcodes, 0, size);
|
__memset (opcodes, 0, size);
|
||||||
@@ -151,10 +132,10 @@ scopes_tree_raw_data (scopes_tree *tree, opcode_counter_t *num)
|
|||||||
return opcodes;
|
return opcodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
scopes_tree *
|
scopes_tree
|
||||||
scopes_tree_init (scopes_tree *parent)
|
scopes_tree_init (scopes_tree parent)
|
||||||
{
|
{
|
||||||
scopes_tree *tree = (scopes_tree *) mem_heap_alloc_block (sizeof (scopes_tree), MEM_HEAP_ALLOC_SHORT_TERM);
|
scopes_tree tree = (scopes_tree) mem_heap_alloc_block (sizeof (scopes_tree_int), MEM_HEAP_ALLOC_SHORT_TERM);
|
||||||
__memset (tree, 0, sizeof (scopes_tree));
|
__memset (tree, 0, sizeof (scopes_tree));
|
||||||
tree->t.magic = TREE_MAGIC;
|
tree->t.magic = TREE_MAGIC;
|
||||||
tree->t.parent = (tree_header *) parent;
|
tree->t.parent = (tree_header *) parent;
|
||||||
@@ -164,9 +145,12 @@ scopes_tree_init (scopes_tree *parent)
|
|||||||
{
|
{
|
||||||
if (parent->t.children_num == 0)
|
if (parent->t.children_num == 0)
|
||||||
{
|
{
|
||||||
parent->t.children = linked_list_init (sizeof (scopes_tree *));
|
parent->t.children = linked_list_init (sizeof (scopes_tree));
|
||||||
}
|
}
|
||||||
linked_list_set_element (parent->t.children, sizeof (scopes_tree *), parent->t.children_num++, tree);
|
linked_list_set_element (parent->t.children, sizeof (scopes_tree), parent->t.children_num, &tree);
|
||||||
|
void *added = linked_list_element (parent->t.children, sizeof (scopes_tree), parent->t.children_num);
|
||||||
|
JERRY_ASSERT (*(scopes_tree *) added == tree);
|
||||||
|
parent->t.children_num++;
|
||||||
}
|
}
|
||||||
tree->opcodes_num = 0;
|
tree->opcodes_num = 0;
|
||||||
tree->opcodes = linked_list_init (sizeof (opcode_t));
|
tree->opcodes = linked_list_init (sizeof (opcode_t));
|
||||||
@@ -174,15 +158,15 @@ scopes_tree_init (scopes_tree *parent)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
scopes_tree_free (scopes_tree *tree)
|
scopes_tree_free (scopes_tree tree)
|
||||||
{
|
{
|
||||||
assert_tree (tree);
|
assert_tree (tree);
|
||||||
for (uint8_t i = 0; i < tree->t.children_num; ++i)
|
|
||||||
{
|
|
||||||
scopes_tree_free ((scopes_tree *) linked_list_element (tree->t.children, sizeof (scopes_tree *), i));
|
|
||||||
}
|
|
||||||
if (tree->t.children_num != 0)
|
if (tree->t.children_num != 0)
|
||||||
{
|
{
|
||||||
|
for (uint8_t i = 0; i < tree->t.children_num; ++i)
|
||||||
|
{
|
||||||
|
scopes_tree_free (*(scopes_tree *) linked_list_element (tree->t.children, sizeof (scopes_tree), i));
|
||||||
|
}
|
||||||
linked_list_free (tree->t.children);
|
linked_list_free (tree->t.children);
|
||||||
}
|
}
|
||||||
linked_list_free (tree->opcodes);
|
linked_list_free (tree->opcodes);
|
||||||
|
|||||||
@@ -20,22 +20,25 @@
|
|||||||
#include "linked-list.h"
|
#include "linked-list.h"
|
||||||
#include "opcodes.h"
|
#include "opcodes.h"
|
||||||
|
|
||||||
typedef struct scopes_tree
|
typedef struct
|
||||||
{
|
{
|
||||||
tree_header t;
|
tree_header t;
|
||||||
opcode_counter_t opcodes_num;
|
opcode_counter_t opcodes_num;
|
||||||
linked_list opcodes;
|
linked_list opcodes;
|
||||||
}
|
}
|
||||||
__packed
|
__packed
|
||||||
scopes_tree;
|
scopes_tree_int;
|
||||||
|
|
||||||
scopes_tree *scopes_tree_init (scopes_tree *);
|
typedef scopes_tree_int * scopes_tree;
|
||||||
void scopes_tree_free (scopes_tree *);
|
|
||||||
opcode_counter_t scopes_tree_opcodes_num (scopes_tree *);
|
scopes_tree scopes_tree_init (scopes_tree);
|
||||||
void scopes_tree_add_opcode (scopes_tree *, opcode_t);
|
void scopes_tree_free (scopes_tree);
|
||||||
void scopes_tree_set_opcode (scopes_tree *, opcode_counter_t, opcode_t);
|
opcode_counter_t scopes_tree_opcodes_num (scopes_tree);
|
||||||
void scopes_tree_set_opcodes_num (scopes_tree *, opcode_counter_t);
|
void scopes_tree_add_opcode (scopes_tree, opcode_t);
|
||||||
opcode_t scopes_tree_opcode (scopes_tree *, opcode_counter_t);
|
void scopes_tree_set_opcode (scopes_tree, opcode_counter_t, opcode_t);
|
||||||
opcode_t *scopes_tree_raw_data (scopes_tree *, opcode_counter_t *);
|
void scopes_tree_set_opcodes_num (scopes_tree, opcode_counter_t);
|
||||||
|
opcode_t scopes_tree_opcode (scopes_tree, opcode_counter_t);
|
||||||
|
opcode_counter_t scopes_tree_count_opcodes (scopes_tree);
|
||||||
|
opcode_t *scopes_tree_raw_data (scopes_tree, opcode_counter_t *);
|
||||||
|
|
||||||
#endif /* SCOPES_TREE_H */
|
#endif /* SCOPES_TREE_H */
|
||||||
|
|||||||
@@ -46,6 +46,6 @@ struct
|
|||||||
__packed
|
__packed
|
||||||
bytecode_data;
|
bytecode_data;
|
||||||
|
|
||||||
scopes_tree *current_scope;
|
scopes_tree current_scope;
|
||||||
|
|
||||||
#endif // BYTECODE_DATA_H
|
#endif // BYTECODE_DATA_H
|
||||||
|
|||||||
@@ -47,6 +47,11 @@ deserialize_bytecode (void)
|
|||||||
opcode_t
|
opcode_t
|
||||||
deserialize_opcode (opcode_counter_t oc)
|
deserialize_opcode (opcode_counter_t oc)
|
||||||
{
|
{
|
||||||
|
if (bytecode_data.opcodes)
|
||||||
|
{
|
||||||
|
JERRY_ASSERT (oc < bytecode_data.opcodes_count);
|
||||||
|
return bytecode_data.opcodes[oc];
|
||||||
|
}
|
||||||
return scopes_tree_opcode (current_scope, oc);
|
return scopes_tree_opcode (current_scope, oc);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,6 +64,9 @@ deserialize_min_temp (void)
|
|||||||
void
|
void
|
||||||
deserializer_init (void)
|
deserializer_init (void)
|
||||||
{
|
{
|
||||||
|
bytecode_data.strings = NULL;
|
||||||
|
bytecode_data.nums = NULL;
|
||||||
|
bytecode_data.opcodes = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
@@ -295,8 +295,8 @@ pp_opcode (opcode_counter_t oc, opcode_t opcode, bool is_rewrite)
|
|||||||
}
|
}
|
||||||
case NAME_TO_ID (try):
|
case NAME_TO_ID (try):
|
||||||
{
|
{
|
||||||
pp_printf ("try (end: %d);", calc_opcode_counter_from_idx_idx (opcode.data.try.oc_idx_1,
|
pp_printf ("try (end: %d);", oc + calc_opcode_counter_from_idx_idx (opcode.data.try.oc_idx_1,
|
||||||
opcode.data.try.oc_idx_2));
|
opcode.data.try.oc_idx_2));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NAME_TO_ID (assignment):
|
case NAME_TO_ID (assignment):
|
||||||
@@ -595,14 +595,14 @@ pp_opcode (opcode_counter_t oc, opcode_t opcode, bool is_rewrite)
|
|||||||
}
|
}
|
||||||
case OPCODE_META_TYPE_FUNCTION_END:
|
case OPCODE_META_TYPE_FUNCTION_END:
|
||||||
{
|
{
|
||||||
pp_printf ("function end: %d;", calc_opcode_counter_from_idx_idx (opcode.data.meta.data_1,
|
pp_printf ("function end: %d;", oc + calc_opcode_counter_from_idx_idx (opcode.data.meta.data_1,
|
||||||
opcode.data.meta.data_2));
|
opcode.data.meta.data_2));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OPCODE_META_TYPE_CATCH:
|
case OPCODE_META_TYPE_CATCH:
|
||||||
{
|
{
|
||||||
pp_printf ("catch end: %d;", calc_opcode_counter_from_idx_idx (opcode.data.meta.data_1,
|
pp_printf ("catch end: %d;", oc + calc_opcode_counter_from_idx_idx (opcode.data.meta.data_1,
|
||||||
opcode.data.meta.data_2));
|
opcode.data.meta.data_2));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OPCODE_META_TYPE_CATCH_EXCEPTION_IDENTIFIER:
|
case OPCODE_META_TYPE_CATCH_EXCEPTION_IDENTIFIER:
|
||||||
@@ -612,8 +612,8 @@ pp_opcode (opcode_counter_t oc, opcode_t opcode, bool is_rewrite)
|
|||||||
}
|
}
|
||||||
case OPCODE_META_TYPE_FINALLY:
|
case OPCODE_META_TYPE_FINALLY:
|
||||||
{
|
{
|
||||||
pp_printf ("finally end: %d;", calc_opcode_counter_from_idx_idx (opcode.data.meta.data_1,
|
pp_printf ("finally end: %d;", oc + calc_opcode_counter_from_idx_idx (opcode.data.meta.data_1,
|
||||||
opcode.data.meta.data_2));
|
opcode.data.meta.data_2));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OPCODE_META_TYPE_END_TRY_CATCH_FINALLY:
|
case OPCODE_META_TYPE_END_TRY_CATCH_FINALLY:
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
static bool print_opcodes;
|
static bool print_opcodes;
|
||||||
|
|
||||||
void
|
void
|
||||||
serializer_set_scope (scopes_tree *new_scope)
|
serializer_set_scope (scopes_tree new_scope)
|
||||||
{
|
{
|
||||||
current_scope = new_scope;
|
current_scope = new_scope;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
void serializer_init (bool show_opcodes);
|
void serializer_init (bool show_opcodes);
|
||||||
void serializer_dump_strings_and_nums (const lp_string *, uint8_t,
|
void serializer_dump_strings_and_nums (const lp_string *, uint8_t,
|
||||||
const ecma_number_t *, uint8_t);
|
const ecma_number_t *, uint8_t);
|
||||||
void serializer_set_scope (scopes_tree *);
|
void serializer_set_scope (scopes_tree);
|
||||||
void serializer_merge_scopes_into_bytecode (void);
|
void serializer_merge_scopes_into_bytecode (void);
|
||||||
void serializer_dump_opcode (opcode_t);
|
void serializer_dump_opcode (opcode_t);
|
||||||
void serializer_set_writing_position (opcode_counter_t);
|
void serializer_set_writing_position (opcode_counter_t);
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ main( int __unused argc,
|
|||||||
|
|
||||||
/* get property2 () { return 1; }, */
|
/* get property2 () { return 1; }, */
|
||||||
[ 9] = getop_func_expr_n (240, 243 /* any tmp reg */, 0),
|
[ 9] = getop_func_expr_n (240, 243 /* any tmp reg */, 0),
|
||||||
[10] = getop_meta (OPCODE_META_TYPE_FUNCTION_END, 0, 14),
|
[10] = getop_meta (OPCODE_META_TYPE_FUNCTION_END, 0, 4),
|
||||||
[11] = getop_reg_var_decl (250, 255),
|
[11] = getop_reg_var_decl (250, 255),
|
||||||
[12] = getop_assignment (250, OPCODE_ARG_TYPE_SMALLINT, 1),
|
[12] = getop_assignment (250, OPCODE_ARG_TYPE_SMALLINT, 1),
|
||||||
[13] = getop_retval (250),
|
[13] = getop_retval (250),
|
||||||
@@ -57,7 +57,7 @@ main( int __unused argc,
|
|||||||
/* set property2 (a) { this.property3 = a * 10; }, */
|
/* set property2 (a) { this.property3 = a * 10; }, */
|
||||||
[15] = getop_func_expr_n (250, 243 /* any tmp reg */, 1),
|
[15] = getop_func_expr_n (250, 243 /* any tmp reg */, 1),
|
||||||
[16] = getop_meta (OPCODE_META_TYPE_VARG, 0, 255),
|
[16] = getop_meta (OPCODE_META_TYPE_VARG, 0, 255),
|
||||||
[17] = getop_meta (OPCODE_META_TYPE_FUNCTION_END, 0, 25),
|
[17] = getop_meta (OPCODE_META_TYPE_FUNCTION_END, 0, 8),
|
||||||
[18] = getop_reg_var_decl (250, 255),
|
[18] = getop_reg_var_decl (250, 255),
|
||||||
[19] = getop_this (250),
|
[19] = getop_this (250),
|
||||||
[20] = getop_assignment (251, OPCODE_ARG_TYPE_STRING, 4),
|
[20] = getop_assignment (251, OPCODE_ARG_TYPE_STRING, 4),
|
||||||
@@ -70,7 +70,7 @@ main( int __unused argc,
|
|||||||
/* set property3 (b) { this.property1 = b; } }; */
|
/* set property3 (b) { this.property1 = b; } }; */
|
||||||
[26] = getop_func_expr_n (250, 243 /* any tmp reg */, 1),
|
[26] = getop_func_expr_n (250, 243 /* any tmp reg */, 1),
|
||||||
[27] = getop_meta (OPCODE_META_TYPE_VARG, 1, 255),
|
[27] = getop_meta (OPCODE_META_TYPE_VARG, 1, 255),
|
||||||
[28] = getop_meta (OPCODE_META_TYPE_FUNCTION_END, 0, 34),
|
[28] = getop_meta (OPCODE_META_TYPE_FUNCTION_END, 0, 6),
|
||||||
[29] = getop_reg_var_decl (250, 255),
|
[29] = getop_reg_var_decl (250, 255),
|
||||||
[30] = getop_this (250),
|
[30] = getop_this (250),
|
||||||
[31] = getop_assignment (251, OPCODE_ARG_TYPE_STRING, 2),
|
[31] = getop_assignment (251, OPCODE_ARG_TYPE_STRING, 2),
|
||||||
|
|||||||
@@ -31,18 +31,18 @@ main( int __unused argc,
|
|||||||
[ 0] = getop_reg_var_decl (255, 255),
|
[ 0] = getop_reg_var_decl (255, 255),
|
||||||
[ 1] = getop_var_decl (0),
|
[ 1] = getop_var_decl (0),
|
||||||
[ 2] = getop_var_decl (1),
|
[ 2] = getop_var_decl (1),
|
||||||
[ 3] = getop_try (0, 8),
|
[ 3] = getop_try (0, 5),
|
||||||
[ 4] = getop_assignment (0, OPCODE_ARG_TYPE_STRING, 1),
|
[ 4] = getop_assignment (0, OPCODE_ARG_TYPE_STRING, 1),
|
||||||
[ 5] = getop_assignment (1, OPCODE_ARG_TYPE_VARIABLE, 0),
|
[ 5] = getop_assignment (1, OPCODE_ARG_TYPE_VARIABLE, 0),
|
||||||
[ 6] = getop_throw (1),
|
[ 6] = getop_throw (1),
|
||||||
[ 7] = getop_assignment (1, OPCODE_ARG_TYPE_SMALLINT, 12),
|
[ 7] = getop_assignment (1, OPCODE_ARG_TYPE_SMALLINT, 12),
|
||||||
[ 8] = getop_meta (OPCODE_META_TYPE_CATCH, 0, 14),
|
[ 8] = getop_meta (OPCODE_META_TYPE_CATCH, 0, 6),
|
||||||
[ 9] = getop_meta (OPCODE_META_TYPE_CATCH_EXCEPTION_IDENTIFIER, 2, 255),
|
[ 9] = getop_meta (OPCODE_META_TYPE_CATCH_EXCEPTION_IDENTIFIER, 2, 255),
|
||||||
[10] = getop_equal_value_type (0, 1, 2),
|
[10] = getop_equal_value_type (0, 1, 2),
|
||||||
[11] = getop_is_true_jmp_down (0, 0, 3),
|
[11] = getop_is_true_jmp_down (0, 0, 3),
|
||||||
[12] = getop_exitval (1),
|
[12] = getop_exitval (1),
|
||||||
[13] = getop_assignment (0, OPCODE_ARG_TYPE_SIMPLE, ECMA_SIMPLE_VALUE_FALSE),
|
[13] = getop_assignment (0, OPCODE_ARG_TYPE_SIMPLE, ECMA_SIMPLE_VALUE_FALSE),
|
||||||
[14] = getop_meta (OPCODE_META_TYPE_FINALLY, 0, 18),
|
[14] = getop_meta (OPCODE_META_TYPE_FINALLY, 0, 4),
|
||||||
[15] = getop_is_false_jmp_down (0, 0, 2),
|
[15] = getop_is_false_jmp_down (0, 0, 2),
|
||||||
[16] = getop_exitval (0),
|
[16] = getop_exitval (0),
|
||||||
[17] = getop_exitval (1),
|
[17] = getop_exitval (1),
|
||||||
|
|||||||
Reference in New Issue
Block a user