[wasm] Support encoding s128 simd types in exceptions.

This adds support for having simd type values (i.e. s128) stored in an
exception. It is the natural combination of the simd propsal and the
exception handling proposal.

R=clemensh@chromium.org
TEST=mjsunit/wasm/exceptions-simd
BUG=v8:8390

Change-Id: I01079f82a6ba4d9152de4dae63e3db1584ca7cd8
Reviewed-on: https://chromium-review.googlesource.com/c/1363141
Commit-Queue: Michael Starzinger <mstarzinger@chromium.org>
Reviewed-by: Clemens Hammacher <clemensh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#58098}
This commit is contained in:
Michael Starzinger 2018-12-07 15:27:56 +01:00 committed by Commit Bot
parent 2713a83bbf
commit 9c2c8f15f8
5 changed files with 102 additions and 5 deletions

View File

@ -2466,7 +2466,7 @@ void InstructionSelector::VisitWord32AtomicPairCompareExchange(Node* node) {
void InstructionSelector::VisitS128Zero(Node* node) {
ArmOperandGenerator g(this);
Emit(kArmS128Zero, g.DefineAsRegister(node), g.DefineAsRegister(node));
Emit(kArmS128Zero, g.DefineAsRegister(node));
}
#define SIMD_VISIT_SPLAT(Type) \

View File

@ -3009,7 +3009,7 @@ void InstructionSelector::VisitInt64AbsWithOverflow(Node* node) {
void InstructionSelector::VisitS128Zero(Node* node) {
Arm64OperandGenerator g(this);
Emit(kArm64S128Zero, g.DefineAsRegister(node), g.DefineAsRegister(node));
Emit(kArm64S128Zero, g.DefineAsRegister(node));
}
#define SIMD_VISIT_SPLAT(Type) \

View File

@ -2628,7 +2628,7 @@ VISIT_ATOMIC_BINOP(Xor)
void InstructionSelector::VisitS128Zero(Node* node) {
X64OperandGenerator g(this);
Emit(kX64S128Zero, g.DefineAsRegister(node), g.DefineAsRegister(node));
Emit(kX64S128Zero, g.DefineAsRegister(node));
}
#define VISIT_SIMD_SPLAT(Type) \

View File

@ -2101,8 +2101,8 @@ uint32_t WasmGraphBuilder::GetExceptionEncodedSize(
encoded_size += 4;
break;
case wasm::kWasmS128:
// TODO(mstarzinger): Implement and test this case.
UNIMPLEMENTED();
DCHECK_EQ(8, ComputeEncodedElementSize(sig->GetParam(i)));
encoded_size += 8;
break;
case wasm::kWasmAnyRef:
encoded_size += 1;
@ -2151,6 +2151,20 @@ Node* WasmGraphBuilder::Throw(uint32_t exception_index,
BuildEncodeException32BitValue(values_array, &index, lower32);
break;
}
case wasm::kWasmS128:
BuildEncodeException32BitValue(
values_array, &index,
graph()->NewNode(m->I32x4ExtractLane(0), value));
BuildEncodeException32BitValue(
values_array, &index,
graph()->NewNode(m->I32x4ExtractLane(1), value));
BuildEncodeException32BitValue(
values_array, &index,
graph()->NewNode(m->I32x4ExtractLane(2), value));
BuildEncodeException32BitValue(
values_array, &index,
graph()->NewNode(m->I32x4ExtractLane(3), value));
break;
case wasm::kWasmAnyRef:
STORE_FIXED_ARRAY_SLOT_ANY(values_array, index, value);
++index;
@ -2269,6 +2283,20 @@ Node** WasmGraphBuilder::GetExceptionValues(
BuildDecodeException64BitValue(values_array, &index));
break;
}
case wasm::kWasmS128:
value = graph()->NewNode(
mcgraph()->machine()->I32x4Splat(),
BuildDecodeException32BitValue(values_array, &index));
value = graph()->NewNode(
mcgraph()->machine()->I32x4ReplaceLane(1), value,
BuildDecodeException32BitValue(values_array, &index));
value = graph()->NewNode(
mcgraph()->machine()->I32x4ReplaceLane(2), value,
BuildDecodeException32BitValue(values_array, &index));
value = graph()->NewNode(
mcgraph()->machine()->I32x4ReplaceLane(3), value,
BuildDecodeException32BitValue(values_array, &index));
break;
case wasm::kWasmAnyRef:
value = LOAD_FIXED_ARRAY_SLOT_ANY(values_array, index);
++index;

View File

@ -0,0 +1,69 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --expose-wasm --experimental-wasm-eh --experimental-wasm-simd --allow-natives-syntax
load("test/mjsunit/wasm/wasm-constants.js");
load("test/mjsunit/wasm/wasm-module-builder.js");
//TODO(mstarzinger): Duplicated in the exceptions.js file. Dedupe.
function assertWasmThrows(instance, runtime_id, values, code) {
try {
if (typeof code === 'function') {
code();
} else {
eval(code);
}
} catch (e) {
assertInstanceof(e, WebAssembly.RuntimeError);
var e_runtime_id = %GetWasmExceptionId(e, instance);
assertTrue(Number.isInteger(e_runtime_id));
assertEquals(e_runtime_id, runtime_id);
var e_values = %GetWasmExceptionValues(e);
assertArrayEquals(values, e_values);
return; // Success.
}
throw new MjsUnitAssertionError('Did not throw expected <' + runtime_id +
'> with values: ' + values);
}
(function TestThrowS128Default() {
var builder = new WasmModuleBuilder();
var kSig_v_s = makeSig([kWasmS128], []);
var except = builder.addException(kSig_v_s);
builder.addFunction("throw_simd", kSig_v_v)
.addLocals({s128_count: 1})
.addBody([
kExprGetLocal, 0,
kExprThrow, 0,
])
.exportFunc();
var instance = builder.instantiate();
assertWasmThrows(instance, except, [0, 0, 0, 0, 0, 0, 0, 0],
() => instance.exports.throw_simd());
})();
(function TestThrowCatchS128Default() {
var builder = new WasmModuleBuilder();
var kSig_v_s = makeSig([kWasmS128], []);
var except = builder.addException(kSig_v_s);
builder.addFunction("throw_catch_simd", kSig_i_v)
.addLocals({s128_count: 1})
.addBody([
kExprTry, kWasmI32,
kExprGetLocal, 0,
kExprThrow, 0,
kExprCatch, except,
// TODO(mstarzinger): Actually return some compressed form of the s128
// value here to make sure it is extracted properly from the exception.
kExprDrop,
kExprI32Const, 1,
kExprEnd,
])
.exportFunc();
var instance = builder.instantiate();
assertEquals(1, instance.exports.throw_catch_simd());
})();