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

[wasm] Pass offset instead of pc to error functions

This adds error functions that receive offsets instead of pc, since the
streaming compiler stores different sections in different buffers, so
computing pointer differences between different sections does not work.
We keep the pc-based methods for now to reduce code-churn and
complexity at the different call sites.

R=ahaas@chromium.org
CC=binji@chromium.org

Bug: v8:8238
Change-Id: I1aa68740bdda93c3341431aa7a81ac01ecfb71bb
Reviewed-on: https://chromium-review.googlesource.com/c/1354463Reviewed-by: 's avatarAndreas Haas <ahaas@chromium.org>
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#57944}
parent d5e8e352
...@@ -181,7 +181,8 @@ class LiftoffCompiler { ...@@ -181,7 +181,8 @@ class LiftoffCompiler {
void unsupported(FullDecoder* decoder, const char* reason) { void unsupported(FullDecoder* decoder, const char* reason) {
ok_ = false; ok_ = false;
TRACE("unsupported: %s\n", reason); TRACE("unsupported: %s\n", reason);
decoder->errorf(decoder->pc(), "unsupported liftoff operation: %s", reason); decoder->errorf(decoder->pc_offset(), "unsupported liftoff operation: %s",
reason);
BindUnboundLabels(decoder); BindUnboundLabels(decoder);
} }
......
...@@ -173,30 +173,24 @@ class Decoder { ...@@ -173,30 +173,24 @@ class Decoder {
return true; return true;
} }
void error(const char* msg) { errorf(pc_, "%s", msg); } void error(const char* msg) { errorf(pc_offset(), "%s", msg); }
void error(const uint8_t* pc, const char* msg) {
errorf(pc_offset(pc), "%s", msg);
}
void error(uint32_t offset, const char* msg) { errorf(offset, "%s", msg); }
void error(const byte* pc, const char* msg) { errorf(pc, "%s", msg); } void PRINTF_FORMAT(3, 4) errorf(uint32_t offset, const char* format, ...) {
va_list args;
va_start(args, format);
verrorf(offset, format, args);
va_end(args);
}
// Sets internal error state. void PRINTF_FORMAT(3, 4) errorf(const uint8_t* pc, const char* format, ...) {
void PRINTF_FORMAT(3, 4) errorf(const byte* pc, const char* format, ...) { va_list args;
// Only report the first error. va_start(args, format);
if (!ok()) return; verrorf(pc_offset(pc), format, args);
#if DEBUG va_end(args);
if (FLAG_wasm_break_on_decoder_error) {
base::OS::DebugBreak();
}
#endif
constexpr int kMaxErrorMsg = 256;
EmbeddedVector<char, kMaxErrorMsg> buffer;
va_list arguments;
va_start(arguments, format);
int len = VSNPrintF(buffer, format, arguments);
CHECK_LT(0, len);
va_end(arguments);
error_msg_.assign(buffer.start(), len);
DCHECK_GE(pc, start_);
error_offset_ = static_cast<uint32_t>(pc - start_) + buffer_offset_;
onFirstError();
} }
// Behavior triggered on first error, overridden in subclasses. // Behavior triggered on first error, overridden in subclasses.
...@@ -247,9 +241,12 @@ class Decoder { ...@@ -247,9 +241,12 @@ class Decoder {
const byte* start() const { return start_; } const byte* start() const { return start_; }
const byte* pc() const { return pc_; } const byte* pc() const { return pc_; }
uint32_t position() const { return static_cast<uint32_t>(pc_ - start_); } uint32_t position() const { return static_cast<uint32_t>(pc_ - start_); }
uint32_t pc_offset() const { uint32_t pc_offset(const uint8_t* pc) const {
return static_cast<uint32_t>(pc_ - start_) + buffer_offset_; DCHECK_LE(start_, pc);
DCHECK_GE(kMaxUInt32 - buffer_offset_, pc - start_);
return static_cast<uint32_t>(pc - start_) + buffer_offset_;
} }
uint32_t pc_offset() const { return pc_offset(pc_); }
uint32_t buffer_offset() const { return buffer_offset_; } uint32_t buffer_offset() const { return buffer_offset_; }
// Takes an offset relative to the module start and returns an offset relative // Takes an offset relative to the module start and returns an offset relative
// to the current buffer of the decoder. // to the current buffer of the decoder.
...@@ -269,6 +266,23 @@ class Decoder { ...@@ -269,6 +266,23 @@ class Decoder {
std::string error_msg_; std::string error_msg_;
private: private:
void verrorf(uint32_t offset, const char* format, va_list args) {
// Only report the first error.
if (!ok()) return;
#if DEBUG
if (FLAG_wasm_break_on_decoder_error) {
base::OS::DebugBreak();
}
#endif
constexpr int kMaxErrorMsg = 256;
EmbeddedVector<char, kMaxErrorMsg> buffer;
int len = VSNPrintF(buffer, format, args);
CHECK_LT(0, len);
error_msg_.assign(buffer.start(), len);
error_offset_ = offset;
onFirstError();
}
template <typename IntType, bool validate> template <typename IntType, bool validate>
inline IntType read_little_endian(const byte* pc, const char* msg) { inline IntType read_little_endian(const byte* pc, const char* msg) {
if (!validate) { if (!validate) {
......
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