Commit a472eccd authored by Clemens Hammacher's avatar Clemens Hammacher Committed by Commit Bot

[wasm] [interpreter] Test unwinding a single activation

A DCHECK was failing if we unwind an activation which is not the
bottom-most. This CL fixes this and adds a test for this.

R=ahaas@chromium.org
BUG=v8:5822

Change-Id: Ib69116b4c45a7b2a0d6cab97ad984dfdcda55918
Reviewed-on: https://chromium-review.googlesource.com/464788Reviewed-by: 's avatarAndreas Haas <ahaas@chromium.org>
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#44332}
parent 3b716a08
......@@ -180,8 +180,9 @@ class InterpreterHandle {
return result == WasmInterpreter::Thread::HANDLED;
} break;
case WasmInterpreter::State::STOPPED:
// Then an exception happened, and the stack was unwound.
DCHECK_EQ(0, thread->GetFrameCount());
// An exception happened, and the current activation was unwound.
DCHECK_EQ(thread->ActivationFrameBase(activation_id),
thread->GetFrameCount());
return false;
// RUNNING should never occur here.
case WasmInterpreter::State::RUNNING:
......
......@@ -1150,8 +1150,10 @@ class ThreadImpl {
TRACE(" => Run()\n");
state_ = WasmInterpreter::RUNNING;
Execute(frames_.back().code, frames_.back().pc, kRunSteps);
} while (state_ == WasmInterpreter::PAUSED && !frames_.empty() &&
!PausedAtBreakpoint());
} while (state_ == WasmInterpreter::PAUSED && !PausedAtBreakpoint());
// If state_ is STOPPED, the current activation must be fully unwound.
DCHECK_IMPLIES(state_ == WasmInterpreter::STOPPED,
current_activation().fp == frames_.size());
return state_;
}
......
......@@ -329,3 +329,39 @@ function checkStack(stack, expected_lines) {
].concat(Array(9).fill(' at main (<WASM>[0]+2)')));
}
})();
(function testUnwindSingleActivation() {
// Create two activations and unwind just the top one.
var builder = new WasmModuleBuilder();
function MyError(i) {
this.i = i;
}
// We call WASM -> func 1 -> WASM -> func2.
// func2 throws, func 1 catches.
function func1() {
try {
return instance.exports.foo();
} catch (e) {
if (!(e instanceof MyError)) throw e;
return e.i + 2;
}
}
function func2() {
throw new MyError(11);
}
var imp1 = builder.addImport('mod', 'func1', kSig_i_v);
var imp2 = builder.addImport('mod', 'func2', kSig_v_v);
builder.addFunction('main', kSig_i_v)
.addBody([kExprCallFunction, imp1, kExprI32Const, 2, kExprI32Mul])
.exportFunc();
builder.addFunction('foo', kSig_v_v)
.addBody([kExprCallFunction, imp2])
.exportFunc();
var instance = builder.instantiate({mod: {func1: func1, func2: func2}});
var interpreted_before = % WasmNumInterpretedCalls(instance);
assertEquals(2 * (11 + 2), instance.exports.main());
assertEquals(interpreted_before + 2, % WasmNumInterpretedCalls(instance));
})();
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