Skip to content

Commit e28b302

Browse files
authored
Port OP_CHECKTYPE (ruby#160)
1 parent e531c50 commit e28b302

File tree

3 files changed

+33
-32
lines changed

3 files changed

+33
-32
lines changed

yjit/src/codegen.rs

Lines changed: 27 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2229,67 +2229,67 @@ fn gen_defined(jit: &mut JITState, ctx: &mut Context, cb: &mut CodeBlock, ocb: &
22292229
22302230
KeepCompiling
22312231
}
2232+
*/
22322233

22332234
fn gen_checktype(jit: &mut JITState, ctx: &mut Context, cb: &mut CodeBlock, ocb: &mut OutlinedCb) -> CodegenStatus
22342235
{
2235-
enum ruby_value_type type_val = (enum ruby_value_type)jit_get_arg(jit, 0);
2236+
let type_val = jit_get_arg(jit, 0).as_usize();
2237+
22362238
// Only three types are emitted by compile.c
2237-
if (type_val == T_STRING || type_val == T_ARRAY || type_val == T_HASH) {
2238-
val_type_t val_type = ctx.get_opnd_type(StackOpnd(0));
2239+
if type_val == RUBY_T_STRING || type_val == RUBY_T_ARRAY || type_val == RUBY_T_HASH {
2240+
let val_type = ctx.get_opnd_type(StackOpnd(0));
22392241
let val = ctx.stack_pop(1);
22402242

2241-
x86opnd_t stack_ret;
2242-
22432243
// Check if we know from type information
2244-
if ((type_val == T_STRING && val_type.type == ETYPE_STRING) ||
2245-
(type_val == T_ARRAY && val_type.type == ETYPE_ARRAY) ||
2246-
(type_val == T_HASH && val_type.type == ETYPE_HASH)) {
2244+
if (type_val == RUBY_T_STRING && val_type == Type::String) ||
2245+
(type_val == RUBY_T_ARRAY && val_type == Type::Array) ||
2246+
(type_val == RUBY_T_HASH && val_type == Type::Hash) {
22472247
// guaranteed type match
2248-
stack_ret = ctx.stack_push(Type::True);
2249-
mov(cb, stack_ret, imm_opnd(Qtrue));
2248+
let stack_ret = ctx.stack_push(Type::True);
2249+
mov(cb, stack_ret, uimm_opnd(Qtrue.as_u64()));
22502250
return KeepCompiling;
22512251
}
2252-
else if (val_type.is_imm || val_type.type != ETYPE_UNKNOWN) {
2252+
else if val_type.is_imm() || val_type != Type::Unknown {
22532253
// guaranteed not to match T_STRING/T_ARRAY/T_HASH
2254-
stack_ret = ctx.stack_push(Type::False);
2255-
mov(cb, stack_ret, imm_opnd(Qfalse));
2254+
let stack_ret = ctx.stack_push(Type::False);
2255+
mov(cb, stack_ret, uimm_opnd(Qfalse.as_u64()));
22562256
return KeepCompiling;
22572257
}
22582258

22592259
mov(cb, REG0, val);
2260-
mov(cb, REG1, imm_opnd(Qfalse));
2260+
mov(cb, REG1, uimm_opnd(Qfalse.as_u64()));
22612261

2262-
uint32_t ret = cb_new_label(cb, "ret");
2262+
let ret = cb.new_label("ret".to_string());
22632263

2264-
if (!val_type.is_heap) {
2264+
if !val_type.is_heap() {
22652265
// if (SPECIAL_CONST_P(val)) {
22662266
// Return Qfalse via REG1 if not on heap
2267-
test(cb, REG0, imm_opnd(RUBY_IMMEDIATE_MASK));
2267+
test(cb, REG0, uimm_opnd(RUBY_IMMEDIATE_MASK as u64));
22682268
jnz_label(cb, ret);
2269-
cmp(cb, REG0, imm_opnd(Qnil));
2269+
cmp(cb, REG0, uimm_opnd(Qnil.as_u64()));
22702270
jbe_label(cb, ret);
22712271
}
22722272

22732273
// Check type on object
2274-
mov(cb, REG0, mem_opnd(64, REG0, offsetof(struct RBasic, flags)));
2275-
and(cb, REG0, imm_opnd(RUBY_T_MASK));
2276-
cmp(cb, REG0, imm_opnd(type_val));
2277-
mov(cb, REG0, imm_opnd(Qtrue));
2274+
mov(cb, REG0, mem_opnd(64, REG0, RUBY_OFFSET_RBASIC_FLAGS));
2275+
and(cb, REG0, uimm_opnd(RUBY_T_MASK as u64));
2276+
cmp(cb, REG0, uimm_opnd(type_val as u64));
2277+
mov(cb, REG0, uimm_opnd(Qtrue.as_u64()));
22782278
// REG1 contains Qfalse from above
22792279
cmove(cb, REG1, REG0);
22802280

2281-
cb_write_label(cb, ret);
2282-
stack_ret = ctx.stack_push(Type::UnknownImm);
2281+
cb.write_label(ret);
2282+
let stack_ret = ctx.stack_push(Type::UnknownImm);
22832283
mov(cb, stack_ret, REG1);
2284-
cb_link_labels(cb);
2284+
cb.link_labels();
22852285

22862286
KeepCompiling
22872287
}
22882288
else {
22892289
CantCompile
22902290
}
22912291
}
2292-
2292+
/*
22932293
fn gen_concatstrings(jit: &mut JITState, ctx: &mut Context, cb: &mut CodeBlock, ocb: &mut OutlinedCb) -> CodegenStatus
22942294
{
22952295
rb_num_t n = (rb_num_t)jit_get_arg(jit, 0);
@@ -5231,6 +5231,7 @@ fn get_gen_fn(opcode: VALUE) -> Option<CodeGenFn>
52315231
OP_SETLOCAL_WC_1 => Some(gen_setlocal_wc1),
52325232
OP_OPT_PLUS => Some(gen_opt_plus),
52335233
OP_NEWHASH => Some(gen_newhash),
5234+
OP_CHECKTYPE => Some(gen_checktype),
52345235

52355236
/*
52365237
yjit_reg_op(BIN(newarray), gen_newarray);
@@ -5244,12 +5245,7 @@ fn get_gen_fn(opcode: VALUE) -> Option<CodeGenFn>
52445245
yjit_reg_op(BIN(getinstancevariable), gen_getinstancevariable);
52455246
yjit_reg_op(BIN(setinstancevariable), gen_setinstancevariable);
52465247
yjit_reg_op(BIN(defined), gen_defined);
5247-
yjit_reg_op(BIN(checktype), gen_checktype);
52485248
yjit_reg_op(BIN(checkkeyword), gen_checkkeyword);
5249-
yjit_reg_op(BIN(opt_lt), gen_opt_lt);
5250-
yjit_reg_op(BIN(opt_le), gen_opt_le);
5251-
yjit_reg_op(BIN(opt_ge), gen_opt_ge);
5252-
yjit_reg_op(BIN(opt_gt), gen_opt_gt);
52535249
yjit_reg_op(BIN(opt_eq), gen_opt_eq);
52545250
yjit_reg_op(BIN(opt_neq), gen_opt_neq);
52555251
yjit_reg_op(BIN(opt_aref), gen_opt_aref);

yjit/src/core.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ impl Type {
7272
}
7373

7474
/// Check if the type is an immediate
75-
fn is_imm(&self) -> bool {
75+
pub fn is_imm(&self) -> bool {
7676
match self {
7777
Type::UnknownImm => true,
7878
Type::Nil => true,

yjit/src/cruby.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,11 @@ impl VALUE {
250250
i.try_into().unwrap()
251251
}
252252

253+
pub fn as_u64(self:VALUE) -> u64 {
254+
let VALUE(i) = self;
255+
i.try_into().unwrap()
256+
}
257+
253258
pub fn as_usize(self:VALUE) -> usize {
254259
let VALUE(us) = self;
255260
us as usize

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy