Commit 57fa8f5b authored by Clemens Hammacher's avatar Clemens Hammacher Committed by Commit Bot

[wasm] Split Result/ResultBase in WasmError and Result

We often use ResultBase or VoidResult to store or pass wasm errors
(errors with locations). This CL extracts a WasmError class which can
store an error (can also be empty), and Result<T> which stores an error
or a T (exactly one of them).

R=titzer@chromium.org

Bug: v8:8689
Change-Id: I3f5203559984a0ae8757e0130a9184957fa28df5
Reviewed-on: https://chromium-review.googlesource.com/c/1409365
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Reviewed-by: 's avatarBen Titzer <titzer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#58827}
parent 3b6d179b
...@@ -5847,10 +5847,11 @@ bool TurbofanWasmCompilationUnit::BuildGraphForWasmFunction( ...@@ -5847,10 +5847,11 @@ bool TurbofanWasmCompilationUnit::BuildGraphForWasmFunction(
if (graph_construction_result.failed()) { if (graph_construction_result.failed()) {
if (FLAG_trace_wasm_compiler) { if (FLAG_trace_wasm_compiler) {
StdoutStream{} << "Compilation failed: " StdoutStream{} << "Compilation failed: "
<< graph_construction_result.error_msg() << std::endl; << graph_construction_result.error().message()
<< std::endl;
} }
native_module->compilation_state()->SetError( native_module->compilation_state()->SetError(
wasm_unit_->func_index_, std::move(graph_construction_result)); wasm_unit_->func_index_, std::move(graph_construction_result).error());
return false; return false;
} }
......
...@@ -14,7 +14,7 @@ namespace internal { ...@@ -14,7 +14,7 @@ namespace internal {
namespace wasm { namespace wasm {
class NativeModule; class NativeModule;
class ResultBase; class WasmError;
enum RuntimeExceptionSupport : bool { enum RuntimeExceptionSupport : bool {
kRuntimeExceptionSupport = true, kRuntimeExceptionSupport = true,
...@@ -96,12 +96,12 @@ enum class CompilationEvent : uint8_t { ...@@ -96,12 +96,12 @@ enum class CompilationEvent : uint8_t {
// This is the PIMPL interface to that private class. // This is the PIMPL interface to that private class.
class CompilationState { class CompilationState {
public: public:
using callback_t = std::function<void(CompilationEvent, const ResultBase*)>; using callback_t = std::function<void(CompilationEvent, const WasmError*)>;
~CompilationState(); ~CompilationState();
void CancelAndWait(); void CancelAndWait();
void SetError(uint32_t func_index, const ResultBase& error_result); void SetError(uint32_t func_index, const WasmError& error);
void SetWireBytesStorage(std::shared_ptr<WireBytesStorage>); void SetWireBytesStorage(std::shared_ptr<WireBytesStorage>);
......
...@@ -218,10 +218,10 @@ class Decoder { ...@@ -218,10 +218,10 @@ class Decoder {
template <typename T, typename U = typename std::remove_reference<T>::type> template <typename T, typename U = typename std::remove_reference<T>::type>
Result<U> toResult(T&& val) { Result<U> toResult(T&& val) {
if (failed()) { if (failed()) {
TRACE("Result error: %s\n", error_msg_.c_str()); TRACE("Result error: %s\n", error_.message().c_str());
return Result<U>::Error(error_offset_, std::move(error_msg_)); return Result<U>{error_};
} }
return Result<U>(std::forward<T>(val)); return Result<U>{std::forward<T>(val)};
} }
// Resets the boundaries of this decoder. // Resets the boundaries of this decoder.
...@@ -232,17 +232,17 @@ class Decoder { ...@@ -232,17 +232,17 @@ class Decoder {
pc_ = start; pc_ = start;
end_ = end; end_ = end;
buffer_offset_ = buffer_offset; buffer_offset_ = buffer_offset;
error_offset_ = 0; error_ = {};
error_msg_.clear();
} }
void Reset(Vector<const uint8_t> bytes, uint32_t buffer_offset = 0) { void Reset(Vector<const uint8_t> bytes, uint32_t buffer_offset = 0) {
Reset(bytes.begin(), bytes.end(), buffer_offset); Reset(bytes.begin(), bytes.end(), buffer_offset);
} }
bool ok() const { return error_msg_.empty(); } bool ok() const { return error_.empty(); }
bool failed() const { return !ok(); } bool failed() const { return !ok(); }
bool more() const { return pc_ < end_; } bool more() const { return pc_ < end_; }
const WasmError& error() const { return error_; }
const byte* start() const { return start_; } const byte* start() const { return start_; }
const byte* pc() const { return pc_; } const byte* pc() const { return pc_; }
...@@ -271,8 +271,7 @@ class Decoder { ...@@ -271,8 +271,7 @@ class Decoder {
const byte* end_; const byte* end_;
// The offset of the current buffer in the module. Needed for streaming. // The offset of the current buffer in the module. Needed for streaming.
uint32_t buffer_offset_; uint32_t buffer_offset_;
uint32_t error_offset_ = 0; WasmError error_;
std::string error_msg_;
private: private:
void verrorf(uint32_t offset, const char* format, va_list args) { void verrorf(uint32_t offset, const char* format, va_list args) {
...@@ -287,8 +286,7 @@ class Decoder { ...@@ -287,8 +286,7 @@ class Decoder {
EmbeddedVector<char, kMaxErrorMsg> buffer; EmbeddedVector<char, kMaxErrorMsg> buffer;
int len = VSNPrintF(buffer, format, args); int len = VSNPrintF(buffer, format, args);
CHECK_LT(0, len); CHECK_LT(0, len);
error_msg_.assign(buffer.start(), len); error_ = {offset, {buffer.start(), static_cast<size_t>(len)}};
error_offset_ = offset;
onFirstError(); onFirstError();
} }
......
...@@ -1423,9 +1423,9 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -1423,9 +1423,9 @@ class WasmFullDecoder : public WasmDecoder<validate> {
} }
bool TraceFailed() { bool TraceFailed() {
TRACE("wasm-error module+%-6d func+%d: %s\n\n", this->error_offset_, TRACE("wasm-error module+%-6d func+%d: %s\n\n", this->error_.offset(),
this->GetBufferRelativeOffset(this->error_offset_), this->GetBufferRelativeOffset(this->error_.offset()),
this->error_msg_.c_str()); this->error_.message().c_str());
return false; return false;
} }
...@@ -2707,7 +2707,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -2707,7 +2707,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
void onFirstError() override { void onFirstError() override {
this->end_ = this->pc_; // Terminate decoding loop. this->end_ = this->pc_; // Terminate decoding loop.
TRACE(" !%s\n", this->error_msg_.c_str()); TRACE(" !%s\n", this->error_.message().c_str());
CALL_INTERFACE(OnFirstError); CALL_INTERFACE(OnFirstError);
} }
......
This diff is collapsed.
...@@ -1000,9 +1000,9 @@ class ModuleDecoderImpl : public Decoder { ...@@ -1000,9 +1000,9 @@ class ModuleDecoderImpl : public Decoder {
CalculateGlobalOffsets(module_.get()); CalculateGlobalOffsets(module_.get());
} }
ModuleResult result = toResult(std::move(module_)); ModuleResult result = toResult(std::move(module_));
if (verify_functions && result.ok() && intermediate_result_.failed()) { if (verify_functions && result.ok() && intermediate_error_.has_error()) {
// Copy error code and location. // Copy error message and location.
result = ModuleResult::ErrorFrom(std::move(intermediate_result_)); return ModuleResult{std::move(intermediate_error_)};
} }
return result; return result;
} }
...@@ -1057,8 +1057,8 @@ class ModuleDecoderImpl : public Decoder { ...@@ -1057,8 +1057,8 @@ class ModuleDecoderImpl : public Decoder {
VerifyFunctionBody(zone->allocator(), 0, wire_bytes, module, VerifyFunctionBody(zone->allocator(), 0, wire_bytes, module,
function.get()); function.get());
if (intermediate_result_.failed()) { if (intermediate_error_.has_error()) {
return FunctionResult::ErrorFrom(std::move(intermediate_result_)); return FunctionResult{std::move(intermediate_error_)};
} }
return FunctionResult(std::move(function)); return FunctionResult(std::move(function));
...@@ -1105,7 +1105,7 @@ class ModuleDecoderImpl : public Decoder { ...@@ -1105,7 +1105,7 @@ class ModuleDecoderImpl : public Decoder {
sizeof(ModuleDecoderImpl::seen_unordered_sections_) > sizeof(ModuleDecoderImpl::seen_unordered_sections_) >
kLastKnownModuleSection, kLastKnownModuleSection,
"not enough bits"); "not enough bits");
VoidResult intermediate_result_; WasmError intermediate_error_;
ModuleOrigin origin_; ModuleOrigin origin_;
bool has_seen_unordered_section(SectionCode section_code) { bool has_seen_unordered_section(SectionCode section_code) {
...@@ -1224,12 +1224,12 @@ class ModuleDecoderImpl : public Decoder { ...@@ -1224,12 +1224,12 @@ class ModuleDecoderImpl : public Decoder {
// If the decode failed and this is the first error, set error code and // If the decode failed and this is the first error, set error code and
// location. // location.
if (result.failed() && intermediate_result_.ok()) { if (result.failed() && intermediate_error_.empty()) {
// Wrap the error message from the function decoder. // Wrap the error message from the function decoder.
std::ostringstream error_msg; std::ostringstream error_msg;
error_msg << "in function " << func_name << ": " << result.error_msg(); error_msg << "in function " << func_name << ": "
intermediate_result_ = << result.error().message();
VoidResult::Error(result.error_offset(), error_msg.str()); intermediate_error_ = WasmError{result.error().offset(), error_msg.str()};
} }
} }
...@@ -1620,8 +1620,8 @@ ModuleResult DecodeWasmModule(const WasmFeatures& enabled, ...@@ -1620,8 +1620,8 @@ ModuleResult DecodeWasmModule(const WasmFeatures& enabled,
size_t size = module_end - module_start; size_t size = module_end - module_start;
CHECK_LE(module_start, module_end); CHECK_LE(module_start, module_end);
if (size >= kV8MaxWasmModuleSize) { if (size >= kV8MaxWasmModuleSize) {
return ModuleResult::Error(0, "size > maximum module size (%zu): %zu", return ModuleResult{WasmError{0, "size > maximum module size (%zu): %zu",
kV8MaxWasmModuleSize, size); kV8MaxWasmModuleSize, size}};
} }
// TODO(bradnelson): Improve histogram handling of size_t. // TODO(bradnelson): Improve histogram handling of size_t.
auto size_counter = auto size_counter =
...@@ -1740,8 +1740,9 @@ FunctionResult DecodeWasmFunctionForTesting( ...@@ -1740,8 +1740,9 @@ FunctionResult DecodeWasmFunctionForTesting(
// TODO(bradnelson): Improve histogram handling of ptrdiff_t. // TODO(bradnelson): Improve histogram handling of ptrdiff_t.
size_histogram->AddSample(static_cast<int>(size)); size_histogram->AddSample(static_cast<int>(size));
if (size > kV8MaxWasmFunctionSize) { if (size > kV8MaxWasmFunctionSize) {
return FunctionResult::Error(0, "size > maximum function size (%zu): %zu", return FunctionResult{WasmError{0,
kV8MaxWasmFunctionSize, size); "size > maximum function size (%zu): %zu",
kV8MaxWasmFunctionSize, size}};
} }
ModuleDecoderImpl decoder(enabled, function_start, function_end, kWasmOrigin); ModuleDecoderImpl decoder(enabled, function_start, function_end, kWasmOrigin);
decoder.SetCounters(counters); decoder.SetCounters(counters);
......
...@@ -128,10 +128,9 @@ class TopTierCompiledCallback { ...@@ -128,10 +128,9 @@ class TopTierCompiledCallback {
: native_module_(std::move(native_module)), : native_module_(std::move(native_module)),
callback_(std::move(callback)) {} callback_(std::move(callback)) {}
void operator()(CompilationEvent event, void operator()(CompilationEvent event, const WasmError* error) const {
const ResultBase* error_result) const {
if (event != CompilationEvent::kFinishedTopTierCompilation) return; if (event != CompilationEvent::kFinishedTopTierCompilation) return;
DCHECK_NULL(error_result); DCHECK_NULL(error);
callback_(native_module_); callback_(native_module_);
#ifdef DEBUG #ifdef DEBUG
DCHECK(!called_); DCHECK(!called_);
...@@ -327,7 +326,7 @@ size_t StreamingDecoder::DecodeVarInt32::ReadBytes( ...@@ -327,7 +326,7 @@ size_t StreamingDecoder::DecodeVarInt32::ReadBytes(
if (decoder.failed()) { if (decoder.failed()) {
if (new_bytes == remaining_buf.size()) { if (new_bytes == remaining_buf.size()) {
// We only report an error if we read all bytes. // We only report an error if we read all bytes.
streaming->Error(decoder.toResult(nullptr)); streaming->Error(decoder.error());
} }
set_offset(offset() + new_bytes); set_offset(offset() + new_bytes);
return new_bytes; return new_bytes;
......
...@@ -51,7 +51,7 @@ class V8_EXPORT_PRIVATE StreamingProcessor { ...@@ -51,7 +51,7 @@ class V8_EXPORT_PRIVATE StreamingProcessor {
// empty array is passed. // empty array is passed.
virtual void OnFinishedStream(OwnedVector<uint8_t> bytes) = 0; virtual void OnFinishedStream(OwnedVector<uint8_t> bytes) = 0;
// Report an error detected in the StreamingDecoder. // Report an error detected in the StreamingDecoder.
virtual void OnError(VoidResult result) = 0; virtual void OnError(const WasmError&) = 0;
// Report the abortion of the stream. // Report the abortion of the stream.
virtual void OnAbort() = 0; virtual void OnAbort() = 0;
...@@ -202,14 +202,14 @@ class V8_EXPORT_PRIVATE StreamingDecoder { ...@@ -202,14 +202,14 @@ class V8_EXPORT_PRIVATE StreamingDecoder {
size_t length, size_t length,
Vector<const uint8_t> length_bytes); Vector<const uint8_t> length_bytes);
std::unique_ptr<DecodingState> Error(VoidResult result) { std::unique_ptr<DecodingState> Error(const WasmError& error) {
if (ok()) processor_->OnError(std::move(result)); if (ok()) processor_->OnError(error);
Fail(); Fail();
return std::unique_ptr<DecodingState>(nullptr); return std::unique_ptr<DecodingState>(nullptr);
} }
std::unique_ptr<DecodingState> Error(std::string message) { std::unique_ptr<DecodingState> Error(std::string message) {
return Error(VoidResult::Error(module_offset_ - 1, std::move(message))); return Error(WasmError{module_offset_ - 1, std::move(message)});
} }
void ProcessModuleHeader() { void ProcessModuleHeader() {
......
...@@ -93,7 +93,7 @@ MaybeHandle<WasmModuleObject> WasmEngine::SyncCompile( ...@@ -93,7 +93,7 @@ MaybeHandle<WasmModuleObject> WasmEngine::SyncCompile(
DecodeWasmModule(enabled, bytes.start(), bytes.end(), false, kWasmOrigin, DecodeWasmModule(enabled, bytes.start(), bytes.end(), false, kWasmOrigin,
isolate->counters(), allocator()); isolate->counters(), allocator());
if (result.failed()) { if (result.failed()) {
thrower->CompileFailed("Wasm decoding failed", result); thrower->CompileFailed("Wasm decoding failed", result.error());
return {}; return {};
} }
......
...@@ -50,7 +50,7 @@ void PrintFToString(std::string& str, size_t str_offset, const char* format, ...@@ -50,7 +50,7 @@ void PrintFToString(std::string& str, size_t str_offset, const char* format,
} // namespace } // namespace
// static // static
std::string ResultBase::FormatError(const char* format, va_list args) { std::string WasmError::FormatError(const char* format, va_list args) {
std::string result; std::string result;
VPrintFToString(result, 0, format, args); VPrintFToString(result, 0, format, args);
return result; return result;
......
...@@ -22,42 +22,44 @@ class Handle; ...@@ -22,42 +22,44 @@ class Handle;
namespace wasm { namespace wasm {
// Base class for Result<T>. class V8_EXPORT_PRIVATE WasmError {
class V8_EXPORT_PRIVATE ResultBase { public:
protected: WasmError() = default;
ResultBase() = default;
ResultBase& operator=(ResultBase&& other) V8_NOEXCEPT = default; WasmError(uint32_t offset, std::string message)
: offset_(offset), message_(std::move(message)) {
// The error message must not be empty, otherwise {empty()} would be true.
DCHECK(!message_.empty());
}
public: PRINTF_FORMAT(3, 4)
ResultBase(ResultBase&& other) V8_NOEXCEPT WasmError(uint32_t offset, const char* format, ...) : offset_(offset) {
: error_offset_(other.error_offset_), va_list args;
error_msg_(std::move(other.error_msg_)) {} va_start(args, format);
message_ = FormatError(format, args);
va_end(args);
// The error message must not be empty, otherwise {empty()} would be true.
DCHECK(!message_.empty());
}
bool ok() const { return error_msg_.empty(); } bool empty() const { return message_.empty(); }
bool failed() const { return !ok(); } bool has_error() const { return !message_.empty(); }
uint32_t error_offset() const { return error_offset_; } uint32_t offset() const { return offset_; }
const std::string& error_msg() const & { return error_msg_; } const std::string& message() const& { return message_; }
std::string&& error_msg() && { return std::move(error_msg_); } std::string&& message() && { return std::move(message_); }
protected: protected:
ResultBase(uint32_t error_offset, std::string error_msg)
: error_offset_(error_offset), error_msg_(std::move(error_msg)) {
// The error message must not be empty, otherwise {failed()} will be false.
DCHECK(!error_msg_.empty());
}
static std::string FormatError(const char* format, va_list args); static std::string FormatError(const char* format, va_list args);
private: private:
uint32_t error_offset_ = 0; uint32_t offset_ = 0;
std::string error_msg_; std::string message_;
}; };
// The overall result of decoding a function or a module. // Either a result of type T, or a WasmError.
template <typename T> template <typename T>
class Result : public ResultBase { class Result {
public: public:
Result() = default; Result() = default;
...@@ -65,33 +67,22 @@ class Result : public ResultBase { ...@@ -65,33 +67,22 @@ class Result : public ResultBase {
explicit Result(S&& value) : value_(std::forward<S>(value)) {} explicit Result(S&& value) : value_(std::forward<S>(value)) {}
template <typename S> template <typename S>
Result(Result<S>&& other) V8_NOEXCEPT : ResultBase(std::move(other)), Result(Result<S>&& other) V8_NOEXCEPT : value_(std::move(other.value_)),
value_(std::move(other).value()) {} error_(std::move(other.error_)) {}
Result& operator=(Result&& other) V8_NOEXCEPT = default; explicit Result(WasmError error) : error_(std::move(error)) {}
static Result<T> PRINTF_FORMAT(2, 3) template <typename S>
Error(uint32_t offset, const char* format, ...) { Result& operator=(Result<S>&& other) V8_NOEXCEPT {
va_list args; value_ = std::move(other.value_);
va_start(args, format); error_ = std::move(other.error_);
Result<T> error_result{offset, FormatError(format, args)}; return *this;
va_end(args);
return error_result;
}
static Result<T> Error(uint32_t error_offset, std::string error_msg) {
// Call private constructor.
return Result<T>{error_offset, std::move(error_msg)};
}
static Result<T> ErrorFrom(ResultBase&& error_result) {
return Error(error_result.error_offset(),
std::move(error_result).error_msg());
} }
static Result<T> ErrorFrom(const ResultBase& error_result) { bool ok() const { return error_.empty(); }
return Error(error_result.error_offset(), error_result.error_msg()); bool failed() const { return error_.has_error(); }
} const WasmError& error() const& { return error_; }
WasmError&& error() && { return std::move(error_); }
// Accessor for the value. Returns const reference if {this} is l-value or // Accessor for the value. Returns const reference if {this} is l-value or
// const, and returns r-value reference if {this} is r-value. This allows to // const, and returns r-value reference if {this} is r-value. This allows to
...@@ -107,10 +98,11 @@ class Result : public ResultBase { ...@@ -107,10 +98,11 @@ class Result : public ResultBase {
} }
private: private:
T value_ = T{}; template <typename S>
friend class Result;
Result(uint32_t error_offset, std::string error_msg) T value_ = T{};
: ResultBase(error_offset, std::move(error_msg)) {} WasmError error_;
DISALLOW_COPY_AND_ASSIGN(Result); DISALLOW_COPY_AND_ASSIGN(Result);
}; };
...@@ -130,15 +122,15 @@ class V8_EXPORT_PRIVATE ErrorThrower { ...@@ -130,15 +122,15 @@ class V8_EXPORT_PRIVATE ErrorThrower {
PRINTF_FORMAT(2, 3) void LinkError(const char* fmt, ...); PRINTF_FORMAT(2, 3) void LinkError(const char* fmt, ...);
PRINTF_FORMAT(2, 3) void RuntimeError(const char* fmt, ...); PRINTF_FORMAT(2, 3) void RuntimeError(const char* fmt, ...);
void CompileFailed(const char* error, const ResultBase& result) { void CompileFailed(const char* context, const WasmError& error) {
DCHECK(result.failed()); DCHECK(error.has_error());
CompileError("%s: %s @+%u", error, result.error_msg().c_str(), CompileError("%s: %s @+%u", context, error.message().c_str(),
result.error_offset()); error.offset());
} }
void CompileFailed(const ResultBase& result) { void CompileFailed(const WasmError& error) {
DCHECK(result.failed()); DCHECK(error.has_error());
CompileError("%s @+%u", result.error_msg().c_str(), result.error_offset()); CompileError("%s @+%u", error.message().c_str(), error.offset());
} }
// Create and return exception object. // Create and return exception object.
......
...@@ -241,9 +241,8 @@ void TestBuildingGraphWithBuilder(compiler::WasmGraphBuilder* builder, ...@@ -241,9 +241,8 @@ void TestBuildingGraphWithBuilder(compiler::WasmGraphBuilder* builder,
} }
#endif #endif
uint32_t pc = result.error_offset(); FATAL("Verification failed; pc = +%x, msg = %s", result.error().offset(),
FATAL("Verification failed; pc = +%x, msg = %s", pc, result.error().message().c_str());
result.error_msg().c_str());
} }
builder->LowerInt64(); builder->LowerInt64();
if (!CpuFeatures::SupportsWasmSimd128()) { if (!CpuFeatures::SupportsWasmSimd128()) {
......
...@@ -51,7 +51,7 @@ std::shared_ptr<WasmModule> DecodeWasmModuleForTesting( ...@@ -51,7 +51,7 @@ std::shared_ptr<WasmModule> DecodeWasmModuleForTesting(
if (decoding_result.failed()) { if (decoding_result.failed()) {
// Module verification failed. throw. // Module verification failed. throw.
thrower->CompileError("DecodeWasmModule failed: %s", thrower->CompileError("DecodeWasmModule failed: %s",
decoding_result.error_msg().c_str()); decoding_result.error().message().c_str());
} }
return std::move(decoding_result).value(); return std::move(decoding_result).value();
......
...@@ -138,17 +138,16 @@ class FunctionBodyDecoderTest : public TestWithZone { ...@@ -138,17 +138,16 @@ class FunctionBodyDecoderTest : public TestWithZone {
VerifyWasmCode(zone()->allocator(), enabled_features_, module, VerifyWasmCode(zone()->allocator(), enabled_features_, module,
&unused_detected_features, body); &unused_detected_features, body);
uint32_t pc = result.error_offset();
std::ostringstream str; std::ostringstream str;
if (expected_success) { if (result.failed()) {
str << "Verification failed: pc = +" << pc str << "Verification failed: pc = +" << result.error().offset()
<< ", msg = " << result.error_msg(); << ", msg = " << result.error().message();
} else { } else {
str << "Verification successed, expected failure; pc = +" << pc; str << "Verification successed, expected failure";
} }
EXPECT_EQ(result.ok(), expected_success) << str.str(); EXPECT_EQ(result.ok(), expected_success) << str.str();
if (!expected_success && message) { if (result.failed() && message) {
EXPECT_THAT(result.error_msg(), ::testing::HasSubstr(message)); EXPECT_THAT(result.error().message(), ::testing::HasSubstr(message));
} }
} }
......
...@@ -135,10 +135,10 @@ struct CheckLEB1 : std::integral_constant<size_t, num> { ...@@ -135,10 +135,10 @@ struct CheckLEB1 : std::integral_constant<size_t, num> {
if (!result.ok()) return; \ if (!result.ok()) return; \
} while (false) } while (false)
#define EXPECT_NOT_OK(result, msg) \ #define EXPECT_NOT_OK(result, msg) \
do { \ do { \
EXPECT_FALSE(result.ok()); \ EXPECT_FALSE(result.ok()); \
EXPECT_THAT(result.error_msg(), HasSubstr(msg)); \ EXPECT_THAT(result.error().message(), HasSubstr(msg)); \
} while (false) } while (false)
static size_t SizeOfVarInt(size_t value) { static size_t SizeOfVarInt(size_t value) {
......
...@@ -74,7 +74,7 @@ class MockStreamingProcessor : public StreamingProcessor { ...@@ -74,7 +74,7 @@ class MockStreamingProcessor : public StreamingProcessor {
} }
// Report an error detected in the StreamingDecoder. // Report an error detected in the StreamingDecoder.
void OnError(DecodeResult result) override { result_->ok = false; } void OnError(const WasmError&) override { result_->ok = false; }
void OnAbort() override {} void OnAbort() override {}
......
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