| Index: src/wasm/module-decoder.cc
|
| diff --git a/src/wasm/module-decoder.cc b/src/wasm/module-decoder.cc
|
| index 1f7ff0b5fe011fdc80b0f7735460e1e164e9ca1a..a2941299b798de7035bd3ab76c65d0117e925837 100644
|
| --- a/src/wasm/module-decoder.cc
|
| +++ b/src/wasm/module-decoder.cc
|
| @@ -107,17 +107,6 @@ class ModuleDecoder : public Decoder {
|
| TRACE("DecodeSection\n");
|
| pos = pc_;
|
|
|
| - // Read and check the section size.
|
| - int section_leb_length = 0;
|
| - uint32_t section_length =
|
| - consume_u32v(§ion_leb_length, "section length");
|
| - if (!checkAvailable(section_length)) {
|
| - // The section would extend beyond the end of the module.
|
| - break;
|
| - }
|
| - const byte* section_start = pc_;
|
| - const byte* expected_section_end = pc_ + section_length;
|
| -
|
| // Read the section name.
|
| int string_leb_length = 0;
|
| uint32_t string_length =
|
| @@ -128,15 +117,21 @@ class ModuleDecoder : public Decoder {
|
| TRACE("Section name of length %u couldn't be read\n", string_length);
|
| break;
|
| }
|
| - if (pc_ > expected_section_end) {
|
| - error(section_name_start, pc_,
|
| - "section name string %u longer than total section bytes %u",
|
| - string_length, section_length);
|
| - }
|
|
|
| WasmSection::Code section =
|
| WasmSection::lookup(section_name_start, string_length);
|
|
|
| + // Read and check the section size.
|
| + int section_leb_length = 0;
|
| + uint32_t section_length =
|
| + consume_u32v(§ion_leb_length, "section length");
|
| + if (!checkAvailable(section_length)) {
|
| + // The section would extend beyond the end of the module.
|
| + break;
|
| + }
|
| + const byte* section_start = pc_;
|
| + const byte* expected_section_end = pc_ + section_length;
|
| +
|
| current_order = CheckSectionOrder(current_order, section);
|
|
|
| switch (section) {
|
| @@ -144,12 +139,13 @@ class ModuleDecoder : public Decoder {
|
| // Terminate section decoding.
|
| limit_ = pc_;
|
| break;
|
| - case WasmSection::Code::Memory:
|
| + case WasmSection::Code::Memory: {
|
| int length;
|
| module->min_mem_pages = consume_u32v(&length, "min memory");
|
| module->max_mem_pages = consume_u32v(&length, "max memory");
|
| module->mem_export = consume_u8("export memory") != 0;
|
| break;
|
| + }
|
| case WasmSection::Code::Signatures: {
|
| int length;
|
| uint32_t signatures_count = consume_u32v(&length, "signatures count");
|
| @@ -159,7 +155,7 @@ class ModuleDecoder : public Decoder {
|
| if (failed()) break;
|
| TRACE("DecodeSignature[%d] module+%d\n", i,
|
| static_cast<int>(pc_ - start_));
|
| - FunctionSig* s = consume_sig(); // read function sig.
|
| + FunctionSig* s = consume_sig();
|
| module->signatures.push_back(s);
|
| }
|
| break;
|
| @@ -202,7 +198,7 @@ class ModuleDecoder : public Decoder {
|
| }
|
| break;
|
| }
|
| - case WasmSection::Code::Functions: {
|
| + case WasmSection::Code::OldFunctions: {
|
| int length;
|
| uint32_t functions_count = consume_u32v(&length, "functions count");
|
| module->functions.reserve(SafeReserve(functions_count));
|
| @@ -385,7 +381,7 @@ class ModuleDecoder : public Decoder {
|
| TRACE("%c", *(section_name_start + i));
|
| }
|
| TRACE("'\n");
|
| - consume_bytes(section_length - string_length - string_leb_length);
|
| + consume_bytes(section_length);
|
| break;
|
| }
|
|
|
| @@ -700,20 +696,48 @@ class ModuleDecoder : public Decoder {
|
| }
|
| }
|
|
|
| - // Parses an inline function signature.
|
| + // Parses a type entry, which is currently limited to functions only.
|
| FunctionSig* consume_sig() {
|
| + const byte* pos = pc_;
|
| + byte form = consume_u8("type form");
|
| + if (form != kWasmFunctionTypeForm) {
|
| + error(pos, pos, "expected function type form (0x%02x), got: 0x%02x",
|
| + kWasmFunctionTypeForm, form);
|
| + return nullptr;
|
| + }
|
| int length;
|
| - byte count = consume_u32v(&length, "param count");
|
| - LocalType ret = consume_local_type();
|
| - FunctionSig::Builder builder(module_zone, ret == kAstStmt ? 0 : 1, count);
|
| - if (ret != kAstStmt) builder.AddReturn(ret);
|
| -
|
| - for (int i = 0; i < count; i++) {
|
| + // parse parameter types
|
| + uint32_t param_count = consume_u32v(&length, "param count");
|
| + std::vector<LocalType> params;
|
| + for (uint32_t i = 0; i < param_count; i++) {
|
| LocalType param = consume_local_type();
|
| if (param == kAstStmt) error(pc_ - 1, "invalid void parameter type");
|
| - builder.AddParam(param);
|
| + params.push_back(param);
|
| + }
|
| +
|
| + // parse return types
|
| + const byte* pt = pc_;
|
| + uint32_t return_count = consume_u32v(&length, "return count");
|
| + if (return_count > kMaxReturnCount) {
|
| + error(pt, pt, "return count of %u exceeds maximum of %u", return_count,
|
| + kMaxReturnCount);
|
| + return nullptr;
|
| + }
|
| + std::vector<LocalType> returns;
|
| + for (uint32_t i = 0; i < return_count; i++) {
|
| + LocalType ret = consume_local_type();
|
| + if (ret == kAstStmt) error(pc_ - 1, "invalid void return type");
|
| + returns.push_back(ret);
|
| }
|
| - return builder.Build();
|
| +
|
| + // FunctionSig stores the return types first.
|
| + LocalType* buffer =
|
| + module_zone->NewArray<LocalType>(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);
|
| }
|
| };
|
|
|
|
|