Skip to content

Commit fb22348

Browse files
authored
Merge pull request ruby#122 from jhawthorn/not_not_bug
Demonstration of bug: ctx_set_opnd_type in jit_rb_obj_not corrupts types
2 parents cdc3115 + 3b63695 commit fb22348

File tree

1 file changed

+24
-3
lines changed

1 file changed

+24
-3
lines changed

yjit_codegen.c

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2257,7 +2257,10 @@ jit_guard_known_klass(jitstate_t *jit, ctx_t *ctx, VALUE known_klass, insn_opnd_
22572257
val_type_t val_type = ctx_get_opnd_type(ctx, insn_opnd);
22582258

22592259
if (known_klass == rb_cNilClass) {
2260+
RUBY_ASSERT(!val_type.is_heap);
22602261
if (val_type.type != ETYPE_NIL) {
2262+
RUBY_ASSERT(val_type.type == ETYPE_UNKNOWN);
2263+
22612264
ADD_COMMENT(cb, "guard object is nil");
22622265
cmp(cb, REG0, imm_opnd(Qnil));
22632266
jit_chain_guard(JCC_JNE, jit, ctx, max_chain_depth, side_exit);
@@ -2266,7 +2269,10 @@ jit_guard_known_klass(jitstate_t *jit, ctx_t *ctx, VALUE known_klass, insn_opnd_
22662269
}
22672270
}
22682271
else if (known_klass == rb_cTrueClass) {
2272+
RUBY_ASSERT(!val_type.is_heap);
22692273
if (val_type.type != ETYPE_TRUE) {
2274+
RUBY_ASSERT(val_type.type == ETYPE_UNKNOWN);
2275+
22702276
ADD_COMMENT(cb, "guard object is true");
22712277
cmp(cb, REG0, imm_opnd(Qtrue));
22722278
jit_chain_guard(JCC_JNE, jit, ctx, max_chain_depth, side_exit);
@@ -2275,7 +2281,10 @@ jit_guard_known_klass(jitstate_t *jit, ctx_t *ctx, VALUE known_klass, insn_opnd_
22752281
}
22762282
}
22772283
else if (known_klass == rb_cFalseClass) {
2284+
RUBY_ASSERT(!val_type.is_heap);
22782285
if (val_type.type != ETYPE_FALSE) {
2286+
RUBY_ASSERT(val_type.type == ETYPE_UNKNOWN);
2287+
22792288
ADD_COMMENT(cb, "guard object is false");
22802289
STATIC_ASSERT(qfalse_is_zero, Qfalse == 0);
22812290
test(cb, REG0, REG0);
@@ -2285,19 +2294,25 @@ jit_guard_known_klass(jitstate_t *jit, ctx_t *ctx, VALUE known_klass, insn_opnd_
22852294
}
22862295
}
22872296
else if (known_klass == rb_cInteger && FIXNUM_P(sample_instance)) {
2297+
RUBY_ASSERT(!val_type.is_heap);
22882298
// We will guard fixnum and bignum as though they were separate classes
22892299
// BIGNUM can be handled by the general else case below
22902300
if (val_type.type != ETYPE_FIXNUM || !val_type.is_imm) {
2301+
RUBY_ASSERT(val_type.type == ETYPE_UNKNOWN);
2302+
22912303
ADD_COMMENT(cb, "guard object is fixnum");
22922304
test(cb, REG0, imm_opnd(RUBY_FIXNUM_FLAG));
22932305
jit_chain_guard(JCC_JZ, jit, ctx, max_chain_depth, side_exit);
22942306
ctx_set_opnd_type(ctx, insn_opnd, TYPE_FIXNUM);
22952307
}
22962308
}
22972309
else if (known_klass == rb_cSymbol && STATIC_SYM_P(sample_instance)) {
2310+
RUBY_ASSERT(!val_type.is_heap);
22982311
// We will guard STATIC vs DYNAMIC as though they were separate classes
22992312
// DYNAMIC symbols can be handled by the general else case below
23002313
if (val_type.type != ETYPE_SYMBOL || !val_type.is_imm) {
2314+
RUBY_ASSERT(val_type.type == ETYPE_UNKNOWN);
2315+
23012316
ADD_COMMENT(cb, "guard object is static symbol");
23022317
STATIC_ASSERT(special_shift_is_8, RUBY_SPECIAL_SHIFT == 8);
23032318
cmp(cb, REG0_8, imm_opnd(RUBY_SYMBOL_FLAG));
@@ -2306,7 +2321,10 @@ jit_guard_known_klass(jitstate_t *jit, ctx_t *ctx, VALUE known_klass, insn_opnd_
23062321
}
23072322
}
23082323
else if (known_klass == rb_cFloat && FLONUM_P(sample_instance)) {
2324+
RUBY_ASSERT(!val_type.is_heap);
23092325
if (val_type.type != ETYPE_FLONUM || !val_type.is_imm) {
2326+
RUBY_ASSERT(val_type.type == ETYPE_UNKNOWN);
2327+
23102328
// We will guard flonum vs heap float as though they were separate classes
23112329
ADD_COMMENT(cb, "guard object is flonum");
23122330
mov(cb, REG1, REG0);
@@ -2334,6 +2352,8 @@ jit_guard_known_klass(jitstate_t *jit, ctx_t *ctx, VALUE known_klass, insn_opnd_
23342352
jit_chain_guard(JCC_JNE, jit, ctx, max_chain_depth, side_exit);
23352353
}
23362354
else {
2355+
RUBY_ASSERT(!val_type.is_imm);
2356+
23372357
// Check that the receiver is a heap object
23382358
// Note: if we get here, the class doesn't have immediate instances.
23392359
if (!val_type.is_heap) {
@@ -2387,18 +2407,19 @@ static bool
23872407
jit_rb_obj_not(jitstate_t *jit, ctx_t *ctx, const struct rb_callinfo *ci, const rb_callable_method_entry_t *cme, rb_iseq_t *block, const int32_t argc)
23882408
{
23892409
const val_type_t recv_opnd = ctx_get_opnd_type(ctx, OPND_STACK(0));
2390-
x86opnd_t out_opnd = ctx_stack_opnd(ctx, 0);
23912410

23922411
if (recv_opnd.type == ETYPE_NIL || recv_opnd.type == ETYPE_FALSE) {
23932412
ADD_COMMENT(cb, "rb_obj_not(nil_or_false)");
2413+
ctx_stack_pop(ctx, 1);
2414+
x86opnd_t out_opnd = ctx_stack_push(ctx, TYPE_TRUE);
23942415
mov(cb, out_opnd, imm_opnd(Qtrue));
2395-
ctx_set_opnd_type(ctx, OPND_STACK(0), TYPE_TRUE);
23962416
}
23972417
else if (recv_opnd.is_heap || recv_opnd.type != ETYPE_UNKNOWN) {
23982418
// Note: recv_opnd.type != ETYPE_NIL && recv_opnd.type != ETYPE_FALSE.
23992419
ADD_COMMENT(cb, "rb_obj_not(truthy)");
2420+
ctx_stack_pop(ctx, 1);
2421+
x86opnd_t out_opnd = ctx_stack_push(ctx, TYPE_FALSE);
24002422
mov(cb, out_opnd, imm_opnd(Qfalse));
2401-
ctx_set_opnd_type(ctx, OPND_STACK(0), TYPE_FALSE);
24022423
}
24032424
else {
24042425
// jit_guard_known_klass() already ran on the receiver which should

0 commit comments

Comments
 (0)