insns_info.inc
Go to the documentation of this file.
#define TS_VALUE 'V'
#define TS_GENTRY 'G'
#define TS_DINDEX 'D'
#define TS_VARIABLE '.'
#define TS_CDHASH 'H'
#define TS_IC 'C'
#define TS_ID 'I'
#define TS_LINDEX 'L'
#define TS_FUNCPTR 'F'
#define TS_ISEQ 'S'
#define TS_NUM 'N'
#define TS_OFFSET 'O'
static const char *const insn_name_info[] = {
"nop",
"getlocal",
"setlocal",
"getspecial",
"setspecial",
"getdynamic",
"setdynamic",
"getinstancevariable",
"setinstancevariable",
"getclassvariable",
"setclassvariable",
"getconstant",
"setconstant",
"getglobal",
"setglobal",
"putnil",
"putself",
"putobject",
"putspecialobject",
"putiseq",
"putstring",
"concatstrings",
"tostring",
"toregexp",
"newarray",
"duparray",
"expandarray",
"concatarray",
"splatarray",
"checkincludearray",
"newhash",
"newrange",
"pop",
"dup",
"dupn",
"swap",
"reput",
"topn",
"setn",
"adjuststack",
"defined",
"trace",
"defineclass",
"send",
"invokesuper",
"invokeblock",
"leave",
"finish",
"throw",
"jump",
"branchif",
"branchunless",
"getinlinecache",
"onceinlinecache",
"setinlinecache",
"opt_case_dispatch",
"opt_checkenv",
"opt_plus",
"opt_minus",
"opt_mult",
"opt_div",
"opt_mod",
"opt_eq",
"opt_neq",
"opt_lt",
"opt_le",
"opt_gt",
"opt_ge",
"opt_ltlt",
"opt_aref",
"opt_aset",
"opt_length",
"opt_size",
"opt_succ",
"opt_not",
"opt_regexpmatch1",
"opt_regexpmatch2",
"opt_call_c_function",
"bitblt",
"answer",
};
static const char *const insn_operand_info[] = {
"",
"L",
"L",
"VN",
"V",
"DN",
"DN",
"IC",
"IC",
"I",
"I",
"I",
"I",
"G",
"G",
"",
"",
"V",
"N",
"S",
"V",
"N",
"",
"NN",
"N",
"V",
"NN",
"",
"V",
"V",
"N",
"N",
"",
"",
"N",
"",
"",
"N",
"N",
"N",
"NVV",
"N",
"ISN",
"INSNC",
"NSN",
"NN",
"",
"",
"N",
"O",
"O",
"O",
"OC",
"OC",
"C",
"HO",
"",
"C",
"C",
"C",
"C",
"C",
"C",
"CC",
"C",
"C",
"C",
"C",
"C",
"C",
"C",
"C",
"C",
"C",
"C",
"V",
"",
"F",
"",
"",
};
static const int insn_len_info[] = {
1,
2,
2,
3,
2,
3,
3,
3,
3,
2,
2,
2,
2,
2,
2,
1,
1,
2,
2,
2,
2,
2,
1,
3,
2,
2,
3,
1,
2,
2,
2,
2,
1,
1,
2,
1,
1,
2,
2,
2,
4,
2,
4,
6,
4,
3,
1,
1,
2,
2,
2,
2,
3,
3,
2,
3,
1,
2,
2,
2,
2,
2,
2,
3,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
1,
2,
1,
1,
};
#ifdef USE_INSN_RET_NUM
static const int insn_stack_push_num_info[] = {
0,
1,
0,
1,
0,
1,
0,
1,
0,
1,
0,
1,
0,
1,
0,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
2,
1,
1,
0,
2,
1,
2,
1,
1,
1,
1,
1,
0,
1,
1,
1,
1,
1,
1,
1,
0,
0,
0,
1,
1,
1,
0,
0,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
0,
1,
1,
};
#endif
#ifdef USE_INSN_STACK_INCREASE
static int
insn_stack_increase(int depth, int insn, VALUE *opes)
{
switch(insn){
case BIN(nop):{
return depth + 0;
}
case BIN(getlocal):{
return depth + 1;
}
case BIN(setlocal):{
return depth + -1;
}
case BIN(getspecial):{
return depth + 1;
}
case BIN(setspecial):{
return depth + -1;
}
case BIN(getdynamic):{
return depth + 1;
}
case BIN(setdynamic):{
return depth + -1;
}
case BIN(getinstancevariable):{
return depth + 1;
}
case BIN(setinstancevariable):{
return depth + -1;
}
case BIN(getclassvariable):{
return depth + 1;
}
case BIN(setclassvariable):{
return depth + -1;
}
case BIN(getconstant):{
return depth + 0;
}
case BIN(setconstant):{
return depth + -2;
}
case BIN(getglobal):{
return depth + 1;
}
case BIN(setglobal):{
return depth + -1;
}
case BIN(putnil):{
return depth + 1;
}
case BIN(putself):{
return depth + 1;
}
case BIN(putobject):{
return depth + 1;
}
case BIN(putspecialobject):{
return depth + 1;
}
case BIN(putiseq):{
return depth + 1;
}
case BIN(putstring):{
return depth + 1;
}
case BIN(concatstrings):{
int inc = 0;
int num = FIX2INT(opes[0]);
inc += 1 - num;;
return depth + inc;
}
case BIN(tostring):{
return depth + 0;
}
case BIN(toregexp):{
int inc = 0;
int cnt = FIX2INT(opes[1]);
inc += 1 - cnt;;
return depth + inc;
}
case BIN(newarray):{
int inc = 0;
int num = FIX2INT(opes[0]);
inc += 1 - num;;
return depth + inc;
}
case BIN(duparray):{
return depth + 1;
}
case BIN(expandarray):{
int inc = 0;
int num = FIX2INT(opes[0]);
int flag = FIX2INT(opes[1]);
inc += num - 1 + (flag & 1 ? 1 : 0);;
return depth + inc;
}
case BIN(concatarray):{
return depth + -1;
}
case BIN(splatarray):{
return depth + 0;
}
case BIN(checkincludearray):{
return depth + 0;
}
case BIN(newhash):{
int inc = 0;
int num = FIX2INT(opes[0]);
inc += 1 - num;;
return depth + inc;
}
case BIN(newrange):{
return depth + -1;
}
case BIN(pop):{
return depth + -1;
}
case BIN(dup):{
return depth + 1;
}
case BIN(dupn):{
int inc = 0;
int n = FIX2INT(opes[0]);
inc += n;;
return depth + inc;
}
case BIN(swap):{
return depth + 0;
}
case BIN(reput):{
int inc = 0;
inc += 0;;
return depth + inc;
}
case BIN(topn):{
int inc = 0;
inc += 1;;
return depth + inc;
}
case BIN(setn):{
int inc = 0;
inc += 0;
return depth + inc;
}
case BIN(adjuststack):{
int inc = 0;
int n = FIX2INT(opes[0]);
inc -= n;
return depth + inc;
}
case BIN(defined):{
return depth + 0;
}
case BIN(trace):{
return depth + 0;
}
case BIN(defineclass):{
return depth + -1;
}
case BIN(send):{
int inc = 0;
int op_argc = FIX2INT(opes[1]);
int op_flag = FIX2INT(opes[3]);
inc += - (int)(op_argc + ((op_flag & VM_CALL_ARGS_BLOCKARG_BIT) ? 1 : 0));;
return depth + inc;
}
case BIN(invokesuper):{
int inc = 0;
int op_argc = FIX2INT(opes[0]);
int op_flag = FIX2INT(opes[2]);
inc += - (int)(op_argc + ((op_flag & VM_CALL_ARGS_BLOCKARG_BIT) ? 1 : 0));;
return depth + inc;
}
case BIN(invokeblock):{
int inc = 0;
int num = FIX2INT(opes[0]);
inc += 1 - num;;
return depth + inc;
}
case BIN(leave):{
return depth + 0;
}
case BIN(finish):{
return depth + 0;
}
case BIN(throw):{
return depth + 0;
}
case BIN(jump):{
return depth + 0;
}
case BIN(branchif):{
return depth + -1;
}
case BIN(branchunless):{
return depth + -1;
}
case BIN(getinlinecache):{
return depth + 1;
}
case BIN(onceinlinecache):{
return depth + 1;
}
case BIN(setinlinecache):{
return depth + 0;
}
case BIN(opt_case_dispatch):{
int inc = 0;
inc += -1;;
return depth + inc;
}
case BIN(opt_checkenv):{
return depth + 0;
}
case BIN(opt_plus):{
return depth + -1;
}
case BIN(opt_minus):{
return depth + -1;
}
case BIN(opt_mult):{
return depth + -1;
}
case BIN(opt_div):{
return depth + -1;
}
case BIN(opt_mod):{
return depth + -1;
}
case BIN(opt_eq):{
return depth + -1;
}
case BIN(opt_neq):{
return depth + -1;
}
case BIN(opt_lt):{
return depth + -1;
}
case BIN(opt_le):{
return depth + -1;
}
case BIN(opt_gt):{
return depth + -1;
}
case BIN(opt_ge):{
return depth + -1;
}
case BIN(opt_ltlt):{
return depth + -1;
}
case BIN(opt_aref):{
return depth + -1;
}
case BIN(opt_aset):{
return depth + -2;
}
case BIN(opt_length):{
return depth + 0;
}
case BIN(opt_size):{
return depth + 0;
}
case BIN(opt_succ):{
return depth + 0;
}
case BIN(opt_not):{
return depth + 0;
}
case BIN(opt_regexpmatch1):{
return depth + 0;
}
case BIN(opt_regexpmatch2):{
return depth + -1;
}
case BIN(opt_call_c_function):{
return depth + 0;
}
case BIN(bitblt):{
return depth + 1;
}
case BIN(answer):{
return depth + 1;
}
default:
rb_bug("insn_sp_increase: unreachable");
}
return 0;
}
#endif
/* some utilities */
static int
insn_len(VALUE insn)
{
return insn_len_info[(int)insn];
}
static const char *
insn_name(VALUE insn)
{
return insn_name_info[(int)insn];
}
static const char *
insn_op_types(VALUE insn)
{
return insn_operand_info[(int)insn];
}
static int
insn_op_type(VALUE insn, long pos)
{
int len = insn_len(insn) - 1;
if(pos < len){
return insn_operand_info[(int)insn][pos];
}
else{
return 0;
}
}
#ifdef USE_INSN_RET_NUM
static int
insn_ret_num(VALUE insn)
{
return insn_stack_push_num_info[(int)insn];
}
#endif