mirror of
https://github.com/jerryscript-project/jerryscript.git
synced 2025-12-15 16:29:21 +00:00
491 lines
11 KiB
C
491 lines
11 KiB
C
/* Copyright 2014 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.
|
|
*/
|
|
|
|
#ifndef OPCODE_STRUCTURES_H
|
|
#define OPCODE_STRUCTURES_H
|
|
|
|
// Jerry bytecode ver:07/04/2014
|
|
#define OP_DEF(name, list) struct __op_##name { list ; } ;
|
|
|
|
|
|
#define OP_CODE_DECL_VOID(name) \
|
|
struct __op_##name { T_IDX __do_not_use; }; \
|
|
OPCODE getop_##name ( void );
|
|
|
|
#define OP_CODE_DECL(name, type, ... ) \
|
|
OP_DEF (name, type##_DECL( __VA_ARGS__ ) ) \
|
|
OPCODE getop_##name ( type );
|
|
|
|
#define T_IDX_IDX T_IDX, T_IDX
|
|
#define T_IDX_IDX_IDX T_IDX, T_IDX, T_IDX
|
|
|
|
#define T_IDX_DECL(name) T_IDX name
|
|
#define T_IDX_IDX_DECL(name1, name2) \
|
|
T_IDX_DECL( name1 ) ; \
|
|
T_IDX_DECL( name2 )
|
|
#define T_IDX_IDX_IDX_DECL(name1, name2, name3) \
|
|
T_IDX_DECL( name1 ) ; \
|
|
T_IDX_DECL( name2 ); \
|
|
T_IDX_DECL( name3 )
|
|
|
|
#define GETOP_IMPL_0(name) \
|
|
OPCODE getop_##name () { \
|
|
OPCODE opdata; \
|
|
opdata.op_idx = __op__idx_##name; \
|
|
return opdata; \
|
|
}
|
|
|
|
#define GETOP_IMPL_1(name, field1) \
|
|
OPCODE getop_##name (T_IDX arg1) { \
|
|
OPCODE opdata; \
|
|
opdata.op_idx = __op__idx_##name; \
|
|
opdata.data.name.field1 = arg1; \
|
|
return opdata; \
|
|
}
|
|
|
|
#define GETOP_IMPL_2(name, field1, field2) \
|
|
OPCODE getop_##name (T_IDX arg1, T_IDX arg2) { \
|
|
OPCODE opdata; \
|
|
opdata.op_idx = __op__idx_##name; \
|
|
opdata.data.name.field1 = arg1; \
|
|
opdata.data.name.field2 = arg2; \
|
|
return opdata; \
|
|
}
|
|
|
|
#define GETOP_IMPL_3(name, field1, field2, field3) \
|
|
OPCODE getop_##name (T_IDX arg1, T_IDX arg2, T_IDX arg3) { \
|
|
OPCODE opdata; \
|
|
opdata.op_idx = __op__idx_##name; \
|
|
opdata.data.name.field1 = arg1; \
|
|
opdata.data.name.field2 = arg2; \
|
|
opdata.data.name.field3 = arg3; \
|
|
return opdata; \
|
|
}
|
|
|
|
/** Instruction tests if BOOLEAN value is TRUE and JMP to DST */
|
|
OP_CODE_DECL (is_true_jmp, T_IDX_IDX,
|
|
value,
|
|
opcode)
|
|
|
|
/** Instruction tests if BOOLEAN value is FALSE and JMP to DST */
|
|
OP_CODE_DECL (is_false_jmp, T_IDX_IDX,
|
|
value,
|
|
opcode)
|
|
|
|
/** Unconditional JMP to the specified opcode index */
|
|
OP_CODE_DECL (jmp, T_IDX,
|
|
opcode_idx)
|
|
|
|
/** Unconditional JMP on opcode_count up */
|
|
OP_CODE_DECL (jmp_up, T_IDX,
|
|
opcode_count)
|
|
|
|
/** Unconditional JMP on opcode_count down */
|
|
OP_CODE_DECL (jmp_down, T_IDX,
|
|
opcode_count)
|
|
|
|
/** dst = L + R */
|
|
OP_CODE_DECL (addition, T_IDX_IDX_IDX,
|
|
dst,
|
|
var_left,
|
|
var_right)
|
|
|
|
/** dst = L - R */
|
|
OP_CODE_DECL (substraction, T_IDX_IDX_IDX,
|
|
dst,
|
|
var_left,
|
|
var_right)
|
|
|
|
/** dst = L / R */
|
|
OP_CODE_DECL (division, T_IDX_IDX_IDX,
|
|
dst,
|
|
var_left,
|
|
var_right)
|
|
|
|
/** dst = L * R */
|
|
OP_CODE_DECL (multiplication, T_IDX_IDX_IDX,
|
|
dst,
|
|
var_left,
|
|
var_right)
|
|
|
|
/** dst = L % R */
|
|
OP_CODE_DECL (remainder, T_IDX_IDX_IDX,
|
|
dst,
|
|
var_left,
|
|
var_right)
|
|
|
|
/** dst = L << R */
|
|
OP_CODE_DECL (b_shift_left, T_IDX_IDX_IDX,
|
|
dst,
|
|
var_left,
|
|
var_right)
|
|
|
|
/** dst = L >> R */
|
|
OP_CODE_DECL (b_shift_right, T_IDX_IDX_IDX,
|
|
dst,
|
|
var_left,
|
|
var_right)
|
|
|
|
/** dst = L >>> R */
|
|
OP_CODE_DECL (b_shift_uright, T_IDX_IDX_IDX,
|
|
dst,
|
|
var_left,
|
|
var_right)
|
|
|
|
// Binary bitwise operators.
|
|
// Operands is a set of 32 bits
|
|
// Returns numerical.
|
|
|
|
/** dst = L & R */
|
|
OP_CODE_DECL (b_and, T_IDX_IDX_IDX,
|
|
dst,
|
|
var_left,
|
|
var_right)
|
|
|
|
/** dst = L | R */
|
|
OP_CODE_DECL (b_or, T_IDX_IDX_IDX,
|
|
dst,
|
|
var_left,
|
|
var_right)
|
|
|
|
/** dst = L ^ R */
|
|
OP_CODE_DECL (b_xor, T_IDX_IDX_IDX,
|
|
dst,
|
|
var_left,
|
|
var_right)
|
|
|
|
/** dst = ~ R */
|
|
OP_CODE_DECL (b_not, T_IDX_IDX,
|
|
dst,
|
|
var_right)
|
|
|
|
// Binary logical operators.
|
|
// Operands are booleans.
|
|
// Return boolean.
|
|
|
|
/** dst = L && R */
|
|
OP_CODE_DECL (logical_and, T_IDX_IDX_IDX,
|
|
dst,
|
|
var_left,
|
|
var_right)
|
|
|
|
/** dst = L || R */
|
|
OP_CODE_DECL (logical_or, T_IDX_IDX_IDX,
|
|
dst,
|
|
var_left,
|
|
var_right)
|
|
|
|
/** dst = ! R */
|
|
OP_CODE_DECL (logical_not, T_IDX_IDX,
|
|
dst,
|
|
var_right)
|
|
|
|
// Equality operations.
|
|
|
|
/** dst = L == R. */
|
|
OP_CODE_DECL (equal_value, T_IDX_IDX_IDX,
|
|
dst,
|
|
var_left,
|
|
var_right)
|
|
|
|
/** dst = L != R. */
|
|
OP_CODE_DECL (not_equal_value, T_IDX_IDX_IDX,
|
|
dst,
|
|
var_left,
|
|
var_right)
|
|
|
|
/** dst = L === R. */
|
|
OP_CODE_DECL (equal_value_type, T_IDX_IDX_IDX,
|
|
dst,
|
|
var_left,
|
|
var_right)
|
|
|
|
/** dst = L !== R. */
|
|
OP_CODE_DECL (not_equal_value_type, T_IDX_IDX_IDX,
|
|
dst,
|
|
var_left,
|
|
var_right)
|
|
|
|
// Relational operations.
|
|
|
|
/** dst = L < R. */
|
|
OP_CODE_DECL (less_than, T_IDX_IDX_IDX,
|
|
dst,
|
|
var_left,
|
|
var_right)
|
|
|
|
/** dst = L > R. */
|
|
OP_CODE_DECL (greater_than, T_IDX_IDX_IDX,
|
|
dst,
|
|
var_left,
|
|
var_right)
|
|
|
|
/** dst = L <= R. */
|
|
OP_CODE_DECL (less_or_equal_than, T_IDX_IDX_IDX,
|
|
dst,
|
|
var_left,
|
|
var_right)
|
|
|
|
/** dst = L >= R. */
|
|
OP_CODE_DECL (greater_or_equal_than, T_IDX_IDX_IDX,
|
|
dst,
|
|
var_left,
|
|
var_right)
|
|
|
|
/** dst = L instanceof R. */
|
|
OP_CODE_DECL (instanceof, T_IDX_IDX_IDX,
|
|
dst,
|
|
var_left,
|
|
var_right)
|
|
|
|
/** dst = L in R. */
|
|
OP_CODE_DECL (in, T_IDX_IDX_IDX,
|
|
dst,
|
|
var_left,
|
|
var_right)
|
|
|
|
/** dst = var_right++. */
|
|
OP_CODE_DECL (post_incr, T_IDX_IDX,
|
|
dst,
|
|
var_right)
|
|
|
|
/** dst = var_right--. */
|
|
OP_CODE_DECL (post_decr, T_IDX_IDX,
|
|
dst,
|
|
var_right)
|
|
|
|
/** dst = ++var_right. */
|
|
OP_CODE_DECL (pre_incr, T_IDX_IDX,
|
|
dst,
|
|
var_right)
|
|
|
|
/** dst = --var_right. */
|
|
OP_CODE_DECL (pre_decr, T_IDX_IDX,
|
|
dst,
|
|
var_right)
|
|
|
|
// Assignment operators.
|
|
// Assign value to LEFT operand based on value of RIGHT operand.
|
|
|
|
/** L = R */
|
|
OP_CODE_DECL (assignment, T_IDX_IDX_IDX,
|
|
var_left,
|
|
type_value_right,
|
|
value_right)
|
|
|
|
// Functions calls, declarations and argument handling
|
|
|
|
/** a = name(); */
|
|
OP_CODE_DECL (call_0, T_IDX_IDX,
|
|
lhs,
|
|
name_lit_idx)
|
|
|
|
/** a = name(arg1); */
|
|
OP_CODE_DECL (call_1, T_IDX_IDX_IDX,
|
|
lhs,
|
|
name_lit_idx,
|
|
arg1_lit_idx)
|
|
|
|
/** a = name(arg1, ... */
|
|
OP_CODE_DECL (call_n, T_IDX_IDX_IDX,
|
|
lhs,
|
|
name_lit_idx,
|
|
arg1_lit_idx)
|
|
|
|
/** a = new name(); */
|
|
OP_CODE_DECL (construct_0, T_IDX_IDX,
|
|
lhs,
|
|
name_lit_idx)
|
|
|
|
/** a = new name(arg1); */
|
|
OP_CODE_DECL (construct_1, T_IDX_IDX_IDX,
|
|
lhs,
|
|
name_lit_idx,
|
|
arg1_lit_idx)
|
|
|
|
/** a = new name(arg1, ... */
|
|
OP_CODE_DECL (construct_n, T_IDX_IDX_IDX,
|
|
lhs,
|
|
name_lit_idx,
|
|
arg1_lit_idx)
|
|
|
|
/** name(); */
|
|
OP_CODE_DECL (func_decl_0, T_IDX,
|
|
name_lit_idx)
|
|
|
|
/** name(arg1); */
|
|
OP_CODE_DECL (func_decl_1, T_IDX_IDX,
|
|
name_lit_idx,
|
|
arg1_lit_idx)
|
|
|
|
/** name(arg1, arg2); */
|
|
OP_CODE_DECL (func_decl_2, T_IDX_IDX_IDX,
|
|
name_lit_idx,
|
|
arg1_lit_idx,
|
|
arg2_lit_idx)
|
|
|
|
/** name(arg1, arg2, ... */
|
|
OP_CODE_DECL (func_decl_n, T_IDX_IDX_IDX,
|
|
name_lit_idx,
|
|
arg1_lit_idx,
|
|
arg2_lit_idx)
|
|
|
|
/** a = name(); */
|
|
OP_CODE_DECL (func_expr_0, T_IDX_IDX,
|
|
lhs,
|
|
name_lit_idx)
|
|
|
|
/** a = name(arg1); */
|
|
OP_CODE_DECL (func_expr_1, T_IDX_IDX_IDX,
|
|
lhs,
|
|
name_lit_idx,
|
|
arg1_lit_idx)
|
|
|
|
/** a = name(arg1, ... */
|
|
OP_CODE_DECL (func_expr_n, T_IDX_IDX_IDX,
|
|
lhs,
|
|
name_lit_idx,
|
|
arg1_lit_idx)
|
|
|
|
/** ..., arg1); */
|
|
OP_CODE_DECL (varg_1_end, T_IDX,
|
|
arg1_lit_idx)
|
|
|
|
/** ..., arg1, arg2); */
|
|
OP_CODE_DECL (varg_2_end, T_IDX_IDX,
|
|
arg1_lit_idx,
|
|
arg2_lit_idx)
|
|
|
|
/** arg1, arg2, arg3, ... */
|
|
OP_CODE_DECL (varg_3, T_IDX_IDX_IDX,
|
|
arg1_lit_idx,
|
|
arg2_lit_idx,
|
|
arg3_lit_idx)
|
|
|
|
/** arg1, arg2, arg3); */
|
|
OP_CODE_DECL (varg_3_end, T_IDX_IDX_IDX,
|
|
arg1_lit_idx,
|
|
arg2_lit_idx,
|
|
arg3_lit_idx)
|
|
|
|
/** exit with status code; */
|
|
OP_CODE_DECL (exitval, T_IDX,
|
|
status_code)
|
|
|
|
/** return value; */
|
|
OP_CODE_DECL (retval, T_IDX,
|
|
ret_value)
|
|
OP_CODE_DECL_VOID (ret)
|
|
|
|
OP_CODE_DECL_VOID (nop)
|
|
|
|
/** a = [] */
|
|
OP_CODE_DECL (array_0, T_IDX,
|
|
lhs)
|
|
|
|
/** a = [b] */
|
|
OP_CODE_DECL (array_1, T_IDX_IDX,
|
|
lhs,
|
|
elem1)
|
|
|
|
/** a = [b, c] */
|
|
OP_CODE_DECL (array_2, T_IDX_IDX_IDX,
|
|
lhs,
|
|
elem1,
|
|
elem2)
|
|
|
|
/** a = [b, c ... */
|
|
OP_CODE_DECL (array_n, T_IDX_IDX_IDX,
|
|
lhs,
|
|
elem1,
|
|
elem2)
|
|
|
|
/** a = b : c */
|
|
OP_CODE_DECL (prop, T_IDX_IDX_IDX,
|
|
lhs,
|
|
name,
|
|
value)
|
|
|
|
/** a = b.c OR a = b[c] */
|
|
OP_CODE_DECL (prop_access, T_IDX_IDX_IDX,
|
|
lhs,
|
|
obj,
|
|
prop)
|
|
|
|
/** a = get prop () */
|
|
OP_CODE_DECL (prop_get_decl, T_IDX_IDX,
|
|
lhs,
|
|
prop)
|
|
|
|
/** a = set prop (arg) */
|
|
OP_CODE_DECL (prop_set_decl, T_IDX_IDX_IDX,
|
|
lhs,
|
|
prop,
|
|
arg)
|
|
|
|
/** a = { } */
|
|
OP_CODE_DECL (obj_0, T_IDX,
|
|
lhs)
|
|
|
|
/** a = { b } */
|
|
OP_CODE_DECL (obj_1, T_IDX_IDX,
|
|
lhs,
|
|
arg1)
|
|
|
|
/** a = { b, c } */
|
|
OP_CODE_DECL (obj_2, T_IDX_IDX_IDX,
|
|
lhs,
|
|
arg1,
|
|
arg2)
|
|
|
|
/** a = { b, c ... */
|
|
OP_CODE_DECL (obj_n, T_IDX_IDX_IDX,
|
|
lhs,
|
|
arg1,
|
|
arg2)
|
|
|
|
/** a = this */
|
|
OP_CODE_DECL (this, T_IDX,
|
|
lhs)
|
|
|
|
/** a = delete b */
|
|
OP_CODE_DECL (delete, T_IDX_IDX,
|
|
lhs,
|
|
obj)
|
|
|
|
/** a = delete b */
|
|
OP_CODE_DECL (typeof, T_IDX_IDX,
|
|
lhs,
|
|
obj)
|
|
|
|
/** with (b) { */
|
|
OP_CODE_DECL (with, T_IDX,
|
|
expr)
|
|
|
|
/** } */
|
|
OP_CODE_DECL_VOID (end_with)
|
|
|
|
// Variable declaration
|
|
OP_CODE_DECL (var_decl, T_IDX,
|
|
variable_name)
|
|
|
|
OP_CODE_DECL (reg_var_decl, T_IDX_IDX,
|
|
min,
|
|
max)
|
|
|
|
|
|
#endif /* OPCODE_STRUCTURES_H */
|
|
|