Commit 860be3a2 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Fix a bug in OSR-entry guard checking

If we had to guard on the type of an object but the variable
ended up being undefined, we treated that as a guard failure
(not sure why).

Fixing that exposed another issue: if we guard that an object
is an int, we will try to unbox it if necessary.  If the variable
wasn't defined, then we will try to unbox some garbage memory.
Use the new handlePotentiallyUndefined to deal with that.
parent 33df3870
...@@ -484,14 +484,26 @@ static void emitBBs(IRGenState* irstate, const char* bb_type, GuardList& out_gua ...@@ -484,14 +484,26 @@ static void emitBBs(IRGenState* irstate, const char* bb_type, GuardList& out_gua
return type_check; return type_check;
} }
}, },
[guard_val](IREmitter& emitter) { return getConstantInt(0, g.i1); }); [guard_val](IREmitter& emitter) { return guard_val ? guard_val : getConstantInt(1, g.i1); });
if (speculated_class == int_cls) { if (speculated_class == int_cls) {
v = unbox_emitter->getBuilder()->CreateCall(g.funcs.unboxInt, from_arg); v = handlePotentiallyUndefined(
(new ConcreteCompilerVariable(BOXED_INT, from_arg, true))->decvref(*unbox_emitter); is_defined_var, INT->llvmType(), osr_unbox_block_end, *unbox_emitter, true,
[from_arg](IREmitter& emitter) {
auto v = emitter.getBuilder()->CreateCall(g.funcs.unboxInt, from_arg);
(new ConcreteCompilerVariable(BOXED_INT, from_arg, true))->decvref(emitter);
return v;
},
[](IREmitter& emitter) { return llvm::UndefValue::get(INT->llvmType()); });
} else if (speculated_class == float_cls) { } else if (speculated_class == float_cls) {
v = unbox_emitter->getBuilder()->CreateCall(g.funcs.unboxFloat, from_arg); v = handlePotentiallyUndefined(
(new ConcreteCompilerVariable(BOXED_FLOAT, from_arg, true))->decvref(*unbox_emitter); is_defined_var, FLOAT->llvmType(), osr_unbox_block_end, *unbox_emitter, true,
[from_arg](IREmitter& emitter) {
auto v = emitter.getBuilder()->CreateCall(g.funcs.unboxFloat, from_arg);
(new ConcreteCompilerVariable(BOXED_FLOAT, from_arg, true))->decvref(emitter);
return v;
},
[](IREmitter& emitter) { return llvm::UndefValue::get(FLOAT->llvmType()); });
} else { } else {
assert(phi_type == typeFromClass(speculated_class)); assert(phi_type == typeFromClass(speculated_class));
v = from_arg; v = from_arg;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment