Skip to content

Instantly share code, notes, and snippets.

@rwy7
Created April 25, 2019 18:57
Show Gist options
  • Save rwy7/1ed1bd35e0392af8e5de2479cb621230 to your computer and use it in GitHub Desktop.
Save rwy7/1ed1bd35e0392af8e5de2479cb621230 to your computer and use it in GitHub Desktop.
static std::int64_t stack[8];
static std::int64_t* sp = stack;
class BadStackMethodBuilder : public OMR::JitBuilder::MethodBuilder {
public:
BadStackMethodBuilder(OMR::JitBuilder::TypeDictionary* t)
: OMR::JitBuilder::MethodBuilder(t) {
// SetReturnType(t->NoType);
}
virtual bool buildIL() override {
/*
push 0
push 0
if (pop) {
push 1;
} else {
push 2;
}
*/
OMR::JitBuilder::TypeDictionary* t = typeDictionary();
DefineFunction("printf", "no-file", "0", (void*)&printf, NoType, 0);
// Create State
{
auto reg = new OMR::JitBuilder::VirtualMachineRegister(
this, "sp", t->PointerTo(t->pInt64), 8, ConstAddress(&sp)
);
auto stack = new OMR::JitBuilder::VirtualMachineOperandStack(
this, 2, t->Int64, reg, true, 0
);
setVMState(stack);
}
// Create constants
OMR::JitBuilder::IlValue* k0 = ConstInt64(0);
OMR::JitBuilder::IlValue* k1 = ConstInt64(1);
OMR::JitBuilder::IlValue* k2 = ConstInt64(2);
// Create builders
OMR::JitBuilder::BytecodeBuilder* b0 = OrphanBytecodeBuilder(0, (char*)"PushZeroTwice");
OMR::JitBuilder::BytecodeBuilder* b1 = OrphanBytecodeBuilder(1, (char*)"ClearStackThenPushOneAndTwo");
OMR::JitBuilder::BytecodeBuilder* b2 = OrphanBytecodeBuilder(2, (char*)"PrintStack");
AppendBuilder(b0);
// PushZeroTwice
{
OMR::JitBuilder::VirtualMachineOperandStack* stack = (OMR::JitBuilder::VirtualMachineOperandStack*)b0->vmState();
stack->Push(b0, k0);
stack->Push(b0, k0);
b0->IfCmpEqualZero(b1, b0->ConstInt64(0)); // always taken
b0->AddFallThroughBuilder(b2);
}
// ClearStackThenPushOneAndTwo
{
OMR::JitBuilder::VirtualMachineOperandStack* stack = (OMR::JitBuilder::VirtualMachineOperandStack*)b1->vmState();
stack->Pop(b1);
stack->Pop(b1);
stack->Push(b1, k1);
stack->Push(b1, k2);
b1->AddFallThroughBuilder(b2);
}
// PrintStack
{
OMR::JitBuilder::VirtualMachineOperandStack* stack = (OMR::JitBuilder::VirtualMachineOperandStack*)b2->vmState();
b2->Call("printf", 3,
b2->Const((void*)"stack: a=%llu b=%llu\n"),
stack->Pop(b2),
stack->Pop(b2)
);
// error: we'll see "1" printed twice.
b2->Return();
}
return true;
}
};
TEST(MyBadStackTest, OverwriteTwoValuesWithOne) {
BadStackMethodBuilder mb(new OMR::JitBuilder::TypeDictionary());
void* fn = nullptr;
compileMethodBuilder(&mb, &fn);
reinterpret_cast<void(*)()>(fn)();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment