Add opcode description table containing an opcode's name, name and possible type of the opcode's arguments.

JerryScript-DCO-1.0-Signed-off-by: Ruben Ayrapetyan r.ayrapetyan@samsung.com
This commit is contained in:
Ruben Ayrapetyan
2015-07-20 21:53:40 +03:00
committed by Evgeny Gavrin
parent 25450d8a12
commit 1990762cf0
12 changed files with 704 additions and 507 deletions
+28 -30
View File
@@ -22,8 +22,6 @@
static idx_t temp_name, max_temp_name; static idx_t temp_name, max_temp_name;
#define OPCODE(name) (__op__idx_##name)
enum enum
{ {
U8_global_size U8_global_size
@@ -585,7 +583,7 @@ dump_triple_address (opcode_t (*getop) (idx_t, idx_t, idx_t), operand res, opera
static void static void
dump_prop_setter_op_meta (op_meta last, operand op) dump_prop_setter_op_meta (op_meta last, operand op)
{ {
JERRY_ASSERT (last.op.op_idx == OPCODE (prop_getter)); JERRY_ASSERT (last.op.op_idx == VM_OP_PROP_GETTER);
switch (op.type) switch (op.type)
{ {
case OPERAND_LITERAL: case OPERAND_LITERAL:
@@ -638,7 +636,7 @@ static operand
dump_triple_address_and_prop_setter_res (void (*dumper) (operand, operand, operand), dump_triple_address_and_prop_setter_res (void (*dumper) (operand, operand, operand),
op_meta last, operand op) op_meta last, operand op)
{ {
JERRY_ASSERT (last.op.op_idx == OPCODE (prop_getter)); JERRY_ASSERT (last.op.op_idx == VM_OP_PROP_GETTER);
const operand obj = create_operand_from_tmp_and_lit (last.op.data.prop_getter.obj, last.lit_id[1]); const operand obj = create_operand_from_tmp_and_lit (last.op.data.prop_getter.obj, last.lit_id[1]);
const operand prop = create_operand_from_tmp_and_lit (last.op.data.prop_getter.prop, last.lit_id[2]); const operand prop = create_operand_from_tmp_and_lit (last.op.data.prop_getter.prop, last.lit_id[2]);
const operand tmp = dump_prop_getter_res (obj, prop); const operand tmp = dump_prop_getter_res (obj, prop);
@@ -652,7 +650,7 @@ dump_prop_setter_or_triple_address_res (void (*dumper) (operand, operand, operan
operand res, operand op) operand res, operand op)
{ {
const op_meta last = STACK_TOP (prop_getters); const op_meta last = STACK_TOP (prop_getters);
if (last.op.op_idx == OPCODE (prop_getter)) if (last.op.op_idx == VM_OP_PROP_GETTER)
{ {
res = dump_triple_address_and_prop_setter_res (dumper, last, op); res = dump_triple_address_and_prop_setter_res (dumper, last, op);
} }
@@ -1123,10 +1121,10 @@ rewrite_varg_header_set_args_count (uint8_t args_count)
op_meta om = serializer_get_op_meta (STACK_TOP (varg_headers)); op_meta om = serializer_get_op_meta (STACK_TOP (varg_headers));
switch (om.op.op_idx) switch (om.op.op_idx)
{ {
case OPCODE (func_expr_n): case VM_OP_FUNC_EXPR_N:
case OPCODE (construct_n): case VM_OP_CONSTRUCT_N:
case OPCODE (call_n): case VM_OP_CALL_N:
case OPCODE (native_call): case VM_OP_NATIVE_CALL:
{ {
const operand res = tmp_operand (); const operand res = tmp_operand ();
om.op.data.func_expr_n.arg_list = args_count; om.op.data.func_expr_n.arg_list = args_count;
@@ -1135,15 +1133,15 @@ rewrite_varg_header_set_args_count (uint8_t args_count)
STACK_DROP (varg_headers, 1); STACK_DROP (varg_headers, 1);
return res; return res;
} }
case OPCODE (func_decl_n): case VM_OP_FUNC_DECL_N:
{ {
om.op.data.func_decl_n.arg_list = args_count; om.op.data.func_decl_n.arg_list = args_count;
serializer_rewrite_op_meta (STACK_TOP (varg_headers), om); serializer_rewrite_op_meta (STACK_TOP (varg_headers), om);
STACK_DROP (varg_headers, 1); STACK_DROP (varg_headers, 1);
return empty_operand (); return empty_operand ();
} }
case OPCODE (array_decl): case VM_OP_ARRAY_DECL:
case OPCODE (obj_decl): case VM_OP_OBJ_DECL:
{ {
const operand res = tmp_operand (); const operand res = tmp_operand ();
om.op.data.obj_decl.list = args_count; om.op.data.obj_decl.list = args_count;
@@ -1501,7 +1499,7 @@ dump_delete (operand res, operand op, bool is_strict, locus loc)
const op_meta last_op_meta = last_dumped_op_meta (); const op_meta last_op_meta = last_dumped_op_meta ();
switch (last_op_meta.op.op_idx) switch (last_op_meta.op.op_idx)
{ {
case OPCODE (prop_getter): case VM_OP_PROP_GETTER:
{ {
const opcode_counter_t oc = (opcode_counter_t) (serializer_get_current_opcode_counter () - 1); const opcode_counter_t oc = (opcode_counter_t) (serializer_get_current_opcode_counter () - 1);
serializer_set_writing_position (oc); serializer_set_writing_position (oc);
@@ -1950,7 +1948,7 @@ rewrite_logical_and_checks (void)
for (uint8_t i = STACK_TOP (U8); i < STACK_SIZE (logical_and_checks); i++) for (uint8_t i = STACK_TOP (U8); i < STACK_SIZE (logical_and_checks); i++)
{ {
op_meta jmp_op_meta = serializer_get_op_meta (STACK_ELEMENT (logical_and_checks, i)); op_meta jmp_op_meta = serializer_get_op_meta (STACK_ELEMENT (logical_and_checks, i));
JERRY_ASSERT (jmp_op_meta.op.op_idx == OPCODE (is_false_jmp_down)); JERRY_ASSERT (jmp_op_meta.op.op_idx == VM_OP_IS_FALSE_JMP_DOWN);
idx_t id1, id2; idx_t id1, id2;
split_opcode_counter (get_diff_from (STACK_ELEMENT (logical_and_checks, i)), &id1, &id2); split_opcode_counter (get_diff_from (STACK_ELEMENT (logical_and_checks, i)), &id1, &id2);
jmp_op_meta.op.data.is_false_jmp_down.opcode_1 = id1; jmp_op_meta.op.data.is_false_jmp_down.opcode_1 = id1;
@@ -1994,7 +1992,7 @@ rewrite_logical_or_checks (void)
for (uint8_t i = STACK_TOP (U8); i < STACK_SIZE (logical_or_checks); i++) for (uint8_t i = STACK_TOP (U8); i < STACK_SIZE (logical_or_checks); i++)
{ {
op_meta jmp_op_meta = serializer_get_op_meta (STACK_ELEMENT (logical_or_checks, i)); op_meta jmp_op_meta = serializer_get_op_meta (STACK_ELEMENT (logical_or_checks, i));
JERRY_ASSERT (jmp_op_meta.op.op_idx == OPCODE (is_true_jmp_down)); JERRY_ASSERT (jmp_op_meta.op.op_idx == VM_OP_IS_TRUE_JMP_DOWN);
idx_t id1, id2; idx_t id1, id2;
split_opcode_counter (get_diff_from (STACK_ELEMENT (logical_or_checks, i)), &id1, &id2); split_opcode_counter (get_diff_from (STACK_ELEMENT (logical_or_checks, i)), &id1, &id2);
jmp_op_meta.op.data.is_true_jmp_down.opcode_1 = id1; jmp_op_meta.op.data.is_true_jmp_down.opcode_1 = id1;
@@ -2030,7 +2028,7 @@ void
rewrite_conditional_check (void) rewrite_conditional_check (void)
{ {
op_meta jmp_op_meta = serializer_get_op_meta (STACK_TOP (conditional_checks)); op_meta jmp_op_meta = serializer_get_op_meta (STACK_TOP (conditional_checks));
JERRY_ASSERT (jmp_op_meta.op.op_idx == OPCODE (is_false_jmp_down)); JERRY_ASSERT (jmp_op_meta.op.op_idx == VM_OP_IS_FALSE_JMP_DOWN);
idx_t id1, id2; idx_t id1, id2;
split_opcode_counter (get_diff_from (STACK_TOP (conditional_checks)), &id1, &id2); split_opcode_counter (get_diff_from (STACK_TOP (conditional_checks)), &id1, &id2);
jmp_op_meta.op.data.is_false_jmp_down.opcode_1 = id1; jmp_op_meta.op.data.is_false_jmp_down.opcode_1 = id1;
@@ -2051,7 +2049,7 @@ void
rewrite_jump_to_end (void) rewrite_jump_to_end (void)
{ {
op_meta jmp_op_meta = serializer_get_op_meta (STACK_TOP (jumps_to_end)); op_meta jmp_op_meta = serializer_get_op_meta (STACK_TOP (jumps_to_end));
JERRY_ASSERT (jmp_op_meta.op.op_idx == OPCODE (jmp_down)); JERRY_ASSERT (jmp_op_meta.op.op_idx == VM_OP_JMP_DOWN);
idx_t id1, id2; idx_t id1, id2;
split_opcode_counter (get_diff_from (STACK_TOP (jumps_to_end)), &id1, &id2); split_opcode_counter (get_diff_from (STACK_TOP (jumps_to_end)), &id1, &id2);
jmp_op_meta.op.data.jmp_down.opcode_1 = id1; jmp_op_meta.op.data.jmp_down.opcode_1 = id1;
@@ -2064,7 +2062,7 @@ void
start_dumping_assignment_expression (void) start_dumping_assignment_expression (void)
{ {
const op_meta last = last_dumped_op_meta (); const op_meta last = last_dumped_op_meta ();
if (last.op.op_idx == OPCODE (prop_getter)) if (last.op.op_idx == VM_OP_PROP_GETTER)
{ {
serializer_set_writing_position ((opcode_counter_t) (serializer_get_current_opcode_counter () - 1)); serializer_set_writing_position ((opcode_counter_t) (serializer_get_current_opcode_counter () - 1));
} }
@@ -2075,7 +2073,7 @@ operand
dump_prop_setter_or_variable_assignment_res (operand res, operand op) dump_prop_setter_or_variable_assignment_res (operand res, operand op)
{ {
const op_meta last = STACK_TOP (prop_getters); const op_meta last = STACK_TOP (prop_getters);
if (last.op.op_idx == OPCODE (prop_getter)) if (last.op.op_idx == VM_OP_PROP_GETTER)
{ {
dump_prop_setter_op_meta (last, op); dump_prop_setter_op_meta (last, op);
} }
@@ -2247,10 +2245,10 @@ rewrite_simple_or_nested_jump_and_get_next (opcode_counter_t jump_oc, /**< posit
{ {
op_meta jump_op_meta = serializer_get_op_meta (jump_oc); op_meta jump_op_meta = serializer_get_op_meta (jump_oc);
bool is_simple_jump = (jump_op_meta.op.op_idx == OPCODE (jmp_down)); bool is_simple_jump = (jump_op_meta.op.op_idx == VM_OP_JMP_DOWN);
JERRY_ASSERT (is_simple_jump JERRY_ASSERT (is_simple_jump
|| (jump_op_meta.op.op_idx == OPCODE (jmp_break_continue))); || (jump_op_meta.op.op_idx == VM_OP_JMP_BREAK_CONTINUE));
idx_t id1, id2, id1_prev, id2_prev; idx_t id1, id2, id1_prev, id2_prev;
split_opcode_counter ((opcode_counter_t) (target_oc - jump_oc), &id1, &id2); split_opcode_counter ((opcode_counter_t) (target_oc - jump_oc), &id1, &id2);
@@ -2265,7 +2263,7 @@ rewrite_simple_or_nested_jump_and_get_next (opcode_counter_t jump_oc, /**< posit
} }
else else
{ {
JERRY_ASSERT (jump_op_meta.op.op_idx == OPCODE (jmp_break_continue)); JERRY_ASSERT (jump_op_meta.op.op_idx == VM_OP_JMP_BREAK_CONTINUE);
id1_prev = jump_op_meta.op.data.jmp_break_continue.opcode_1; id1_prev = jump_op_meta.op.data.jmp_break_continue.opcode_1;
id2_prev = jump_op_meta.op.data.jmp_break_continue.opcode_2; id2_prev = jump_op_meta.op.data.jmp_break_continue.opcode_2;
@@ -2311,7 +2309,7 @@ rewrite_case_clause (void)
idx_t id1, id2; idx_t id1, id2;
split_opcode_counter (get_diff_from (jmp_oc), &id1, &id2); split_opcode_counter (get_diff_from (jmp_oc), &id1, &id2);
op_meta jmp_op_meta = serializer_get_op_meta (jmp_oc); op_meta jmp_op_meta = serializer_get_op_meta (jmp_oc);
JERRY_ASSERT (jmp_op_meta.op.op_idx == OPCODE (is_true_jmp_down)); JERRY_ASSERT (jmp_op_meta.op.op_idx == VM_OP_IS_TRUE_JMP_DOWN);
jmp_op_meta.op.data.is_true_jmp_down.opcode_1 = id1; jmp_op_meta.op.data.is_true_jmp_down.opcode_1 = id1;
jmp_op_meta.op.data.is_true_jmp_down.opcode_2 = id2; jmp_op_meta.op.data.is_true_jmp_down.opcode_2 = id2;
serializer_rewrite_op_meta (jmp_oc, jmp_op_meta); serializer_rewrite_op_meta (jmp_oc, jmp_op_meta);
@@ -2325,7 +2323,7 @@ rewrite_default_clause (void)
idx_t id1, id2; idx_t id1, id2;
split_opcode_counter (get_diff_from (jmp_oc), &id1, &id2); split_opcode_counter (get_diff_from (jmp_oc), &id1, &id2);
op_meta jmp_op_meta = serializer_get_op_meta (jmp_oc); op_meta jmp_op_meta = serializer_get_op_meta (jmp_oc);
JERRY_ASSERT (jmp_op_meta.op.op_idx == OPCODE (jmp_down)); JERRY_ASSERT (jmp_op_meta.op.op_idx == VM_OP_JMP_DOWN);
jmp_op_meta.op.data.jmp_down.opcode_1 = id1; jmp_op_meta.op.data.jmp_down.opcode_1 = id1;
jmp_op_meta.op.data.jmp_down.opcode_2 = id2; jmp_op_meta.op.data.jmp_down.opcode_2 = id2;
serializer_rewrite_op_meta (jmp_oc, jmp_op_meta); serializer_rewrite_op_meta (jmp_oc, jmp_op_meta);
@@ -2463,7 +2461,7 @@ void
rewrite_try (void) rewrite_try (void)
{ {
op_meta try_op_meta = serializer_get_op_meta (STACK_TOP (tries)); op_meta try_op_meta = serializer_get_op_meta (STACK_TOP (tries));
JERRY_ASSERT (try_op_meta.op.op_idx == OPCODE (try_block)); JERRY_ASSERT (try_op_meta.op.op_idx == VM_OP_TRY_BLOCK);
idx_t id1, id2; idx_t id1, id2;
split_opcode_counter (get_diff_from (STACK_TOP (tries)), &id1, &id2); split_opcode_counter (get_diff_from (STACK_TOP (tries)), &id1, &id2);
try_op_meta.op.data.try_block.oc_idx_1 = id1; try_op_meta.op.data.try_block.oc_idx_1 = id1;
@@ -2487,7 +2485,7 @@ void
rewrite_catch (void) rewrite_catch (void)
{ {
op_meta catch_op_meta = serializer_get_op_meta (STACK_TOP (catches)); op_meta catch_op_meta = serializer_get_op_meta (STACK_TOP (catches));
JERRY_ASSERT (catch_op_meta.op.op_idx == OPCODE (meta) JERRY_ASSERT (catch_op_meta.op.op_idx == VM_OP_META
&& catch_op_meta.op.data.meta.type == OPCODE_META_TYPE_CATCH); && catch_op_meta.op.data.meta.type == OPCODE_META_TYPE_CATCH);
idx_t id1, id2; idx_t id1, id2;
split_opcode_counter (get_diff_from (STACK_TOP (catches)), &id1, &id2); split_opcode_counter (get_diff_from (STACK_TOP (catches)), &id1, &id2);
@@ -2509,7 +2507,7 @@ void
rewrite_finally (void) rewrite_finally (void)
{ {
op_meta finally_op_meta = serializer_get_op_meta (STACK_TOP (finallies)); op_meta finally_op_meta = serializer_get_op_meta (STACK_TOP (finallies));
JERRY_ASSERT (finally_op_meta.op.op_idx == OPCODE (meta) JERRY_ASSERT (finally_op_meta.op.op_idx == VM_OP_META
&& finally_op_meta.op.data.meta.type == OPCODE_META_TYPE_FINALLY); && finally_op_meta.op.data.meta.type == OPCODE_META_TYPE_FINALLY);
idx_t id1, id2; idx_t id1, id2;
split_opcode_counter (get_diff_from (STACK_TOP (finallies)), &id1, &id2); split_opcode_counter (get_diff_from (STACK_TOP (finallies)), &id1, &id2);
@@ -2540,7 +2538,7 @@ dumper_variable_declaration_exists (lit_cpointer_t lit_id)
oc > 0; oc--) oc > 0; oc--)
{ {
const op_meta var_decl_op_meta = serializer_get_op_meta (oc); const op_meta var_decl_op_meta = serializer_get_op_meta (oc);
if (var_decl_op_meta.op.op_idx != OPCODE (var_decl)) if (var_decl_op_meta.op.op_idx != VM_OP_VAR_DECL)
{ {
break; break;
} }
@@ -2589,7 +2587,7 @@ rewrite_scope_code_flags (opcode_counter_t scope_code_flags_oc, /**< position of
JERRY_ASSERT ((idx_t) scope_flags == scope_flags); JERRY_ASSERT ((idx_t) scope_flags == scope_flags);
op_meta opm = serializer_get_op_meta (scope_code_flags_oc); op_meta opm = serializer_get_op_meta (scope_code_flags_oc);
JERRY_ASSERT (opm.op.op_idx == OPCODE (meta)); JERRY_ASSERT (opm.op.op_idx == VM_OP_META);
JERRY_ASSERT (opm.op.data.meta.type == OPCODE_META_TYPE_SCOPE_CODE_FLAGS); JERRY_ASSERT (opm.op.data.meta.type == OPCODE_META_TYPE_SCOPE_CODE_FLAGS);
JERRY_ASSERT (opm.op.data.meta.data_1 == INVALID_VALUE); JERRY_ASSERT (opm.op.data.meta.data_1 == INVALID_VALUE);
JERRY_ASSERT (opm.op.data.meta.data_2 == INVALID_VALUE); JERRY_ASSERT (opm.op.data.meta.data_2 == INVALID_VALUE);
@@ -2616,7 +2614,7 @@ rewrite_reg_var_decl (void)
{ {
opcode_counter_t reg_var_decl_oc = STACK_TOP (reg_var_decls); opcode_counter_t reg_var_decl_oc = STACK_TOP (reg_var_decls);
op_meta opm = serializer_get_op_meta (reg_var_decl_oc); op_meta opm = serializer_get_op_meta (reg_var_decl_oc);
JERRY_ASSERT (opm.op.op_idx == OPCODE (reg_var_decl)); JERRY_ASSERT (opm.op.op_idx == VM_OP_REG_VAR_DECL);
opm.op.data.reg_var_decl.max = max_temp_name; opm.op.data.reg_var_decl.max = max_temp_name;
serializer_rewrite_op_meta (reg_var_decl_oc, opm); serializer_rewrite_op_meta (reg_var_decl_oc, opm);
STACK_DROP (reg_var_decls, 1); STACK_DROP (reg_var_decls, 1);
-2
View File
@@ -61,8 +61,6 @@ STATIC_STACK (scopes, scopes_tree)
#define EMIT_ERROR(type, MESSAGE) PARSE_ERROR(type, MESSAGE, tok.loc) #define EMIT_ERROR(type, MESSAGE) PARSE_ERROR(type, MESSAGE, tok.loc)
#define EMIT_ERROR_VARG(type, MESSAGE, ...) PARSE_ERROR_VARG(type, MESSAGE, tok.loc, __VA_ARGS__) #define EMIT_ERROR_VARG(type, MESSAGE, ...) PARSE_ERROR_VARG(type, MESSAGE, tok.loc, __VA_ARGS__)
#define OPCODE_IS(OP, ID) (OP.op_idx == __op__idx_##ID)
static operand parse_expression (bool, jsp_eval_ret_store_t); 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);
+121 -124
View File
@@ -17,7 +17,6 @@
#include "jsp-mm.h" #include "jsp-mm.h"
#include "scopes-tree.h" #include "scopes-tree.h"
#define OPCODE(op) (__op__idx_##op)
#define HASH_SIZE 128 #define HASH_SIZE 128
static hash_table lit_id_to_uid = null_hash; static hash_table lit_id_to_uid = null_hash;
@@ -232,53 +231,53 @@ generate_opcode (scopes_tree tree, opcode_counter_t opc_index, lit_id_hash_table
and '0' otherwise. */ and '0' otherwise. */
switch (om->op.op_idx) switch (om->op.op_idx)
{ {
case OPCODE (prop_getter): case VM_OP_PROP_GETTER:
case OPCODE (prop_setter): case VM_OP_PROP_SETTER:
case OPCODE (delete_prop): case VM_OP_DELETE_PROP:
case OPCODE (b_shift_left): case VM_OP_B_SHIFT_LEFT:
case OPCODE (b_shift_right): case VM_OP_B_SHIFT_RIGHT:
case OPCODE (b_shift_uright): case VM_OP_B_SHIFT_URIGHT:
case OPCODE (b_and): case VM_OP_B_AND:
case OPCODE (b_or): case VM_OP_B_OR:
case OPCODE (b_xor): case VM_OP_B_XOR:
case OPCODE (equal_value): case VM_OP_EQUAL_VALUE:
case OPCODE (not_equal_value): case VM_OP_NOT_EQUAL_VALUE:
case OPCODE (equal_value_type): case VM_OP_EQUAL_VALUE_TYPE:
case OPCODE (not_equal_value_type): case VM_OP_NOT_EQUAL_VALUE_TYPE:
case OPCODE (less_than): case VM_OP_LESS_THAN:
case OPCODE (greater_than): case VM_OP_GREATER_THAN:
case OPCODE (less_or_equal_than): case VM_OP_LESS_OR_EQUAL_THAN:
case OPCODE (greater_or_equal_than): case VM_OP_GREATER_OR_EQUAL_THAN:
case OPCODE (instanceof): case VM_OP_INSTANCEOF:
case OPCODE (in): case VM_OP_IN:
case OPCODE (addition): case VM_OP_ADDITION:
case OPCODE (substraction): case VM_OP_SUBSTRACTION:
case OPCODE (division): case VM_OP_DIVISION:
case OPCODE (multiplication): case VM_OP_MULTIPLICATION:
case OPCODE (remainder): case VM_OP_REMAINDER:
{ {
change_uid (om, lit_ids, 0x111); change_uid (om, lit_ids, 0x111);
break; break;
} }
case OPCODE (call_n): case VM_OP_CALL_N:
case OPCODE (native_call): case VM_OP_NATIVE_CALL:
case OPCODE (construct_n): case VM_OP_CONSTRUCT_N:
case OPCODE (func_expr_n): case VM_OP_FUNC_EXPR_N:
case OPCODE (delete_var): case VM_OP_DELETE_VAR:
case OPCODE (typeof): case VM_OP_TYPEOF:
case OPCODE (b_not): case VM_OP_B_NOT:
case OPCODE (logical_not): case VM_OP_LOGICAL_NOT:
case OPCODE (post_incr): case VM_OP_POST_INCR:
case OPCODE (post_decr): case VM_OP_POST_DECR:
case OPCODE (pre_incr): case VM_OP_PRE_INCR:
case OPCODE (pre_decr): case VM_OP_PRE_DECR:
case OPCODE (unary_plus): case VM_OP_UNARY_PLUS:
case OPCODE (unary_minus): case VM_OP_UNARY_MINUS:
{ {
change_uid (om, lit_ids, 0x110); change_uid (om, lit_ids, 0x110);
break; break;
} }
case OPCODE (assignment): case VM_OP_ASSIGNMENT:
{ {
switch (om->op.data.assignment.type_value_right) switch (om->op.data.assignment.type_value_right)
{ {
@@ -301,34 +300,33 @@ generate_opcode (scopes_tree tree, opcode_counter_t opc_index, lit_id_hash_table
} }
break; break;
} }
case OPCODE (func_decl_n): case VM_OP_FUNC_DECL_N:
case OPCODE (array_decl): case VM_OP_ARRAY_DECL:
case OPCODE (obj_decl): case VM_OP_OBJ_DECL:
case OPCODE (this_binding): case VM_OP_THIS_BINDING:
case OPCODE (with): case VM_OP_WITH:
case OPCODE (for_in): case VM_OP_FOR_IN:
case OPCODE (throw_value): case VM_OP_THROW_VALUE:
case OPCODE (is_true_jmp_up): case VM_OP_IS_TRUE_JMP_UP:
case OPCODE (is_true_jmp_down): case VM_OP_IS_TRUE_JMP_DOWN:
case OPCODE (is_false_jmp_up): case VM_OP_IS_FALSE_JMP_UP:
case OPCODE (is_false_jmp_down): case VM_OP_IS_FALSE_JMP_DOWN:
case OPCODE (var_decl): case VM_OP_VAR_DECL:
case OPCODE (retval): case VM_OP_RETVAL:
{ {
change_uid (om, lit_ids, 0x100); change_uid (om, lit_ids, 0x100);
break; break;
} }
case OPCODE (ret): case VM_OP_RET:
case OPCODE (try_block): case VM_OP_TRY_BLOCK:
case OPCODE (jmp_up): case VM_OP_JMP_UP:
case OPCODE (jmp_down): case VM_OP_JMP_DOWN:
case OPCODE (nop): case VM_OP_REG_VAR_DECL:
case OPCODE (reg_var_decl):
{ {
change_uid (om, lit_ids, 0x000); change_uid (om, lit_ids, 0x000);
break; break;
} }
case OPCODE (meta): case VM_OP_META:
{ {
switch (om->op.data.meta.type) switch (om->op.data.meta.type)
{ {
@@ -372,53 +370,53 @@ count_new_literals_in_opcode (scopes_tree tree, opcode_counter_t opc_index)
op_meta *om = extract_op_meta (tree, opc_index); op_meta *om = extract_op_meta (tree, opc_index);
switch (om->op.op_idx) switch (om->op.op_idx)
{ {
case OPCODE (prop_getter): case VM_OP_PROP_GETTER:
case OPCODE (prop_setter): case VM_OP_PROP_SETTER:
case OPCODE (delete_prop): case VM_OP_DELETE_PROP:
case OPCODE (b_shift_left): case VM_OP_B_SHIFT_LEFT:
case OPCODE (b_shift_right): case VM_OP_B_SHIFT_RIGHT:
case OPCODE (b_shift_uright): case VM_OP_B_SHIFT_URIGHT:
case OPCODE (b_and): case VM_OP_B_AND:
case OPCODE (b_or): case VM_OP_B_OR:
case OPCODE (b_xor): case VM_OP_B_XOR:
case OPCODE (equal_value): case VM_OP_EQUAL_VALUE:
case OPCODE (not_equal_value): case VM_OP_NOT_EQUAL_VALUE:
case OPCODE (equal_value_type): case VM_OP_EQUAL_VALUE_TYPE:
case OPCODE (not_equal_value_type): case VM_OP_NOT_EQUAL_VALUE_TYPE:
case OPCODE (less_than): case VM_OP_LESS_THAN:
case OPCODE (greater_than): case VM_OP_GREATER_THAN:
case OPCODE (less_or_equal_than): case VM_OP_LESS_OR_EQUAL_THAN:
case OPCODE (greater_or_equal_than): case VM_OP_GREATER_OR_EQUAL_THAN:
case OPCODE (instanceof): case VM_OP_INSTANCEOF:
case OPCODE (in): case VM_OP_IN:
case OPCODE (addition): case VM_OP_ADDITION:
case OPCODE (substraction): case VM_OP_SUBSTRACTION:
case OPCODE (division): case VM_OP_DIVISION:
case OPCODE (multiplication): case VM_OP_MULTIPLICATION:
case OPCODE (remainder): case VM_OP_REMAINDER:
{ {
insert_uids_to_lit_id_map (om, 0x111); insert_uids_to_lit_id_map (om, 0x111);
break; break;
} }
case OPCODE (call_n): case VM_OP_CALL_N:
case OPCODE (native_call): case VM_OP_NATIVE_CALL:
case OPCODE (construct_n): case VM_OP_CONSTRUCT_N:
case OPCODE (func_expr_n): case VM_OP_FUNC_EXPR_N:
case OPCODE (delete_var): case VM_OP_DELETE_VAR:
case OPCODE (typeof): case VM_OP_TYPEOF:
case OPCODE (b_not): case VM_OP_B_NOT:
case OPCODE (logical_not): case VM_OP_LOGICAL_NOT:
case OPCODE (post_incr): case VM_OP_POST_INCR:
case OPCODE (post_decr): case VM_OP_POST_DECR:
case OPCODE (pre_incr): case VM_OP_PRE_INCR:
case OPCODE (pre_decr): case VM_OP_PRE_DECR:
case OPCODE (unary_plus): case VM_OP_UNARY_PLUS:
case OPCODE (unary_minus): case VM_OP_UNARY_MINUS:
{ {
insert_uids_to_lit_id_map (om, 0x110); insert_uids_to_lit_id_map (om, 0x110);
break; break;
} }
case OPCODE (assignment): case VM_OP_ASSIGNMENT:
{ {
switch (om->op.data.assignment.type_value_right) switch (om->op.data.assignment.type_value_right)
{ {
@@ -441,33 +439,32 @@ count_new_literals_in_opcode (scopes_tree tree, opcode_counter_t opc_index)
} }
break; break;
} }
case OPCODE (func_decl_n): case VM_OP_FUNC_DECL_N:
case OPCODE (array_decl): case VM_OP_ARRAY_DECL:
case OPCODE (obj_decl): case VM_OP_OBJ_DECL:
case OPCODE (this_binding): case VM_OP_THIS_BINDING:
case OPCODE (with): case VM_OP_WITH:
case OPCODE (throw_value): case VM_OP_THROW_VALUE:
case OPCODE (is_true_jmp_up): case VM_OP_IS_TRUE_JMP_UP:
case OPCODE (is_true_jmp_down): case VM_OP_IS_TRUE_JMP_DOWN:
case OPCODE (is_false_jmp_up): case VM_OP_IS_FALSE_JMP_UP:
case OPCODE (is_false_jmp_down): case VM_OP_IS_FALSE_JMP_DOWN:
case OPCODE (var_decl): case VM_OP_VAR_DECL:
case OPCODE (retval): case VM_OP_RETVAL:
{ {
insert_uids_to_lit_id_map (om, 0x100); insert_uids_to_lit_id_map (om, 0x100);
break; break;
} }
case OPCODE (ret): case VM_OP_RET:
case OPCODE (try_block): case VM_OP_TRY_BLOCK:
case OPCODE (jmp_up): case VM_OP_JMP_UP:
case OPCODE (jmp_down): case VM_OP_JMP_DOWN:
case OPCODE (nop): case VM_OP_REG_VAR_DECL:
case OPCODE (reg_var_decl):
{ {
insert_uids_to_lit_id_map (om, 0x000); insert_uids_to_lit_id_map (om, 0x000);
break; break;
} }
case OPCODE (meta): case VM_OP_META:
{ {
switch (om->op.data.meta.type) switch (om->op.data.meta.type)
{ {
@@ -525,12 +522,12 @@ scopes_tree_count_literals_in_blocks (scopes_tree tree)
for (opc_index = 0; opc_index < tree->opcodes_num; opc_index++) for (opc_index = 0; opc_index < tree->opcodes_num; opc_index++)
{ {
op_meta *om = extract_op_meta (tree, opc_index); op_meta *om = extract_op_meta (tree, opc_index);
if (om->op.op_idx != OPCODE (var_decl) if (om->op.op_idx != VM_OP_VAR_DECL
&& om->op.op_idx != OPCODE (meta) && !header) && om->op.op_idx != VM_OP_META && !header)
{ {
break; break;
} }
if (om->op.op_idx == OPCODE (reg_var_decl)) if (om->op.op_idx == VM_OP_REG_VAR_DECL)
{ {
header = false; header = false;
} }
@@ -572,12 +569,12 @@ merge_subscopes (scopes_tree tree, opcode_t *data, lit_id_hash_table *lit_ids)
for (opc_index = 0; opc_index < tree->opcodes_num; opc_index++) for (opc_index = 0; opc_index < tree->opcodes_num; opc_index++)
{ {
op_meta *om = extract_op_meta (tree, opc_index); op_meta *om = extract_op_meta (tree, opc_index);
if (om->op.op_idx != OPCODE (var_decl) if (om->op.op_idx != VM_OP_VAR_DECL
&& om->op.op_idx != OPCODE (meta) && !header) && om->op.op_idx != VM_OP_META && !header)
{ {
break; break;
} }
if (om->op.op_idx == OPCODE (reg_var_decl)) if (om->op.op_idx == VM_OP_REG_VAR_DECL)
{ {
header = false; header = false;
} }
@@ -44,7 +44,7 @@ opfunc_try_block (opcode_t opdata, /**< operation data */
frame_ctx_p->pos = try_end_oc; frame_ctx_p->pos = try_end_oc;
opcode_t next_opcode = vm_get_opcode (frame_ctx_p->opcodes_p, frame_ctx_p->pos); opcode_t next_opcode = vm_get_opcode (frame_ctx_p->opcodes_p, frame_ctx_p->pos);
JERRY_ASSERT (next_opcode.op_idx == __op__idx_meta); JERRY_ASSERT (next_opcode.op_idx == VM_OP_META);
if (next_opcode.data.meta.type == OPCODE_META_TYPE_CATCH) if (next_opcode.data.meta.type == OPCODE_META_TYPE_CATCH)
{ {
@@ -55,7 +55,7 @@ opfunc_try_block (opcode_t opdata, /**< operation data */
if (ecma_is_completion_value_throw (try_completion)) if (ecma_is_completion_value_throw (try_completion))
{ {
next_opcode = vm_get_opcode (frame_ctx_p->opcodes_p, frame_ctx_p->pos); next_opcode = vm_get_opcode (frame_ctx_p->opcodes_p, frame_ctx_p->pos);
JERRY_ASSERT (next_opcode.op_idx == __op__idx_meta); JERRY_ASSERT (next_opcode.op_idx == VM_OP_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 (next_opcode.data.meta.data_1, lit_cpointer_t catch_exc_val_var_name_lit_cp = serializer_get_literal_cp_by_uid (next_opcode.data.meta.data_1,
@@ -99,7 +99,7 @@ opfunc_try_block (opcode_t opdata, /**< operation data */
} }
next_opcode = vm_get_opcode (frame_ctx_p->opcodes_p, frame_ctx_p->pos); next_opcode = vm_get_opcode (frame_ctx_p->opcodes_p, frame_ctx_p->pos);
JERRY_ASSERT (next_opcode.op_idx == __op__idx_meta); JERRY_ASSERT (next_opcode.op_idx == VM_OP_META);
if (next_opcode.data.meta.type == OPCODE_META_TYPE_FINALLY) if (next_opcode.data.meta.type == OPCODE_META_TYPE_FINALLY)
{ {
@@ -122,7 +122,7 @@ opfunc_try_block (opcode_t opdata, /**< operation data */
} }
next_opcode = vm_get_opcode (frame_ctx_p->opcodes_p, frame_ctx_p->pos++); next_opcode = vm_get_opcode (frame_ctx_p->opcodes_p, frame_ctx_p->pos++);
JERRY_ASSERT (next_opcode.op_idx == __op__idx_meta); JERRY_ASSERT (next_opcode.op_idx == VM_OP_META);
JERRY_ASSERT (next_opcode.data.meta.type == OPCODE_META_TYPE_END_TRY_CATCH_FINALLY); JERRY_ASSERT (next_opcode.data.meta.type == OPCODE_META_TYPE_END_TRY_CATCH_FINALLY);
return try_completion; return try_completion;
+1 -1
View File
@@ -204,7 +204,7 @@ opfunc_for_in (opcode_t opdata, /**< operation data */
int_data_p->pos++; int_data_p->pos++;
opcode_t meta_opcode = vm_get_opcode (int_data_p->opcodes_p, for_in_end_oc); opcode_t meta_opcode = vm_get_opcode (int_data_p->opcodes_p, for_in_end_oc);
JERRY_ASSERT (meta_opcode.op_idx == __op__idx_meta); JERRY_ASSERT (meta_opcode.op_idx == VM_OP_META);
JERRY_ASSERT (meta_opcode.data.meta.type == OPCODE_META_TYPE_END_FOR_IN); JERRY_ASSERT (meta_opcode.data.meta.type == OPCODE_META_TYPE_END_FOR_IN);
/* 3. */ /* 3. */
+2 -2
View File
@@ -45,7 +45,7 @@ fill_varg_list (vm_frame_ctx_t *frame_ctx_p, /**< interpreter context */
if (ecma_is_completion_value_empty (evaluate_arg_completion)) if (ecma_is_completion_value_empty (evaluate_arg_completion))
{ {
opcode_t next_opcode = vm_get_opcode (frame_ctx_p->opcodes_p, frame_ctx_p->pos); opcode_t next_opcode = vm_get_opcode (frame_ctx_p->opcodes_p, frame_ctx_p->pos);
JERRY_ASSERT (next_opcode.op_idx == __op__idx_meta); JERRY_ASSERT (next_opcode.op_idx == VM_OP_META);
JERRY_ASSERT (next_opcode.data.meta.type == OPCODE_META_TYPE_VARG); JERRY_ASSERT (next_opcode.data.meta.type == OPCODE_META_TYPE_VARG);
const idx_t varg_var_idx = next_opcode.data.meta.data_1; const idx_t varg_var_idx = next_opcode.data.meta.data_1;
@@ -92,7 +92,7 @@ fill_params_list (vm_frame_ctx_t *frame_ctx_p, /**< interpreter context */
param_index++) param_index++)
{ {
opcode_t next_opcode = vm_get_opcode (frame_ctx_p->opcodes_p, frame_ctx_p->pos); opcode_t next_opcode = vm_get_opcode (frame_ctx_p->opcodes_p, frame_ctx_p->pos);
JERRY_ASSERT (next_opcode.op_idx == __op__idx_meta); JERRY_ASSERT (next_opcode.op_idx == VM_OP_META);
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,
+34 -53
View File
@@ -45,30 +45,6 @@
* corresponding to the instruction, containing the idx argument. * corresponding to the instruction, containing the idx argument.
*/ */
#define OP_UNIMPLEMENTED_LIST(op) \
static char __attr_unused___ unimplemented_list_end
#define DEFINE_UNIMPLEMENTED_OP(op) \
ecma_completion_value_t opfunc_ ## op (opcode_t opdata, vm_frame_ctx_t *frame_ctx_p) \
{ \
JERRY_UNIMPLEMENTED_REF_UNUSED_VARS (opdata, frame_ctx_p); \
}
OP_UNIMPLEMENTED_LIST (DEFINE_UNIMPLEMENTED_OP);
#undef DEFINE_UNIMPLEMENTED_OP
/**
* 'Nop' opcode handler.
*/
ecma_completion_value_t
opfunc_nop (opcode_t opdata __attr_unused___, /**< operation data */
vm_frame_ctx_t *frame_ctx_p) /**< interpreter context */
{
frame_ctx_p->pos++;
return ecma_make_empty_completion_value ();
} /* opfunc_nop */
/** /**
* 'Assignment' opcode handler. * 'Assignment' opcode handler.
* *
@@ -719,7 +695,7 @@ vm_helper_call_get_call_flags_and_this_arg (vm_frame_ctx_t *int_data_p, /**< int
idx_t this_arg_var_idx = INVALID_VALUE; idx_t this_arg_var_idx = INVALID_VALUE;
opcode_t next_opcode = vm_get_opcode (int_data_p->opcodes_p, int_data_p->pos); opcode_t next_opcode = vm_get_opcode (int_data_p->opcodes_p, int_data_p->pos);
if (next_opcode.op_idx == __op__idx_meta if (next_opcode.op_idx == VM_OP_META
&& next_opcode.data.meta.type == OPCODE_META_TYPE_CALL_SITE_INFO) && next_opcode.data.meta.type == OPCODE_META_TYPE_CALL_SITE_INFO)
{ {
call_flags = (opcode_call_flags_t) next_opcode.data.meta.data_1; call_flags = (opcode_call_flags_t) next_opcode.data.meta.data_1;
@@ -1081,7 +1057,7 @@ opfunc_obj_decl (opcode_t opdata, /**< operation data */
if (ecma_is_completion_value_empty (evaluate_prop_completion)) if (ecma_is_completion_value_empty (evaluate_prop_completion))
{ {
opcode_t next_opcode = vm_get_opcode (frame_ctx_p->opcodes_p, frame_ctx_p->pos); opcode_t next_opcode = vm_get_opcode (frame_ctx_p->opcodes_p, frame_ctx_p->pos);
JERRY_ASSERT (next_opcode.op_idx == __op__idx_meta); JERRY_ASSERT (next_opcode.op_idx == VM_OP_META);
const opcode_meta_type type = (opcode_meta_type) next_opcode.data.meta.type; const opcode_meta_type type = (opcode_meta_type) next_opcode.data.meta.type;
JERRY_ASSERT (type == OPCODE_META_TYPE_VARG_PROP_DATA JERRY_ASSERT (type == OPCODE_META_TYPE_VARG_PROP_DATA
@@ -1456,7 +1432,7 @@ opfunc_with (opcode_t opdata, /**< operation data */
#ifndef JERRY_NDEBUG #ifndef JERRY_NDEBUG
opcode_t meta_opcode = vm_get_opcode (frame_ctx_p->opcodes_p, with_end_oc); opcode_t meta_opcode = vm_get_opcode (frame_ctx_p->opcodes_p, with_end_oc);
JERRY_ASSERT (meta_opcode.op_idx == __op__idx_meta); JERRY_ASSERT (meta_opcode.op_idx == VM_OP_META);
JERRY_ASSERT (meta_opcode.data.meta.type == OPCODE_META_TYPE_END_WITH); JERRY_ASSERT (meta_opcode.data.meta.type == OPCODE_META_TYPE_END_WITH);
#endif /* !JERRY_NDEBUG */ #endif /* !JERRY_NDEBUG */
@@ -1855,34 +1831,39 @@ read_meta_opcode_counter (opcode_meta_type expected_type, /**< expected type of
return calc_opcode_counter_from_idx_idx (data_1, data_2); return calc_opcode_counter_from_idx_idx (data_1, data_2);
} /* read_meta_opcode_counter */ } /* read_meta_opcode_counter */
#define GETOP_DEF_1(a, name, field1) \ #define VM_OP_0(opcode_name, opcode_name_uppercase) \
opcode_t getop_##name (idx_t arg1) \ opcode_t getop_##opcode_name (void) \
{ \ { \
opcode_t opdata; \ opcode_t opdata; \
opdata.op_idx = __op__idx_##name; \ opdata.op_idx = VM_OP_##opcode_name_uppercase; \
opdata.data.name.field1 = arg1; \ return opdata; \
}
#define VM_OP_1(opcode_name, opcode_name_uppercase, arg1, arg1_type) \
opcode_t getop_##opcode_name (idx_t arg1_v) \
{ \
opcode_t opdata; \
opdata.op_idx = VM_OP_##opcode_name_uppercase; \
opdata.data.opcode_name.arg1 = arg1_v; \
return opdata; \
}
#define VM_OP_2(opcode_name, opcode_name_uppercase, arg1, arg1_type, arg2, arg2_type) \
opcode_t getop_##opcode_name (idx_t arg1_v, idx_t arg2_v) \
{ \
opcode_t opdata; \
opdata.op_idx = VM_OP_##opcode_name_uppercase; \
opdata.data.opcode_name.arg1 = arg1_v; \
opdata.data.opcode_name.arg2 = arg2_v; \
return opdata; \
}
#define VM_OP_3(opcode_name, opcode_name_uppercase, arg1, arg1_type, arg2, arg2_type, arg3, arg3_type) \
opcode_t getop_##opcode_name (idx_t arg1_v, idx_t arg2_v, idx_t arg3_v) \
{ \
opcode_t opdata; \
opdata.op_idx = VM_OP_##opcode_name_uppercase; \
opdata.data.opcode_name.arg1 = arg1_v; \
opdata.data.opcode_name.arg2 = arg2_v; \
opdata.data.opcode_name.arg3 = arg3_v; \
return opdata; \ return opdata; \
} }
#define GETOP_DEF_2(a, name, field1, field2) \ #include "vm-opcodes.inc.h"
opcode_t getop_##name (idx_t arg1, idx_t arg2) \
{ \
opcode_t opdata; \
opdata.op_idx = __op__idx_##name; \
opdata.data.name.field1 = arg1; \
opdata.data.name.field2 = arg2; \
return opdata; \
}
#define GETOP_DEF_3(a, name, field1, field2, field3) \
opcode_t getop_##name (idx_t arg1, idx_t arg2, idx_t arg3) \
{ \
opcode_t opdata; \
opdata.op_idx = __op__idx_##name; \
opdata.data.name.field1 = arg1; \
opdata.data.name.field2 = arg2; \
opdata.data.name.field3 = arg3; \
return opdata; \
}
OP_ARGS_LIST (GETOP_DEF)
+74 -158
View File
@@ -117,6 +117,27 @@ typedef enum : idx_t
OPCODE_REG_LAST = OPCODE_REG_GENERAL_FIRST /**< identifier of last register */ OPCODE_REG_LAST = OPCODE_REG_GENERAL_FIRST /**< identifier of last register */
} opcode_special_reg_t; } opcode_special_reg_t;
/**
* Types of byte-code instruction arguments, used for instruction description
*
* See also:
* vm-opcodes.inc.h
*/
typedef enum
{
VM_OP_ARG_TYPE_EMPTY = (1u << 0), /**< empty argument (no value) */
VM_OP_ARG_TYPE_REGISTER = (1u << 1), /**< register variable (index) */
VM_OP_ARG_TYPE_IDENTIFIER = (1u << 2), /**< identifier - named variable (string literal) */
VM_OP_ARG_TYPE_STRING = (1u << 3), /**< string constant value (string literal) */
VM_OP_ARG_TYPE_NUMBER = (1u << 4), /**< number constant value (number literal) */
VM_OP_ARG_TYPE_INTEGER_CONST = (1u << 5), /**< a 8-bit integer constant (any idx_t) */
VM_OP_ARG_TYPE_TYPE_OF_NEXT = (1u << 6), /**< opcode_arg_type_operand value,
* representing type of argument encoded in next idx */
/** variable - an identifier or a register */
VM_OP_ARG_TYPE_VARIABLE = (VM_OP_ARG_TYPE_REGISTER | VM_OP_ARG_TYPE_IDENTIFIER)
} vm_op_arg_type_t;
/** /**
* Forward declaration of opcode structure * Forward declaration of opcode structure
*/ */
@@ -170,180 +191,75 @@ typedef struct
opcode_counter_t calc_opcode_counter_from_idx_idx (const idx_t oc_idx_1, const idx_t oc_idx_2); opcode_counter_t calc_opcode_counter_from_idx_idx (const idx_t oc_idx_1, const idx_t oc_idx_2);
opcode_counter_t read_meta_opcode_counter (opcode_meta_type expected_type, vm_frame_ctx_t *frame_ctx_p); opcode_counter_t read_meta_opcode_counter (opcode_meta_type expected_type, vm_frame_ctx_t *frame_ctx_p);
#define OP_CALLS_AND_ARGS(p, a) \
p##_3 (a, call_n, lhs, function_var_idx, arg_list) \
p##_3 (a, native_call, lhs, name, arg_list) \
p##_3 (a, construct_n, lhs, name_lit_idx, arg_list) \
p##_2 (a, func_decl_n, name_lit_idx, arg_list) \
p##_3 (a, func_expr_n, lhs, name_lit_idx, arg_list) \
p##_1 (a, retval, ret_value) \
p##_0 (a, ret)
#define OP_INITS(p, a) \
p##_2 (a, array_decl, lhs, list) \
p##_3 (a, prop_getter, lhs, obj, prop) \
p##_3 (a, prop_setter, obj, prop, rhs) \
p##_2 (a, obj_decl, lhs, list) \
p##_1 (a, this_binding, lhs) \
p##_2 (a, delete_var, lhs, name) \
p##_3 (a, delete_prop, lhs, base, name) \
p##_2 (a, typeof, lhs, obj) \
p##_3 (a, for_in, expr, oc_idx_1, oc_idx_2) \
p##_3 (a, with, expr, oc_idx_1, oc_idx_2) \
p##_2 (a, try_block, oc_idx_1, oc_idx_2) \
p##_1 (a, throw_value, var)
#define OP_ASSIGNMENTS(p, a) \
p##_3 (a, assignment, var_left, type_value_right, value_right)
#define OP_B_SHIFTS(p, a) \
p##_3 (a, b_shift_left, dst, var_left, var_right) \
p##_3 (a, b_shift_right, dst, var_left, var_right) \
p##_3 (a, b_shift_uright, dst, var_left, var_right)
#define OP_B_BITWISE(p, a) \
p##_3 (a, b_and, dst, var_left, var_right) \
p##_3 (a, b_or, dst, var_left, var_right) \
p##_3 (a, b_xor, dst, var_left, var_right) \
p##_2 (a, b_not, dst, var_right)
#define OP_B_LOGICAL(p, a) \
p##_2 (a, logical_not, dst, var_right)
#define OP_EQUALITY(p, a) \
p##_3 (a, equal_value, dst, var_left, var_right) \
p##_3 (a, not_equal_value, dst, var_left, var_right) \
p##_3 (a, equal_value_type, dst, var_left, var_right) \
p##_3 (a, not_equal_value_type, dst, var_left, var_right)
#define OP_RELATIONAL(p, a) \
p##_3 (a, less_than, dst, var_left, var_right) \
p##_3 (a, greater_than, dst, var_left, var_right) \
p##_3 (a, less_or_equal_than, dst, var_left, var_right) \
p##_3 (a, greater_or_equal_than, dst, var_left, var_right) \
p##_3 (a, instanceof, dst, var_left, var_right) \
p##_3 (a, in, dst, var_left, var_right)
#define OP_ARITHMETIC(p, a) \
p##_2 (a, post_incr, dst, var_right) \
p##_2 (a, post_decr, dst, var_right) \
p##_2 (a, pre_incr, dst, var_right) \
p##_2 (a, pre_decr, dst, var_right) \
p##_3 (a, addition, dst, var_left, var_right) \
p##_3 (a, substraction, dst, var_left, var_right) \
p##_3 (a, division, dst, var_left, var_right) \
p##_3 (a, multiplication, dst, var_left, var_right) \
p##_3 (a, remainder, dst, var_left, var_right) \
p##_2 (a, unary_minus, dst, var) \
p##_2 (a, unary_plus, dst, var)
#define OP_JUMPS(p, a) \
p##_2 (a, jmp_up, opcode_1, opcode_2) \
p##_2 (a, jmp_down, opcode_1, opcode_2) \
p##_0 (a, nop) \
p##_3 (a, is_true_jmp_up, value, opcode_1, opcode_2) \
p##_3 (a, is_true_jmp_down, value, opcode_1, opcode_2) \
p##_3 (a, is_false_jmp_up, value, opcode_1, opcode_2) \
p##_3 (a, is_false_jmp_down, value, opcode_1, opcode_2) \
p##_2 (a, jmp_break_continue, opcode_1, opcode_2)
#define OP_LIST_FULL(p, a) \
OP_CALLS_AND_ARGS (p, a) \
OP_INITS (p, a) \
OP_ASSIGNMENTS (p, a) \
OP_B_LOGICAL (p, a) \
OP_B_BITWISE (p, a) \
OP_B_SHIFTS (p, a) \
OP_EQUALITY (p, a) \
OP_RELATIONAL (p, a) \
OP_ARITHMETIC (p, a) \
OP_JUMPS (p, a) \
p##_1 (a, var_decl, variable_name) \
p##_2 (a, reg_var_decl, min, max) \
p##_3 (a, meta, type, data_1, data_2)
#define OP_LIST(a) OP_LIST_FULL (OP, a)
#define OP_ARGS_LIST(a) OP_LIST_FULL (a, void)
#define OP_DATA_0(action, name) \
typedef struct \
{ \
idx_t __do_not_use; \
} __op_##name;
#define OP_DATA_1(action, name, arg1) \
typedef struct \
{ \
idx_t arg1; \
} __op_##name;
#define OP_DATA_2(action, name, arg1, arg2) \
typedef struct \
{ \
idx_t arg1; \
idx_t arg2; \
} __op_##name;
#define OP_DATA_3(action, name, arg1, arg2, arg3) \
typedef struct \
{ \
idx_t arg1; \
idx_t arg2; \
idx_t arg3; \
} __op_##name;
OP_ARGS_LIST (OP_DATA)
#define __OP_STRUCT_FIELD(name, arg1, arg2, arg3) __op_##name name;
typedef struct opcode_t typedef struct opcode_t
{ {
idx_t op_idx; idx_t op_idx;
union union
{ {
OP_LIST (OP_STRUCT_FIELD) #define VM_OP_1(opcode_name, opcode_name_uppercase, arg1, arg1_type) \
struct \
{ \
idx_t arg1; \
} opcode_name;
#define VM_OP_2(opcode_name, opcode_name_uppercase, arg1, arg1_type, arg2, arg2_type) \
struct \
{ \
idx_t arg1; \
idx_t arg2; \
} opcode_name;
#define VM_OP_3(opcode_name, opcode_name_uppercase, arg1, arg1_type, arg2, arg2_type, arg3, arg3_type) \
struct \
{ \
idx_t arg1; \
idx_t arg2; \
idx_t arg3; \
} opcode_name;
#include "vm-opcodes.inc.h"
} data; } data;
} opcode_t; } opcode_t;
#undef __OP_STRUCT_FIELD
#define __OP_ENUM_FIELD(name, arg1, arg2, arg3) __op__idx_##name ,
enum __opcode_idx enum __opcode_idx
{ {
OP_LIST (OP_ENUM_FIELD) #define VM_OP_0(opcode_name, opcode_name_uppercase) \
LAST_OP VM_OP_ ## opcode_name_uppercase,
}; #define VM_OP_1(opcode_name, opcode_name_uppercase, arg1, arg1_type) \
#undef __OP_ENUM_FIELD VM_OP_ ## opcode_name_uppercase,
#define VM_OP_2(opcode_name, opcode_name_uppercase, arg1, arg1_type, arg2, arg2_type) \
VM_OP_ ## opcode_name_uppercase,
#define VM_OP_3(opcode_name, opcode_name_uppercase, arg1, arg1_type, arg2, arg2_type, arg3, arg3_type) \
VM_OP_ ## opcode_name_uppercase,
#define __OP_FUNC_DECL(name, arg1, arg2, arg3) ecma_completion_value_t opfunc_##name (opcode_t, vm_frame_ctx_t*); #include "vm-opcodes.inc.h"
OP_LIST (OP_FUNC_DECL)
#undef __OP_FUNC_DECL VM_OP__COUNT /**< number of opcodes */
};
#define VM_OP_0(opcode_name, opcode_name_uppercase) \
ecma_completion_value_t opfunc_##opcode_name (opcode_t, vm_frame_ctx_t*);
#define VM_OP_1(opcode_name, opcode_name_uppercase, arg1, arg1_type) \
ecma_completion_value_t opfunc_##opcode_name (opcode_t, vm_frame_ctx_t*);
#define VM_OP_2(opcode_name, opcode_name_uppercase, arg1, arg1_type, arg2, arg2_type) \
ecma_completion_value_t opfunc_##opcode_name (opcode_t, vm_frame_ctx_t*);
#define VM_OP_3(opcode_name, opcode_name_uppercase, arg1, arg1_type, arg2, arg2_type, arg3, arg3_type) \
ecma_completion_value_t opfunc_##opcode_name (opcode_t, vm_frame_ctx_t*);
#include "vm-opcodes.inc.h"
typedef ecma_completion_value_t (*opfunc) (opcode_t, vm_frame_ctx_t *); typedef ecma_completion_value_t (*opfunc) (opcode_t, vm_frame_ctx_t *);
#define GETOP_DECL_0(a, name) \ #define VM_OP_0(opcode_name, opcode_name_uppercase) \
opcode_t getop_##name (void); opcode_t getop_##opcode_name (void);
#define VM_OP_1(opcode_name, opcode_name_uppercase, arg1, arg1_type) \
opcode_t getop_##opcode_name (idx_t);
#define VM_OP_2(opcode_name, opcode_name_uppercase, arg1, arg1_type, arg2, arg2_type) \
opcode_t getop_##opcode_name (idx_t, idx_t);
#define VM_OP_3(opcode_name, opcode_name_uppercase, arg1, arg1_type, arg2, arg2_type, arg3, arg3_type) \
opcode_t getop_##opcode_name (idx_t, idx_t, idx_t);
#define GETOP_DECL_1(a, name, arg1) \ #include "vm-opcodes.inc.h"
opcode_t getop_##name (idx_t);
#define GETOP_DECL_2(a, name, arg1, arg2) \
opcode_t getop_##name (idx_t, idx_t);
#define GETOP_DECL_3(a, name, arg1, arg2, arg3) \
opcode_t getop_##name (idx_t, idx_t, idx_t);
#define GETOP_DEF_0(a, name) \
opcode_t getop_##name (void) \
{ \
opcode_t opdata; \
opdata.op_idx = __op__idx_##name; \
return opdata; \
}
OP_ARGS_LIST (GETOP_DECL)
#undef GETOP_DECL_0
#undef GETOP_DECL_1
#undef GETOP_DECL_2
#undef GETOP_DECL_3
typedef struct typedef struct
{ {
+100 -95
View File
@@ -25,24 +25,32 @@
#include "serializer.h" #include "serializer.h"
#include "lit-literal.h" #include "lit-literal.h"
#define NAME_TO_ID(op) (__op__idx_##op)
#define __OPCODE_STR(name, arg1, arg2, arg3) \
#name,
#define __OPCODE_SIZE(name, arg1, arg2, arg3) \
(uint8_t) (sizeof (__op_##name) + 1),
static const char* opcode_names[] = static const char* opcode_names[] =
{ {
OP_LIST (OPCODE_STR) #define VM_OP_0(opcode_name, opcode_name_uppercase) \
"" #opcode_name,
#define VM_OP_1(opcode_name, opcode_name_uppercase, arg1, arg1_type) \
#opcode_name,
#define VM_OP_2(opcode_name, opcode_name_uppercase, arg1, arg1_type, arg2, arg2_type) \
#opcode_name,
#define VM_OP_3(opcode_name, opcode_name_uppercase, arg1, arg1_type, arg2, arg2_type, arg3, arg3_type) \
#opcode_name,
#include "vm-opcodes.inc.h"
}; };
static uint8_t opcode_sizes[] = static uint8_t opcode_sizes[] =
{ {
OP_LIST (OPCODE_SIZE) #define VM_OP_0(opcode_name, opcode_name_uppercase) \
0 0,
#define VM_OP_1(opcode_name, opcode_name_uppercase, arg1, arg1_type) \
1,
#define VM_OP_2(opcode_name, opcode_name_uppercase, arg1, arg1_type, arg2, arg2_type) \
2,
#define VM_OP_3(opcode_name, opcode_name_uppercase, arg1, arg1_type, arg2, arg2_type, arg3, arg3_type) \
3,
#include "vm-opcodes.inc.h"
}; };
static char buff[ECMA_MAX_CHARS_IN_STRINGIFIED_NUMBER]; static char buff[ECMA_MAX_CHARS_IN_STRINGIFIED_NUMBER];
@@ -150,7 +158,7 @@ pp_printf (const char *format, opcode_t opcode, lit_cpointer_t lit_ids[], opcode
} }
#define PP_OP(op_name, format) \ #define PP_OP(op_name, format) \
case NAME_TO_ID (op_name): pp_printf (format, opm.op, opm.lit_id, oc, 1); break; case op_name: pp_printf (format, opm.op, opm.lit_id, oc, 1); break;
#define VAR(i) var_to_str (opm.op, opm.lit_id, oc, i) #define VAR(i) var_to_str (opm.op, opm.lit_id, oc, i)
#define OC(i, j) __extension__({ raw_opcode* raw = (raw_opcode *) &opm.op; \ #define OC(i, j) __extension__({ raw_opcode* raw = (raw_opcode *) &opm.op; \
calc_opcode_counter_from_idx_idx (raw->uids[i], raw->uids[j]); }) calc_opcode_counter_from_idx_idx (raw->uids[i], raw->uids[j]); })
@@ -164,12 +172,10 @@ dump_asm (opcode_counter_t oc, opcode_t opcode)
uint8_t i = 0; uint8_t i = 0;
uint8_t opcode_id = opcode.op_idx; uint8_t opcode_id = opcode.op_idx;
printf ("%3d: %20s ", oc, opcode_names[opcode_id]); printf ("%3d: %20s ", oc, opcode_names[opcode_id]);
if (opcode_id != NAME_TO_ID (nop) && opcode_id != NAME_TO_ID (ret))
for (i = 1; i < opcode_sizes[opcode_id]; i++)
{ {
for (i = 1; i < opcode_sizes[opcode_id]; i++) printf ("%4d ", ((raw_opcode *) &opcode)->uids[i]);
{
printf ("%4d ", ((raw_opcode *) &opcode)->uids[i]);
}
} }
for (; i < 4; i++) for (; i < 4; i++)
@@ -189,58 +195,57 @@ pp_op_meta (const opcode_t *opcodes_p,
switch (opm.op.op_idx) switch (opm.op.op_idx)
{ {
PP_OP (addition, "%s = %s + %s;"); PP_OP (VM_OP_ADDITION, "%s = %s + %s;");
PP_OP (substraction, "%s = %s - %s;"); PP_OP (VM_OP_SUBSTRACTION, "%s = %s - %s;");
PP_OP (division, "%s = %s / %s;"); PP_OP (VM_OP_DIVISION, "%s = %s / %s;");
PP_OP (multiplication, "%s = %s * %s;"); PP_OP (VM_OP_MULTIPLICATION, "%s = %s * %s;");
PP_OP (remainder, "%s = %s %% %s;"); PP_OP (VM_OP_REMAINDER, "%s = %s %% %s;");
PP_OP (unary_minus, "%s = -%s;"); PP_OP (VM_OP_UNARY_MINUS, "%s = -%s;");
PP_OP (unary_plus, "%s = +%s;"); PP_OP (VM_OP_UNARY_PLUS, "%s = +%s;");
PP_OP (b_shift_left, "%s = %s << %s;"); PP_OP (VM_OP_B_SHIFT_LEFT, "%s = %s << %s;");
PP_OP (b_shift_right, "%s = %s >> %s;"); PP_OP (VM_OP_B_SHIFT_RIGHT, "%s = %s >> %s;");
PP_OP (b_shift_uright, "%s = %s >>> %s;"); PP_OP (VM_OP_B_SHIFT_URIGHT, "%s = %s >>> %s;");
PP_OP (b_and, "%s = %s & %s;"); PP_OP (VM_OP_B_AND, "%s = %s & %s;");
PP_OP (b_or, "%s = %s | %s;"); PP_OP (VM_OP_B_OR, "%s = %s | %s;");
PP_OP (b_xor, "%s = %s ^ %s;"); PP_OP (VM_OP_B_XOR, "%s = %s ^ %s;");
PP_OP (b_not, "%s = ~ %s;"); PP_OP (VM_OP_B_NOT, "%s = ~ %s;");
PP_OP (logical_not, "%s = ! %s;"); PP_OP (VM_OP_LOGICAL_NOT, "%s = ! %s;");
PP_OP (equal_value, "%s = %s == %s;"); PP_OP (VM_OP_EQUAL_VALUE, "%s = %s == %s;");
PP_OP (not_equal_value, "%s = %s != %s;"); PP_OP (VM_OP_NOT_EQUAL_VALUE, "%s = %s != %s;");
PP_OP (equal_value_type, "%s = %s === %s;"); PP_OP (VM_OP_EQUAL_VALUE_TYPE, "%s = %s === %s;");
PP_OP (not_equal_value_type, "%s = %s !== %s;"); PP_OP (VM_OP_NOT_EQUAL_VALUE_TYPE, "%s = %s !== %s;");
PP_OP (less_than, "%s = %s < %s;"); PP_OP (VM_OP_LESS_THAN, "%s = %s < %s;");
PP_OP (greater_than, "%s = %s > %s;"); PP_OP (VM_OP_GREATER_THAN, "%s = %s > %s;");
PP_OP (less_or_equal_than, "%s = %s <= %s;"); PP_OP (VM_OP_LESS_OR_EQUAL_THAN, "%s = %s <= %s;");
PP_OP (greater_or_equal_than, "%s = %s >= %s;"); PP_OP (VM_OP_GREATER_OR_EQUAL_THAN, "%s = %s >= %s;");
PP_OP (instanceof, "%s = %s instanceof %s;"); PP_OP (VM_OP_INSTANCEOF, "%s = %s instanceof %s;");
PP_OP (in, "%s = %s in %s;"); PP_OP (VM_OP_IN, "%s = %s in %s;");
PP_OP (post_incr, "%s = %s++;"); PP_OP (VM_OP_POST_INCR, "%s = %s++;");
PP_OP (post_decr, "%s = %s--;"); PP_OP (VM_OP_POST_DECR, "%s = %s--;");
PP_OP (pre_incr, "%s = ++%s;"); PP_OP (VM_OP_PRE_INCR, "%s = ++%s;");
PP_OP (pre_decr, "%s = --%s;"); PP_OP (VM_OP_PRE_DECR, "%s = --%s;");
PP_OP (throw_value, "throw %s;"); PP_OP (VM_OP_THROW_VALUE, "throw %s;");
PP_OP (reg_var_decl, "var %s .. %s;"); PP_OP (VM_OP_REG_VAR_DECL, "var %s .. %s;");
PP_OP (var_decl, "var %s;"); PP_OP (VM_OP_VAR_DECL, "var %s;");
PP_OP (nop, ";"); PP_OP (VM_OP_RETVAL, "return %s;");
PP_OP (retval, "return %s;"); PP_OP (VM_OP_RET, "ret;");
PP_OP (ret, "ret;"); PP_OP (VM_OP_PROP_GETTER, "%s = %s[%s];");
PP_OP (prop_getter, "%s = %s[%s];"); PP_OP (VM_OP_PROP_SETTER, "%s[%s] = %s;");
PP_OP (prop_setter, "%s[%s] = %s;"); PP_OP (VM_OP_THIS_BINDING, "%s = this;");
PP_OP (this_binding, "%s = this;"); PP_OP (VM_OP_DELETE_VAR, "%s = delete %s;");
PP_OP (delete_var, "%s = delete %s;"); PP_OP (VM_OP_DELETE_PROP, "%s = delete %s.%s;");
PP_OP (delete_prop, "%s = delete %s.%s;"); PP_OP (VM_OP_TYPEOF, "%s = typeof %s;");
PP_OP (typeof, "%s = typeof %s;"); PP_OP (VM_OP_WITH, "with (%s);");
PP_OP (with, "with (%s);"); PP_OP (VM_OP_FOR_IN, "for_in (%s);");
PP_OP (for_in, "for_in (%s);"); case VM_OP_IS_TRUE_JMP_UP: printf ("if (%s) goto %d;", VAR (1), oc - OC (2, 3)); break;
case NAME_TO_ID (is_true_jmp_up): printf ("if (%s) goto %d;", VAR (1), oc - OC (2, 3)); break; case VM_OP_IS_FALSE_JMP_UP: printf ("if (%s == false) goto %d;", VAR (1), oc - OC (2, 3)); break;
case NAME_TO_ID (is_false_jmp_up): printf ("if (%s == false) goto %d;", VAR (1), oc - OC (2, 3)); break; case VM_OP_IS_TRUE_JMP_DOWN: printf ("if (%s) goto %d;", VAR (1), oc + OC (2, 3)); break;
case NAME_TO_ID (is_true_jmp_down): printf ("if (%s) goto %d;", VAR (1), oc + OC (2, 3)); break; case VM_OP_IS_FALSE_JMP_DOWN: printf ("if (%s == false) goto %d;", VAR (1), oc + OC (2, 3)); break;
case NAME_TO_ID (is_false_jmp_down): printf ("if (%s == false) goto %d;", VAR (1), oc + OC (2, 3)); break; case VM_OP_JMP_UP: printf ("goto %d;", oc - OC (1, 2)); break;
case NAME_TO_ID (jmp_up): printf ("goto %d;", oc - OC (1, 2)); break; case VM_OP_JMP_DOWN: printf ("goto %d;", oc + OC (1, 2)); break;
case NAME_TO_ID (jmp_down): printf ("goto %d;", oc + OC (1, 2)); break; case VM_OP_JMP_BREAK_CONTINUE: printf ("goto_nested %d;", oc + OC (1, 2)); break;
case NAME_TO_ID (jmp_break_continue): printf ("goto_nested %d;", oc + OC (1, 2)); break; case VM_OP_TRY_BLOCK: printf ("try (end: %d);", oc + OC (1, 2)); break;
case NAME_TO_ID (try_block): printf ("try (end: %d);", oc + OC (1, 2)); break; case VM_OP_ASSIGNMENT:
case NAME_TO_ID (assignment):
{ {
printf ("%s = ", VAR (1)); printf ("%s = ", VAR (1));
switch (opm.op.data.assignment.type_value_right) switch (opm.op.data.assignment.type_value_right)
@@ -267,14 +272,14 @@ pp_op_meta (const opcode_t *opcodes_p,
} }
break; break;
} }
case NAME_TO_ID (call_n): case VM_OP_CALL_N:
{ {
vargs_num = opm.op.data.call_n.arg_list; vargs_num = opm.op.data.call_n.arg_list;
seen_vargs = 0; seen_vargs = 0;
break; break;
} }
case NAME_TO_ID (native_call): case VM_OP_NATIVE_CALL:
{ {
if (opm.op.data.native_call.arg_list == 0) if (opm.op.data.native_call.arg_list == 0)
{ {
@@ -297,7 +302,7 @@ pp_op_meta (const opcode_t *opcodes_p,
} }
break; break;
} }
case NAME_TO_ID (construct_n): case VM_OP_CONSTRUCT_N:
{ {
if (opm.op.data.construct_n.arg_list == 0) if (opm.op.data.construct_n.arg_list == 0)
{ {
@@ -310,7 +315,7 @@ pp_op_meta (const opcode_t *opcodes_p,
} }
break; break;
} }
case NAME_TO_ID (func_decl_n): case VM_OP_FUNC_DECL_N:
{ {
if (opm.op.data.func_decl_n.arg_list == 0) if (opm.op.data.func_decl_n.arg_list == 0)
{ {
@@ -323,7 +328,7 @@ pp_op_meta (const opcode_t *opcodes_p,
} }
break; break;
} }
case NAME_TO_ID (func_expr_n): case VM_OP_FUNC_EXPR_N:
{ {
if (opm.op.data.func_expr_n.arg_list == 0) if (opm.op.data.func_expr_n.arg_list == 0)
{ {
@@ -343,7 +348,7 @@ pp_op_meta (const opcode_t *opcodes_p,
} }
break; break;
} }
case NAME_TO_ID (array_decl): case VM_OP_ARRAY_DECL:
{ {
if (opm.op.data.array_decl.list == 0) if (opm.op.data.array_decl.list == 0)
{ {
@@ -356,7 +361,7 @@ pp_op_meta (const opcode_t *opcodes_p,
} }
break; break;
} }
case NAME_TO_ID (obj_decl): case VM_OP_OBJ_DECL:
{ {
if (opm.op.data.obj_decl.list == 0) if (opm.op.data.obj_decl.list == 0)
{ {
@@ -369,7 +374,7 @@ pp_op_meta (const opcode_t *opcodes_p,
} }
break; break;
} }
case NAME_TO_ID (meta): case VM_OP_META:
{ {
switch (opm.op.data.meta.type) switch (opm.op.data.meta.type)
{ {
@@ -398,13 +403,13 @@ pp_op_meta (const opcode_t *opcodes_p,
start--; start--;
switch (serializer_get_opcode (opcodes_p, start).op_idx) switch (serializer_get_opcode (opcodes_p, start).op_idx)
{ {
case NAME_TO_ID (call_n): case VM_OP_CALL_N:
case NAME_TO_ID (native_call): case VM_OP_NATIVE_CALL:
case NAME_TO_ID (construct_n): case VM_OP_CONSTRUCT_N:
case NAME_TO_ID (func_decl_n): case VM_OP_FUNC_DECL_N:
case NAME_TO_ID (func_expr_n): case VM_OP_FUNC_EXPR_N:
case NAME_TO_ID (array_decl): case VM_OP_ARRAY_DECL:
case NAME_TO_ID (obj_decl): case VM_OP_OBJ_DECL:
{ {
found = true; found = true;
break; break;
@@ -414,12 +419,12 @@ pp_op_meta (const opcode_t *opcodes_p,
opcode_t start_op = serializer_get_opcode (opcodes_p, start); opcode_t start_op = serializer_get_opcode (opcodes_p, start);
switch (start_op.op_idx) switch (start_op.op_idx)
{ {
case NAME_TO_ID (call_n): case VM_OP_CALL_N:
{ {
pp_printf ("%s = %s (", start_op, NULL, start, 1); pp_printf ("%s = %s (", start_op, NULL, start, 1);
break; break;
} }
case NAME_TO_ID (native_call): case VM_OP_NATIVE_CALL:
{ {
pp_printf ("%s = ", start_op, NULL, start, 1); pp_printf ("%s = ", start_op, NULL, start, 1);
switch (start_op.data.native_call.name) switch (start_op.data.native_call.name)
@@ -434,17 +439,17 @@ pp_op_meta (const opcode_t *opcodes_p,
} }
break; break;
} }
case NAME_TO_ID (construct_n): case VM_OP_CONSTRUCT_N:
{ {
pp_printf ("%s = new %s (", start_op, NULL, start, 1); pp_printf ("%s = new %s (", start_op, NULL, start, 1);
break; break;
} }
case NAME_TO_ID (func_decl_n): case VM_OP_FUNC_DECL_N:
{ {
pp_printf ("function %s (", start_op, NULL, start, 1); pp_printf ("function %s (", start_op, NULL, start, 1);
break; break;
} }
case NAME_TO_ID (func_expr_n): case VM_OP_FUNC_EXPR_N:
{ {
if (start_op.data.func_expr_n.name_lit_idx == INVALID_VALUE) if (start_op.data.func_expr_n.name_lit_idx == INVALID_VALUE)
{ {
@@ -456,12 +461,12 @@ pp_op_meta (const opcode_t *opcodes_p,
} }
break; break;
} }
case NAME_TO_ID (array_decl): case VM_OP_ARRAY_DECL:
{ {
pp_printf ("%s = [", start_op, NULL, start, 1); pp_printf ("%s = [", start_op, NULL, start, 1);
break; break;
} }
case NAME_TO_ID (obj_decl): case VM_OP_OBJ_DECL:
{ {
pp_printf ("%s = {", start_op, NULL, start, 1); pp_printf ("%s = {", start_op, NULL, start, 1);
break; break;
@@ -477,7 +482,7 @@ pp_op_meta (const opcode_t *opcodes_p,
switch (meta_op.op_idx) switch (meta_op.op_idx)
{ {
case NAME_TO_ID (meta): case VM_OP_META:
{ {
switch (meta_op.data.meta.type) switch (meta_op.data.meta.type)
{ {
@@ -531,12 +536,12 @@ pp_op_meta (const opcode_t *opcodes_p,
} }
switch (start_op.op_idx) switch (start_op.op_idx)
{ {
case NAME_TO_ID (array_decl): case VM_OP_ARRAY_DECL:
{ {
printf ("];"); printf ("];");
break; break;
} }
case NAME_TO_ID (obj_decl): case VM_OP_OBJ_DECL:
{ {
printf ("};"); printf ("};");
break; break;
+315
View File
@@ -0,0 +1,315 @@
/* Copyright 2015 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* List of VM opcodes
*/
#ifndef VM_OP_0
# define VM_OP_0(opcode_name, opcode_name_uppercase)
#endif /* !VM_OP_0 */
#ifndef VM_OP_1
# define VM_OP_1(opcode_name, opcode_name_uppercase, arg1, arg1_type)
#endif /* !VM_OP_1 */
#ifndef VM_OP_2
# define VM_OP_2(opcode_name, opcode_name_uppercase, arg1, arg1_type, arg2, arg2_type)
#endif /* !VM_OP_2 */
#ifndef VM_OP_3
# define VM_OP_3(opcode_name, opcode_name_uppercase, arg1, arg1_type, arg2, arg2_type, arg3, arg3_type)
#endif /* !VM_OP_3 */
VM_OP_3 (call_n, CALL_N,
lhs, VM_OP_ARG_TYPE_VARIABLE,
function_var_idx, VM_OP_ARG_TYPE_VARIABLE,
arg_list, VM_OP_ARG_TYPE_INTEGER_CONST)
VM_OP_3 (native_call, NATIVE_CALL,
lhs, VM_OP_ARG_TYPE_VARIABLE,
name, VM_OP_ARG_TYPE_INTEGER_CONST,
arg_list, VM_OP_ARG_TYPE_INTEGER_CONST)
VM_OP_3 (construct_n, CONSTRUCT_N,
lhs, VM_OP_ARG_TYPE_VARIABLE,
name_lit_idx, VM_OP_ARG_TYPE_VARIABLE,
arg_list, VM_OP_ARG_TYPE_INTEGER_CONST)
VM_OP_2 (func_decl_n, FUNC_DECL_N,
name_lit_idx, VM_OP_ARG_TYPE_STRING,
arg_list, VM_OP_ARG_TYPE_INTEGER_CONST)
VM_OP_3 (func_expr_n, FUNC_EXPR_N,
lhs, VM_OP_ARG_TYPE_VARIABLE,
name_lit_idx, VM_OP_ARG_TYPE_STRING |
VM_OP_ARG_TYPE_EMPTY,
arg_list, VM_OP_ARG_TYPE_INTEGER_CONST)
VM_OP_1 (retval, RETVAL,
ret_value, VM_OP_ARG_TYPE_VARIABLE)
VM_OP_0 (ret, RET)
VM_OP_2 (array_decl, ARRAY_DECL,
lhs, VM_OP_ARG_TYPE_VARIABLE,
list, VM_OP_ARG_TYPE_INTEGER_CONST)
VM_OP_2 (obj_decl, OBJ_DECL,
lhs, VM_OP_ARG_TYPE_VARIABLE,
list, VM_OP_ARG_TYPE_INTEGER_CONST)
VM_OP_3 (prop_getter, PROP_GETTER,
lhs, VM_OP_ARG_TYPE_VARIABLE,
obj, VM_OP_ARG_TYPE_VARIABLE,
prop, VM_OP_ARG_TYPE_VARIABLE)
VM_OP_3 (prop_setter, PROP_SETTER,
obj, VM_OP_ARG_TYPE_VARIABLE,
prop, VM_OP_ARG_TYPE_VARIABLE,
rhs, VM_OP_ARG_TYPE_VARIABLE)
VM_OP_1 (this_binding, THIS_BINDING,
lhs, VM_OP_ARG_TYPE_VARIABLE)
VM_OP_2 (delete_var, DELETE_VAR,
lhs, VM_OP_ARG_TYPE_VARIABLE,
name, VM_OP_ARG_TYPE_VARIABLE)
VM_OP_3 (delete_prop, DELETE_PROP,
lhs, VM_OP_ARG_TYPE_VARIABLE,
base, VM_OP_ARG_TYPE_VARIABLE,
name, VM_OP_ARG_TYPE_VARIABLE)
VM_OP_2 (typeof, TYPEOF,
lhs, VM_OP_ARG_TYPE_VARIABLE,
obj, VM_OP_ARG_TYPE_VARIABLE)
VM_OP_3 (for_in, FOR_IN,
expr, VM_OP_ARG_TYPE_VARIABLE,
oc_idx_1, VM_OP_ARG_TYPE_INTEGER_CONST,
oc_idx_2, VM_OP_ARG_TYPE_INTEGER_CONST)
VM_OP_3 (with, WITH,
expr, VM_OP_ARG_TYPE_VARIABLE,
oc_idx_1, VM_OP_ARG_TYPE_INTEGER_CONST,
oc_idx_2, VM_OP_ARG_TYPE_INTEGER_CONST)
VM_OP_2 (try_block, TRY_BLOCK,
oc_idx_1, VM_OP_ARG_TYPE_INTEGER_CONST,
oc_idx_2, VM_OP_ARG_TYPE_INTEGER_CONST)
VM_OP_1 (throw_value, THROW_VALUE,
var, VM_OP_ARG_TYPE_VARIABLE)
VM_OP_3 (assignment, ASSIGNMENT,
var_left, VM_OP_ARG_TYPE_VARIABLE,
type_value_right, VM_OP_ARG_TYPE_TYPE_OF_NEXT,
value_right, VM_OP_ARG_TYPE_VARIABLE |
VM_OP_ARG_TYPE_STRING |
VM_OP_ARG_TYPE_NUMBER |
VM_OP_ARG_TYPE_INTEGER_CONST)
VM_OP_3 (b_shift_left, B_SHIFT_LEFT,
dst, VM_OP_ARG_TYPE_VARIABLE,
var_left, VM_OP_ARG_TYPE_VARIABLE,
var_right, VM_OP_ARG_TYPE_VARIABLE)
VM_OP_3 (b_shift_right, B_SHIFT_RIGHT,
dst, VM_OP_ARG_TYPE_VARIABLE,
var_left, VM_OP_ARG_TYPE_VARIABLE,
var_right, VM_OP_ARG_TYPE_VARIABLE)
VM_OP_3 (b_shift_uright, B_SHIFT_URIGHT,
dst, VM_OP_ARG_TYPE_VARIABLE,
var_left, VM_OP_ARG_TYPE_VARIABLE,
var_right, VM_OP_ARG_TYPE_VARIABLE)
VM_OP_3 (b_and, B_AND,
dst, VM_OP_ARG_TYPE_VARIABLE,
var_left, VM_OP_ARG_TYPE_VARIABLE,
var_right, VM_OP_ARG_TYPE_VARIABLE)
VM_OP_3 (b_or, B_OR,
dst, VM_OP_ARG_TYPE_VARIABLE,
var_left, VM_OP_ARG_TYPE_VARIABLE,
var_right, VM_OP_ARG_TYPE_VARIABLE)
VM_OP_3 (b_xor, B_XOR,
dst, VM_OP_ARG_TYPE_VARIABLE,
var_left, VM_OP_ARG_TYPE_VARIABLE,
var_right, VM_OP_ARG_TYPE_VARIABLE)
VM_OP_2 (b_not, B_NOT,
dst, VM_OP_ARG_TYPE_VARIABLE,
var_right, VM_OP_ARG_TYPE_VARIABLE)
VM_OP_2 (logical_not, LOGICAL_NOT,
dst, VM_OP_ARG_TYPE_VARIABLE,
var_right, VM_OP_ARG_TYPE_VARIABLE)
VM_OP_3 (equal_value, EQUAL_VALUE,
dst, VM_OP_ARG_TYPE_VARIABLE,
var_left, VM_OP_ARG_TYPE_VARIABLE,
var_right, VM_OP_ARG_TYPE_VARIABLE)
VM_OP_3 (not_equal_value, NOT_EQUAL_VALUE,
dst, VM_OP_ARG_TYPE_VARIABLE,
var_left, VM_OP_ARG_TYPE_VARIABLE,
var_right, VM_OP_ARG_TYPE_VARIABLE)
VM_OP_3 (equal_value_type, EQUAL_VALUE_TYPE,
dst, VM_OP_ARG_TYPE_VARIABLE,
var_left, VM_OP_ARG_TYPE_VARIABLE,
var_right, VM_OP_ARG_TYPE_VARIABLE)
VM_OP_3 (not_equal_value_type, NOT_EQUAL_VALUE_TYPE,
dst, VM_OP_ARG_TYPE_VARIABLE,
var_left, VM_OP_ARG_TYPE_VARIABLE,
var_right, VM_OP_ARG_TYPE_VARIABLE)
VM_OP_3 (less_than, LESS_THAN,
dst, VM_OP_ARG_TYPE_VARIABLE,
var_left, VM_OP_ARG_TYPE_VARIABLE,
var_right, VM_OP_ARG_TYPE_VARIABLE)
VM_OP_3 (greater_than, GREATER_THAN,
dst, VM_OP_ARG_TYPE_VARIABLE,
var_left, VM_OP_ARG_TYPE_VARIABLE,
var_right, VM_OP_ARG_TYPE_VARIABLE)
VM_OP_3 (less_or_equal_than, LESS_OR_EQUAL_THAN,
dst, VM_OP_ARG_TYPE_VARIABLE,
var_left, VM_OP_ARG_TYPE_VARIABLE,
var_right, VM_OP_ARG_TYPE_VARIABLE)
VM_OP_3 (greater_or_equal_than, GREATER_OR_EQUAL_THAN,
dst, VM_OP_ARG_TYPE_VARIABLE,
var_left, VM_OP_ARG_TYPE_VARIABLE,
var_right, VM_OP_ARG_TYPE_VARIABLE)
VM_OP_3 (instanceof, INSTANCEOF,
dst, VM_OP_ARG_TYPE_VARIABLE,
var_left, VM_OP_ARG_TYPE_VARIABLE,
var_right, VM_OP_ARG_TYPE_VARIABLE)
VM_OP_3 (in, IN,
dst, VM_OP_ARG_TYPE_VARIABLE,
var_left, VM_OP_ARG_TYPE_VARIABLE,
var_right, VM_OP_ARG_TYPE_VARIABLE)
VM_OP_2 (post_incr, POST_INCR,
dst, VM_OP_ARG_TYPE_VARIABLE,
var_right, VM_OP_ARG_TYPE_VARIABLE)
VM_OP_2 (post_decr, POST_DECR,
dst, VM_OP_ARG_TYPE_VARIABLE,
var_right, VM_OP_ARG_TYPE_VARIABLE)
VM_OP_2 (pre_incr, PRE_INCR,
dst, VM_OP_ARG_TYPE_VARIABLE,
var_right, VM_OP_ARG_TYPE_VARIABLE)
VM_OP_2 (pre_decr, PRE_DECR,
dst, VM_OP_ARG_TYPE_VARIABLE,
var_right, VM_OP_ARG_TYPE_VARIABLE)
VM_OP_3 (addition, ADDITION,
dst, VM_OP_ARG_TYPE_VARIABLE,
var_left, VM_OP_ARG_TYPE_VARIABLE,
var_right, VM_OP_ARG_TYPE_VARIABLE)
VM_OP_3 (substraction, SUBSTRACTION,
dst, VM_OP_ARG_TYPE_VARIABLE,
var_left, VM_OP_ARG_TYPE_VARIABLE,
var_right, VM_OP_ARG_TYPE_VARIABLE)
VM_OP_3 (division, DIVISION,
dst, VM_OP_ARG_TYPE_VARIABLE,
var_left, VM_OP_ARG_TYPE_VARIABLE,
var_right, VM_OP_ARG_TYPE_VARIABLE)
VM_OP_3 (multiplication, MULTIPLICATION,
dst, VM_OP_ARG_TYPE_VARIABLE,
var_left, VM_OP_ARG_TYPE_VARIABLE,
var_right, VM_OP_ARG_TYPE_VARIABLE)
VM_OP_3 (remainder, REMAINDER,
dst, VM_OP_ARG_TYPE_VARIABLE,
var_left, VM_OP_ARG_TYPE_VARIABLE,
var_right, VM_OP_ARG_TYPE_VARIABLE)
VM_OP_2 (unary_minus, UNARY_MINUS,
dst, VM_OP_ARG_TYPE_VARIABLE,
var, VM_OP_ARG_TYPE_VARIABLE)
VM_OP_2 (unary_plus, UNARY_PLUS,
dst, VM_OP_ARG_TYPE_VARIABLE,
var, VM_OP_ARG_TYPE_VARIABLE)
VM_OP_2 (jmp_up, JMP_UP,
opcode_1, VM_OP_ARG_TYPE_INTEGER_CONST,
opcode_2, VM_OP_ARG_TYPE_INTEGER_CONST)
VM_OP_2 (jmp_down, JMP_DOWN,
opcode_1, VM_OP_ARG_TYPE_INTEGER_CONST,
opcode_2, VM_OP_ARG_TYPE_INTEGER_CONST)
VM_OP_2 (jmp_break_continue, JMP_BREAK_CONTINUE,
opcode_1, VM_OP_ARG_TYPE_INTEGER_CONST,
opcode_2, VM_OP_ARG_TYPE_INTEGER_CONST)
VM_OP_3 (is_true_jmp_up, IS_TRUE_JMP_UP,
value, VM_OP_ARG_TYPE_VARIABLE,
opcode_1, VM_OP_ARG_TYPE_INTEGER_CONST,
opcode_2, VM_OP_ARG_TYPE_INTEGER_CONST)
VM_OP_3 (is_true_jmp_down, IS_TRUE_JMP_DOWN,
value, VM_OP_ARG_TYPE_VARIABLE,
opcode_1, VM_OP_ARG_TYPE_INTEGER_CONST,
opcode_2, VM_OP_ARG_TYPE_INTEGER_CONST)
VM_OP_3 (is_false_jmp_up, IS_FALSE_JMP_UP,
value, VM_OP_ARG_TYPE_VARIABLE,
opcode_1, VM_OP_ARG_TYPE_INTEGER_CONST,
opcode_2, VM_OP_ARG_TYPE_INTEGER_CONST)
VM_OP_3 (is_false_jmp_down, IS_FALSE_JMP_DOWN,
value, VM_OP_ARG_TYPE_VARIABLE,
opcode_1, VM_OP_ARG_TYPE_INTEGER_CONST,
opcode_2, VM_OP_ARG_TYPE_INTEGER_CONST)
VM_OP_1 (var_decl, VAR_DECL,
variable_name, VM_OP_ARG_TYPE_STRING)
VM_OP_2 (reg_var_decl, REG_VAR_DECL,
min, VM_OP_ARG_TYPE_REGISTER,
max, VM_OP_ARG_TYPE_REGISTER)
VM_OP_3 (meta, META,
type, VM_OP_ARG_TYPE_INTEGER_CONST,
data_1, VM_OP_ARG_TYPE_INTEGER_CONST |
VM_OP_ARG_TYPE_VARIABLE,
data_2, VM_OP_ARG_TYPE_INTEGER_CONST |
VM_OP_ARG_TYPE_VARIABLE)
#undef VM_OP_0
#undef VM_OP_1
#undef VM_OP_2
#undef VM_OP_3
+24 -10
View File
@@ -30,24 +30,38 @@
*/ */
vm_frame_ctx_t *vm_top_context_p = NULL; vm_frame_ctx_t *vm_top_context_p = NULL;
#define __INIT_OP_FUNC(name, arg1, arg2, arg3) [ __op__idx_##name ] = opfunc_##name, static const opfunc __opfuncs[VM_OP__COUNT] =
static const opfunc __opfuncs[LAST_OP] =
{ {
OP_LIST (INIT_OP_FUNC) #define VM_OP_0(opcode_name, opcode_name_uppercase) \
[ VM_OP_ ## opcode_name_uppercase ] = opfunc_ ## opcode_name,
#define VM_OP_1(opcode_name, opcode_name_uppercase, arg1, arg1_type) \
[ VM_OP_ ## opcode_name_uppercase ] = opfunc_ ## opcode_name,
#define VM_OP_2(opcode_name, opcode_name_uppercase, arg1, arg1_type, arg2, arg2_type) \
[ VM_OP_ ## opcode_name_uppercase ] = opfunc_ ## opcode_name,
#define VM_OP_3(opcode_name, opcode_name_uppercase, arg1, arg1_type, arg2, arg2_type, arg3, arg3_type) \
[ VM_OP_ ## opcode_name_uppercase ] = opfunc_ ## opcode_name,
#include "vm-opcodes.inc.h"
}; };
#undef __INIT_OP_FUNC
JERRY_STATIC_ASSERT (sizeof (opcode_t) <= 4); JERRY_STATIC_ASSERT (sizeof (opcode_t) <= 4);
const opcode_t *__program = NULL; const opcode_t *__program = NULL;
#ifdef MEM_STATS #ifdef MEM_STATS
#define __OP_FUNC_NAME(name, arg1, arg2, arg3) #name, static const char *__op_names[VM_OP__COUNT] =
static const char *__op_names[LAST_OP] =
{ {
OP_LIST (OP_FUNC_NAME) #define VM_OP_0(opcode_name, opcode_name_uppercase) \
#opcode_name,
#define VM_OP_1(opcode_name, opcode_name_uppercase, arg1, arg1_type) \
#opcode_name,
#define VM_OP_2(opcode_name, opcode_name_uppercase, arg1, arg1_type, arg2, arg2_type) \
#opcode_name,
#define VM_OP_3(opcode_name, opcode_name_uppercase, arg1, arg1_type, arg2, arg2_type, arg3, arg3_type) \
#opcode_name,
#include "vm-opcodes.inc.h"
}; };
#undef __OP_FUNC_NAME
#define INTERP_MEM_PRINT_INDENTATION_STEP (5) #define INTERP_MEM_PRINT_INDENTATION_STEP (5)
#define INTERP_MEM_PRINT_INDENTATION_MAX (125) #define INTERP_MEM_PRINT_INDENTATION_MAX (125)
@@ -527,7 +541,7 @@ vm_run_from_pos (const opcode_t *opcodes_p, /**< byte-code array */
ecma_completion_value_t completion; ecma_completion_value_t completion;
const opcode_t *curr = &opcodes_p[start_pos]; const opcode_t *curr = &opcodes_p[start_pos];
JERRY_ASSERT (curr->op_idx == __op__idx_reg_var_decl); JERRY_ASSERT (curr->op_idx == VM_OP_REG_VAR_DECL);
const idx_t min_reg_num = curr->data.reg_var_decl.min; const idx_t min_reg_num = curr->data.reg_var_decl.min;
const idx_t max_reg_num = curr->data.reg_var_decl.max; const idx_t max_reg_num = curr->data.reg_var_decl.max;
@@ -597,7 +611,7 @@ vm_get_scope_flags (const opcode_t *opcodes_p, /**< byte-code array */
opcode_counter_t counter) /**< opcode counter */ opcode_counter_t counter) /**< opcode counter */
{ {
opcode_t flags_opcode = vm_get_opcode (opcodes_p, counter); opcode_t flags_opcode = vm_get_opcode (opcodes_p, counter);
JERRY_ASSERT (flags_opcode.op_idx == __op__idx_meta JERRY_ASSERT (flags_opcode.op_idx == VM_OP_META
&& flags_opcode.data.meta.type == OPCODE_META_TYPE_SCOPE_CODE_FLAGS); && flags_opcode.data.meta.type == OPCODE_META_TYPE_SCOPE_CODE_FLAGS);
return (opcode_scope_code_flags_t) flags_opcode.data.meta.data_1; return (opcode_scope_code_flags_t) flags_opcode.data.meta.data_1;
} /* vm_get_scope_flags */ } /* vm_get_scope_flags */
+1 -28
View File
@@ -20,43 +20,16 @@
#include "test-common.h" #include "test-common.h"
#define NAME_TO_ID(op) (__op__idx_##op)
#define __OPCODE_SIZE(name, arg1, arg2, arg3) \
(uint8_t) (sizeof (__op_##name) + 1),
static uint8_t opcode_sizes[] =
{
OP_LIST (OPCODE_SIZE)
0
};
static bool static bool
opcodes_equal (const opcode_t *opcodes1, opcode_t *opcodes2, uint16_t size) opcodes_equal (const opcode_t *opcodes1, opcode_t *opcodes2, uint16_t size)
{ {
uint16_t i; uint16_t i;
for (i = 0; i < size; i++) for (i = 0; i < size; i++)
{ {
uint8_t opcode_num1 = opcodes1[i].op_idx, opcode_num2 = opcodes2[i].op_idx; if (memcmp (&opcodes1[i], &opcodes2[i], sizeof (opcode_t)) != 0)
uint8_t j;
if (opcode_num1 != opcode_num2)
{ {
return false; return false;
} }
if (opcode_num1 == NAME_TO_ID (nop) || opcode_num1 == NAME_TO_ID (ret))
{
return true;
}
for (j = 1; j < opcode_sizes[opcode_num1]; j++)
{
if (((uint8_t*)&opcodes1[i])[j] != ((uint8_t*)&opcodes2[i])[j])
{
return false;
}
}
} }
return true; return true;