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)
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