Commit 5ee459e8 authored by Michael Starzinger's avatar Michael Starzinger Committed by Commit Bot

[wasm] Add exception attributes to binary format.

This adds an attribute field to the binary encoding of exception types
in the exceptions and import section. Currently the attribute value is
not used and expected to be zero, but it ensures the binary encoding is
extensible for future changes.

R=clemensh@chromium.org
TEST=unittests/WasmModuleVerifyTest
BUG=v8:8153

Change-Id: I6f0e10cb1b6515177d8200ebf1f4f0b122832868
Reviewed-on: https://chromium-review.googlesource.com/c/1291075
Commit-Queue: Michael Starzinger <mstarzinger@chromium.org>
Reviewed-by: 's avatarClemens Hammacher <clemensh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#56841}
parent 12e0d1f2
......@@ -550,6 +550,7 @@ class ModuleDecoderImpl : public Decoder {
}
import->index = static_cast<uint32_t>(module_->exceptions.size());
WasmExceptionSig* exception_sig = nullptr;
consume_exception_attribute(); // Attribute ignored for now.
consume_exception_sig_index(module_.get(), &exception_sig);
module_->exceptions.emplace_back(exception_sig);
break;
......@@ -894,6 +895,7 @@ class ModuleDecoderImpl : public Decoder {
TRACE("DecodeException[%d] module+%d\n", i,
static_cast<int>(pc_ - start_));
WasmExceptionSig* exception_sig = nullptr;
consume_exception_attribute(); // Attribute ignored for now.
consume_exception_sig_index(module_.get(), &exception_sig);
module_->exceptions.emplace_back(exception_sig);
}
......@@ -1432,12 +1434,11 @@ class ModuleDecoderImpl : public Decoder {
params.push_back(param);
}
std::vector<ValueType> returns;
uint32_t return_count = 0;
// parse return types
const size_t max_return_count = enabled_features_.mv
? kV8MaxWasmFunctionMultiReturns
: kV8MaxWasmFunctionReturns;
return_count = consume_count("return count", max_return_count);
uint32_t return_count = consume_count("return count", max_return_count);
if (failed()) return nullptr;
for (uint32_t i = 0; ok() && i < return_count; ++i) {
ValueType ret = consume_value_type();
......@@ -1454,6 +1455,17 @@ class ModuleDecoderImpl : public Decoder {
return new (zone) FunctionSig(return_count, param_count, buffer);
}
// Consume the attribute field of an exception.
uint32_t consume_exception_attribute() {
const byte* pos = pc_;
uint32_t attribute = consume_u32v("exception attribute");
if (attribute != kExceptionAttribute) {
errorf(pos, "exception attribute %u not supported", attribute);
return 0;
}
return attribute;
}
};
ModuleResult DecodeWasmModule(const WasmFeatures& enabled,
......
......@@ -85,6 +85,8 @@ static_assert(kWasmPageSize == size_t{1} << kWasmPageSizeLog2, "consistency");
using WasmCodePosition = int;
constexpr WasmCodePosition kNoCodePosition = -1;
constexpr uint32_t kExceptionAttribute = 0;
} // namespace wasm
} // namespace internal
} // namespace v8
......
......@@ -102,6 +102,8 @@ let kExternalException = 4;
let kTableZero = 0;
let kMemoryZero = 0;
let kExceptionAttribute = 0;
// Useful signatures
let kSig_i_i = makeSig([kWasmI32], [kWasmI32]);
let kSig_l_l = makeSig([kWasmI64], [kWasmI64]);
......
......@@ -401,6 +401,7 @@ class WasmModuleBuilder {
section.emit_u32v(imp.initial); // initial
if (has_max) section.emit_u32v(imp.maximum); // maximum
} else if (imp.kind == kExternalException) {
section.emit_u32v(kExceptionAttribute);
section.emit_u32v(imp.type);
} else {
throw new Error("unknown/unsupported import kind " + imp.kind);
......@@ -508,6 +509,7 @@ class WasmModuleBuilder {
binary.emit_section(kExceptionSectionCode, section => {
section.emit_u32v(wasm.exceptions.length);
for (let type of wasm.exceptions) {
section.emit_u32v(kExceptionAttribute);
section.emit_u32v(type);
}
});
......
......@@ -105,6 +105,8 @@ struct CheckLEB1 : std::integral_constant<size_t, num> {
#define LINEAR_MEMORY_INDEX_0 0
#define EXCEPTION_ENTRY(sig_index) U32V_1(kExceptionAttribute), sig_index
#define EXPECT_VERIFIES(data) \
do { \
ModuleResult result = DecodeModule(data, data + sizeof(data)); \
......@@ -475,7 +477,8 @@ TEST_F(WasmModuleVerifyTest, ZeroExceptions) {
TEST_F(WasmModuleVerifyTest, OneI32Exception) {
static const byte data[] = {
SECTION(Type, ENTRY_COUNT(1), SIG_ENTRY_v_x(kLocalI32)), // sig#0 (i32)
SECTION(Exception, ENTRY_COUNT(1), SIG_INDEX(0))}; // except[0] (sig#0)
SECTION(Exception, ENTRY_COUNT(1),
EXCEPTION_ENTRY(SIG_INDEX(0)))}; // except[0] (sig#0)
FAIL_IF_NO_EXPERIMENTAL_EH(data);
WASM_FEATURE_SCOPE(eh);
......@@ -494,8 +497,8 @@ TEST_F(WasmModuleVerifyTest, TwoExceptions) {
SIG_ENTRY_v_x(kLocalI32), // sig#0 (i32)
SIG_ENTRY_v_xx(kLocalF32, kLocalI64)), // sig#1 (f32, i64)
SECTION(Exception, ENTRY_COUNT(2),
SIG_INDEX(1), // except[0] (sig#1)
SIG_INDEX(0))}; // except[1] (sig#0)
EXCEPTION_ENTRY(SIG_INDEX(1)), // except[0] (sig#1)
EXCEPTION_ENTRY(SIG_INDEX(0)))}; // except[1] (sig#0)
FAIL_IF_NO_EXPERIMENTAL_EH(data);
WASM_FEATURE_SCOPE(eh);
......@@ -514,7 +517,8 @@ TEST_F(WasmModuleVerifyTest, Exception_invalid_sig_index) {
static const byte data[] = {
SIGNATURES_SECTION_VOID_VOID,
SECTION(Exception, ENTRY_COUNT(1),
SIG_INDEX(23))}; // except[0] (sig#23 [out-of-bounds])
EXCEPTION_ENTRY(
SIG_INDEX(23)))}; // except[0] (sig#23 [out-of-bounds])
FAIL_IF_NO_EXPERIMENTAL_EH(data);
// Should fail decoding exception section.
......@@ -527,7 +531,8 @@ TEST_F(WasmModuleVerifyTest, Exception_invalid_sig_return) {
static const byte data[] = {
SECTION(Type, ENTRY_COUNT(1), SIG_ENTRY_i_i),
SECTION(Exception, ENTRY_COUNT(1),
SIG_INDEX(0))}; // except[0] (sig#0 [invalid-return-type])
EXCEPTION_ENTRY(
SIG_INDEX(0)))}; // except[0] (sig#0 [invalid-return-type])
FAIL_IF_NO_EXPERIMENTAL_EH(data);
// Should fail decoding exception section.
......@@ -536,6 +541,19 @@ TEST_F(WasmModuleVerifyTest, Exception_invalid_sig_return) {
EXPECT_NOT_OK(result, "exception signature 0 has non-void return");
}
TEST_F(WasmModuleVerifyTest, Exception_invalid_attribute) {
static const byte data[] = {
SECTION(Type, ENTRY_COUNT(1), SIG_ENTRY_i_i),
SECTION(Exception, ENTRY_COUNT(1), 23,
SIG_INDEX(0))}; // except[0] (sig#0) [invalid-attribute]
FAIL_IF_NO_EXPERIMENTAL_EH(data);
// Should fail decoding exception section.
WASM_FEATURE_SCOPE(eh);
ModuleResult result = DecodeModule(data, data + sizeof(data));
EXPECT_NOT_OK(result, "exception attribute 23 not supported");
}
TEST_F(WasmModuleVerifyTest, ExceptionSectionCorrectPlacement) {
static const byte data[] = {SECTION(Import, ENTRY_COUNT(0)),
SECTION(Exception, ENTRY_COUNT(0)),
......@@ -568,13 +586,14 @@ TEST_F(WasmModuleVerifyTest, ExceptionSectionBeforeImport) {
}
TEST_F(WasmModuleVerifyTest, ExceptionImport) {
static const byte data[] = {SIGNATURES_SECTION_VOID_VOID,
SECTION(Import, // section header
ENTRY_COUNT(1), // number of imports
ADD_COUNT('m'), // module name
ADD_COUNT('e', 'x'), // exception name
kExternalException, // import kind
SIG_INDEX(0))}; // except[0] (sig#0)
static const byte data[] = {
SIGNATURES_SECTION_VOID_VOID,
SECTION(Import, // section header
ENTRY_COUNT(1), // number of imports
ADD_COUNT('m'), // module name
ADD_COUNT('e', 'x'), // exception name
kExternalException, // import kind
EXCEPTION_ENTRY(SIG_INDEX(0)))}; // except[0] (sig#0)
FAIL_IF_NO_EXPERIMENTAL_EH(data);
WASM_FEATURE_SCOPE(eh);
......@@ -585,13 +604,14 @@ TEST_F(WasmModuleVerifyTest, ExceptionImport) {
}
TEST_F(WasmModuleVerifyTest, ExceptionExport) {
static const byte data[] = {SIGNATURES_SECTION_VOID_VOID,
SECTION(Exception, ENTRY_COUNT(1),
SIG_INDEX(0)), // except[0] (sig#0)
SECTION(Export, ENTRY_COUNT(1), // --
NO_NAME, // --
kExternalException, // --
EXCEPTION_INDEX(0))};
static const byte data[] = {
SIGNATURES_SECTION_VOID_VOID,
SECTION(Exception, ENTRY_COUNT(1),
EXCEPTION_ENTRY(SIG_INDEX(0))), // except[0] (sig#0)
SECTION(Export, ENTRY_COUNT(1), // --
NO_NAME, // --
kExternalException, // --
EXCEPTION_INDEX(0))};
FAIL_IF_NO_EXPERIMENTAL_EH(data);
WASM_FEATURE_SCOPE(eh);
......@@ -2228,6 +2248,7 @@ TEST_F(WasmModuleVerifyTest, MultipleNameSections) {
#undef FOUR_EMPTY_BODIES
#undef SIGNATURES_SECTION_VOID_VOID
#undef LINEAR_MEMORY_INDEX_0
#undef EXCEPTION_ENTRY
#undef EXPECT_VERIFIES
#undef EXPECT_FAILURE_LEN
#undef EXPECT_FAILURE
......
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