[wasm] Fix throwing and catching exceptions
This reimplements functionality that was present before the decoder refactoring. It's implemented a bit differently though by generating the code for re-throwing an uncaught exception earlier (when generating code for the catch). R=titzer@chromium.org, kschimpf@chromium.org Bug: v8:6600 Change-Id: Ie2f11837851c0602ab31506fa63475fc2d0b5047 Reviewed-on: https://chromium-review.googlesource.com/641550 Commit-Queue: Brad Nelson <bradnelson@chromium.org> Reviewed-by: Brad Nelson <bradnelson@chromium.org> Cr-Commit-Position: refs/heads/master@{#47687}
This commit is contained in:
parent
693e8ac59f
commit
9ee7e4ec98
@ -1243,7 +1243,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
|
||||
break;
|
||||
}
|
||||
|
||||
if (c->is_try_catch()) {
|
||||
if (CHECK_ERROR(c->is_try_catch())) {
|
||||
OPCODE_ERROR(opcode, "multiple catch blocks not implemented");
|
||||
break;
|
||||
}
|
||||
|
@ -176,18 +176,10 @@ class WasmGraphBuildingInterface
|
||||
SetEnv(c->interface_data.end_env);
|
||||
}
|
||||
|
||||
void PopControl(Decoder* decoder, const Control& block) {
|
||||
void PopControl(Decoder* decoder, Control& block) {
|
||||
if (block.is_onearmed_if()) {
|
||||
Goto(decoder, block.interface_data.false_env,
|
||||
block.interface_data.end_env);
|
||||
} else if (block.is_try_catch()) {
|
||||
SsaEnv* fallthru_ssa_env = ssa_env_;
|
||||
DCHECK_NOT_NULL(block.interface_data.try_info->catch_env);
|
||||
SetEnv(block.interface_data.try_info->catch_env);
|
||||
BUILD(Rethrow);
|
||||
// TODO(clemensh): Make this work again.
|
||||
// FallThruTo(decoder, &block);
|
||||
SetEnv(fallthru_ssa_env);
|
||||
}
|
||||
}
|
||||
|
||||
@ -400,8 +392,10 @@ class WasmGraphBuildingInterface
|
||||
|
||||
void Catch(Decoder* decoder, const ExceptionIndexOperand<true>& operand,
|
||||
Control* block) {
|
||||
DCHECK_NOT_NULL(block->interface_data.try_info);
|
||||
DCHECK(block->is_try_catch());
|
||||
current_catch_ = block->interface_data.previous_catch;
|
||||
SsaEnv* catch_env = block->interface_data.try_info->catch_env;
|
||||
SetEnv(catch_env);
|
||||
|
||||
// Get the exception and see if wanted exception.
|
||||
TFNode* exception_as_i32 = BUILD(
|
||||
@ -412,12 +406,18 @@ class WasmGraphBuildingInterface
|
||||
TFNode* if_true = nullptr;
|
||||
TFNode* if_false = nullptr;
|
||||
BUILD(BranchNoHint, compare_i32, &if_true, &if_false);
|
||||
SsaEnv* end_env = ssa_env_;
|
||||
SsaEnv* false_env = Split(decoder, end_env);
|
||||
SsaEnv* false_env = Split(decoder, catch_env);
|
||||
false_env->control = if_false;
|
||||
SsaEnv* true_env = Steal(decoder->zone(), ssa_env_);
|
||||
SsaEnv* true_env = Steal(decoder->zone(), catch_env);
|
||||
true_env->control = if_true;
|
||||
block->interface_data.try_info->catch_env = false_env;
|
||||
|
||||
// Generate code to re-throw the exception.
|
||||
DCHECK_NOT_NULL(block->interface_data.try_info->catch_env);
|
||||
SetEnv(false_env);
|
||||
BUILD(Rethrow);
|
||||
FallThruTo(decoder, block);
|
||||
|
||||
SetEnv(true_env);
|
||||
// TODO(kschimpf): Add code to pop caught exception from isolate.
|
||||
}
|
||||
|
@ -34,8 +34,6 @@ assertFalse(test_throw === 0);
|
||||
assertEquals("object", typeof test_throw.exports);
|
||||
assertEquals("function", typeof test_throw.exports.throw_if_param_not_zero);
|
||||
|
||||
/* TODO(kschimpf) Convert these tests to work for the proposed exceptions.
|
||||
|
||||
// Test expected behavior of throws
|
||||
assertEquals(1, test_throw.exports.throw_if_param_not_zero(0));
|
||||
assertWasmThrows([], function() { test_throw.exports.throw_if_param_not_zero(10) });
|
||||
@ -74,6 +72,8 @@ assertEquals("function", typeof test_catch.exports.simple_throw_catch_to_0_1);
|
||||
assertEquals(0, test_catch.exports.simple_throw_catch_to_0_1(0));
|
||||
assertEquals(1, test_catch.exports.simple_throw_catch_to_0_1(1));
|
||||
|
||||
/* TODO(kschimpf) Convert these tests to work for the proposed exceptions.
|
||||
|
||||
// The following methods do not attempt to catch the exception they raise.
|
||||
var test_throw = (function () {
|
||||
var builder = new WasmModuleBuilder();
|
||||
|
Loading…
Reference in New Issue
Block a user