package org.jruby.ir;
class OpFlags {
final static int f_has_side_effect = 0x00001;
final static int f_can_raise_exception = 0x00002;
final static int f_is_marker_op = 0x00004;
final static int f_is_jump_or_branch = 0x00008;
final static int f_is_return = 0x00010;
final static int f_is_exception = 0x00020;
final static int f_is_debug_op = 0x00040;
final static int f_is_load = 0x00080;
final static int f_is_store = 0x00100;
final static int f_is_call = 0x00200;
final static int f_is_arg_receive = 0x00400;
final static int f_modifies_code = 0x00800;
final static int f_inline_unfriendly = 0x01000;
final static int f_is_book_keeping_op = 0x02000;
final static int f_is_float_op = 0x04000;
final static int f_is_int_op = 0x08000;
}
public enum Operation {
NOP(0),
JUMP(OpFlags.f_is_jump_or_branch),
BNE(OpFlags.f_is_jump_or_branch),
B_UNDEF(OpFlags.f_is_jump_or_branch),
B_NIL(OpFlags.f_is_jump_or_branch),
B_TRUE(OpFlags.f_is_jump_or_branch),
B_FALSE(OpFlags.f_is_jump_or_branch),
B_SWITCH(OpFlags.f_is_jump_or_branch),
RECV_SELF(0),
RECV_PRE_REQD_ARG(OpFlags.f_is_arg_receive),
RECV_POST_REQD_ARG(OpFlags.f_is_arg_receive),
RECV_KW_ARG(OpFlags.f_is_arg_receive),
RECV_KW_REST_ARG(OpFlags.f_is_arg_receive),
RECV_REST_ARG(OpFlags.f_is_arg_receive),
RECV_OPT_ARG(OpFlags.f_is_arg_receive),
RECV_RUBY_EXC(OpFlags.f_is_arg_receive),
RECV_JRUBY_EXC(OpFlags.f_is_arg_receive),
LOAD_IMPLICIT_CLOSURE(OpFlags.f_is_arg_receive),
REIFY_CLOSURE(0),
LOAD_FRAME_CLOSURE(0),
CALL(OpFlags.f_has_side_effect | OpFlags.f_is_call | OpFlags.f_can_raise_exception),
NORESULT_CALL(OpFlags.f_has_side_effect | OpFlags.f_is_call | OpFlags.f_can_raise_exception),
ATTR_ASSIGN(OpFlags.f_is_call | OpFlags.f_has_side_effect | OpFlags.f_can_raise_exception),
ARRAY_DEREF(OpFlags.f_is_call | OpFlags.f_has_side_effect | OpFlags.f_can_raise_exception),
AS_STRING(OpFlags.f_is_call | OpFlags.f_has_side_effect | OpFlags.f_can_raise_exception),
CLASS_SUPER(OpFlags.f_has_side_effect | OpFlags.f_is_call | OpFlags.f_can_raise_exception),
INSTANCE_SUPER(OpFlags.f_has_side_effect | OpFlags.f_is_call | OpFlags.f_can_raise_exception),
UNRESOLVED_SUPER(OpFlags.f_has_side_effect | OpFlags.f_is_call | OpFlags.f_can_raise_exception),
ZSUPER(OpFlags.f_has_side_effect | OpFlags.f_is_call | OpFlags.f_can_raise_exception),
CALL_1F(OpFlags.f_has_side_effect | OpFlags.f_is_call | OpFlags.f_can_raise_exception),
CALL_1D(OpFlags.f_has_side_effect | OpFlags.f_is_call | OpFlags.f_can_raise_exception),
CALL_1O(OpFlags.f_has_side_effect | OpFlags.f_is_call | OpFlags.f_can_raise_exception),
CALL_2O(OpFlags.f_has_side_effect | OpFlags.f_is_call | OpFlags.f_can_raise_exception),
CALL_1OB(OpFlags.f_has_side_effect | OpFlags.f_is_call | OpFlags.f_can_raise_exception),
CALL_0O(OpFlags.f_has_side_effect | OpFlags.f_is_call | OpFlags.f_can_raise_exception),
NORESULT_CALL_1O(OpFlags.f_has_side_effect | OpFlags.f_is_call | OpFlags.f_can_raise_exception),
EQQ(OpFlags.f_has_side_effect | OpFlags.f_can_raise_exception),
LAMBDA(OpFlags.f_has_side_effect | OpFlags.f_can_raise_exception),
MATCH(OpFlags.f_has_side_effect | OpFlags.f_can_raise_exception),
YIELD(OpFlags.f_has_side_effect | OpFlags.f_can_raise_exception),
RETURN(OpFlags.f_has_side_effect | OpFlags.f_is_return),
NONLOCAL_RETURN(OpFlags.f_has_side_effect | OpFlags.f_is_return | OpFlags.f_can_raise_exception),
BREAK(OpFlags.f_has_side_effect | OpFlags.f_is_return | OpFlags.f_can_raise_exception),
RETURN_OR_RETHROW_SAVED_EXC(OpFlags.f_has_side_effect | OpFlags.f_is_return),
ALIAS(OpFlags.f_has_side_effect| OpFlags.f_modifies_code | OpFlags.f_can_raise_exception),
DEF_MODULE(OpFlags.f_has_side_effect | OpFlags.f_modifies_code | OpFlags.f_inline_unfriendly | OpFlags.f_can_raise_exception),
DEF_CLASS(OpFlags.f_has_side_effect | OpFlags.f_modifies_code | OpFlags.f_inline_unfriendly | OpFlags.f_can_raise_exception),
DEF_META_CLASS(OpFlags.f_has_side_effect | OpFlags.f_modifies_code | OpFlags.f_inline_unfriendly | OpFlags.f_can_raise_exception),
DEF_INST_METH(OpFlags.f_has_side_effect | OpFlags.f_modifies_code | OpFlags.f_inline_unfriendly | OpFlags.f_can_raise_exception),
DEF_CLASS_METH(OpFlags.f_has_side_effect | OpFlags.f_modifies_code | OpFlags.f_inline_unfriendly | OpFlags.f_can_raise_exception),
PROCESS_MODULE_BODY(OpFlags.f_has_side_effect | OpFlags.f_modifies_code | OpFlags.f_inline_unfriendly | OpFlags.f_can_raise_exception),
UNDEF_METHOD(OpFlags.f_has_side_effect | OpFlags.f_modifies_code | OpFlags.f_can_raise_exception),
GVAR_ALIAS(OpFlags.f_has_side_effect | OpFlags.f_can_raise_exception | OpFlags.f_modifies_code),
LABEL(OpFlags.f_is_book_keeping_op | OpFlags.f_is_marker_op),
EXC_REGION_START(OpFlags.f_is_book_keeping_op | OpFlags.f_is_marker_op),
EXC_REGION_END(OpFlags.f_is_book_keeping_op | OpFlags.f_is_marker_op),
LEXICAL_SEARCH_CONST(OpFlags.f_can_raise_exception),
INHERITANCE_SEARCH_CONST(OpFlags.f_can_raise_exception),
SEARCH_CONST(OpFlags.f_can_raise_exception),
SEARCH_MODULE_FOR_CONST(OpFlags.f_can_raise_exception),
GET_GLOBAL_VAR(OpFlags.f_is_load),
GET_FIELD(OpFlags.f_is_load),
GET_CVAR(OpFlags.f_is_load | OpFlags.f_can_raise_exception),
PUT_GLOBAL_VAR(OpFlags.f_is_store | OpFlags.f_has_side_effect | OpFlags.f_can_raise_exception),
PUT_CONST(OpFlags.f_is_store | OpFlags.f_has_side_effect | OpFlags.f_can_raise_exception),
PUT_CVAR(OpFlags.f_is_store | OpFlags.f_has_side_effect | OpFlags.f_can_raise_exception),
PUT_FIELD(OpFlags.f_is_store | OpFlags.f_has_side_effect | OpFlags.f_can_raise_exception),
LINE_NUM(OpFlags.f_is_book_keeping_op | OpFlags.f_is_debug_op),
TRACE(OpFlags.f_is_book_keeping_op | OpFlags.f_is_debug_op | OpFlags.f_has_side_effect),
ARG_SCOPE_DEPTH(0),
BINDING_LOAD(OpFlags.f_is_load),
BINDING_STORE(OpFlags.f_is_store | OpFlags.f_has_side_effect),
BUILD_BACKREF(OpFlags.f_can_raise_exception),
BUILD_COMPOUND_ARRAY(OpFlags.f_can_raise_exception),
BUILD_COMPOUND_STRING(OpFlags.f_can_raise_exception),
BUILD_DREGEXP(OpFlags.f_can_raise_exception),
BUILD_RANGE(OpFlags.f_can_raise_exception),
BUILD_SPLAT(OpFlags.f_can_raise_exception),
CHECK_ARGS_ARRAY_ARITY(OpFlags.f_can_raise_exception),
CHECK_ARITY(OpFlags.f_is_book_keeping_op | OpFlags.f_can_raise_exception),
CHECK_FOR_LJE(OpFlags.f_has_side_effect | OpFlags.f_can_raise_exception),
CLASS_VAR_MODULE(0),
COPY(0),
GET_ENCODING(0),
MASGN_OPT(0),
MASGN_REQD(0),
MASGN_REST(0),
RAISE_ARGUMENT_ERROR(OpFlags.f_can_raise_exception),
RAISE_REQUIRED_KEYWORD_ARGUMENT_ERROR(OpFlags.f_can_raise_exception),
RECORD_END_BLOCK(OpFlags.f_has_side_effect),
RESCUE_EQQ(OpFlags.f_can_raise_exception),
RUNTIME_HELPER(OpFlags.f_has_side_effect | OpFlags.f_can_raise_exception),
SET_CAPTURED_VAR(OpFlags.f_can_raise_exception),
THREAD_POLL(OpFlags.f_is_book_keeping_op | OpFlags.f_has_side_effect | OpFlags.f_can_raise_exception),
THROW(OpFlags.f_has_side_effect | OpFlags.f_can_raise_exception | OpFlags.f_is_exception),
TO_ARY(OpFlags.f_has_side_effect | OpFlags.f_can_raise_exception),
BLOCK_GIVEN(0),
GET_ERROR_INFO(0),
RESTORE_ERROR_INFO(OpFlags.f_has_side_effect),
BOX_FIXNUM(0),
BOX_FLOAT(0),
BOX_BOOLEAN(0),
UNBOX_FIXNUM(0),
UNBOX_FLOAT(0),
UNBOX_BOOLEAN(0),
IADD(OpFlags.f_is_int_op),
ISUB(OpFlags.f_is_int_op),
IMUL(OpFlags.f_is_int_op),
IDIV(OpFlags.f_is_int_op),
ILT(OpFlags.f_is_int_op),
IGT(OpFlags.f_is_int_op),
IOR(OpFlags.f_is_int_op),
IAND(OpFlags.f_is_int_op),
IXOR(OpFlags.f_is_int_op),
ISHL(OpFlags.f_is_int_op),
ISHR(OpFlags.f_is_int_op),
IEQ(OpFlags.f_is_int_op),
FADD(OpFlags.f_is_float_op),
FSUB(OpFlags.f_is_float_op),
FMUL(OpFlags.f_is_float_op),
FDIV(OpFlags.f_is_float_op),
FLT(OpFlags.f_is_float_op),
FGT(OpFlags.f_is_float_op),
FEQ(OpFlags.f_is_float_op),
MODULE_GUARD(OpFlags.f_is_jump_or_branch),
PUSH_METHOD_FRAME(OpFlags.f_is_book_keeping_op | OpFlags.f_has_side_effect),
PUSH_BACKREF_FRAME(OpFlags.f_is_book_keeping_op | OpFlags.f_has_side_effect),
PUSH_METHOD_BINDING(OpFlags.f_is_book_keeping_op | OpFlags.f_has_side_effect),
POP_METHOD_FRAME(OpFlags.f_is_book_keeping_op | OpFlags.f_has_side_effect),
POP_BACKREF_FRAME(OpFlags.f_is_book_keeping_op | OpFlags.f_has_side_effect),
PUSH_BLOCK_FRAME(OpFlags.f_is_book_keeping_op | OpFlags.f_has_side_effect),
PUSH_BLOCK_BINDING(OpFlags.f_is_book_keeping_op | OpFlags.f_has_side_effect),
POP_BLOCK_FRAME(OpFlags.f_is_book_keeping_op | OpFlags.f_has_side_effect),
POP_BINDING(OpFlags.f_is_book_keeping_op | OpFlags.f_has_side_effect),
SAVE_BINDING_VIZ(OpFlags.f_is_book_keeping_op | OpFlags.f_has_side_effect),
RESTORE_BINDING_VIZ(OpFlags.f_is_book_keeping_op | OpFlags.f_has_side_effect),
TOGGLE_BACKTRACE(OpFlags.f_is_book_keeping_op | OpFlags.f_has_side_effect),
UPDATE_BLOCK_STATE(OpFlags.f_is_book_keeping_op | OpFlags.f_has_side_effect),
PREPARE_BLOCK_ARGS(OpFlags.f_is_book_keeping_op | OpFlags.f_has_side_effect | OpFlags.f_can_raise_exception),
PREPARE_SINGLE_BLOCK_ARG(OpFlags.f_is_book_keeping_op | OpFlags.f_has_side_effect | OpFlags.f_can_raise_exception),
PREPARE_FIXED_BLOCK_ARGS(OpFlags.f_is_book_keeping_op | OpFlags.f_has_side_effect | OpFlags.f_can_raise_exception),
PREPARE_NO_BLOCK_ARGS(OpFlags.f_is_book_keeping_op | OpFlags.f_has_side_effect | OpFlags.f_can_raise_exception);
public final OpClass opClass;
private int flags;
Operation(int flags) {
this.flags = flags;
if (this.isArgReceive()) {
this.opClass = OpClass.ARG_OP;
} else if ((flags & OpFlags.f_is_return) > 0) {
this.opClass = OpClass.RET_OP;
} else if (this.isBranch()) {
this.opClass = OpClass.BRANCH_OP;
} else if (this.isBookKeepingOp()) {
this.opClass = OpClass.BOOK_KEEPING_OP;
} else if (this.isCall()) {
this.opClass = OpClass.CALL_OP;
} else if ((flags & OpFlags.f_is_int_op) > 0) {
this.opClass = OpClass.INT_OP;
} else if ((flags & OpFlags.f_is_float_op) > 0) {
this.opClass = OpClass.FLOAT_OP;
} else {
this.opClass = OpClass.OTHER_OP;
}
}
public boolean transfersControl() {
return (flags & (OpFlags.f_is_jump_or_branch | OpFlags.f_is_return | OpFlags.f_is_exception)) > 0;
}
public boolean isLoad() {
return (flags & OpFlags.f_is_load) > 0;
}
public boolean isStore() {
return (flags & OpFlags.f_is_store) > 0;
}
public boolean isCall() {
return (flags & OpFlags.f_is_call) > 0;
}
public boolean isBranch() {
return (flags & OpFlags.f_is_jump_or_branch) > 0;
}
public boolean isReturn() {
return (flags & OpFlags.f_is_return) > 0;
}
public boolean isException() {
return (flags & OpFlags.f_is_exception) > 0;
}
public boolean isArgReceive() {
return (flags & OpFlags.f_is_arg_receive) > 0;
}
public boolean startsBasicBlock() {
return this == LABEL;
}
public boolean endsBasicBlock() {
return transfersControl();
}
public boolean hasSideEffects() {
return (flags & OpFlags.f_has_side_effect) > 0;
}
public boolean isDebugOp() {
return (flags & OpFlags.f_is_debug_op) > 0;
}
public boolean isBookKeepingOp() {
return (flags & OpFlags.f_is_book_keeping_op) > 0;
}
public boolean canRaiseException() {
return (flags & OpFlags.f_can_raise_exception) > 0;
}
public boolean modifiesCode() {
return (flags & OpFlags.f_modifies_code) > 0;
}
public boolean inlineUnfriendly() {
return (flags & OpFlags.f_inline_unfriendly) > 0;
}
@Override
public String toString() {
return name().toLowerCase();
}
private static final Operation[] VALUES = values();
public static Operation fromOrdinal(int value) {
if (value < 0 || value >= VALUES.length) {
throw new RuntimeException("invalid ordinal: " + value);
} else {
return VALUES[value];
}
}
}