summaryrefslogtreecommitdiff
path: root/deps/v8/src/wasm/module-decoder.cc
diff options
context:
space:
mode:
authorMichaël Zasso <targos@protonmail.com>2017-06-06 10:28:14 +0200
committerMichaël Zasso <targos@protonmail.com>2017-06-07 10:33:31 +0200
commit3dc8c3bed4cf3a77607edbb0b015e33f8b60fc09 (patch)
tree9dee56e142638b34f1eccbd0ad88c3bce5377c29 /deps/v8/src/wasm/module-decoder.cc
parent91a1bbe3055a660194ca4d403795aa0c03e9d056 (diff)
downloadnode-new-3dc8c3bed4cf3a77607edbb0b015e33f8b60fc09.tar.gz
deps: update V8 to 5.9.211.32
PR-URL: https://github.com/nodejs/node/pull/13263 Reviewed-By: Gibson Fahnestock <gibfahn@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Franziska Hinkelmann <franziska.hinkelmann@gmail.com> Reviewed-By: Myles Borins <myles.borins@gmail.com>
Diffstat (limited to 'deps/v8/src/wasm/module-decoder.cc')
-rw-r--r--deps/v8/src/wasm/module-decoder.cc402
1 files changed, 170 insertions, 232 deletions
diff --git a/deps/v8/src/wasm/module-decoder.cc b/deps/v8/src/wasm/module-decoder.cc
index 440e5dcbb9..2b58065e77 100644
--- a/deps/v8/src/wasm/module-decoder.cc
+++ b/deps/v8/src/wasm/module-decoder.cc
@@ -30,7 +30,7 @@ namespace wasm {
#define TRACE(...)
#endif
-const char* SectionName(WasmSectionCode code) {
+const char* SectionName(SectionCode code) {
switch (code) {
case kUnknownSectionCode:
return "Unknown";
@@ -90,6 +90,24 @@ ValueType TypeOf(const WasmModule* module, const WasmInitExpr& expr) {
}
}
+// Reads a length-prefixed string, checking that it is within bounds. Returns
+// the offset of the string, and the length as an out parameter.
+uint32_t consume_string(Decoder& decoder, uint32_t* length, bool validate_utf8,
+ const char* name) {
+ *length = decoder.consume_u32v("string length");
+ uint32_t offset = decoder.pc_offset();
+ const byte* string_start = decoder.pc();
+ // Consume bytes before validation to guarantee that the string is not oob.
+ if (*length > 0) {
+ decoder.consume_bytes(*length, name);
+ if (decoder.ok() && validate_utf8 &&
+ !unibrow::Utf8::Validate(string_start, *length)) {
+ decoder.errorf(string_start, "%s: no valid UTF-8 string", name);
+ }
+ }
+ return offset;
+}
+
// An iterator over the sections in a WASM binary module.
// Automatically skips all unknown sections.
class WasmSectionIterator {
@@ -106,7 +124,7 @@ class WasmSectionIterator {
return section_code_ != kUnknownSectionCode && decoder_.more();
}
- inline WasmSectionCode section_code() const { return section_code_; }
+ inline SectionCode section_code() const { return section_code_; }
inline const byte* section_start() const { return section_start_; }
@@ -127,24 +145,24 @@ class WasmSectionIterator {
void advance() {
if (decoder_.pc() != section_end_) {
const char* msg = decoder_.pc() < section_end_ ? "shorter" : "longer";
- decoder_.error(decoder_.pc(), decoder_.pc(),
- "section was %s than expected size "
- "(%u bytes expected, %zu decoded)",
- msg, section_length(),
- static_cast<size_t>(decoder_.pc() - section_start_));
+ decoder_.errorf(decoder_.pc(),
+ "section was %s than expected size "
+ "(%u bytes expected, %zu decoded)",
+ msg, section_length(),
+ static_cast<size_t>(decoder_.pc() - section_start_));
}
next();
}
private:
Decoder& decoder_;
- WasmSectionCode section_code_;
+ SectionCode section_code_;
const byte* section_start_;
const byte* payload_start_;
const byte* section_end_;
// Reads the section code/name at the current position and sets up
- // the internal fields.
+ // the embedder fields.
void next() {
while (true) {
if (!decoder_.more()) {
@@ -166,14 +184,14 @@ class WasmSectionIterator {
if (section_code == kUnknownSectionCode) {
// Check for the known "name" section.
- uint32_t string_length = decoder_.consume_u32v("section name length");
- const byte* section_name_start = decoder_.pc();
- decoder_.consume_bytes(string_length, "section name");
+ uint32_t string_length;
+ uint32_t string_offset = wasm::consume_string(decoder_, &string_length,
+ true, "section name");
if (decoder_.failed() || decoder_.pc() > section_end_) {
- TRACE("Section name of length %u couldn't be read\n", string_length);
section_code_ = kUnknownSectionCode;
return;
}
+ const byte* section_name_start = decoder_.start() + string_offset;
payload_start_ = decoder_.pc();
TRACE(" +%d section name : \"%.*s\"\n",
@@ -184,15 +202,15 @@ class WasmSectionIterator {
strncmp(reinterpret_cast<const char*>(section_name_start),
kNameString, kNameStringLength) == 0) {
section_code = kNameSectionCode;
- } else {
- section_code = kUnknownSectionCode;
}
} else if (!IsValidSectionCode(section_code)) {
- decoder_.error(decoder_.pc(), decoder_.pc(),
- "unknown section code #0x%02x", section_code);
+ decoder_.errorf(decoder_.pc(), "unknown section code #0x%02x",
+ section_code);
section_code = kUnknownSectionCode;
}
- section_code_ = static_cast<WasmSectionCode>(section_code);
+ section_code_ = decoder_.failed()
+ ? kUnknownSectionCode
+ : static_cast<SectionCode>(section_code);
TRACE("Section: %s\n", SectionName(section_code_));
if (section_code_ == kUnknownSectionCode &&
@@ -215,9 +233,8 @@ class ModuleDecoder : public Decoder {
ModuleDecoder(Zone* zone, const byte* module_start, const byte* module_end,
ModuleOrigin origin)
: Decoder(module_start, module_end),
- module_zone(zone),
+ module_zone_(zone),
origin_(FLAG_assume_asmjs_origin ? kAsmJsOrigin : origin) {
- result_.start = start_;
if (end_ < start_) {
error(start_, "end is less than start");
end_ = start_;
@@ -255,30 +272,30 @@ class ModuleDecoder : public Decoder {
// Decodes an entire module.
ModuleResult DecodeModule(bool verify_functions = true) {
pc_ = start_;
- WasmModule* module = new WasmModule(module_zone);
+ WasmModule* module = new WasmModule(module_zone_);
module->min_mem_pages = 0;
module->max_mem_pages = 0;
module->mem_export = false;
- module->origin = origin_;
+ module->set_origin(origin_);
const byte* pos = pc_;
uint32_t magic_word = consume_u32("wasm magic");
#define BYTES(x) (x & 0xff), (x >> 8) & 0xff, (x >> 16) & 0xff, (x >> 24) & 0xff
if (magic_word != kWasmMagic) {
- error(pos, pos,
- "expected magic word %02x %02x %02x %02x, "
- "found %02x %02x %02x %02x",
- BYTES(kWasmMagic), BYTES(magic_word));
+ errorf(pos,
+ "expected magic word %02x %02x %02x %02x, "
+ "found %02x %02x %02x %02x",
+ BYTES(kWasmMagic), BYTES(magic_word));
}
pos = pc_;
{
uint32_t magic_version = consume_u32("wasm version");
if (magic_version != kWasmVersion) {
- error(pos, pos,
- "expected version %02x %02x %02x %02x, "
- "found %02x %02x %02x %02x",
- BYTES(kWasmVersion), BYTES(magic_version));
+ errorf(pos,
+ "expected version %02x %02x %02x %02x, "
+ "found %02x %02x %02x %02x",
+ BYTES(kWasmVersion), BYTES(magic_version));
}
}
@@ -317,9 +334,9 @@ class ModuleDecoder : public Decoder {
WasmImport* import = &module->import_table.back();
const byte* pos = pc_;
import->module_name_offset =
- consume_string(&import->module_name_length, true);
+ consume_string(&import->module_name_length, true, "module name");
import->field_name_offset =
- consume_string(&import->field_name_length, true);
+ consume_string(&import->field_name_length, true, "field name");
import->kind = static_cast<WasmExternalKind>(consume_u8("import kind"));
switch (import->kind) {
@@ -379,7 +396,7 @@ class ModuleDecoder : public Decoder {
break;
}
default:
- error(pos, pos, "unknown import kind 0x%02x", import->kind);
+ errorf(pos, "unknown import kind 0x%02x", import->kind);
break;
}
}
@@ -476,7 +493,8 @@ class ModuleDecoder : public Decoder {
});
WasmExport* exp = &module->export_table.back();
- exp->name_offset = consume_string(&exp->name_length, true);
+ exp->name_offset =
+ consume_string(&exp->name_length, true, "field name");
const byte* pos = pc();
exp->kind = static_cast<WasmExternalKind>(consume_u8("export kind"));
switch (exp->kind) {
@@ -515,7 +533,7 @@ class ModuleDecoder : public Decoder {
break;
}
default:
- error(pos, pos, "invalid export kind 0x%02x", exp->kind);
+ errorf(pos, "invalid export kind 0x%02x", exp->kind);
break;
}
}
@@ -539,9 +557,8 @@ class ModuleDecoder : public Decoder {
DCHECK(!cmp_less(*it, *last)); // Vector must be sorted.
if (!cmp_less(*last, *it)) {
const byte* pc = start_ + it->name_offset;
- error(pc, pc,
- "Duplicate export name '%.*s' for functions %d and %d",
- it->name_length, pc, last->index, it->index);
+ errorf(pc, "Duplicate export name '%.*s' for functions %d and %d",
+ it->name_length, pc, last->index, it->index);
break;
}
}
@@ -570,14 +587,14 @@ class ModuleDecoder : public Decoder {
const byte* pos = pc();
uint32_t table_index = consume_u32v("table index");
if (table_index != 0) {
- error(pos, pos, "illegal table index %u != 0", table_index);
+ errorf(pos, "illegal table index %u != 0", table_index);
}
WasmIndirectFunctionTable* table = nullptr;
if (table_index >= module->function_tables.size()) {
- error(pos, pos, "out of bounds table index %u", table_index);
- } else {
- table = &module->function_tables[table_index];
+ errorf(pos, "out of bounds table index %u", table_index);
+ break;
}
+ table = &module->function_tables[table_index];
WasmInitExpr offset = consume_init_expr(module, kWasmI32);
uint32_t num_elem =
consume_count("number of elements", kV8MaxWasmTableEntries);
@@ -587,11 +604,12 @@ class ModuleDecoder : public Decoder {
for (uint32_t j = 0; ok() && j < num_elem; j++) {
WasmFunction* func = nullptr;
uint32_t index = consume_func_index(module, &func);
+ DCHECK_EQ(func != nullptr, ok());
+ if (!func) break;
+ DCHECK_EQ(index, func->func_index);
init->entries.push_back(index);
- if (table && index < module->functions.size()) {
- // Canonicalize signature indices during decoding.
- table->map.FindOrInsert(module->functions[index].sig);
- }
+ // Canonicalize signature indices during decoding.
+ table->map.FindOrInsert(func->sig);
}
}
@@ -603,8 +621,8 @@ class ModuleDecoder : public Decoder {
const byte* pos = pc_;
uint32_t functions_count = consume_u32v("functions count");
if (functions_count != module->num_declared_functions) {
- error(pos, pos, "function body count %u mismatch (%u expected)",
- functions_count, module->num_declared_functions);
+ errorf(pos, "function body count %u mismatch (%u expected)",
+ functions_count, module->num_declared_functions);
}
for (uint32_t i = 0; ok() && i < functions_count; ++i) {
WasmFunction* function =
@@ -651,22 +669,37 @@ class ModuleDecoder : public Decoder {
// TODO(titzer): find a way to report name errors as warnings.
// Use an inner decoder so that errors don't fail the outer decoder.
Decoder inner(start_, pc_, end_);
- uint32_t functions_count = inner.consume_u32v("functions count");
-
- for (uint32_t i = 0; inner.ok() && i < functions_count; ++i) {
- uint32_t function_name_length = 0;
- uint32_t name_offset =
- consume_string(inner, &function_name_length, false);
- uint32_t func_index = i;
- if (inner.ok() && func_index < module->functions.size()) {
- module->functions[func_index].name_offset = name_offset;
- module->functions[func_index].name_length = function_name_length;
- }
-
- uint32_t local_names_count = inner.consume_u32v("local names count");
- for (uint32_t j = 0; inner.ok() && j < local_names_count; j++) {
- uint32_t length = inner.consume_u32v("string length");
- inner.consume_bytes(length, "string");
+ // Decode all name subsections.
+ // Be lenient with their order.
+ while (inner.ok() && inner.more()) {
+ uint8_t name_type = inner.consume_u8("name type");
+ if (name_type & 0x80) inner.error("name type if not varuint7");
+
+ uint32_t name_payload_len = inner.consume_u32v("name payload length");
+ if (!inner.checkAvailable(name_payload_len)) break;
+
+ // Decode function names, ignore the rest.
+ // Local names will be decoded when needed.
+ if (name_type == NameSectionType::kFunction) {
+ uint32_t functions_count = inner.consume_u32v("functions count");
+
+ for (; inner.ok() && functions_count > 0; --functions_count) {
+ uint32_t function_index = inner.consume_u32v("function index");
+ uint32_t name_length = 0;
+ uint32_t name_offset = wasm::consume_string(inner, &name_length,
+ false, "function name");
+ // Be lenient with errors in the name section: Ignore illegal
+ // or out-of-order indexes and non-UTF8 names. You can even assign
+ // to the same function multiple times (last valid one wins).
+ if (inner.ok() && function_index < module->functions.size() &&
+ unibrow::Utf8::Validate(inner.start() + name_offset,
+ name_length)) {
+ module->functions[function_index].name_offset = name_offset;
+ module->functions[function_index].name_length = name_length;
+ }
+ }
+ } else {
+ inner.consume_bytes(name_payload_len, "name subsection payload");
}
}
// Skip the whole names section in the outer decoder.
@@ -676,8 +709,8 @@ class ModuleDecoder : public Decoder {
// ===== Remaining sections ==============================================
if (section_iter.more() && ok()) {
- error(pc(), pc(), "unexpected section: %s",
- SectionName(section_iter.section_code()));
+ errorf(pc(), "unexpected section: %s",
+ SectionName(section_iter.section_code()));
}
if (ok()) {
@@ -686,7 +719,8 @@ class ModuleDecoder : public Decoder {
const WasmModule* finished_module = module;
ModuleResult result = toResult(finished_module);
if (verify_functions && result.ok()) {
- result.MoveFrom(result_); // Copy error code and location.
+ // Copy error code and location.
+ result.MoveErrorFrom(intermediate_result_);
}
if (FLAG_dump_wasm_module) DumpModule(result);
return result;
@@ -705,7 +739,8 @@ class ModuleDecoder : public Decoder {
if (ok()) VerifyFunctionBody(0, module_env, function);
FunctionResult result;
- result.MoveFrom(result_); // Copy error code and location.
+ // Copy error code and location.
+ result.MoveErrorFrom(intermediate_result_);
result.val = function;
return result;
}
@@ -723,8 +758,8 @@ class ModuleDecoder : public Decoder {
}
private:
- Zone* module_zone;
- ModuleResult result_;
+ Zone* module_zone_;
+ Result<bool> intermediate_result_;
ModuleOrigin origin_;
uint32_t off(const byte* ptr) { return static_cast<uint32_t>(ptr - start_); }
@@ -759,25 +794,25 @@ class ModuleDecoder : public Decoder {
case WasmInitExpr::kGlobalIndex: {
uint32_t other_index = global->init.val.global_index;
if (other_index >= index) {
- error(pos, pos,
- "invalid global index in init expression, "
- "index %u, other_index %u",
- index, other_index);
+ errorf(pos,
+ "invalid global index in init expression, "
+ "index %u, other_index %u",
+ index, other_index);
} else if (module->globals[other_index].type != global->type) {
- error(pos, pos,
- "type mismatch in global initialization "
- "(from global #%u), expected %s, got %s",
- other_index, WasmOpcodes::TypeName(global->type),
- WasmOpcodes::TypeName(module->globals[other_index].type));
+ errorf(pos,
+ "type mismatch in global initialization "
+ "(from global #%u), expected %s, got %s",
+ other_index, WasmOpcodes::TypeName(global->type),
+ WasmOpcodes::TypeName(module->globals[other_index].type));
}
break;
}
default:
if (global->type != TypeOf(module, global->init)) {
- error(pos, pos,
- "type error in global initialization, expected %s, got %s",
- WasmOpcodes::TypeName(global->type),
- WasmOpcodes::TypeName(TypeOf(module, global->init)));
+ errorf(pos,
+ "type error in global initialization, expected %s, got %s",
+ WasmOpcodes::TypeName(global->type),
+ WasmOpcodes::TypeName(TypeOf(module, global->init)));
}
}
}
@@ -836,52 +871,31 @@ class ModuleDecoder : public Decoder {
start_ + function->code_start_offset,
start_ + function->code_end_offset};
DecodeResult result = VerifyWasmCode(
- module_zone->allocator(),
+ module_zone_->allocator(),
menv == nullptr ? nullptr : menv->module_env.module, body);
if (result.failed()) {
// Wrap the error message from the function decoder.
std::ostringstream str;
- str << "in function " << func_name << ": ";
- str << result;
- std::string strval = str.str();
- const char* raw = strval.c_str();
- size_t len = strlen(raw);
- char* buffer = new char[len];
- strncpy(buffer, raw, len);
- buffer[len - 1] = 0;
+ str << "in function " << func_name << ": " << result.error_msg;
- // Copy error code and location.
- result_.MoveFrom(result);
- result_.error_msg.reset(buffer);
+ // Set error code and location, if this is the first error.
+ if (intermediate_result_.ok()) {
+ intermediate_result_.MoveErrorFrom(result);
+ }
}
}
- uint32_t consume_string(uint32_t* length, bool validate_utf8) {
- return consume_string(*this, length, validate_utf8);
- }
-
- // Reads a length-prefixed string, checking that it is within bounds. Returns
- // the offset of the string, and the length as an out parameter.
- uint32_t consume_string(Decoder& decoder, uint32_t* length,
- bool validate_utf8) {
- *length = decoder.consume_u32v("string length");
- uint32_t offset = decoder.pc_offset();
- const byte* string_start = decoder.pc();
- // Consume bytes before validation to guarantee that the string is not oob.
- if (*length > 0) decoder.consume_bytes(*length, "string");
- if (decoder.ok() && validate_utf8 &&
- !unibrow::Utf8::Validate(string_start, *length)) {
- decoder.error(string_start, "no valid UTF-8 string");
- }
- return offset;
+ uint32_t consume_string(uint32_t* length, bool validate_utf8,
+ const char* name) {
+ return wasm::consume_string(*this, length, validate_utf8, name);
}
uint32_t consume_sig_index(WasmModule* module, FunctionSig** sig) {
const byte* pos = pc_;
uint32_t sig_index = consume_u32v("signature index");
if (sig_index >= module->signatures.size()) {
- error(pos, pos, "signature index %u out of bounds (%d signatures)",
- sig_index, static_cast<int>(module->signatures.size()));
+ errorf(pos, "signature index %u out of bounds (%d signatures)", sig_index,
+ static_cast<int>(module->signatures.size()));
*sig = nullptr;
return 0;
}
@@ -893,8 +907,7 @@ class ModuleDecoder : public Decoder {
const byte* p = pc_;
uint32_t count = consume_u32v(name);
if (count > maximum) {
- error(p, p, "%s of %u exceeds internal limit of %zu", name, count,
- maximum);
+ errorf(p, "%s of %u exceeds internal limit of %zu", name, count, maximum);
return static_cast<uint32_t>(maximum);
}
return count;
@@ -918,8 +931,8 @@ class ModuleDecoder : public Decoder {
const byte* pos = pc_;
uint32_t index = consume_u32v(name);
if (index >= vector.size()) {
- error(pos, pos, "%s %u out of bounds (%d entries)", name, index,
- static_cast<int>(vector.size()));
+ errorf(pos, "%s %u out of bounds (%d entr%s)", name, index,
+ static_cast<int>(vector.size()), vector.size() == 1 ? "y" : "ies");
*ptr = nullptr;
return 0;
}
@@ -936,23 +949,23 @@ class ModuleDecoder : public Decoder {
*initial = consume_u32v("initial size");
*has_max = false;
if (*initial > max_initial) {
- error(pos, pos,
- "initial %s size (%u %s) is larger than implementation limit (%u)",
- name, *initial, units, max_initial);
+ errorf(pos,
+ "initial %s size (%u %s) is larger than implementation limit (%u)",
+ name, *initial, units, max_initial);
}
if (flags & 1) {
*has_max = true;
pos = pc();
*maximum = consume_u32v("maximum size");
if (*maximum > max_maximum) {
- error(
- pos, pos,
+ errorf(
+ pos,
"maximum %s size (%u %s) is larger than implementation limit (%u)",
name, *maximum, units, max_maximum);
}
if (*maximum < *initial) {
- error(pos, pos, "maximum %s size (%u %s) is less than initial (%u %s)",
- name, *maximum, units, *initial, units);
+ errorf(pos, "maximum %s size (%u %s) is less than initial (%u %s)",
+ name, *maximum, units, *initial, units);
}
} else {
*has_max = false;
@@ -964,7 +977,7 @@ class ModuleDecoder : public Decoder {
const byte* pos = pc();
uint8_t value = consume_u8(name);
if (value != expected) {
- error(pos, pos, "expected %s 0x%02x, got 0x%02x", name, expected, value);
+ errorf(pos, "expected %s 0x%02x, got 0x%02x", name, expected, value);
return false;
}
return true;
@@ -977,7 +990,7 @@ class ModuleDecoder : public Decoder {
unsigned len = 0;
switch (opcode) {
case kExprGetGlobal: {
- GlobalIndexOperand operand(this, pc() - 1);
+ GlobalIndexOperand<true> operand(this, pc() - 1);
if (module->globals.size() <= operand.index) {
error("global index is out of bounds");
expr.kind = WasmInitExpr::kNone;
@@ -999,28 +1012,28 @@ class ModuleDecoder : public Decoder {
break;
}
case kExprI32Const: {
- ImmI32Operand operand(this, pc() - 1);
+ ImmI32Operand<true> operand(this, pc() - 1);
expr.kind = WasmInitExpr::kI32Const;
expr.val.i32_const = operand.value;
len = operand.length;
break;
}
case kExprF32Const: {
- ImmF32Operand operand(this, pc() - 1);
+ ImmF32Operand<true> operand(this, pc() - 1);
expr.kind = WasmInitExpr::kF32Const;
expr.val.f32_const = operand.value;
len = operand.length;
break;
}
case kExprI64Const: {
- ImmI64Operand operand(this, pc() - 1);
+ ImmI64Operand<true> operand(this, pc() - 1);
expr.kind = WasmInitExpr::kI64Const;
expr.val.i64_const = operand.value;
len = operand.length;
break;
}
case kExprF64Const: {
- ImmF64Operand operand(this, pc() - 1);
+ ImmF64Operand<true> operand(this, pc() - 1);
expr.kind = WasmInitExpr::kF64Const;
expr.val.f64_const = operand.value;
len = operand.length;
@@ -1037,9 +1050,9 @@ class ModuleDecoder : public Decoder {
expr.kind = WasmInitExpr::kNone;
}
if (expected != kWasmStmt && TypeOf(module, expr) != kWasmI32) {
- error(pos, pos, "type error in init expression, expected %s, got %s",
- WasmOpcodes::TypeName(expected),
- WasmOpcodes::TypeName(TypeOf(module, expr)));
+ errorf(pos, "type error in init expression, expected %s, got %s",
+ WasmOpcodes::TypeName(expected),
+ WasmOpcodes::TypeName(TypeOf(module, expr)));
}
return expr;
}
@@ -1113,80 +1126,31 @@ class ModuleDecoder : public Decoder {
// FunctionSig stores the return types first.
ValueType* buffer =
- module_zone->NewArray<ValueType>(param_count + return_count);
+ module_zone_->NewArray<ValueType>(param_count + return_count);
uint32_t b = 0;
for (uint32_t i = 0; i < return_count; ++i) buffer[b++] = returns[i];
for (uint32_t i = 0; i < param_count; ++i) buffer[b++] = params[i];
- return new (module_zone) FunctionSig(return_count, param_count, buffer);
- }
-};
-
-// Helpers for nice error messages.
-class ModuleError : public ModuleResult {
- public:
- explicit ModuleError(const char* msg) {
- error_code = kError;
- size_t len = strlen(msg) + 1;
- char* result = new char[len];
- strncpy(result, msg, len);
- result[len - 1] = 0;
- error_msg.reset(result);
+ return new (module_zone_) FunctionSig(return_count, param_count, buffer);
}
};
-// Helpers for nice error messages.
-class FunctionError : public FunctionResult {
- public:
- explicit FunctionError(const char* msg) {
- error_code = kError;
- size_t len = strlen(msg) + 1;
- char* result = new char[len];
- strncpy(result, msg, len);
- result[len - 1] = 0;
- error_msg.reset(result);
- }
-};
-
-// Find section with given section code. Return Vector of the payload, or null
-// Vector if section is not found or module bytes are invalid.
-Vector<const byte> FindSection(const byte* module_start, const byte* module_end,
- WasmSectionCode code) {
- Decoder decoder(module_start, module_end);
-
- uint32_t magic_word = decoder.consume_u32("wasm magic");
- if (magic_word != kWasmMagic) decoder.error("wrong magic word");
-
- uint32_t magic_version = decoder.consume_u32("wasm version");
- if (magic_version != kWasmVersion) decoder.error("wrong wasm version");
-
- WasmSectionIterator section_iter(decoder);
- while (section_iter.more()) {
- if (section_iter.section_code() == code) {
- return Vector<const uint8_t>(section_iter.payload_start(),
- section_iter.payload_length());
- }
- decoder.consume_bytes(section_iter.payload_length(), "section payload");
- section_iter.advance();
- }
-
- return Vector<const uint8_t>();
-}
-
} // namespace
ModuleResult DecodeWasmModule(Isolate* isolate, const byte* module_start,
const byte* module_end, bool verify_functions,
ModuleOrigin origin) {
HistogramTimerScope wasm_decode_module_time_scope(
- isolate->counters()->wasm_decode_module_time());
+ IsWasm(origin) ? isolate->counters()->wasm_decode_wasm_module_time()
+ : isolate->counters()->wasm_decode_asm_module_time());
size_t size = module_end - module_start;
- if (module_start > module_end) return ModuleError("start > end");
+ if (module_start > module_end) return ModuleResult::Error("start > end");
if (size >= kV8MaxWasmModuleSize)
- return ModuleError("size > maximum module size");
+ return ModuleResult::Error("size > maximum module size: %zu", size);
// TODO(bradnelson): Improve histogram handling of size_t.
- isolate->counters()->wasm_module_size_bytes()->AddSample(
- static_cast<int>(size));
+ (IsWasm(origin) ? isolate->counters()->wasm_wasm_module_size_bytes()
+ : isolate->counters()->wasm_asm_module_size_bytes())
+ ->AddSample(static_cast<int>(size));
// Signatures are stored in zone memory, which have the same lifetime
// as the {module}.
Zone* zone = new Zone(isolate->allocator(), ZONE_NAME);
@@ -1196,8 +1160,10 @@ ModuleResult DecodeWasmModule(Isolate* isolate, const byte* module_start,
// TODO(titzer): this isn't accurate, since it doesn't count the data
// allocated on the C++ heap.
// https://bugs.chromium.org/p/chromium/issues/detail?id=657320
- isolate->counters()->wasm_decode_module_peak_memory_bytes()->AddSample(
- static_cast<int>(zone->allocation_size()));
+ (IsWasm(origin)
+ ? isolate->counters()->wasm_decode_wasm_module_peak_memory_bytes()
+ : isolate->counters()->wasm_decode_asm_module_peak_memory_bytes())
+ ->AddSample(static_cast<int>(zone->allocation_size()));
return result;
}
@@ -1218,51 +1184,23 @@ FunctionResult DecodeWasmFunction(Isolate* isolate, Zone* zone,
ModuleBytesEnv* module_env,
const byte* function_start,
const byte* function_end) {
+ bool is_wasm = module_env->module_env.is_wasm();
HistogramTimerScope wasm_decode_function_time_scope(
- isolate->counters()->wasm_decode_function_time());
+ is_wasm ? isolate->counters()->wasm_decode_wasm_function_time()
+ : isolate->counters()->wasm_decode_asm_function_time());
size_t size = function_end - function_start;
- if (function_start > function_end) return FunctionError("start > end");
+ if (function_start > function_end)
+ return FunctionResult::Error("start > end");
if (size > kV8MaxWasmFunctionSize)
- return FunctionError("size > maximum function size");
- isolate->counters()->wasm_function_size_bytes()->AddSample(
- static_cast<int>(size));
+ return FunctionResult::Error("size > maximum function size: %zu", size);
+ (is_wasm ? isolate->counters()->wasm_wasm_function_size_bytes()
+ : isolate->counters()->wasm_asm_function_size_bytes())
+ ->AddSample(static_cast<int>(size));
WasmFunction* function = new WasmFunction();
ModuleDecoder decoder(zone, function_start, function_end, kWasmOrigin);
return decoder.DecodeSingleFunction(module_env, function);
}
-FunctionOffsetsResult DecodeWasmFunctionOffsets(const byte* module_start,
- const byte* module_end) {
- // Find and decode the code section.
- Vector<const byte> code_section =
- FindSection(module_start, module_end, kCodeSectionCode);
- Decoder decoder(code_section.start(), code_section.end());
- FunctionOffsets table;
- if (!code_section.start()) {
- decoder.error("no code section");
- return decoder.toResult(std::move(table));
- }
-
- uint32_t functions_count = decoder.consume_u32v("functions count");
- // Reserve space for the entries, taking care of invalid input.
- if (functions_count < static_cast<unsigned>(code_section.length()) / 2) {
- table.reserve(functions_count);
- }
-
- int section_offset = static_cast<int>(code_section.start() - module_start);
- DCHECK_LE(0, section_offset);
- for (uint32_t i = 0; i < functions_count && decoder.ok(); ++i) {
- uint32_t size = decoder.consume_u32v("body size");
- int offset = static_cast<int>(section_offset + decoder.pc_offset());
- table.emplace_back(offset, static_cast<int>(size));
- DCHECK(table.back().first >= 0 && table.back().second >= 0);
- decoder.consume_bytes(size);
- }
- if (decoder.more()) decoder.error("unexpected additional bytes");
-
- return decoder.toResult(std::move(table));
-}
-
AsmJsOffsetsResult DecodeAsmJsOffsets(const byte* tables_start,
const byte* tables_end) {
AsmJsOffsets table;