LCOV - code coverage report
Current view: top level - src/wasm - streaming-decoder.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 154 154 100.0 %
Date: 2019-04-17 Functions: 36 43 83.7 %

          Line data    Source code
       1             : // Copyright 2017 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #include "src/wasm/streaming-decoder.h"
       6             : 
       7             : #include "src/base/template-utils.h"
       8             : #include "src/handles.h"
       9             : #include "src/objects-inl.h"
      10             : #include "src/objects/descriptor-array.h"
      11             : #include "src/objects/dictionary.h"
      12             : #include "src/wasm/decoder.h"
      13             : #include "src/wasm/leb-helper.h"
      14             : #include "src/wasm/module-decoder.h"
      15             : #include "src/wasm/wasm-code-manager.h"
      16             : #include "src/wasm/wasm-limits.h"
      17             : #include "src/wasm/wasm-objects.h"
      18             : #include "src/wasm/wasm-result.h"
      19             : 
      20             : #define TRACE_STREAMING(...)                            \
      21             :   do {                                                  \
      22             :     if (FLAG_trace_wasm_streaming) PrintF(__VA_ARGS__); \
      23             :   } while (false)
      24             : 
      25             : namespace v8 {
      26             : namespace internal {
      27             : namespace wasm {
      28             : 
      29        2873 : void StreamingDecoder::OnBytesReceived(Vector<const uint8_t> bytes) {
      30        2873 :   if (deserializing()) {
      31             :     wire_bytes_for_deserializing_.insert(wire_bytes_for_deserializing_.end(),
      32           8 :                                          bytes.begin(), bytes.end());
      33           8 :     return;
      34             :   }
      35             : 
      36             :   TRACE_STREAMING("OnBytesReceived(%zu bytes)\n", bytes.size());
      37             : 
      38             :   size_t current = 0;
      39       13057 :   while (ok() && current < bytes.size()) {
      40             :     size_t num_bytes =
      41       10192 :         state_->ReadBytes(this, bytes.SubVector(current, bytes.size()));
      42       10192 :     current += num_bytes;
      43       10192 :     module_offset_ += num_bytes;
      44       10192 :     if (state_->offset() == state_->buffer().size()) {
      45       18656 :       state_ = state_->Next(this);
      46             :     }
      47             :   }
      48        2865 :   total_size_ += bytes.size();
      49        2865 :   if (ok()) {
      50        1767 :     processor_->OnFinishedChunk();
      51             :   }
      52             : }
      53             : 
      54        6559 : size_t StreamingDecoder::DecodingState::ReadBytes(StreamingDecoder* streaming,
      55             :                                                   Vector<const uint8_t> bytes) {
      56       13118 :   Vector<uint8_t> remaining_buf = buffer() + offset();
      57       13118 :   size_t num_bytes = std::min(bytes.size(), remaining_buf.size());
      58             :   TRACE_STREAMING("ReadBytes(%zu bytes)\n", num_bytes);
      59             :   memcpy(remaining_buf.start(), &bytes.first(), num_bytes);
      60        6559 :   set_offset(offset() + num_bytes);
      61        6559 :   return num_bytes;
      62             : }
      63             : 
      64        1502 : void StreamingDecoder::Finish() {
      65             :   TRACE_STREAMING("Finish\n");
      66        1502 :   if (!ok()) return;
      67             : 
      68         551 :   if (deserializing()) {
      69           8 :     Vector<const uint8_t> wire_bytes = VectorOf(wire_bytes_for_deserializing_);
      70             :     // Try to deserialize the module from wire bytes and module bytes.
      71          12 :     if (processor_->Deserialize(compiled_module_bytes_, wire_bytes)) return;
      72             : 
      73             :     // Deserialization failed. Restart decoding using |wire_bytes|.
      74           4 :     compiled_module_bytes_ = {};
      75             :     DCHECK(!deserializing());
      76           4 :     OnBytesReceived(wire_bytes);
      77             :     // The decoder has received all wire bytes; fall through and finish.
      78             :   }
      79             : 
      80         547 :   if (!state_->is_finishing_allowed()) {
      81             :     // The byte stream ended too early, we report an error.
      82         285 :     Error("unexpected end of stream");
      83          95 :     return;
      84             :   }
      85             : 
      86         452 :   OwnedVector<uint8_t> bytes = OwnedVector<uint8_t>::New(total_size_);
      87             :   uint8_t* cursor = bytes.start();
      88             :   {
      89             : #define BYTES(x) (x & 0xFF), (x >> 8) & 0xFF, (x >> 16) & 0xFF, (x >> 24) & 0xFF
      90         452 :     uint8_t module_header[]{BYTES(kWasmMagic), BYTES(kWasmVersion)};
      91             : #undef BYTES
      92             :     memcpy(cursor, module_header, arraysize(module_header));
      93         452 :     cursor += arraysize(module_header);
      94             :   }
      95        1626 :   for (const auto& buffer : section_buffers_) {
      96             :     DCHECK_LE(cursor - bytes.start() + buffer->length(), total_size_);
      97             :     memcpy(cursor, buffer->bytes().start(), buffer->length());
      98        1174 :     cursor += buffer->length();
      99             :   }
     100        1356 :   processor_->OnFinishedStream(std::move(bytes));
     101             : }
     102             : 
     103          72 : void StreamingDecoder::Abort() {
     104             :   TRACE_STREAMING("Abort\n");
     105          72 :   if (!ok()) return;  // Failed already.
     106          72 :   processor_->OnAbort();
     107             :   Fail();
     108             : }
     109             : 
     110           4 : void StreamingDecoder::SetModuleCompiledCallback(
     111             :     ModuleCompiledCallback callback) {
     112             :   DCHECK_NULL(module_compiled_callback_);
     113           4 :   module_compiled_callback_ = callback;
     114           4 : }
     115             : 
     116           8 : bool StreamingDecoder::SetCompiledModuleBytes(
     117             :     Vector<const uint8_t> compiled_module_bytes) {
     118           8 :   compiled_module_bytes_ = compiled_module_bytes;
     119           8 :   return true;
     120             : }
     121             : 
     122             : namespace {
     123             : 
     124          40 : class TopTierCompiledCallback {
     125             :  public:
     126             :   TopTierCompiledCallback(std::weak_ptr<NativeModule> native_module,
     127             :                           StreamingDecoder::ModuleCompiledCallback callback)
     128             :       : native_module_(std::move(native_module)),
     129             :         callback_(std::move(callback)) {}
     130             : 
     131           8 :   void operator()(CompilationEvent event) const {
     132           8 :     if (event != CompilationEvent::kFinishedTopTierCompilation) return;
     133             :     // If the native module is still alive, get back a shared ptr and call the
     134             :     // callback.
     135           4 :     if (std::shared_ptr<NativeModule> native_module = native_module_.lock()) {
     136             :       callback_(native_module);
     137             :     }
     138             : #ifdef DEBUG
     139             :     DCHECK(!called_);
     140             :     called_ = true;
     141             : #endif
     142             :   }
     143             : 
     144             :  private:
     145             :   const std::weak_ptr<NativeModule> native_module_;
     146             :   const StreamingDecoder::ModuleCompiledCallback callback_;
     147             : #ifdef DEBUG
     148             :   mutable bool called_ = false;
     149             : #endif
     150             : };
     151             : 
     152             : }  // namespace
     153             : 
     154         284 : void StreamingDecoder::NotifyNativeModuleCreated(
     155             :     const std::shared_ptr<NativeModule>& native_module) {
     156         284 :   if (!module_compiled_callback_) return;
     157             :   auto* comp_state = native_module->compilation_state();
     158          16 :   comp_state->AddCallback(TopTierCompiledCallback{
     159           4 :       std::move(native_module), std::move(module_compiled_callback_)});
     160             :   module_compiled_callback_ = {};
     161             : }
     162             : 
     163             : // An abstract class to share code among the states which decode VarInts. This
     164             : // class takes over the decoding of the VarInt and then calls the actual decode
     165             : // code with the decoded value.
     166        3650 : class StreamingDecoder::DecodeVarInt32 : public DecodingState {
     167             :  public:
     168             :   explicit DecodeVarInt32(size_t max_value, const char* field_name)
     169        3650 :       : max_value_(max_value), field_name_(field_name) {}
     170             : 
     171       14304 :   Vector<uint8_t> buffer() override { return ArrayVector(byte_buffer_); }
     172             : 
     173             :   size_t ReadBytes(StreamingDecoder* streaming,
     174             :                    Vector<const uint8_t> bytes) override;
     175             : 
     176             :   std::unique_ptr<DecodingState> Next(StreamingDecoder* streaming) override;
     177             : 
     178             :   virtual std::unique_ptr<DecodingState> NextWithValue(
     179             :       StreamingDecoder* streaming) = 0;
     180             : 
     181             :  protected:
     182             :   uint8_t byte_buffer_[kMaxVarInt32Size];
     183             :   // The maximum valid value decoded in this state. {Next} returns an error if
     184             :   // this value is exceeded.
     185             :   const size_t max_value_;
     186             :   const char* const field_name_;
     187             :   size_t value_ = 0;
     188             :   size_t bytes_consumed_ = 0;
     189             : };
     190             : 
     191        4746 : class StreamingDecoder::DecodeModuleHeader : public DecodingState {
     192             :  public:
     193        5927 :   Vector<uint8_t> buffer() override { return ArrayVector(byte_buffer_); }
     194             : 
     195             :   std::unique_ptr<DecodingState> Next(StreamingDecoder* streaming) override;
     196             : 
     197             :  private:
     198             :   // Checks if the magic bytes of the module header are correct.
     199             :   void CheckHeader(Decoder* decoder);
     200             : 
     201             :   // The size of the module header.
     202             :   static constexpr size_t kModuleHeaderSize = 8;
     203             :   uint8_t byte_buffer_[kModuleHeaderSize];
     204             : };
     205             : 
     206        5092 : class StreamingDecoder::DecodeSectionID : public DecodingState {
     207             :  public:
     208             :   explicit DecodeSectionID(uint32_t module_offset)
     209        2546 :       : module_offset_(module_offset) {}
     210             : 
     211        4148 :   Vector<uint8_t> buffer() override { return {&id_, 1}; }
     212         452 :   bool is_finishing_allowed() const override { return true; }
     213             : 
     214             :   std::unique_ptr<DecodingState> Next(StreamingDecoder* streaming) override;
     215             : 
     216             :  private:
     217             :   uint8_t id_ = 0;
     218             :   // The start offset of this section in the module.
     219             :   const uint32_t module_offset_;
     220             : };
     221             : 
     222        4148 : class StreamingDecoder::DecodeSectionLength : public DecodeVarInt32 {
     223             :  public:
     224             :   explicit DecodeSectionLength(uint8_t id, uint32_t module_offset)
     225             :       : DecodeVarInt32(kV8MaxWasmModuleSize, "section length"),
     226             :         section_id_(id),
     227        2074 :         module_offset_(module_offset) {}
     228             : 
     229             :   std::unique_ptr<DecodingState> NextWithValue(
     230             :       StreamingDecoder* streaming) override;
     231             : 
     232             :  private:
     233             :   const uint8_t section_id_;
     234             :   // The start offset of this section in the module.
     235             :   const uint32_t module_offset_;
     236             : };
     237             : 
     238        2664 : class StreamingDecoder::DecodeSectionPayload : public DecodingState {
     239             :  public:
     240             :   explicit DecodeSectionPayload(SectionBuffer* section_buffer)
     241        1332 :       : section_buffer_(section_buffer) {}
     242             : 
     243        5528 :   Vector<uint8_t> buffer() override { return section_buffer_->payload(); }
     244             : 
     245             :   std::unique_ptr<DecodingState> Next(StreamingDecoder* streaming) override;
     246             : 
     247             :  private:
     248             :   SectionBuffer* const section_buffer_;
     249             : };
     250             : 
     251        1184 : class StreamingDecoder::DecodeNumberOfFunctions : public DecodeVarInt32 {
     252             :  public:
     253             :   explicit DecodeNumberOfFunctions(SectionBuffer* section_buffer)
     254             :       : DecodeVarInt32(kV8MaxWasmFunctions, "functions count"),
     255         592 :         section_buffer_(section_buffer) {}
     256             : 
     257             :   std::unique_ptr<DecodingState> NextWithValue(
     258             :       StreamingDecoder* streaming) override;
     259             : 
     260             :  private:
     261             :   SectionBuffer* const section_buffer_;
     262             : };
     263             : 
     264        1968 : class StreamingDecoder::DecodeFunctionLength : public DecodeVarInt32 {
     265             :  public:
     266             :   explicit DecodeFunctionLength(SectionBuffer* section_buffer,
     267             :                                 size_t buffer_offset,
     268             :                                 size_t num_remaining_functions)
     269             :       : DecodeVarInt32(kV8MaxWasmFunctionSize, "body size"),
     270             :         section_buffer_(section_buffer),
     271             :         buffer_offset_(buffer_offset),
     272             :         // We are reading a new function, so one function less is remaining.
     273         984 :         num_remaining_functions_(num_remaining_functions - 1) {
     274             :     DCHECK_GT(num_remaining_functions, 0);
     275             :   }
     276             : 
     277             :   std::unique_ptr<DecodingState> NextWithValue(
     278             :       StreamingDecoder* streaming) override;
     279             : 
     280             :  private:
     281             :   SectionBuffer* const section_buffer_;
     282             :   const size_t buffer_offset_;
     283             :   const size_t num_remaining_functions_;
     284             : };
     285             : 
     286        1698 : class StreamingDecoder::DecodeFunctionBody : public DecodingState {
     287             :  public:
     288             :   explicit DecodeFunctionBody(SectionBuffer* section_buffer,
     289             :                               size_t buffer_offset, size_t function_body_length,
     290             :                               size_t num_remaining_functions,
     291             :                               uint32_t module_offset)
     292             :       : section_buffer_(section_buffer),
     293             :         buffer_offset_(buffer_offset),
     294             :         function_body_length_(function_body_length),
     295             :         num_remaining_functions_(num_remaining_functions),
     296         849 :         module_offset_(module_offset) {}
     297             : 
     298        2629 :   Vector<uint8_t> buffer() override {
     299             :     Vector<uint8_t> remaining_buffer =
     300        2629 :         section_buffer_->bytes() + buffer_offset_;
     301        2629 :     return remaining_buffer.SubVector(0, function_body_length_);
     302             :   }
     303             : 
     304             :   std::unique_ptr<DecodingState> Next(StreamingDecoder* streaming) override;
     305             : 
     306             :  private:
     307             :   SectionBuffer* const section_buffer_;
     308             :   const size_t buffer_offset_;
     309             :   const size_t function_body_length_;
     310             :   const size_t num_remaining_functions_;
     311             :   const uint32_t module_offset_;
     312             : };
     313             : 
     314        3633 : size_t StreamingDecoder::DecodeVarInt32::ReadBytes(
     315             :     StreamingDecoder* streaming, Vector<const uint8_t> bytes) {
     316        3633 :   Vector<uint8_t> buf = buffer();
     317             :   Vector<uint8_t> remaining_buf = buf + offset();
     318        7266 :   size_t new_bytes = std::min(bytes.size(), remaining_buf.size());
     319             :   TRACE_STREAMING("ReadBytes of a VarInt\n");
     320             :   memcpy(remaining_buf.start(), &bytes.first(), new_bytes);
     321        3633 :   buf.Truncate(offset() + new_bytes);
     322             :   Decoder decoder(buf,
     323        3633 :                   streaming->module_offset() - static_cast<uint32_t>(offset()));
     324        7266 :   value_ = decoder.consume_u32v(field_name_);
     325             :   // The number of bytes we actually needed to read.
     326             :   DCHECK_GT(decoder.pc(), buffer().start());
     327        3633 :   bytes_consumed_ = static_cast<size_t>(decoder.pc() - buf.start());
     328             :   TRACE_STREAMING("  ==> %zu bytes consumed\n", bytes_consumed_);
     329             : 
     330        3633 :   if (decoder.failed()) {
     331          60 :     if (new_bytes == remaining_buf.size()) {
     332             :       // We only report an error if we read all bytes.
     333          78 :       streaming->Error(decoder.error());
     334             :     }
     335          60 :     set_offset(offset() + new_bytes);
     336          60 :     return new_bytes;
     337             :   }
     338             : 
     339             :   // We read all the bytes we needed.
     340             :   DCHECK_GT(bytes_consumed_, offset());
     341        3573 :   new_bytes = bytes_consumed_ - offset();
     342             :   // Set the offset to the buffer size to signal that we are at the end of this
     343             :   // section.
     344        7146 :   set_offset(buffer().size());
     345        3573 :   return new_bytes;
     346             : }
     347             : 
     348             : std::unique_ptr<StreamingDecoder::DecodingState>
     349        3612 : StreamingDecoder::DecodeVarInt32::Next(StreamingDecoder* streaming) {
     350        3612 :   if (!streaming->ok()) return nullptr;
     351             : 
     352        3573 :   if (value_ > max_value_) {
     353          72 :     std::ostringstream oss;
     354          36 :     oss << "function size > maximum function size: " << value_ << " < "
     355          36 :         << max_value_;
     356          72 :     return streaming->Error(oss.str());
     357             :   }
     358             : 
     359        3537 :   return NextWithValue(streaming);
     360             : }
     361             : 
     362             : std::unique_ptr<StreamingDecoder::DecodingState>
     363        1501 : StreamingDecoder::DecodeModuleHeader::Next(StreamingDecoder* streaming) {
     364             :   TRACE_STREAMING("DecodeModuleHeader\n");
     365        1501 :   streaming->ProcessModuleHeader();
     366        1501 :   if (!streaming->ok()) return nullptr;
     367             :   return base::make_unique<DecodeSectionID>(streaming->module_offset());
     368             : }
     369             : 
     370             : std::unique_ptr<StreamingDecoder::DecodingState>
     371        2074 : StreamingDecoder::DecodeSectionID::Next(StreamingDecoder* streaming) {
     372             :   TRACE_STREAMING("DecodeSectionID: %s section\n",
     373             :                   SectionName(static_cast<SectionCode>(id_)));
     374        4148 :   return base::make_unique<DecodeSectionLength>(id_, module_offset_);
     375             : }
     376             : 
     377             : std::unique_ptr<StreamingDecoder::DecodingState>
     378        2031 : StreamingDecoder::DecodeSectionLength::NextWithValue(
     379             :     StreamingDecoder* streaming) {
     380             :   TRACE_STREAMING("DecodeSectionLength(%zu)\n", value_);
     381             :   SectionBuffer* buf =
     382        2031 :       streaming->CreateNewBuffer(module_offset_, section_id_, value_,
     383        4062 :                                  buffer().SubVector(0, bytes_consumed_));
     384             :   DCHECK_NOT_NULL(buf);
     385        2031 :   if (value_ == 0) {
     386          56 :     if (section_id_ == SectionCode::kCodeSectionCode) {
     387          38 :       return streaming->Error("code section cannot have size 0");
     388             :     }
     389             :     // Process section without payload as well, to enforce section order and
     390             :     // other feature checks specific to each individual section.
     391          37 :     streaming->ProcessSection(buf);
     392          37 :     if (!streaming->ok()) return nullptr;
     393             :     // There is no payload, we go to the next section immediately.
     394             :     return base::make_unique<DecodeSectionID>(streaming->module_offset_);
     395             :   } else {
     396        1975 :     if (section_id_ == SectionCode::kCodeSectionCode) {
     397             :       // Explicitly check for multiple code sections as module decoder never
     398             :       // sees the code section and hence cannot track this section.
     399         643 :       if (streaming->code_section_processed_) {
     400             :         // TODO(mstarzinger): This error message (and other in this class) is
     401             :         // different for non-streaming decoding. Bring them in sync and test.
     402         102 :         return streaming->Error("code section can only appear once");
     403             :       }
     404         592 :       streaming->code_section_processed_ = true;
     405             :       // We reached the code section. All functions of the code section are put
     406             :       // into the same SectionBuffer.
     407        1184 :       return base::make_unique<DecodeNumberOfFunctions>(buf);
     408             :     }
     409             :     return base::make_unique<DecodeSectionPayload>(buf);
     410             :   }
     411             : }
     412             : 
     413             : std::unique_ptr<StreamingDecoder::DecodingState>
     414        1292 : StreamingDecoder::DecodeSectionPayload::Next(StreamingDecoder* streaming) {
     415             :   TRACE_STREAMING("DecodeSectionPayload\n");
     416        1292 :   streaming->ProcessSection(section_buffer_);
     417        1292 :   if (!streaming->ok()) return nullptr;
     418             :   return base::make_unique<DecodeSectionID>(streaming->module_offset());
     419             : }
     420             : 
     421             : std::unique_ptr<StreamingDecoder::DecodingState>
     422         576 : StreamingDecoder::DecodeNumberOfFunctions::NextWithValue(
     423             :     StreamingDecoder* streaming) {
     424             :   TRACE_STREAMING("DecodeNumberOfFunctions(%zu)\n", value_);
     425             :   // Copy the bytes we read into the section buffer.
     426         576 :   Vector<uint8_t> payload_buf = section_buffer_->payload();
     427         576 :   if (payload_buf.size() < bytes_consumed_) {
     428          48 :     return streaming->Error("invalid code section length");
     429             :   }
     430        1104 :   memcpy(payload_buf.start(), buffer().start(), bytes_consumed_);
     431             : 
     432             :   // {value} is the number of functions.
     433         552 :   if (value_ == 0) {
     434          16 :     if (payload_buf.size() != bytes_consumed_) {
     435          24 :       return streaming->Error("not all code section bytes were used");
     436             :     }
     437             :     return base::make_unique<DecodeSectionID>(streaming->module_offset());
     438             :   }
     439             : 
     440             :   DCHECK_GE(kMaxInt, value_);
     441        1072 :   streaming->StartCodeSection(static_cast<int>(value_),
     442         536 :                               streaming->section_buffers_.back());
     443         536 :   if (!streaming->ok()) return nullptr;
     444        1572 :   return base::make_unique<DecodeFunctionLength>(
     445         524 :       section_buffer_, section_buffer_->payload_offset() + bytes_consumed_,
     446             :       value_);
     447             : }
     448             : 
     449             : std::unique_ptr<StreamingDecoder::DecodingState>
     450         930 : StreamingDecoder::DecodeFunctionLength::NextWithValue(
     451             :     StreamingDecoder* streaming) {
     452             :   TRACE_STREAMING("DecodeFunctionLength(%zu)\n", value_);
     453             :   // Copy the bytes we consumed into the section buffer.
     454         930 :   Vector<uint8_t> fun_length_buffer = section_buffer_->bytes() + buffer_offset_;
     455         930 :   if (fun_length_buffer.size() < bytes_consumed_) {
     456          96 :     return streaming->Error("read past code section end");
     457             :   }
     458        1764 :   memcpy(fun_length_buffer.start(), buffer().start(), bytes_consumed_);
     459             : 
     460             :   // {value} is the length of the function.
     461         903 :   if (value_ == 0) return streaming->Error("invalid function length (0)");
     462             : 
     463         861 :   if (buffer_offset_ + bytes_consumed_ + value_ > section_buffer_->length()) {
     464          24 :     return streaming->Error("not enough code section bytes");
     465             :   }
     466             : 
     467             :   return base::make_unique<DecodeFunctionBody>(
     468             :       section_buffer_, buffer_offset_ + bytes_consumed_, value_,
     469             :       num_remaining_functions_, streaming->module_offset());
     470             : }
     471             : 
     472             : std::unique_ptr<StreamingDecoder::DecodingState>
     473         849 : StreamingDecoder::DecodeFunctionBody::Next(StreamingDecoder* streaming) {
     474             :   TRACE_STREAMING("DecodeFunctionBody\n");
     475        1698 :   streaming->ProcessFunctionBody(buffer(), module_offset_);
     476         849 :   if (!streaming->ok()) return nullptr;
     477             : 
     478         841 :   size_t end_offset = buffer_offset_ + function_body_length_;
     479         841 :   if (num_remaining_functions_ > 0) {
     480         920 :     return base::make_unique<DecodeFunctionLength>(section_buffer_, end_offset,
     481             :                                                    num_remaining_functions_);
     482             :   }
     483             :   // We just read the last function body. Continue with the next section.
     484         381 :   if (end_offset != section_buffer_->length()) {
     485          98 :     return streaming->Error("not all code section bytes were used");
     486             :   }
     487             :   return base::make_unique<DecodeSectionID>(streaming->module_offset());
     488             : }
     489             : 
     490        1582 : StreamingDecoder::StreamingDecoder(
     491             :     std::unique_ptr<StreamingProcessor> processor)
     492             :     : processor_(std::move(processor)),
     493             :       // A module always starts with a module header.
     494        4746 :       state_(new DecodeModuleHeader()) {}
     495             : 
     496        2031 : StreamingDecoder::SectionBuffer* StreamingDecoder::CreateNewBuffer(
     497             :     uint32_t module_offset, uint8_t section_id, size_t length,
     498             :     Vector<const uint8_t> length_bytes) {
     499             :   // Section buffers are allocated in the same order they appear in the module,
     500             :   // they will be processed and later on concatenated in that same order.
     501        4062 :   section_buffers_.emplace_back(std::make_shared<SectionBuffer>(
     502        2031 :       module_offset, section_id, length, length_bytes));
     503        2031 :   return section_buffers_.back().get();
     504             : }
     505             : 
     506             : }  // namespace wasm
     507             : }  // namespace internal
     508      121996 : }  // namespace v8
     509             : 
     510             : #undef TRACE_STREAMING

Generated by: LCOV version 1.10