LCOV - code coverage report
Current view: top level - src/wasm - streaming-decoder.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 167 167 100.0 %
Date: 2019-01-20 Functions: 36 45 80.0 %

          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        2908 : void StreamingDecoder::OnBytesReceived(Vector<const uint8_t> bytes) {
      30        2908 :   if (deserializing()) {
      31             :     wire_bytes_for_deserializing_.insert(wire_bytes_for_deserializing_.end(),
      32          10 :                                          bytes.begin(), bytes.end());
      33        2908 :     return;
      34             :   }
      35             : 
      36             :   TRACE_STREAMING("OnBytesReceived(%zu bytes)\n", bytes.size());
      37             : 
      38             :   size_t current = 0;
      39       12459 :   while (ok() && current < bytes.size()) {
      40             :     size_t num_bytes =
      41        9561 :         state_->ReadBytes(this, bytes.SubVector(current, bytes.size()));
      42        9561 :     current += num_bytes;
      43        9561 :     module_offset_ += num_bytes;
      44        9561 :     if (state_->offset() == state_->buffer().size()) {
      45       17376 :       state_ = state_->Next(this);
      46             :     }
      47             :   }
      48        2898 :   total_size_ += bytes.size();
      49        2898 :   if (ok()) {
      50        1774 :     processor_->OnFinishedChunk();
      51             :   }
      52             : }
      53             : 
      54        6145 : size_t StreamingDecoder::DecodingState::ReadBytes(StreamingDecoder* streaming,
      55       12290 :                                                   Vector<const uint8_t> bytes) {
      56       12290 :   Vector<uint8_t> remaining_buf = buffer() + offset();
      57       12290 :   size_t num_bytes = std::min(bytes.size(), remaining_buf.size());
      58             :   TRACE_STREAMING("ReadBytes(%zu bytes)\n", num_bytes);
      59        6145 :   memcpy(remaining_buf.start(), &bytes.first(), num_bytes);
      60        6145 :   set_offset(offset() + num_bytes);
      61        6145 :   return num_bytes;
      62             : }
      63             : 
      64        1480 : void StreamingDecoder::Finish() {
      65             :   TRACE_STREAMING("Finish\n");
      66        1480 :   if (!ok()) return;
      67             : 
      68         520 :   if (deserializing()) {
      69          10 :     Vector<const uint8_t> wire_bytes = VectorOf(wire_bytes_for_deserializing_);
      70             :     // Try to deserialize the module from wire bytes and module bytes.
      71          15 :     if (processor_->Deserialize(compiled_module_bytes_, wire_bytes)) return;
      72             : 
      73             :     // Deserialization failed. Restart decoding using |wire_bytes|.
      74           5 :     compiled_module_bytes_ = {};
      75             :     DCHECK(!deserializing());
      76           5 :     OnBytesReceived(wire_bytes);
      77             :     // The decoder has received all wire bytes; fall through and finish.
      78             :   }
      79             : 
      80         515 :   if (!state_->is_finishing_allowed()) {
      81             :     // The byte stream ended too early, we report an error.
      82         291 :     Error("unexpected end of stream");
      83          97 :     return;
      84             :   }
      85             : 
      86         418 :   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         418 :     uint8_t module_header[]{BYTES(kWasmMagic), BYTES(kWasmVersion)};
      91             : #undef BYTES
      92             :     memcpy(cursor, module_header, arraysize(module_header));
      93         418 :     cursor += arraysize(module_header);
      94             :   }
      95        1810 :   for (const auto& buffer : section_buffers_) {
      96             :     DCHECK_LE(cursor - bytes.start() + buffer->length(), total_size_);
      97        1948 :     memcpy(cursor, buffer->bytes().start(), buffer->length());
      98         974 :     cursor += buffer->length();
      99             :   }
     100        1254 :   processor_->OnFinishedStream(std::move(bytes));
     101             : }
     102             : 
     103          70 : void StreamingDecoder::Abort() {
     104             :   TRACE_STREAMING("Abort\n");
     105         140 :   if (!ok()) return;  // Failed already.
     106          65 :   processor_->OnAbort();
     107             :   Fail();
     108             : }
     109             : 
     110           5 : void StreamingDecoder::SetModuleCompiledCallback(
     111             :     ModuleCompiledCallback callback) {
     112             :   DCHECK_NULL(module_compiled_callback_);
     113           5 :   module_compiled_callback_ = callback;
     114           5 : }
     115             : 
     116          10 : bool StreamingDecoder::SetCompiledModuleBytes(
     117             :     Vector<const uint8_t> compiled_module_bytes) {
     118          10 :   compiled_module_bytes_ = compiled_module_bytes;
     119          10 :   return true;
     120             : }
     121             : 
     122             : namespace {
     123             : 
     124          50 : class TopTierCompiledCallback {
     125             :  public:
     126             :   TopTierCompiledCallback(std::shared_ptr<NativeModule> native_module,
     127             :                           StreamingDecoder::ModuleCompiledCallback callback)
     128             :       : native_module_(std::move(native_module)),
     129           5 :         callback_(std::move(callback)) {}
     130             : 
     131             :   void operator()(CompilationEvent event, const WasmError* error) const {
     132          10 :     if (event != CompilationEvent::kFinishedTopTierCompilation) return;
     133             :     DCHECK_NULL(error);
     134           5 :     callback_(native_module_);
     135             : #ifdef DEBUG
     136             :     DCHECK(!called_);
     137             :     called_ = true;
     138             : #endif
     139             :   }
     140             : 
     141             :  private:
     142             :   const std::shared_ptr<NativeModule> native_module_;
     143             :   const StreamingDecoder::ModuleCompiledCallback callback_;
     144             : #ifdef DEBUG
     145             :   mutable bool called_ = false;
     146             : #endif
     147             : };
     148             : 
     149             : }  // namespace
     150             : 
     151         253 : void StreamingDecoder::NotifyNativeModuleCreated(
     152             :     const std::shared_ptr<NativeModule>& native_module) {
     153         506 :   if (!module_compiled_callback_) return;
     154           5 :   auto* comp_state = native_module->compilation_state();
     155             :   comp_state->AddCallback(TopTierCompiledCallback{
     156          20 :       std::move(native_module), std::move(module_compiled_callback_)});
     157             :   module_compiled_callback_ = {};
     158             : }
     159             : 
     160             : // An abstract class to share code among the states which decode VarInts. This
     161             : // class takes over the decoding of the VarInt and then calls the actual decode
     162             : // code with the decoded value.
     163        3440 : class StreamingDecoder::DecodeVarInt32 : public DecodingState {
     164             :  public:
     165             :   explicit DecodeVarInt32(size_t max_value, const char* field_name)
     166        3440 :       : max_value_(max_value), field_name_(field_name) {}
     167             : 
     168       13420 :   Vector<uint8_t> buffer() override { return ArrayVector(byte_buffer_); }
     169             : 
     170             :   size_t ReadBytes(StreamingDecoder* streaming,
     171             :                    Vector<const uint8_t> bytes) override;
     172             : 
     173             :   std::unique_ptr<DecodingState> Next(StreamingDecoder* streaming) override;
     174             : 
     175             :   virtual std::unique_ptr<DecodingState> NextWithValue(
     176             :       StreamingDecoder* streaming) = 0;
     177             : 
     178             :  protected:
     179             :   uint8_t byte_buffer_[kMaxVarInt32Size];
     180             :   // The maximum valid value decoded in this state. {Next} returns an error if
     181             :   // this value is exceeded.
     182             :   const size_t max_value_;
     183             :   const char* const field_name_;
     184             :   size_t value_ = 0;
     185             :   size_t bytes_consumed_ = 0;
     186             : };
     187             : 
     188        4680 : class StreamingDecoder::DecodeModuleHeader : public DecodingState {
     189             :  public:
     190        5890 :   Vector<uint8_t> buffer() override { return ArrayVector(byte_buffer_); }
     191             : 
     192             :   std::unique_ptr<DecodingState> Next(StreamingDecoder* streaming) override;
     193             : 
     194             :  private:
     195             :   // Checks if the magic bytes of the module header are correct.
     196             :   void CheckHeader(Decoder* decoder);
     197             : 
     198             :   // The size of the module header.
     199             :   static constexpr size_t kModuleHeaderSize = 8;
     200             :   uint8_t byte_buffer_[kModuleHeaderSize];
     201             : };
     202             : 
     203        4604 : class StreamingDecoder::DecodeSectionID : public DecodingState {
     204             :  public:
     205             :   explicit DecodeSectionID(uint32_t module_offset)
     206        2302 :       : module_offset_(module_offset) {}
     207             : 
     208        3718 :   Vector<uint8_t> buffer() override { return {&id_, 1}; }
     209         418 :   bool is_finishing_allowed() const override { return true; }
     210             : 
     211             :   std::unique_ptr<DecodingState> Next(StreamingDecoder* streaming) override;
     212             : 
     213             :  private:
     214             :   uint8_t id_ = 0;
     215             :   // The start offset of this section in the module.
     216             :   const uint32_t module_offset_;
     217             : };
     218             : 
     219        3718 : class StreamingDecoder::DecodeSectionLength : public DecodeVarInt32 {
     220             :  public:
     221             :   explicit DecodeSectionLength(uint8_t id, uint32_t module_offset)
     222             :       : DecodeVarInt32(kV8MaxWasmModuleSize, "section length"),
     223             :         section_id_(id),
     224        1859 :         module_offset_(module_offset) {}
     225             : 
     226             :   std::unique_ptr<DecodingState> NextWithValue(
     227             :       StreamingDecoder* streaming) override;
     228             : 
     229             :  private:
     230             :   const uint8_t section_id_;
     231             :   // The start offset of this section in the module.
     232             :   const uint32_t module_offset_;
     233             : };
     234             : 
     235        2270 : class StreamingDecoder::DecodeSectionPayload : public DecodingState {
     236             :  public:
     237             :   explicit DecodeSectionPayload(SectionBuffer* section_buffer)
     238        1135 :       : section_buffer_(section_buffer) {}
     239             : 
     240        4752 :   Vector<uint8_t> buffer() override { return section_buffer_->payload(); }
     241             : 
     242             :   std::unique_ptr<DecodingState> Next(StreamingDecoder* streaming) override;
     243             : 
     244             :  private:
     245             :   SectionBuffer* const section_buffer_;
     246             : };
     247             : 
     248        1152 : class StreamingDecoder::DecodeNumberOfFunctions : public DecodeVarInt32 {
     249             :  public:
     250             :   explicit DecodeNumberOfFunctions(SectionBuffer* section_buffer)
     251             :       : DecodeVarInt32(kV8MaxWasmFunctions, "functions count"),
     252         576 :         section_buffer_(section_buffer) {}
     253             : 
     254             :   std::unique_ptr<DecodingState> NextWithValue(
     255             :       StreamingDecoder* streaming) override;
     256             : 
     257             :  private:
     258             :   SectionBuffer* const section_buffer_;
     259             : };
     260             : 
     261        2010 : class StreamingDecoder::DecodeFunctionLength : public DecodeVarInt32 {
     262             :  public:
     263             :   explicit DecodeFunctionLength(SectionBuffer* section_buffer,
     264             :                                 size_t buffer_offset,
     265             :                                 size_t num_remaining_functions)
     266             :       : DecodeVarInt32(kV8MaxWasmFunctionSize, "body size"),
     267             :         section_buffer_(section_buffer),
     268             :         buffer_offset_(buffer_offset),
     269             :         // We are reading a new function, so one function less is remaining.
     270        1005 :         num_remaining_functions_(num_remaining_functions - 1) {
     271             :     DCHECK_GT(num_remaining_functions, 0);
     272             :   }
     273             : 
     274             :   std::unique_ptr<DecodingState> NextWithValue(
     275             :       StreamingDecoder* streaming) override;
     276             : 
     277             :  private:
     278             :   SectionBuffer* const section_buffer_;
     279             :   const size_t buffer_offset_;
     280             :   const size_t num_remaining_functions_;
     281             : };
     282             : 
     283        1712 : class StreamingDecoder::DecodeFunctionBody : public DecodingState {
     284             :  public:
     285             :   explicit DecodeFunctionBody(SectionBuffer* section_buffer,
     286             :                               size_t buffer_offset, size_t function_body_length,
     287             :                               size_t num_remaining_functions,
     288             :                               uint32_t module_offset)
     289             :       : section_buffer_(section_buffer),
     290             :         buffer_offset_(buffer_offset),
     291             :         function_body_length_(function_body_length),
     292             :         num_remaining_functions_(num_remaining_functions),
     293         856 :         module_offset_(module_offset) {}
     294             : 
     295        2650 :   Vector<uint8_t> buffer() override {
     296             :     Vector<uint8_t> remaining_buffer =
     297        2650 :         section_buffer_->bytes() + buffer_offset_;
     298        2650 :     return remaining_buffer.SubVector(0, function_body_length_);
     299             :   }
     300             : 
     301             :   std::unique_ptr<DecodingState> Next(StreamingDecoder* streaming) override;
     302             : 
     303             :  private:
     304             :   SectionBuffer* const section_buffer_;
     305             :   const size_t buffer_offset_;
     306             :   const size_t function_body_length_;
     307             :   const size_t num_remaining_functions_;
     308             :   const uint32_t module_offset_;
     309             : };
     310             : 
     311        3416 : size_t StreamingDecoder::DecodeVarInt32::ReadBytes(
     312        3416 :     StreamingDecoder* streaming, Vector<const uint8_t> bytes) {
     313        3416 :   Vector<uint8_t> buf = buffer();
     314       10248 :   Vector<uint8_t> remaining_buf = buf + offset();
     315        6832 :   size_t new_bytes = std::min(bytes.size(), remaining_buf.size());
     316             :   TRACE_STREAMING("ReadBytes of a VarInt\n");
     317        3416 :   memcpy(remaining_buf.start(), &bytes.first(), new_bytes);
     318        3416 :   buf.Truncate(offset() + new_bytes);
     319             :   Decoder decoder(buf, streaming->module_offset());
     320        6832 :   value_ = decoder.consume_u32v(field_name_);
     321             :   // The number of bytes we actually needed to read.
     322             :   DCHECK_GT(decoder.pc(), buffer().start());
     323        3416 :   bytes_consumed_ = static_cast<size_t>(decoder.pc() - buf.start());
     324             :   TRACE_STREAMING("  ==> %zu bytes consumed\n", bytes_consumed_);
     325             : 
     326        3416 :   if (decoder.failed()) {
     327          65 :     if (new_bytes == remaining_buf.size()) {
     328             :       // We only report an error if we read all bytes.
     329          84 :       streaming->Error(decoder.error());
     330             :     }
     331          65 :     set_offset(offset() + new_bytes);
     332          65 :     return new_bytes;
     333             :   }
     334             : 
     335             :   // We read all the bytes we needed.
     336             :   DCHECK_GT(bytes_consumed_, offset());
     337        3351 :   new_bytes = bytes_consumed_ - offset();
     338             :   // Set the offset to the buffer size to signal that we are at the end of this
     339             :   // section.
     340        6702 :   set_offset(buffer().size());
     341        3351 :   return new_bytes;
     342             : }
     343             : 
     344             : std::unique_ptr<StreamingDecoder::DecodingState>
     345        3393 : StreamingDecoder::DecodeVarInt32::Next(StreamingDecoder* streaming) {
     346        3393 :   if (!streaming->ok()) return nullptr;
     347             : 
     348        3351 :   if (value_ > max_value_) {
     349          42 :     std::ostringstream oss;
     350          84 :     oss << "function size > maximum function size: " << value_ << " < "
     351          42 :         << max_value_;
     352          84 :     return streaming->Error(oss.str());
     353             :   }
     354             : 
     355        3309 :   return NextWithValue(streaming);
     356             : }
     357             : 
     358             : std::unique_ptr<StreamingDecoder::DecodingState>
     359        2382 : StreamingDecoder::DecodeModuleHeader::Next(StreamingDecoder* streaming) {
     360             :   TRACE_STREAMING("DecodeModuleHeader\n");
     361        1488 :   streaming->ProcessModuleHeader();
     362        1488 :   if (!streaming->ok()) return nullptr;
     363        1788 :   return base::make_unique<DecodeSectionID>(streaming->module_offset());
     364             : }
     365             : 
     366             : std::unique_ptr<StreamingDecoder::DecodingState>
     367        1859 : StreamingDecoder::DecodeSectionID::Next(StreamingDecoder* streaming) {
     368             :   TRACE_STREAMING("DecodeSectionID: %s section\n",
     369             :                   SectionName(static_cast<SectionCode>(id_)));
     370        3718 :   return base::make_unique<DecodeSectionLength>(id_, module_offset_);
     371             : }
     372             : 
     373             : std::unique_ptr<StreamingDecoder::DecodingState>
     374        1811 : StreamingDecoder::DecodeSectionLength::NextWithValue(
     375             :     StreamingDecoder* streaming) {
     376             :   TRACE_STREAMING("DecodeSectionLength(%zu)\n", value_);
     377             :   SectionBuffer* buf =
     378             :       streaming->CreateNewBuffer(module_offset_, section_id_, value_,
     379        3622 :                                  buffer().SubVector(0, bytes_consumed_));
     380        1811 :   if (!buf) return nullptr;
     381        1768 :   if (value_ == 0) {
     382          57 :     if (section_id_ == SectionCode::kCodeSectionCode) {
     383          40 :       return streaming->Error("Code section cannot have size 0");
     384             :     }
     385          37 :     streaming->ProcessSection(buf);
     386          37 :     if (!streaming->ok()) return nullptr;
     387             :     // There is no payload, we go to the next section immediately.
     388          74 :     return base::make_unique<DecodeSectionID>(streaming->module_offset_);
     389             :   } else {
     390        1711 :     if (section_id_ == SectionCode::kCodeSectionCode) {
     391             :       // We reached the code section. All functions of the code section are put
     392             :       // into the same SectionBuffer.
     393        1152 :       return base::make_unique<DecodeNumberOfFunctions>(buf);
     394             :     }
     395             :     return base::make_unique<DecodeSectionPayload>(buf);
     396             :   }
     397             : }
     398             : 
     399             : std::unique_ptr<StreamingDecoder::DecodingState>
     400        2160 : StreamingDecoder::DecodeSectionPayload::Next(StreamingDecoder* streaming) {
     401             :   TRACE_STREAMING("DecodeSectionPayload\n");
     402        1092 :   streaming->ProcessSection(section_buffer_);
     403        1092 :   if (!streaming->ok()) return nullptr;
     404        2136 :   return base::make_unique<DecodeSectionID>(streaming->module_offset());
     405             : }
     406             : 
     407             : std::unique_ptr<StreamingDecoder::DecodingState>
     408         558 : StreamingDecoder::DecodeNumberOfFunctions::NextWithValue(
     409           5 :     StreamingDecoder* streaming) {
     410             :   TRACE_STREAMING("DecodeNumberOfFunctions(%zu)\n", value_);
     411             :   // Copy the bytes we read into the section buffer.
     412        1061 :   Vector<uint8_t> payload_buf = section_buffer_->payload();
     413         558 :   if (payload_buf.size() < bytes_consumed_) {
     414          48 :     return streaming->Error("Invalid code section length");
     415             :   }
     416        1068 :   memcpy(payload_buf.start(), buffer().start(), bytes_consumed_);
     417             : 
     418             :   // {value} is the number of functions.
     419         534 :   if (value_ == 0) {
     420          17 :     if (payload_buf.size() != bytes_consumed_) {
     421          24 :       return streaming->Error("not all code section bytes were consumed");
     422             :     }
     423          10 :     return base::make_unique<DecodeSectionID>(streaming->module_offset());
     424             :   }
     425             : 
     426        1034 :   streaming->StartCodeSection(value_, streaming->section_buffers_.back());
     427         517 :   if (!streaming->ok()) return nullptr;
     428             :   return base::make_unique<DecodeFunctionLength>(
     429        1006 :       section_buffer_, section_buffer_->payload_offset() + bytes_consumed_,
     430        1509 :       value_);
     431             : }
     432             : 
     433             : std::unique_ptr<StreamingDecoder::DecodingState>
     434         940 : StreamingDecoder::DecodeFunctionLength::NextWithValue(
     435         856 :     StreamingDecoder* streaming) {
     436             :   TRACE_STREAMING("DecodeFunctionLength(%zu)\n", value_);
     437             :   // Copy the bytes we consumed into the section buffer.
     438         940 :   Vector<uint8_t> fun_length_buffer = section_buffer_->bytes() + buffer_offset_;
     439         940 :   if (fun_length_buffer.size() < bytes_consumed_) {
     440          96 :     return streaming->Error("Invalid code section length");
     441             :   }
     442        1784 :   memcpy(fun_length_buffer.start(), buffer().start(), bytes_consumed_);
     443             : 
     444             :   // {value} is the length of the function.
     445         914 :   if (value_ == 0) return streaming->Error("Invalid function length (0)");
     446             : 
     447        1740 :   if (buffer_offset_ + bytes_consumed_ + value_ > section_buffer_->length()) {
     448          28 :     return streaming->Error("not enough code section bytes");
     449             :   }
     450             : 
     451             :   return base::make_unique<DecodeFunctionBody>(
     452             :       section_buffer_, buffer_offset_ + bytes_consumed_, value_,
     453        1712 :       num_remaining_functions_, streaming->module_offset());
     454             : }
     455             : 
     456             : std::unique_ptr<StreamingDecoder::DecodingState>
     457        1154 : StreamingDecoder::DecodeFunctionBody::Next(StreamingDecoder* streaming) {
     458             :   TRACE_STREAMING("DecodeFunctionBody\n");
     459        1712 :   streaming->ProcessFunctionBody(buffer(), module_offset_);
     460         856 :   if (!streaming->ok()) return nullptr;
     461             : 
     462         856 :   size_t end_offset = buffer_offset_ + function_body_length_;
     463         856 :   if (num_remaining_functions_ > 0) {
     464             :     return base::make_unique<DecodeFunctionLength>(section_buffer_, end_offset,
     465        1004 :                                                    num_remaining_functions_);
     466             :   }
     467             :   // We just read the last function body. Continue with the next section.
     468         708 :   if (end_offset != section_buffer_->length()) {
     469         112 :     return streaming->Error("not all code section bytes were used");
     470             :   }
     471         596 :   return base::make_unique<DecodeSectionID>(streaming->module_offset());
     472             : }
     473             : 
     474        1560 : StreamingDecoder::StreamingDecoder(
     475             :     std::unique_ptr<StreamingProcessor> processor)
     476             :     : processor_(std::move(processor)),
     477             :       // A module always starts with a module header.
     478        4680 :       state_(new DecodeModuleHeader()) {}
     479             : 
     480        1811 : StreamingDecoder::SectionBuffer* StreamingDecoder::CreateNewBuffer(
     481             :     uint32_t module_offset, uint8_t section_id, size_t length,
     482             :     Vector<const uint8_t> length_bytes) {
     483             :   // Check the order of sections. Unknown sections can appear at any position.
     484        1811 :   if (section_id != kUnknownSectionCode) {
     485        1698 :     if (section_id < next_section_id_) {
     486         129 :       Error("Unexpected section");
     487          43 :       return nullptr;
     488             :     }
     489        1655 :     next_section_id_ = section_id + 1;
     490             :   }
     491             :   section_buffers_.emplace_back(std::make_shared<SectionBuffer>(
     492        3536 :       module_offset, section_id, length, length_bytes));
     493        1768 :   return section_buffers_.back().get();
     494             : }
     495             : 
     496             : }  // namespace wasm
     497             : }  // namespace internal
     498      183867 : }  // namespace v8
     499             : 
     500             : #undef TRACE_STREAMING

Generated by: LCOV version 1.10