зеркало из https://github.com/github/ruby.git
Port gen_checktype to the new IR assembler backend (https://github.com/Shopify/ruby/pull/343)
This commit is contained in:
Родитель
4b1ab009c4
Коммит
6ab71a8598
|
@ -3066,3 +3066,11 @@ assert_equal '10', %q{
|
||||||
|
|
||||||
a.length
|
a.length
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# checktype
|
||||||
|
assert_equal 'false', %q{
|
||||||
|
def function()
|
||||||
|
[1, 2] in [Integer, String]
|
||||||
|
end
|
||||||
|
function()
|
||||||
|
}
|
||||||
|
|
|
@ -2217,11 +2217,10 @@ fn gen_defined(
|
||||||
KeepCompiling
|
KeepCompiling
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
fn gen_checktype(
|
fn gen_checktype(
|
||||||
jit: &mut JITState,
|
jit: &mut JITState,
|
||||||
ctx: &mut Context,
|
ctx: &mut Context,
|
||||||
cb: &mut CodeBlock,
|
asm: &mut Assembler,
|
||||||
_ocb: &mut OutlinedCb,
|
_ocb: &mut OutlinedCb,
|
||||||
) -> CodegenStatus {
|
) -> CodegenStatus {
|
||||||
let type_val = jit_get_arg(jit, 0).as_u32();
|
let type_val = jit_get_arg(jit, 0).as_u32();
|
||||||
|
@ -2235,42 +2234,37 @@ fn gen_checktype(
|
||||||
match val_type.known_value_type() {
|
match val_type.known_value_type() {
|
||||||
Some(value_type) => {
|
Some(value_type) => {
|
||||||
if value_type == type_val {
|
if value_type == type_val {
|
||||||
jit_putobject(jit, ctx, cb, Qtrue);
|
jit_putobject(jit, ctx, asm, Qtrue);
|
||||||
return KeepCompiling;
|
return KeepCompiling;
|
||||||
} else {
|
} else {
|
||||||
jit_putobject(jit, ctx, cb, Qfalse);
|
jit_putobject(jit, ctx, asm, Qfalse);
|
||||||
return KeepCompiling;
|
return KeepCompiling;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
|
||||||
mov(cb, REG0, val);
|
let ret = asm.new_label("ret");
|
||||||
mov(cb, REG1, uimm_opnd(Qfalse.as_u64()));
|
|
||||||
|
|
||||||
let ret = cb.new_label("ret".to_string());
|
|
||||||
|
|
||||||
if !val_type.is_heap() {
|
if !val_type.is_heap() {
|
||||||
// if (SPECIAL_CONST_P(val)) {
|
// if (SPECIAL_CONST_P(val)) {
|
||||||
// Return Qfalse via REG1 if not on heap
|
// Return Qfalse via REG1 if not on heap
|
||||||
test(cb, REG0, uimm_opnd(RUBY_IMMEDIATE_MASK as u64));
|
asm.test(val, Opnd::UImm(RUBY_IMMEDIATE_MASK as u64));
|
||||||
jnz_label(cb, ret);
|
asm.jnz(ret);
|
||||||
cmp(cb, REG0, uimm_opnd(Qnil.as_u64()));
|
asm.cmp(val, Opnd::UImm(Qnil.into()));
|
||||||
jbe_label(cb, ret);
|
asm.jbe(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check type on object
|
// Check type on object
|
||||||
mov(cb, REG0, mem_opnd(64, REG0, RUBY_OFFSET_RBASIC_FLAGS));
|
let object_type = asm.and(
|
||||||
and(cb, REG0, uimm_opnd(RUBY_T_MASK as u64));
|
Opnd::mem(64, val, RUBY_OFFSET_RBASIC_FLAGS),
|
||||||
cmp(cb, REG0, uimm_opnd(type_val as u64));
|
Opnd::UImm(RUBY_T_MASK.into()));
|
||||||
mov(cb, REG0, uimm_opnd(Qtrue.as_u64()));
|
asm.cmp(object_type, Opnd::UImm(type_val.into()));
|
||||||
// REG1 contains Qfalse from above
|
let ret_opnd = asm.csel_e(Opnd::UImm(Qfalse.into()), Opnd::UImm(Qtrue.into()));
|
||||||
cmove(cb, REG1, REG0);
|
|
||||||
|
|
||||||
cb.write_label(ret);
|
asm.write_label(ret);
|
||||||
let stack_ret = ctx.stack_push(Type::UnknownImm);
|
let stack_ret = ctx.stack_push(Type::UnknownImm);
|
||||||
mov(cb, stack_ret, REG1);
|
asm.mov(stack_ret, ret_opnd);
|
||||||
cb.link_labels();
|
|
||||||
|
|
||||||
KeepCompiling
|
KeepCompiling
|
||||||
} else {
|
} else {
|
||||||
|
@ -2278,6 +2272,7 @@ fn gen_checktype(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
fn gen_concatstrings(
|
fn gen_concatstrings(
|
||||||
jit: &mut JITState,
|
jit: &mut JITState,
|
||||||
ctx: &mut Context,
|
ctx: &mut Context,
|
||||||
|
@ -5979,7 +5974,7 @@ fn get_gen_fn(opcode: VALUE) -> Option<InsnGenFn> {
|
||||||
YARVINSN_duphash => Some(gen_duphash),
|
YARVINSN_duphash => Some(gen_duphash),
|
||||||
YARVINSN_newarray => Some(gen_newarray),
|
YARVINSN_newarray => Some(gen_newarray),
|
||||||
YARVINSN_duparray => Some(gen_duparray),
|
YARVINSN_duparray => Some(gen_duparray),
|
||||||
//YARVINSN_checktype => Some(gen_checktype),
|
YARVINSN_checktype => Some(gen_checktype),
|
||||||
YARVINSN_opt_lt => Some(gen_opt_lt),
|
YARVINSN_opt_lt => Some(gen_opt_lt),
|
||||||
/*
|
/*
|
||||||
YARVINSN_opt_le => Some(gen_opt_le),
|
YARVINSN_opt_le => Some(gen_opt_le),
|
||||||
|
|
Загрузка…
Ссылка в новой задаче