[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/1354463
Reviewed-by: Andreas Haas <ahaas@chromium.org>
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#57944}
This commit is contained in:
Clemens Hammacher 2018-11-29 16:35:16 +01:00 committed by Commit Bot
parent d5e8e35249
commit fd7d6b8be0
2 changed files with 40 additions and 25 deletions

View File

@ -181,7 +181,8 @@ class LiftoffCompiler {
void unsupported(FullDecoder* decoder, const char* reason) {
ok_ = false;
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);
}

View File

@ -173,30 +173,24 @@ class Decoder {
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 byte* pc, const char* format, ...) {
// 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;
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();
void PRINTF_FORMAT(3, 4) errorf(const uint8_t* pc, const char* format, ...) {
va_list args;
va_start(args, format);
verrorf(pc_offset(pc), format, args);
va_end(args);
}
// Behavior triggered on first error, overridden in subclasses.
@ -247,9 +241,12 @@ class Decoder {
const byte* start() const { return start_; }
const byte* pc() const { return pc_; }
uint32_t position() const { return static_cast<uint32_t>(pc_ - start_); }
uint32_t pc_offset() const {
return static_cast<uint32_t>(pc_ - start_) + buffer_offset_;
uint32_t pc_offset(const uint8_t* pc) const {
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_; }
// Takes an offset relative to the module start and returns an offset relative
// to the current buffer of the decoder.
@ -269,6 +266,23 @@ class Decoder {
std::string error_msg_;
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>
inline IntType read_little_endian(const byte* pc, const char* msg) {
if (!validate) {