Optimize instructions when creating an array just to call include?
(#12123)
* Add opt_duparray_send insn to skip the allocation on `#include?` If the method isn't going to modify the array we don't need to copy it. This avoids the allocation / array copy for things like `[:a, :b].include?(x)`. This adds a BOP for include? and tracks redefinition for it on Array. Co-authored-by: Andrew Novoselac <andrew.novoselac@shopify.com> * YJIT: Implement opt_duparray_send include_p Co-authored-by: Andrew Novoselac <andrew.novoselac@shopify.com> * Update opt_newarray_send to support simple forms of include?(arg) Similar to opt_duparray_send but for non-static arrays. * YJIT: Implement opt_newarray_send include_p --------- Co-authored-by: Andrew Novoselac <andrew.novoselac@shopify.com>
This commit is contained in:
parent
c1dcd1d496
commit
1dd40ec18a
Notes:
git
2024-11-26 19:31:33 +00:00
Merged-By: maximecb <maximecb@ruby-lang.org>
@ -214,8 +214,21 @@ tests = [
|
||||
'true'.freeze
|
||||
},
|
||||
|
||||
[ 'opt_duparray_send', %q{ x = :a; [:a, :b].include?(x) }, ],
|
||||
[ 'opt_duparray_send', <<-'},', ], # {
|
||||
class Array
|
||||
def include?(i)
|
||||
i == 1
|
||||
end
|
||||
end
|
||||
x = 1
|
||||
[:a, :b].include?(x)
|
||||
},
|
||||
|
||||
[ 'opt_newarray_send', %q{ ![ ].hash.nil? }, ],
|
||||
|
||||
[ 'opt_newarray_send', %q{ v=2; [1, Object.new, 2].include?(v) }, ],
|
||||
|
||||
[ 'opt_newarray_send', %q{ [ ].max.nil? }, ],
|
||||
[ 'opt_newarray_send', %q{ [1, x = 2, 3].max == 3 }, ],
|
||||
[ 'opt_newarray_send', <<-'},', ], # {
|
||||
|
@ -5228,6 +5228,7 @@ end
|
||||
test
|
||||
RUBY
|
||||
|
||||
# opt_newarray_send pack/buffer
|
||||
assert_equal '[true, true]', <<~'RUBY'
|
||||
def pack
|
||||
v = 1.23
|
||||
@ -5244,6 +5245,7 @@ assert_equal '[true, true]', <<~'RUBY'
|
||||
[pack, with_buffer]
|
||||
RUBY
|
||||
|
||||
# String#[] / String#slice
|
||||
assert_equal 'ok', <<~'RUBY'
|
||||
def error(klass)
|
||||
yield
|
||||
@ -5283,3 +5285,27 @@ assert_equal 'ok', <<~'RUBY'
|
||||
|
||||
test
|
||||
RUBY
|
||||
|
||||
# opt_duparray_send :include?
|
||||
assert_equal '[true, false]', <<~'RUBY'
|
||||
def test(x)
|
||||
[:a, :b].include?(x)
|
||||
end
|
||||
|
||||
[
|
||||
test(:b),
|
||||
test(:c),
|
||||
]
|
||||
RUBY
|
||||
|
||||
# opt_newarray_send :include?
|
||||
assert_equal '[true, false]', <<~'RUBY'
|
||||
def test(x)
|
||||
[Object.new, :a, :b].include?(x.to_sym)
|
||||
end
|
||||
|
||||
[
|
||||
test("b"),
|
||||
test("c"),
|
||||
]
|
||||
RUBY
|
||||
|
79
compile.c
79
compile.c
@ -4170,8 +4170,87 @@ iseq_specialized_instruction(rb_iseq_t *iseq, INSN *iobj)
|
||||
return COMPILE_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// Break the "else if" chain since some prior checks abort after sub-ifs.
|
||||
// We already found "newarray". To match `[...].include?(arg)` we look for
|
||||
// the instruction(s) representing the argument followed by a "send".
|
||||
if ((IS_INSN_ID(niobj, putstring) || IS_INSN_ID(niobj, putchilledstring) ||
|
||||
IS_INSN_ID(niobj, putobject) ||
|
||||
IS_INSN_ID(niobj, putself) ||
|
||||
IS_INSN_ID(niobj, getlocal) ||
|
||||
IS_INSN_ID(niobj, getinstancevariable)) &&
|
||||
IS_NEXT_INSN_ID(&niobj->link, send)) {
|
||||
|
||||
LINK_ELEMENT *sendobj = &(niobj->link); // Below we call ->next;
|
||||
const struct rb_callinfo *ci;
|
||||
// Allow any number (0 or more) of simple method calls on the argument
|
||||
// (as in `[...].include?(arg.method1.method2)`.
|
||||
do {
|
||||
sendobj = sendobj->next;
|
||||
ci = (struct rb_callinfo *)OPERAND_AT(sendobj, 0);
|
||||
} while (vm_ci_simple(ci) && vm_ci_argc(ci) == 0 && IS_NEXT_INSN_ID(sendobj, send));
|
||||
|
||||
// If this send is for .include? with one arg we can do our opt.
|
||||
if (vm_ci_simple(ci) && vm_ci_argc(ci) == 1 && vm_ci_mid(ci) == idIncludeP) {
|
||||
VALUE num = iobj->operands[0];
|
||||
INSN *sendins = (INSN *)sendobj;
|
||||
sendins->insn_id = BIN(opt_newarray_send);
|
||||
sendins->operand_size = insn_len(sendins->insn_id) - 1;
|
||||
sendins->operands = compile_data_calloc2(iseq, sendins->operand_size, sizeof(VALUE));
|
||||
sendins->operands[0] = FIXNUM_INC(num, 1);
|
||||
sendins->operands[1] = INT2FIX(VM_OPT_NEWARRAY_SEND_INCLUDE_P);
|
||||
// Remove the original "newarray" insn.
|
||||
ELEM_REMOVE(&iobj->link);
|
||||
return COMPILE_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* duparray [...]
|
||||
* some insn for the arg...
|
||||
* send <calldata!mid:include?, argc:1, ARGS_SIMPLE>, nil
|
||||
* =>
|
||||
* arg insn...
|
||||
* opt_duparray_send [...], :include?, 1
|
||||
*/
|
||||
if (IS_INSN_ID(iobj, duparray) && iobj->link.next && IS_INSN(iobj->link.next)) {
|
||||
INSN *niobj = (INSN *)iobj->link.next;
|
||||
if ((IS_INSN_ID(niobj, getlocal) ||
|
||||
IS_INSN_ID(niobj, getinstancevariable) ||
|
||||
IS_INSN_ID(niobj, putself)) &&
|
||||
IS_NEXT_INSN_ID(&niobj->link, send)) {
|
||||
|
||||
LINK_ELEMENT *sendobj = &(niobj->link); // Below we call ->next;
|
||||
const struct rb_callinfo *ci;
|
||||
// Allow any number (0 or more) of simple method calls on the argument
|
||||
// (as in `[...].include?(arg.method1.method2)`.
|
||||
do {
|
||||
sendobj = sendobj->next;
|
||||
ci = (struct rb_callinfo *)OPERAND_AT(sendobj, 0);
|
||||
} while (vm_ci_simple(ci) && vm_ci_argc(ci) == 0 && IS_NEXT_INSN_ID(sendobj, send));
|
||||
|
||||
if (vm_ci_simple(ci) && vm_ci_argc(ci) == 1 && vm_ci_mid(ci) == idIncludeP) {
|
||||
// Move the array arg from duparray to opt_duparray_send.
|
||||
VALUE ary = iobj->operands[0];
|
||||
rb_obj_reveal(ary, rb_cArray);
|
||||
|
||||
INSN *sendins = (INSN *)sendobj;
|
||||
sendins->insn_id = BIN(opt_duparray_send);
|
||||
sendins->operand_size = insn_len(sendins->insn_id) - 1;;
|
||||
sendins->operands = compile_data_calloc2(iseq, sendins->operand_size, sizeof(VALUE));
|
||||
sendins->operands[0] = ary;
|
||||
sendins->operands[1] = rb_id2sym(idIncludeP);
|
||||
sendins->operands[2] = INT2FIX(1);
|
||||
|
||||
// Remove the duparray insn.
|
||||
ELEM_REMOVE(&iobj->link);
|
||||
return COMPILE_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (IS_INSN_ID(iobj, send)) {
|
||||
const struct rb_callinfo *ci = (struct rb_callinfo *)OPERAND_AT(iobj, 0);
|
||||
const rb_iseq_t *blockiseq = (rb_iseq_t *)OPERAND_AT(iobj, 1);
|
||||
|
@ -61,6 +61,7 @@ firstline, predefined = __LINE__+1, %[\
|
||||
path
|
||||
pack
|
||||
buffer
|
||||
include?
|
||||
|
||||
_ UScore
|
||||
|
||||
|
25
insns.def
25
insns.def
@ -991,6 +991,28 @@ opt_str_uminus
|
||||
}
|
||||
}
|
||||
|
||||
DEFINE_INSN
|
||||
opt_duparray_send
|
||||
(VALUE ary, ID method, rb_num_t argc)
|
||||
(...)
|
||||
(VALUE val)
|
||||
/* This instruction typically has no funcalls. But it may compare array
|
||||
* contents to each other which may call methods when necessary.
|
||||
* No way to detect such method calls beforehand.
|
||||
* We must mark it as not leaf. */
|
||||
// attr bool leaf = false; /* has rb_funcall() */
|
||||
// attr rb_snum_t sp_inc = 1 - (rb_snum_t)argc;
|
||||
// attr rb_snum_t comptime_sp_inc = 1 - (rb_snum_t)argc;
|
||||
{
|
||||
switch(method) {
|
||||
case idIncludeP:
|
||||
val = vm_opt_duparray_include_p(ec, ary, TOPN(0));
|
||||
break;
|
||||
default:
|
||||
rb_bug("unreachable");
|
||||
}
|
||||
}
|
||||
|
||||
DEFINE_INSN
|
||||
opt_newarray_send
|
||||
(rb_num_t num, rb_num_t method)
|
||||
@ -1014,6 +1036,9 @@ opt_newarray_send
|
||||
case VM_OPT_NEWARRAY_SEND_MAX:
|
||||
val = vm_opt_newarray_max(ec, num, STACK_ADDR_FROM_TOP(num));
|
||||
break;
|
||||
case VM_OPT_NEWARRAY_SEND_INCLUDE_P:
|
||||
val = vm_opt_newarray_include_p(ec, (long)num-1, STACK_ADDR_FROM_TOP(num), TOPN(0));
|
||||
break;
|
||||
case VM_OPT_NEWARRAY_SEND_PACK:
|
||||
val = vm_opt_newarray_pack_buffer(ec, (long)num-1, STACK_ADDR_FROM_TOP(num), TOPN(0), Qundef);
|
||||
break;
|
||||
|
@ -38,6 +38,7 @@ enum ruby_basic_operators {
|
||||
BOP_CMP,
|
||||
BOP_DEFAULT,
|
||||
BOP_PACK,
|
||||
BOP_INCLUDE_P,
|
||||
|
||||
BOP_LAST_
|
||||
};
|
||||
|
@ -1114,6 +1114,33 @@ class TestArray < Test::Unit::TestCase
|
||||
assert_not_include(a, [1,2])
|
||||
end
|
||||
|
||||
def test_monkey_patch_include?
|
||||
assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}", timeout: 30)
|
||||
begin;
|
||||
$-w = false
|
||||
class Array
|
||||
alias :old_include? :include?
|
||||
def include? x
|
||||
return true if x == :always
|
||||
old_include?(x)
|
||||
end
|
||||
end
|
||||
def test
|
||||
a, c, always = :a, :c, :always
|
||||
[
|
||||
[:a, :b].include?(a),
|
||||
[:a, :b].include?(c),
|
||||
[:a, :b].include?(always),
|
||||
]
|
||||
end
|
||||
v = test
|
||||
class Array
|
||||
alias :include? :old_include?
|
||||
end
|
||||
assert_equal [true, false, true], v
|
||||
end;
|
||||
end
|
||||
|
||||
def test_intersect?
|
||||
a = @cls[ 1, 2, 3]
|
||||
assert_send([a, :intersect?, [3]])
|
||||
|
@ -1107,4 +1107,113 @@ class TestRubyOptimization < Test::Unit::TestCase
|
||||
def o.to_s; 1; end
|
||||
assert_match %r{\A#<Object:0x[0-9a-f]+>\z}, "#{o}"
|
||||
end
|
||||
|
||||
def test_opt_duparray_send_include_p
|
||||
[
|
||||
'x = :b; [:a, :b].include?(x)',
|
||||
'@c = :b; [:a, :b].include?(@c)',
|
||||
'@c = "b"; %i[a b].include?(@c.to_sym)',
|
||||
'[:a, :b].include?(self) == false',
|
||||
].each do |code|
|
||||
iseq = RubyVM::InstructionSequence.compile(code)
|
||||
insn = iseq.disasm
|
||||
assert_match(/opt_duparray_send/, insn)
|
||||
assert_no_match(/\bduparray\b/, insn)
|
||||
assert_equal(true, eval(code))
|
||||
end
|
||||
|
||||
x, y = :b, :c
|
||||
assert_equal(true, [:a, :b].include?(x))
|
||||
assert_equal(false, [:a, :b].include?(y))
|
||||
|
||||
assert_in_out_err([], <<~RUBY, ["1,2", "3,3", "1,2", "4,4"])
|
||||
class Array
|
||||
prepend(Module.new do
|
||||
def include?(i)
|
||||
puts self.join(",")
|
||||
# Modify self to prove that we are operating on a copy.
|
||||
map! { i }
|
||||
puts self.join(",")
|
||||
end
|
||||
end)
|
||||
end
|
||||
def x(i)
|
||||
[1, 2].include?(i)
|
||||
end
|
||||
x(3)
|
||||
x(4)
|
||||
RUBY
|
||||
|
||||
# Ensure raises happen correctly.
|
||||
assert_in_out_err([], <<~RUBY, ["will raise", "int 1 not 3"])
|
||||
class Integer
|
||||
undef_method :==
|
||||
def == x
|
||||
raise "int \#{self} not \#{x}"
|
||||
end
|
||||
end
|
||||
x = 3
|
||||
puts "will raise"
|
||||
begin
|
||||
p [1, 2].include?(x)
|
||||
rescue
|
||||
puts $!
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
def test_opt_newarray_send_include_p
|
||||
[
|
||||
'b = :b; [:a, b].include?(:b)',
|
||||
# Use Object.new to ensure that we get newarray rather than duparray.
|
||||
'value = 1; [Object.new, true, "true", 1].include?(value)',
|
||||
'value = 1; [Object.new, "1"].include?(value.to_s)',
|
||||
'[Object.new, "1"].include?(self) == false',
|
||||
].each do |code|
|
||||
iseq = RubyVM::InstructionSequence.compile(code)
|
||||
insn = iseq.disasm
|
||||
assert_match(/opt_newarray_send/, insn)
|
||||
assert_no_match(/\bnewarray\b/, insn)
|
||||
assert_equal(true, eval(code))
|
||||
end
|
||||
|
||||
x, y = :b, :c
|
||||
assert_equal(true, [:a, x].include?(x))
|
||||
assert_equal(false, [:a, x].include?(y))
|
||||
|
||||
assert_in_out_err([], <<~RUBY, ["1,3", "3,3", "1,4", "4,4"])
|
||||
class Array
|
||||
prepend(Module.new do
|
||||
def include?(i)
|
||||
puts self.join(",")
|
||||
# Modify self to prove that we are operating on a copy.
|
||||
map! { i }
|
||||
puts self.join(",")
|
||||
end
|
||||
end)
|
||||
end
|
||||
def x(i)
|
||||
[1, i].include?(i)
|
||||
end
|
||||
x(3)
|
||||
x(4)
|
||||
RUBY
|
||||
|
||||
# Ensure raises happen correctly.
|
||||
assert_in_out_err([], <<~RUBY, ["will raise", "int 1 not 3"])
|
||||
class Integer
|
||||
undef_method :==
|
||||
def == x
|
||||
raise "int \#{self} not \#{x}"
|
||||
end
|
||||
end
|
||||
x = 3
|
||||
puts "will raise"
|
||||
begin
|
||||
p [1, x].include?(x)
|
||||
rescue
|
||||
puts $!
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
|
1
vm.c
1
vm.c
@ -2263,6 +2263,7 @@ vm_init_redefined_flag(void)
|
||||
OP(NilP, NIL_P), (C(NilClass));
|
||||
OP(Cmp, CMP), (C(Integer), C(Float), C(String));
|
||||
OP(Default, DEFAULT), (C(Hash));
|
||||
OP(IncludeP, INCLUDE_P), (C(Array));
|
||||
#undef C
|
||||
#undef OP
|
||||
}
|
||||
|
@ -1313,6 +1313,7 @@ enum vm_opt_newarray_send_type {
|
||||
VM_OPT_NEWARRAY_SEND_HASH = 3,
|
||||
VM_OPT_NEWARRAY_SEND_PACK = 4,
|
||||
VM_OPT_NEWARRAY_SEND_PACK_BUFFER = 5,
|
||||
VM_OPT_NEWARRAY_SEND_INCLUDE_P = 6,
|
||||
};
|
||||
|
||||
enum vm_special_object_type {
|
||||
|
@ -6158,6 +6158,29 @@ vm_opt_str_freeze(VALUE str, int bop, ID id)
|
||||
/* this macro is mandatory to use OPTIMIZED_CMP. What a design! */
|
||||
#define id_cmp idCmp
|
||||
|
||||
static VALUE
|
||||
vm_opt_duparray_include_p(rb_execution_context_t *ec, const VALUE ary, VALUE target)
|
||||
{
|
||||
if (BASIC_OP_UNREDEFINED_P(BOP_INCLUDE_P, ARRAY_REDEFINED_OP_FLAG)) {
|
||||
return rb_ary_includes(ary, target);
|
||||
}
|
||||
else {
|
||||
VALUE args[1] = {target};
|
||||
|
||||
// duparray
|
||||
RUBY_DTRACE_CREATE_HOOK(ARRAY, RARRAY_LEN(ary));
|
||||
VALUE dupary = rb_ary_resurrect(ary);
|
||||
|
||||
return rb_vm_call_with_refinements(ec, dupary, idIncludeP, 1, args, RB_NO_KEYWORDS);
|
||||
}
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_vm_opt_duparray_include_p(rb_execution_context_t *ec, const VALUE ary, VALUE target)
|
||||
{
|
||||
return vm_opt_duparray_include_p(ec, ary, target);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
vm_opt_newarray_max(rb_execution_context_t *ec, rb_num_t num, const VALUE *ptr)
|
||||
{
|
||||
@ -6239,6 +6262,26 @@ rb_vm_opt_newarray_hash(rb_execution_context_t *ec, rb_num_t num, const VALUE *p
|
||||
VALUE rb_setup_fake_ary(struct RArray *fake_ary, const VALUE *list, long len);
|
||||
VALUE rb_ec_pack_ary(rb_execution_context_t *ec, VALUE ary, VALUE fmt, VALUE buffer);
|
||||
|
||||
static VALUE
|
||||
vm_opt_newarray_include_p(rb_execution_context_t *ec, rb_num_t num, const VALUE *ptr, VALUE target)
|
||||
{
|
||||
if (BASIC_OP_UNREDEFINED_P(BOP_INCLUDE_P, ARRAY_REDEFINED_OP_FLAG)) {
|
||||
struct RArray fake_ary;
|
||||
VALUE ary = rb_setup_fake_ary(&fake_ary, ptr, num);
|
||||
return rb_ary_includes(ary, target);
|
||||
}
|
||||
else {
|
||||
VALUE args[1] = {target};
|
||||
return rb_vm_call_with_refinements(ec, rb_ary_new4(num, ptr), idIncludeP, 1, args, RB_NO_KEYWORDS);
|
||||
}
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_vm_opt_newarray_include_p(rb_execution_context_t *ec, rb_num_t num, const VALUE *ptr, VALUE target)
|
||||
{
|
||||
return vm_opt_newarray_include_p(ec, num, ptr, target);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
vm_opt_newarray_pack_buffer(rb_execution_context_t *ec, rb_num_t num, const VALUE *ptr, VALUE fmt, VALUE buffer)
|
||||
{
|
||||
|
@ -4306,6 +4306,53 @@ fn gen_opt_newarray_max(
|
||||
Some(KeepCompiling)
|
||||
}
|
||||
|
||||
fn gen_opt_duparray_send(
|
||||
jit: &mut JITState,
|
||||
asm: &mut Assembler,
|
||||
) -> Option<CodegenStatus> {
|
||||
let method = jit.get_arg(1).as_u64();
|
||||
|
||||
if method == ID!(include_p) {
|
||||
gen_opt_duparray_send_include_p(jit, asm)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn gen_opt_duparray_send_include_p(
|
||||
jit: &mut JITState,
|
||||
asm: &mut Assembler,
|
||||
) -> Option<CodegenStatus> {
|
||||
asm_comment!(asm, "opt_duparray_send include_p");
|
||||
|
||||
let ary = jit.get_arg(0);
|
||||
let argc = jit.get_arg(2).as_usize();
|
||||
|
||||
// Save the PC and SP because we may call #include?
|
||||
jit_prepare_non_leaf_call(jit, asm);
|
||||
|
||||
extern "C" {
|
||||
fn rb_vm_opt_duparray_include_p(ec: EcPtr, ary: VALUE, target: VALUE) -> VALUE;
|
||||
}
|
||||
|
||||
let target = asm.ctx.sp_opnd(-1);
|
||||
|
||||
let val_opnd = asm.ccall(
|
||||
rb_vm_opt_duparray_include_p as *const u8,
|
||||
vec![
|
||||
EC,
|
||||
ary.into(),
|
||||
target,
|
||||
],
|
||||
);
|
||||
|
||||
asm.stack_pop(argc);
|
||||
let stack_ret = asm.stack_push(Type::Unknown);
|
||||
asm.mov(stack_ret, val_opnd);
|
||||
|
||||
Some(KeepCompiling)
|
||||
}
|
||||
|
||||
fn gen_opt_newarray_send(
|
||||
jit: &mut JITState,
|
||||
asm: &mut Assembler,
|
||||
@ -4318,6 +4365,8 @@ fn gen_opt_newarray_send(
|
||||
gen_opt_newarray_max(jit, asm)
|
||||
} else if method == VM_OPT_NEWARRAY_SEND_HASH {
|
||||
gen_opt_newarray_hash(jit, asm)
|
||||
} else if method == VM_OPT_NEWARRAY_SEND_INCLUDE_P {
|
||||
gen_opt_newarray_include_p(jit, asm)
|
||||
} else if method == VM_OPT_NEWARRAY_SEND_PACK {
|
||||
gen_opt_newarray_pack_buffer(jit, asm, 1, None)
|
||||
} else if method == VM_OPT_NEWARRAY_SEND_PACK_BUFFER {
|
||||
@ -4403,6 +4452,42 @@ fn gen_opt_newarray_hash(
|
||||
Some(KeepCompiling)
|
||||
}
|
||||
|
||||
fn gen_opt_newarray_include_p(
|
||||
jit: &mut JITState,
|
||||
asm: &mut Assembler,
|
||||
) -> Option<CodegenStatus> {
|
||||
asm_comment!(asm, "opt_newarray_send include?");
|
||||
|
||||
let num = jit.get_arg(0).as_u32();
|
||||
|
||||
// Save the PC and SP because we may call customized methods.
|
||||
jit_prepare_non_leaf_call(jit, asm);
|
||||
|
||||
extern "C" {
|
||||
fn rb_vm_opt_newarray_include_p(ec: EcPtr, num: u32, elts: *const VALUE, target: VALUE) -> VALUE;
|
||||
}
|
||||
|
||||
let values_opnd = asm.ctx.sp_opnd(-(num as i32));
|
||||
let values_ptr = asm.lea(values_opnd);
|
||||
let target = asm.ctx.sp_opnd(-1);
|
||||
|
||||
let val_opnd = asm.ccall(
|
||||
rb_vm_opt_newarray_include_p as *const u8,
|
||||
vec![
|
||||
EC,
|
||||
(num - 1).into(),
|
||||
values_ptr,
|
||||
target
|
||||
],
|
||||
);
|
||||
|
||||
asm.stack_pop(num.as_usize());
|
||||
let stack_ret = asm.stack_push(Type::Unknown);
|
||||
asm.mov(stack_ret, val_opnd);
|
||||
|
||||
Some(KeepCompiling)
|
||||
}
|
||||
|
||||
fn gen_opt_newarray_min(
|
||||
jit: &mut JITState,
|
||||
asm: &mut Assembler,
|
||||
@ -10466,6 +10551,7 @@ fn get_gen_fn(opcode: VALUE) -> Option<InsnGenFn> {
|
||||
YARVINSN_opt_hash_freeze => Some(gen_opt_hash_freeze),
|
||||
YARVINSN_opt_str_freeze => Some(gen_opt_str_freeze),
|
||||
YARVINSN_opt_str_uminus => Some(gen_opt_str_uminus),
|
||||
YARVINSN_opt_duparray_send => Some(gen_opt_duparray_send),
|
||||
YARVINSN_opt_newarray_send => Some(gen_opt_newarray_send),
|
||||
YARVINSN_splatarray => Some(gen_splatarray),
|
||||
YARVINSN_splatkw => Some(gen_splatkw),
|
||||
|
@ -824,6 +824,7 @@ pub(crate) mod ids {
|
||||
name: respond_to_missing content: b"respond_to_missing?"
|
||||
name: to_ary content: b"to_ary"
|
||||
name: eq content: b"=="
|
||||
name: include_p content: b"include?"
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -343,7 +343,8 @@ pub const BOP_OR: ruby_basic_operators = 29;
|
||||
pub const BOP_CMP: ruby_basic_operators = 30;
|
||||
pub const BOP_DEFAULT: ruby_basic_operators = 31;
|
||||
pub const BOP_PACK: ruby_basic_operators = 32;
|
||||
pub const BOP_LAST_: ruby_basic_operators = 33;
|
||||
pub const BOP_INCLUDE_P: ruby_basic_operators = 33;
|
||||
pub const BOP_LAST_: ruby_basic_operators = 34;
|
||||
pub type ruby_basic_operators = u32;
|
||||
pub type rb_serial_t = ::std::os::raw::c_ulonglong;
|
||||
pub const imemo_env: imemo_type = 0;
|
||||
@ -607,6 +608,7 @@ pub const VM_OPT_NEWARRAY_SEND_MIN: vm_opt_newarray_send_type = 2;
|
||||
pub const VM_OPT_NEWARRAY_SEND_HASH: vm_opt_newarray_send_type = 3;
|
||||
pub const VM_OPT_NEWARRAY_SEND_PACK: vm_opt_newarray_send_type = 4;
|
||||
pub const VM_OPT_NEWARRAY_SEND_PACK_BUFFER: vm_opt_newarray_send_type = 5;
|
||||
pub const VM_OPT_NEWARRAY_SEND_INCLUDE_P: vm_opt_newarray_send_type = 6;
|
||||
pub type vm_opt_newarray_send_type = u32;
|
||||
pub const VM_SPECIAL_OBJECT_VMCORE: vm_special_object_type = 1;
|
||||
pub const VM_SPECIAL_OBJECT_CBASE: vm_special_object_type = 2;
|
||||
@ -789,161 +791,163 @@ pub const YARVINSN_opt_hash_freeze: ruby_vminsn_type = 60;
|
||||
pub const YARVINSN_opt_str_freeze: ruby_vminsn_type = 61;
|
||||
pub const YARVINSN_opt_nil_p: ruby_vminsn_type = 62;
|
||||
pub const YARVINSN_opt_str_uminus: ruby_vminsn_type = 63;
|
||||
pub const YARVINSN_opt_newarray_send: ruby_vminsn_type = 64;
|
||||
pub const YARVINSN_invokesuper: ruby_vminsn_type = 65;
|
||||
pub const YARVINSN_invokesuperforward: ruby_vminsn_type = 66;
|
||||
pub const YARVINSN_invokeblock: ruby_vminsn_type = 67;
|
||||
pub const YARVINSN_leave: ruby_vminsn_type = 68;
|
||||
pub const YARVINSN_throw: ruby_vminsn_type = 69;
|
||||
pub const YARVINSN_jump: ruby_vminsn_type = 70;
|
||||
pub const YARVINSN_branchif: ruby_vminsn_type = 71;
|
||||
pub const YARVINSN_branchunless: ruby_vminsn_type = 72;
|
||||
pub const YARVINSN_branchnil: ruby_vminsn_type = 73;
|
||||
pub const YARVINSN_once: ruby_vminsn_type = 74;
|
||||
pub const YARVINSN_opt_case_dispatch: ruby_vminsn_type = 75;
|
||||
pub const YARVINSN_opt_plus: ruby_vminsn_type = 76;
|
||||
pub const YARVINSN_opt_minus: ruby_vminsn_type = 77;
|
||||
pub const YARVINSN_opt_mult: ruby_vminsn_type = 78;
|
||||
pub const YARVINSN_opt_div: ruby_vminsn_type = 79;
|
||||
pub const YARVINSN_opt_mod: ruby_vminsn_type = 80;
|
||||
pub const YARVINSN_opt_eq: ruby_vminsn_type = 81;
|
||||
pub const YARVINSN_opt_neq: ruby_vminsn_type = 82;
|
||||
pub const YARVINSN_opt_lt: ruby_vminsn_type = 83;
|
||||
pub const YARVINSN_opt_le: ruby_vminsn_type = 84;
|
||||
pub const YARVINSN_opt_gt: ruby_vminsn_type = 85;
|
||||
pub const YARVINSN_opt_ge: ruby_vminsn_type = 86;
|
||||
pub const YARVINSN_opt_ltlt: ruby_vminsn_type = 87;
|
||||
pub const YARVINSN_opt_and: ruby_vminsn_type = 88;
|
||||
pub const YARVINSN_opt_or: ruby_vminsn_type = 89;
|
||||
pub const YARVINSN_opt_aref: ruby_vminsn_type = 90;
|
||||
pub const YARVINSN_opt_aset: ruby_vminsn_type = 91;
|
||||
pub const YARVINSN_opt_aset_with: ruby_vminsn_type = 92;
|
||||
pub const YARVINSN_opt_aref_with: ruby_vminsn_type = 93;
|
||||
pub const YARVINSN_opt_length: ruby_vminsn_type = 94;
|
||||
pub const YARVINSN_opt_size: ruby_vminsn_type = 95;
|
||||
pub const YARVINSN_opt_empty_p: ruby_vminsn_type = 96;
|
||||
pub const YARVINSN_opt_succ: ruby_vminsn_type = 97;
|
||||
pub const YARVINSN_opt_not: ruby_vminsn_type = 98;
|
||||
pub const YARVINSN_opt_regexpmatch2: ruby_vminsn_type = 99;
|
||||
pub const YARVINSN_invokebuiltin: ruby_vminsn_type = 100;
|
||||
pub const YARVINSN_opt_invokebuiltin_delegate: ruby_vminsn_type = 101;
|
||||
pub const YARVINSN_opt_invokebuiltin_delegate_leave: ruby_vminsn_type = 102;
|
||||
pub const YARVINSN_getlocal_WC_0: ruby_vminsn_type = 103;
|
||||
pub const YARVINSN_getlocal_WC_1: ruby_vminsn_type = 104;
|
||||
pub const YARVINSN_setlocal_WC_0: ruby_vminsn_type = 105;
|
||||
pub const YARVINSN_setlocal_WC_1: ruby_vminsn_type = 106;
|
||||
pub const YARVINSN_putobject_INT2FIX_0_: ruby_vminsn_type = 107;
|
||||
pub const YARVINSN_putobject_INT2FIX_1_: ruby_vminsn_type = 108;
|
||||
pub const YARVINSN_trace_nop: ruby_vminsn_type = 109;
|
||||
pub const YARVINSN_trace_getlocal: ruby_vminsn_type = 110;
|
||||
pub const YARVINSN_trace_setlocal: ruby_vminsn_type = 111;
|
||||
pub const YARVINSN_trace_getblockparam: ruby_vminsn_type = 112;
|
||||
pub const YARVINSN_trace_setblockparam: ruby_vminsn_type = 113;
|
||||
pub const YARVINSN_trace_getblockparamproxy: ruby_vminsn_type = 114;
|
||||
pub const YARVINSN_trace_getspecial: ruby_vminsn_type = 115;
|
||||
pub const YARVINSN_trace_setspecial: ruby_vminsn_type = 116;
|
||||
pub const YARVINSN_trace_getinstancevariable: ruby_vminsn_type = 117;
|
||||
pub const YARVINSN_trace_setinstancevariable: ruby_vminsn_type = 118;
|
||||
pub const YARVINSN_trace_getclassvariable: ruby_vminsn_type = 119;
|
||||
pub const YARVINSN_trace_setclassvariable: ruby_vminsn_type = 120;
|
||||
pub const YARVINSN_trace_opt_getconstant_path: ruby_vminsn_type = 121;
|
||||
pub const YARVINSN_trace_getconstant: ruby_vminsn_type = 122;
|
||||
pub const YARVINSN_trace_setconstant: ruby_vminsn_type = 123;
|
||||
pub const YARVINSN_trace_getglobal: ruby_vminsn_type = 124;
|
||||
pub const YARVINSN_trace_setglobal: ruby_vminsn_type = 125;
|
||||
pub const YARVINSN_trace_putnil: ruby_vminsn_type = 126;
|
||||
pub const YARVINSN_trace_putself: ruby_vminsn_type = 127;
|
||||
pub const YARVINSN_trace_putobject: ruby_vminsn_type = 128;
|
||||
pub const YARVINSN_trace_putspecialobject: ruby_vminsn_type = 129;
|
||||
pub const YARVINSN_trace_putstring: ruby_vminsn_type = 130;
|
||||
pub const YARVINSN_trace_putchilledstring: ruby_vminsn_type = 131;
|
||||
pub const YARVINSN_trace_concatstrings: ruby_vminsn_type = 132;
|
||||
pub const YARVINSN_trace_anytostring: ruby_vminsn_type = 133;
|
||||
pub const YARVINSN_trace_toregexp: ruby_vminsn_type = 134;
|
||||
pub const YARVINSN_trace_intern: ruby_vminsn_type = 135;
|
||||
pub const YARVINSN_trace_newarray: ruby_vminsn_type = 136;
|
||||
pub const YARVINSN_trace_pushtoarraykwsplat: ruby_vminsn_type = 137;
|
||||
pub const YARVINSN_trace_duparray: ruby_vminsn_type = 138;
|
||||
pub const YARVINSN_trace_duphash: ruby_vminsn_type = 139;
|
||||
pub const YARVINSN_trace_expandarray: ruby_vminsn_type = 140;
|
||||
pub const YARVINSN_trace_concatarray: ruby_vminsn_type = 141;
|
||||
pub const YARVINSN_trace_concattoarray: ruby_vminsn_type = 142;
|
||||
pub const YARVINSN_trace_pushtoarray: ruby_vminsn_type = 143;
|
||||
pub const YARVINSN_trace_splatarray: ruby_vminsn_type = 144;
|
||||
pub const YARVINSN_trace_splatkw: ruby_vminsn_type = 145;
|
||||
pub const YARVINSN_trace_newhash: ruby_vminsn_type = 146;
|
||||
pub const YARVINSN_trace_newrange: ruby_vminsn_type = 147;
|
||||
pub const YARVINSN_trace_pop: ruby_vminsn_type = 148;
|
||||
pub const YARVINSN_trace_dup: ruby_vminsn_type = 149;
|
||||
pub const YARVINSN_trace_dupn: ruby_vminsn_type = 150;
|
||||
pub const YARVINSN_trace_swap: ruby_vminsn_type = 151;
|
||||
pub const YARVINSN_trace_opt_reverse: ruby_vminsn_type = 152;
|
||||
pub const YARVINSN_trace_topn: ruby_vminsn_type = 153;
|
||||
pub const YARVINSN_trace_setn: ruby_vminsn_type = 154;
|
||||
pub const YARVINSN_trace_adjuststack: ruby_vminsn_type = 155;
|
||||
pub const YARVINSN_trace_defined: ruby_vminsn_type = 156;
|
||||
pub const YARVINSN_trace_definedivar: ruby_vminsn_type = 157;
|
||||
pub const YARVINSN_trace_checkmatch: ruby_vminsn_type = 158;
|
||||
pub const YARVINSN_trace_checkkeyword: ruby_vminsn_type = 159;
|
||||
pub const YARVINSN_trace_checktype: ruby_vminsn_type = 160;
|
||||
pub const YARVINSN_trace_defineclass: ruby_vminsn_type = 161;
|
||||
pub const YARVINSN_trace_definemethod: ruby_vminsn_type = 162;
|
||||
pub const YARVINSN_trace_definesmethod: ruby_vminsn_type = 163;
|
||||
pub const YARVINSN_trace_send: ruby_vminsn_type = 164;
|
||||
pub const YARVINSN_trace_sendforward: ruby_vminsn_type = 165;
|
||||
pub const YARVINSN_trace_opt_send_without_block: ruby_vminsn_type = 166;
|
||||
pub const YARVINSN_trace_objtostring: ruby_vminsn_type = 167;
|
||||
pub const YARVINSN_trace_opt_ary_freeze: ruby_vminsn_type = 168;
|
||||
pub const YARVINSN_trace_opt_hash_freeze: ruby_vminsn_type = 169;
|
||||
pub const YARVINSN_trace_opt_str_freeze: ruby_vminsn_type = 170;
|
||||
pub const YARVINSN_trace_opt_nil_p: ruby_vminsn_type = 171;
|
||||
pub const YARVINSN_trace_opt_str_uminus: ruby_vminsn_type = 172;
|
||||
pub const YARVINSN_trace_opt_newarray_send: ruby_vminsn_type = 173;
|
||||
pub const YARVINSN_trace_invokesuper: ruby_vminsn_type = 174;
|
||||
pub const YARVINSN_trace_invokesuperforward: ruby_vminsn_type = 175;
|
||||
pub const YARVINSN_trace_invokeblock: ruby_vminsn_type = 176;
|
||||
pub const YARVINSN_trace_leave: ruby_vminsn_type = 177;
|
||||
pub const YARVINSN_trace_throw: ruby_vminsn_type = 178;
|
||||
pub const YARVINSN_trace_jump: ruby_vminsn_type = 179;
|
||||
pub const YARVINSN_trace_branchif: ruby_vminsn_type = 180;
|
||||
pub const YARVINSN_trace_branchunless: ruby_vminsn_type = 181;
|
||||
pub const YARVINSN_trace_branchnil: ruby_vminsn_type = 182;
|
||||
pub const YARVINSN_trace_once: ruby_vminsn_type = 183;
|
||||
pub const YARVINSN_trace_opt_case_dispatch: ruby_vminsn_type = 184;
|
||||
pub const YARVINSN_trace_opt_plus: ruby_vminsn_type = 185;
|
||||
pub const YARVINSN_trace_opt_minus: ruby_vminsn_type = 186;
|
||||
pub const YARVINSN_trace_opt_mult: ruby_vminsn_type = 187;
|
||||
pub const YARVINSN_trace_opt_div: ruby_vminsn_type = 188;
|
||||
pub const YARVINSN_trace_opt_mod: ruby_vminsn_type = 189;
|
||||
pub const YARVINSN_trace_opt_eq: ruby_vminsn_type = 190;
|
||||
pub const YARVINSN_trace_opt_neq: ruby_vminsn_type = 191;
|
||||
pub const YARVINSN_trace_opt_lt: ruby_vminsn_type = 192;
|
||||
pub const YARVINSN_trace_opt_le: ruby_vminsn_type = 193;
|
||||
pub const YARVINSN_trace_opt_gt: ruby_vminsn_type = 194;
|
||||
pub const YARVINSN_trace_opt_ge: ruby_vminsn_type = 195;
|
||||
pub const YARVINSN_trace_opt_ltlt: ruby_vminsn_type = 196;
|
||||
pub const YARVINSN_trace_opt_and: ruby_vminsn_type = 197;
|
||||
pub const YARVINSN_trace_opt_or: ruby_vminsn_type = 198;
|
||||
pub const YARVINSN_trace_opt_aref: ruby_vminsn_type = 199;
|
||||
pub const YARVINSN_trace_opt_aset: ruby_vminsn_type = 200;
|
||||
pub const YARVINSN_trace_opt_aset_with: ruby_vminsn_type = 201;
|
||||
pub const YARVINSN_trace_opt_aref_with: ruby_vminsn_type = 202;
|
||||
pub const YARVINSN_trace_opt_length: ruby_vminsn_type = 203;
|
||||
pub const YARVINSN_trace_opt_size: ruby_vminsn_type = 204;
|
||||
pub const YARVINSN_trace_opt_empty_p: ruby_vminsn_type = 205;
|
||||
pub const YARVINSN_trace_opt_succ: ruby_vminsn_type = 206;
|
||||
pub const YARVINSN_trace_opt_not: ruby_vminsn_type = 207;
|
||||
pub const YARVINSN_trace_opt_regexpmatch2: ruby_vminsn_type = 208;
|
||||
pub const YARVINSN_trace_invokebuiltin: ruby_vminsn_type = 209;
|
||||
pub const YARVINSN_trace_opt_invokebuiltin_delegate: ruby_vminsn_type = 210;
|
||||
pub const YARVINSN_trace_opt_invokebuiltin_delegate_leave: ruby_vminsn_type = 211;
|
||||
pub const YARVINSN_trace_getlocal_WC_0: ruby_vminsn_type = 212;
|
||||
pub const YARVINSN_trace_getlocal_WC_1: ruby_vminsn_type = 213;
|
||||
pub const YARVINSN_trace_setlocal_WC_0: ruby_vminsn_type = 214;
|
||||
pub const YARVINSN_trace_setlocal_WC_1: ruby_vminsn_type = 215;
|
||||
pub const YARVINSN_trace_putobject_INT2FIX_0_: ruby_vminsn_type = 216;
|
||||
pub const YARVINSN_trace_putobject_INT2FIX_1_: ruby_vminsn_type = 217;
|
||||
pub const VM_INSTRUCTION_SIZE: ruby_vminsn_type = 218;
|
||||
pub const YARVINSN_opt_duparray_send: ruby_vminsn_type = 64;
|
||||
pub const YARVINSN_opt_newarray_send: ruby_vminsn_type = 65;
|
||||
pub const YARVINSN_invokesuper: ruby_vminsn_type = 66;
|
||||
pub const YARVINSN_invokesuperforward: ruby_vminsn_type = 67;
|
||||
pub const YARVINSN_invokeblock: ruby_vminsn_type = 68;
|
||||
pub const YARVINSN_leave: ruby_vminsn_type = 69;
|
||||
pub const YARVINSN_throw: ruby_vminsn_type = 70;
|
||||
pub const YARVINSN_jump: ruby_vminsn_type = 71;
|
||||
pub const YARVINSN_branchif: ruby_vminsn_type = 72;
|
||||
pub const YARVINSN_branchunless: ruby_vminsn_type = 73;
|
||||
pub const YARVINSN_branchnil: ruby_vminsn_type = 74;
|
||||
pub const YARVINSN_once: ruby_vminsn_type = 75;
|
||||
pub const YARVINSN_opt_case_dispatch: ruby_vminsn_type = 76;
|
||||
pub const YARVINSN_opt_plus: ruby_vminsn_type = 77;
|
||||
pub const YARVINSN_opt_minus: ruby_vminsn_type = 78;
|
||||
pub const YARVINSN_opt_mult: ruby_vminsn_type = 79;
|
||||
pub const YARVINSN_opt_div: ruby_vminsn_type = 80;
|
||||
pub const YARVINSN_opt_mod: ruby_vminsn_type = 81;
|
||||
pub const YARVINSN_opt_eq: ruby_vminsn_type = 82;
|
||||
pub const YARVINSN_opt_neq: ruby_vminsn_type = 83;
|
||||
pub const YARVINSN_opt_lt: ruby_vminsn_type = 84;
|
||||
pub const YARVINSN_opt_le: ruby_vminsn_type = 85;
|
||||
pub const YARVINSN_opt_gt: ruby_vminsn_type = 86;
|
||||
pub const YARVINSN_opt_ge: ruby_vminsn_type = 87;
|
||||
pub const YARVINSN_opt_ltlt: ruby_vminsn_type = 88;
|
||||
pub const YARVINSN_opt_and: ruby_vminsn_type = 89;
|
||||
pub const YARVINSN_opt_or: ruby_vminsn_type = 90;
|
||||
pub const YARVINSN_opt_aref: ruby_vminsn_type = 91;
|
||||
pub const YARVINSN_opt_aset: ruby_vminsn_type = 92;
|
||||
pub const YARVINSN_opt_aset_with: ruby_vminsn_type = 93;
|
||||
pub const YARVINSN_opt_aref_with: ruby_vminsn_type = 94;
|
||||
pub const YARVINSN_opt_length: ruby_vminsn_type = 95;
|
||||
pub const YARVINSN_opt_size: ruby_vminsn_type = 96;
|
||||
pub const YARVINSN_opt_empty_p: ruby_vminsn_type = 97;
|
||||
pub const YARVINSN_opt_succ: ruby_vminsn_type = 98;
|
||||
pub const YARVINSN_opt_not: ruby_vminsn_type = 99;
|
||||
pub const YARVINSN_opt_regexpmatch2: ruby_vminsn_type = 100;
|
||||
pub const YARVINSN_invokebuiltin: ruby_vminsn_type = 101;
|
||||
pub const YARVINSN_opt_invokebuiltin_delegate: ruby_vminsn_type = 102;
|
||||
pub const YARVINSN_opt_invokebuiltin_delegate_leave: ruby_vminsn_type = 103;
|
||||
pub const YARVINSN_getlocal_WC_0: ruby_vminsn_type = 104;
|
||||
pub const YARVINSN_getlocal_WC_1: ruby_vminsn_type = 105;
|
||||
pub const YARVINSN_setlocal_WC_0: ruby_vminsn_type = 106;
|
||||
pub const YARVINSN_setlocal_WC_1: ruby_vminsn_type = 107;
|
||||
pub const YARVINSN_putobject_INT2FIX_0_: ruby_vminsn_type = 108;
|
||||
pub const YARVINSN_putobject_INT2FIX_1_: ruby_vminsn_type = 109;
|
||||
pub const YARVINSN_trace_nop: ruby_vminsn_type = 110;
|
||||
pub const YARVINSN_trace_getlocal: ruby_vminsn_type = 111;
|
||||
pub const YARVINSN_trace_setlocal: ruby_vminsn_type = 112;
|
||||
pub const YARVINSN_trace_getblockparam: ruby_vminsn_type = 113;
|
||||
pub const YARVINSN_trace_setblockparam: ruby_vminsn_type = 114;
|
||||
pub const YARVINSN_trace_getblockparamproxy: ruby_vminsn_type = 115;
|
||||
pub const YARVINSN_trace_getspecial: ruby_vminsn_type = 116;
|
||||
pub const YARVINSN_trace_setspecial: ruby_vminsn_type = 117;
|
||||
pub const YARVINSN_trace_getinstancevariable: ruby_vminsn_type = 118;
|
||||
pub const YARVINSN_trace_setinstancevariable: ruby_vminsn_type = 119;
|
||||
pub const YARVINSN_trace_getclassvariable: ruby_vminsn_type = 120;
|
||||
pub const YARVINSN_trace_setclassvariable: ruby_vminsn_type = 121;
|
||||
pub const YARVINSN_trace_opt_getconstant_path: ruby_vminsn_type = 122;
|
||||
pub const YARVINSN_trace_getconstant: ruby_vminsn_type = 123;
|
||||
pub const YARVINSN_trace_setconstant: ruby_vminsn_type = 124;
|
||||
pub const YARVINSN_trace_getglobal: ruby_vminsn_type = 125;
|
||||
pub const YARVINSN_trace_setglobal: ruby_vminsn_type = 126;
|
||||
pub const YARVINSN_trace_putnil: ruby_vminsn_type = 127;
|
||||
pub const YARVINSN_trace_putself: ruby_vminsn_type = 128;
|
||||
pub const YARVINSN_trace_putobject: ruby_vminsn_type = 129;
|
||||
pub const YARVINSN_trace_putspecialobject: ruby_vminsn_type = 130;
|
||||
pub const YARVINSN_trace_putstring: ruby_vminsn_type = 131;
|
||||
pub const YARVINSN_trace_putchilledstring: ruby_vminsn_type = 132;
|
||||
pub const YARVINSN_trace_concatstrings: ruby_vminsn_type = 133;
|
||||
pub const YARVINSN_trace_anytostring: ruby_vminsn_type = 134;
|
||||
pub const YARVINSN_trace_toregexp: ruby_vminsn_type = 135;
|
||||
pub const YARVINSN_trace_intern: ruby_vminsn_type = 136;
|
||||
pub const YARVINSN_trace_newarray: ruby_vminsn_type = 137;
|
||||
pub const YARVINSN_trace_pushtoarraykwsplat: ruby_vminsn_type = 138;
|
||||
pub const YARVINSN_trace_duparray: ruby_vminsn_type = 139;
|
||||
pub const YARVINSN_trace_duphash: ruby_vminsn_type = 140;
|
||||
pub const YARVINSN_trace_expandarray: ruby_vminsn_type = 141;
|
||||
pub const YARVINSN_trace_concatarray: ruby_vminsn_type = 142;
|
||||
pub const YARVINSN_trace_concattoarray: ruby_vminsn_type = 143;
|
||||
pub const YARVINSN_trace_pushtoarray: ruby_vminsn_type = 144;
|
||||
pub const YARVINSN_trace_splatarray: ruby_vminsn_type = 145;
|
||||
pub const YARVINSN_trace_splatkw: ruby_vminsn_type = 146;
|
||||
pub const YARVINSN_trace_newhash: ruby_vminsn_type = 147;
|
||||
pub const YARVINSN_trace_newrange: ruby_vminsn_type = 148;
|
||||
pub const YARVINSN_trace_pop: ruby_vminsn_type = 149;
|
||||
pub const YARVINSN_trace_dup: ruby_vminsn_type = 150;
|
||||
pub const YARVINSN_trace_dupn: ruby_vminsn_type = 151;
|
||||
pub const YARVINSN_trace_swap: ruby_vminsn_type = 152;
|
||||
pub const YARVINSN_trace_opt_reverse: ruby_vminsn_type = 153;
|
||||
pub const YARVINSN_trace_topn: ruby_vminsn_type = 154;
|
||||
pub const YARVINSN_trace_setn: ruby_vminsn_type = 155;
|
||||
pub const YARVINSN_trace_adjuststack: ruby_vminsn_type = 156;
|
||||
pub const YARVINSN_trace_defined: ruby_vminsn_type = 157;
|
||||
pub const YARVINSN_trace_definedivar: ruby_vminsn_type = 158;
|
||||
pub const YARVINSN_trace_checkmatch: ruby_vminsn_type = 159;
|
||||
pub const YARVINSN_trace_checkkeyword: ruby_vminsn_type = 160;
|
||||
pub const YARVINSN_trace_checktype: ruby_vminsn_type = 161;
|
||||
pub const YARVINSN_trace_defineclass: ruby_vminsn_type = 162;
|
||||
pub const YARVINSN_trace_definemethod: ruby_vminsn_type = 163;
|
||||
pub const YARVINSN_trace_definesmethod: ruby_vminsn_type = 164;
|
||||
pub const YARVINSN_trace_send: ruby_vminsn_type = 165;
|
||||
pub const YARVINSN_trace_sendforward: ruby_vminsn_type = 166;
|
||||
pub const YARVINSN_trace_opt_send_without_block: ruby_vminsn_type = 167;
|
||||
pub const YARVINSN_trace_objtostring: ruby_vminsn_type = 168;
|
||||
pub const YARVINSN_trace_opt_ary_freeze: ruby_vminsn_type = 169;
|
||||
pub const YARVINSN_trace_opt_hash_freeze: ruby_vminsn_type = 170;
|
||||
pub const YARVINSN_trace_opt_str_freeze: ruby_vminsn_type = 171;
|
||||
pub const YARVINSN_trace_opt_nil_p: ruby_vminsn_type = 172;
|
||||
pub const YARVINSN_trace_opt_str_uminus: ruby_vminsn_type = 173;
|
||||
pub const YARVINSN_trace_opt_duparray_send: ruby_vminsn_type = 174;
|
||||
pub const YARVINSN_trace_opt_newarray_send: ruby_vminsn_type = 175;
|
||||
pub const YARVINSN_trace_invokesuper: ruby_vminsn_type = 176;
|
||||
pub const YARVINSN_trace_invokesuperforward: ruby_vminsn_type = 177;
|
||||
pub const YARVINSN_trace_invokeblock: ruby_vminsn_type = 178;
|
||||
pub const YARVINSN_trace_leave: ruby_vminsn_type = 179;
|
||||
pub const YARVINSN_trace_throw: ruby_vminsn_type = 180;
|
||||
pub const YARVINSN_trace_jump: ruby_vminsn_type = 181;
|
||||
pub const YARVINSN_trace_branchif: ruby_vminsn_type = 182;
|
||||
pub const YARVINSN_trace_branchunless: ruby_vminsn_type = 183;
|
||||
pub const YARVINSN_trace_branchnil: ruby_vminsn_type = 184;
|
||||
pub const YARVINSN_trace_once: ruby_vminsn_type = 185;
|
||||
pub const YARVINSN_trace_opt_case_dispatch: ruby_vminsn_type = 186;
|
||||
pub const YARVINSN_trace_opt_plus: ruby_vminsn_type = 187;
|
||||
pub const YARVINSN_trace_opt_minus: ruby_vminsn_type = 188;
|
||||
pub const YARVINSN_trace_opt_mult: ruby_vminsn_type = 189;
|
||||
pub const YARVINSN_trace_opt_div: ruby_vminsn_type = 190;
|
||||
pub const YARVINSN_trace_opt_mod: ruby_vminsn_type = 191;
|
||||
pub const YARVINSN_trace_opt_eq: ruby_vminsn_type = 192;
|
||||
pub const YARVINSN_trace_opt_neq: ruby_vminsn_type = 193;
|
||||
pub const YARVINSN_trace_opt_lt: ruby_vminsn_type = 194;
|
||||
pub const YARVINSN_trace_opt_le: ruby_vminsn_type = 195;
|
||||
pub const YARVINSN_trace_opt_gt: ruby_vminsn_type = 196;
|
||||
pub const YARVINSN_trace_opt_ge: ruby_vminsn_type = 197;
|
||||
pub const YARVINSN_trace_opt_ltlt: ruby_vminsn_type = 198;
|
||||
pub const YARVINSN_trace_opt_and: ruby_vminsn_type = 199;
|
||||
pub const YARVINSN_trace_opt_or: ruby_vminsn_type = 200;
|
||||
pub const YARVINSN_trace_opt_aref: ruby_vminsn_type = 201;
|
||||
pub const YARVINSN_trace_opt_aset: ruby_vminsn_type = 202;
|
||||
pub const YARVINSN_trace_opt_aset_with: ruby_vminsn_type = 203;
|
||||
pub const YARVINSN_trace_opt_aref_with: ruby_vminsn_type = 204;
|
||||
pub const YARVINSN_trace_opt_length: ruby_vminsn_type = 205;
|
||||
pub const YARVINSN_trace_opt_size: ruby_vminsn_type = 206;
|
||||
pub const YARVINSN_trace_opt_empty_p: ruby_vminsn_type = 207;
|
||||
pub const YARVINSN_trace_opt_succ: ruby_vminsn_type = 208;
|
||||
pub const YARVINSN_trace_opt_not: ruby_vminsn_type = 209;
|
||||
pub const YARVINSN_trace_opt_regexpmatch2: ruby_vminsn_type = 210;
|
||||
pub const YARVINSN_trace_invokebuiltin: ruby_vminsn_type = 211;
|
||||
pub const YARVINSN_trace_opt_invokebuiltin_delegate: ruby_vminsn_type = 212;
|
||||
pub const YARVINSN_trace_opt_invokebuiltin_delegate_leave: ruby_vminsn_type = 213;
|
||||
pub const YARVINSN_trace_getlocal_WC_0: ruby_vminsn_type = 214;
|
||||
pub const YARVINSN_trace_getlocal_WC_1: ruby_vminsn_type = 215;
|
||||
pub const YARVINSN_trace_setlocal_WC_0: ruby_vminsn_type = 216;
|
||||
pub const YARVINSN_trace_setlocal_WC_1: ruby_vminsn_type = 217;
|
||||
pub const YARVINSN_trace_putobject_INT2FIX_0_: ruby_vminsn_type = 218;
|
||||
pub const YARVINSN_trace_putobject_INT2FIX_1_: ruby_vminsn_type = 219;
|
||||
pub const VM_INSTRUCTION_SIZE: ruby_vminsn_type = 220;
|
||||
pub type ruby_vminsn_type = u32;
|
||||
pub type rb_iseq_callback = ::std::option::Option<
|
||||
unsafe extern "C" fn(arg1: *const rb_iseq_t, arg2: *mut ::std::os::raw::c_void),
|
||||
|
Loading…
x
Reference in New Issue
Block a user