[wasm] Fix CFI failures due to Wasm threads.
R=ahaas@chromium.org,machenbach@chromium.org BUG= Review-Url: https://codereview.chromium.org/2055803002 Cr-Commit-Position: refs/heads/master@{#36866}
This commit is contained in:
parent
280b838255
commit
26afd571c5
@ -1675,13 +1675,19 @@ class WasmInterpreterInternals : public ZoneObject {
|
||||
public:
|
||||
WasmModuleInstance* instance_;
|
||||
CodeMap codemap_;
|
||||
ZoneVector<ThreadImpl> threads_;
|
||||
ZoneVector<ThreadImpl*> threads_;
|
||||
|
||||
WasmInterpreterInternals(Zone* zone, WasmModuleInstance* instance)
|
||||
: instance_(instance),
|
||||
codemap_(instance_ ? instance_->module : nullptr, zone),
|
||||
threads_(zone) {
|
||||
threads_.push_back(ThreadImpl(zone, &codemap_, instance));
|
||||
threads_.push_back(new ThreadImpl(zone, &codemap_, instance));
|
||||
}
|
||||
|
||||
void Delete() {
|
||||
// TODO(titzer): CFI doesn't like threads in the ZoneVector.
|
||||
for (auto t : threads_) delete t;
|
||||
threads_.resize(0);
|
||||
}
|
||||
};
|
||||
|
||||
@ -1693,11 +1699,11 @@ WasmInterpreter::WasmInterpreter(WasmModuleInstance* instance,
|
||||
: zone_(allocator),
|
||||
internals_(new (&zone_) WasmInterpreterInternals(&zone_, instance)) {}
|
||||
|
||||
WasmInterpreter::~WasmInterpreter() {}
|
||||
WasmInterpreter::~WasmInterpreter() { internals_->Delete(); }
|
||||
|
||||
void WasmInterpreter::Run() { internals_->threads_[0].Run(); }
|
||||
void WasmInterpreter::Run() { internals_->threads_[0]->Run(); }
|
||||
|
||||
void WasmInterpreter::Pause() { internals_->threads_[0].Pause(); }
|
||||
void WasmInterpreter::Pause() { internals_->threads_[0]->Pause(); }
|
||||
|
||||
bool WasmInterpreter::SetBreakpoint(const WasmFunction* function, pc_t pc,
|
||||
bool enabled) {
|
||||
@ -1740,7 +1746,7 @@ int WasmInterpreter::GetThreadCount() {
|
||||
return 1; // only one thread for now.
|
||||
}
|
||||
|
||||
WasmInterpreter::Thread& WasmInterpreter::GetThread(int id) {
|
||||
WasmInterpreter::Thread* WasmInterpreter::GetThread(int id) {
|
||||
CHECK_EQ(0, id); // only one thread for now.
|
||||
return internals_->threads_[id];
|
||||
}
|
||||
|
@ -163,7 +163,7 @@ class WasmInterpreter {
|
||||
// Thread iteration and inspection.
|
||||
//==========================================================================
|
||||
int GetThreadCount();
|
||||
Thread& GetThread(int id);
|
||||
Thread* GetThread(int id);
|
||||
|
||||
//==========================================================================
|
||||
// Stack frame inspection.
|
||||
|
@ -176,7 +176,7 @@ TEST(Breakpoint_I32Add) {
|
||||
r.Build(code, code + arraysize(code));
|
||||
|
||||
WasmInterpreter* interpreter = r.interpreter();
|
||||
WasmInterpreter::Thread& thread = interpreter->GetThread(0);
|
||||
WasmInterpreter::Thread* thread = interpreter->GetThread(0);
|
||||
for (int i = 0; i < kNumBreakpoints; i++) {
|
||||
interpreter->SetBreakpoint(r.function(), kLocalsDeclSize + offsets[i],
|
||||
true);
|
||||
@ -184,23 +184,23 @@ TEST(Breakpoint_I32Add) {
|
||||
|
||||
FOR_UINT32_INPUTS(a) {
|
||||
for (uint32_t b = 11; b < 3000000000u; b += 1000000000u) {
|
||||
thread.Reset();
|
||||
thread->Reset();
|
||||
WasmVal args[] = {WasmVal(*a), WasmVal(b)};
|
||||
thread.PushFrame(r.function(), args);
|
||||
thread->PushFrame(r.function(), args);
|
||||
|
||||
for (int i = 0; i < kNumBreakpoints; i++) {
|
||||
thread.Run(); // run to next breakpoint
|
||||
thread->Run(); // run to next breakpoint
|
||||
// Check the thread stopped at the right pc.
|
||||
CHECK_EQ(WasmInterpreter::PAUSED, thread.state());
|
||||
CHECK_EQ(kLocalsDeclSize + offsets[i], thread.GetBreakpointPc());
|
||||
CHECK_EQ(WasmInterpreter::PAUSED, thread->state());
|
||||
CHECK_EQ(kLocalsDeclSize + offsets[i], thread->GetBreakpointPc());
|
||||
}
|
||||
|
||||
thread.Run(); // run to completion
|
||||
thread->Run(); // run to completion
|
||||
|
||||
// Check the thread finished with the right value.
|
||||
CHECK_EQ(WasmInterpreter::FINISHED, thread.state());
|
||||
CHECK_EQ(WasmInterpreter::FINISHED, thread->state());
|
||||
uint32_t expected = (*a) + (b);
|
||||
CHECK_EQ(expected, thread.GetReturnValue().to<uint32_t>());
|
||||
CHECK_EQ(expected, thread->GetReturnValue().to<uint32_t>());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -215,28 +215,28 @@ TEST(Step_I32Mul) {
|
||||
r.Build(code, code + arraysize(code));
|
||||
|
||||
WasmInterpreter* interpreter = r.interpreter();
|
||||
WasmInterpreter::Thread& thread = interpreter->GetThread(0);
|
||||
WasmInterpreter::Thread* thread = interpreter->GetThread(0);
|
||||
|
||||
FOR_UINT32_INPUTS(a) {
|
||||
for (uint32_t b = 33; b < 3000000000u; b += 1000000000u) {
|
||||
thread.Reset();
|
||||
thread->Reset();
|
||||
WasmVal args[] = {WasmVal(*a), WasmVal(b)};
|
||||
thread.PushFrame(r.function(), args);
|
||||
thread->PushFrame(r.function(), args);
|
||||
|
||||
// Run instructions one by one.
|
||||
for (int i = 0; i < kTraceLength - 1; i++) {
|
||||
thread.Step();
|
||||
thread->Step();
|
||||
// Check the thread stopped.
|
||||
CHECK_EQ(WasmInterpreter::PAUSED, thread.state());
|
||||
CHECK_EQ(WasmInterpreter::PAUSED, thread->state());
|
||||
}
|
||||
|
||||
// Run last instruction.
|
||||
thread.Step();
|
||||
thread->Step();
|
||||
|
||||
// Check the thread finished with the right value.
|
||||
CHECK_EQ(WasmInterpreter::FINISHED, thread.state());
|
||||
CHECK_EQ(WasmInterpreter::FINISHED, thread->state());
|
||||
uint32_t expected = (*a) * (b);
|
||||
CHECK_EQ(expected, thread.GetReturnValue().to<uint32_t>());
|
||||
CHECK_EQ(expected, thread->GetReturnValue().to<uint32_t>());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -254,7 +254,7 @@ TEST(Breakpoint_I32And_disable) {
|
||||
r.Build(code, code + arraysize(code));
|
||||
|
||||
WasmInterpreter* interpreter = r.interpreter();
|
||||
WasmInterpreter::Thread& thread = interpreter->GetThread(0);
|
||||
WasmInterpreter::Thread* thread = interpreter->GetThread(0);
|
||||
|
||||
FOR_UINT32_INPUTS(a) {
|
||||
for (uint32_t b = 11; b < 3000000000u; b += 1000000000u) {
|
||||
@ -262,23 +262,23 @@ TEST(Breakpoint_I32And_disable) {
|
||||
for (int do_break = 0; do_break < 2; do_break++) {
|
||||
interpreter->SetBreakpoint(r.function(), kLocalsDeclSize + offsets[0],
|
||||
do_break);
|
||||
thread.Reset();
|
||||
thread->Reset();
|
||||
WasmVal args[] = {WasmVal(*a), WasmVal(b)};
|
||||
thread.PushFrame(r.function(), args);
|
||||
thread->PushFrame(r.function(), args);
|
||||
|
||||
if (do_break) {
|
||||
thread.Run(); // run to next breakpoint
|
||||
thread->Run(); // run to next breakpoint
|
||||
// Check the thread stopped at the right pc.
|
||||
CHECK_EQ(WasmInterpreter::PAUSED, thread.state());
|
||||
CHECK_EQ(kLocalsDeclSize + offsets[0], thread.GetBreakpointPc());
|
||||
CHECK_EQ(WasmInterpreter::PAUSED, thread->state());
|
||||
CHECK_EQ(kLocalsDeclSize + offsets[0], thread->GetBreakpointPc());
|
||||
}
|
||||
|
||||
thread.Run(); // run to completion
|
||||
thread->Run(); // run to completion
|
||||
|
||||
// Check the thread finished with the right value.
|
||||
CHECK_EQ(WasmInterpreter::FINISHED, thread.state());
|
||||
CHECK_EQ(WasmInterpreter::FINISHED, thread->state());
|
||||
uint32_t expected = (*a) & (b);
|
||||
CHECK_EQ(expected, thread.GetReturnValue().to<uint32_t>());
|
||||
CHECK_EQ(expected, thread->GetReturnValue().to<uint32_t>());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -706,13 +706,13 @@ class WasmRunner {
|
||||
ReturnType CallInterpreter(Vector<WasmVal> args) {
|
||||
CHECK_EQ(args.length(),
|
||||
static_cast<int>(compiler_.function_->sig->parameter_count()));
|
||||
WasmInterpreter::Thread& thread = interpreter()->GetThread(0);
|
||||
thread.Reset();
|
||||
thread.PushFrame(compiler_.function_, args.start());
|
||||
if (thread.Run() == WasmInterpreter::FINISHED) {
|
||||
WasmVal val = thread.GetReturnValue();
|
||||
WasmInterpreter::Thread* thread = interpreter()->GetThread(0);
|
||||
thread->Reset();
|
||||
thread->PushFrame(compiler_.function_, args.start());
|
||||
if (thread->Run() == WasmInterpreter::FINISHED) {
|
||||
WasmVal val = thread->GetReturnValue();
|
||||
return val.to<ReturnType>();
|
||||
} else if (thread.state() == WasmInterpreter::TRAPPED) {
|
||||
} else if (thread->state() == WasmInterpreter::TRAPPED) {
|
||||
// TODO(titzer): return the correct trap code
|
||||
int64_t result = 0xdeadbeefdeadbeef;
|
||||
return static_cast<ReturnType>(result);
|
||||
|
Loading…
Reference in New Issue
Block a user