LCOV - code coverage report
Current view: top level - src/wasm - streaming-decoder.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 138 139 99.3 %
Date: 2017-10-20 Functions: 32 41 78.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-objects.h"
      16             : #include "src/wasm/wasm-result.h"
      17             : 
      18             : namespace v8 {
      19             : namespace internal {
      20             : namespace wasm {
      21             : 
      22       14433 : void StreamingDecoder::OnBytesReceived(Vector<const uint8_t> bytes) {
      23             :   size_t current = 0;
      24       14433 :   while (ok() && current < bytes.size()) {
      25             :     size_t num_bytes =
      26       17622 :         state_->ReadBytes(this, bytes.SubVector(current, bytes.size()));
      27        8811 :     current += num_bytes;
      28        8811 :     module_offset_ += num_bytes;
      29        8811 :     if (state_->is_finished()) {
      30       15884 :       state_ = state_->Next(this);
      31             :     }
      32             :   }
      33        2811 :   total_size_ += bytes.size();
      34        2811 :   if (ok()) {
      35        1666 :     processor_->OnFinishedChunk();
      36             :   }
      37        2811 : }
      38             : 
      39        5688 : size_t StreamingDecoder::DecodingState::ReadBytes(StreamingDecoder* streaming,
      40       11376 :                                                   Vector<const uint8_t> bytes) {
      41       11376 :   size_t num_bytes = std::min(bytes.size(), remaining());
      42       11376 :   memcpy(buffer() + offset(), &bytes.first(), num_bytes);
      43        5688 :   set_offset(offset() + num_bytes);
      44        5688 :   return num_bytes;
      45             : }
      46             : 
      47        1402 : void StreamingDecoder::Finish() {
      48        1402 :   if (!ok()) {
      49             :     return;
      50             :   }
      51             : 
      52         431 :   if (!state_->is_finishing_allowed()) {
      53             :     // The byte stream ended too early, we report an error.
      54         261 :     Error("unexpected end of stream");
      55          87 :     return;
      56             :   }
      57             : 
      58         344 :   std::unique_ptr<uint8_t[]> bytes(new uint8_t[total_size_]);
      59             :   uint8_t* cursor = bytes.get();
      60             :   {
      61             : #define BYTES(x) (x & 0xff), (x >> 8) & 0xff, (x >> 16) & 0xff, (x >> 24) & 0xff
      62         344 :     uint8_t module_header[]{BYTES(kWasmMagic), BYTES(kWasmVersion)};
      63             : #undef BYTES
      64             :     memcpy(cursor, module_header, arraysize(module_header));
      65         344 :     cursor += arraysize(module_header);
      66             :   }
      67        1430 :   for (auto&& buffer : section_buffers_) {
      68             :     DCHECK_LE(cursor - bytes.get() + buffer->length(), total_size_);
      69         742 :     memcpy(cursor, buffer->bytes(), buffer->length());
      70         742 :     cursor += buffer->length();
      71             :   }
      72        1032 :   processor_->OnFinishedStream(std::move(bytes), total_size_);
      73             : }
      74             : 
      75          72 : void StreamingDecoder::Abort() {
      76         138 :   if (ok()) processor_->OnAbort();
      77          72 : }
      78             : 
      79             : // An abstract class to share code among the states which decode VarInts. This
      80             : // class takes over the decoding of the VarInt and then calls the actual decode
      81             : // code with the decoded value.
      82        3150 : class StreamingDecoder::DecodeVarInt32 : public DecodingState {
      83             :  public:
      84             :   explicit DecodeVarInt32(size_t max_value, const char* field_name)
      85        3150 :       : max_value_(max_value), field_name_(field_name) {}
      86       15425 :   uint8_t* buffer() override { return byte_buffer_; }
      87        9369 :   size_t size() const override { return kMaxVarInt32Size; }
      88             : 
      89             :   size_t ReadBytes(StreamingDecoder* streaming,
      90             :                    Vector<const uint8_t> bytes) override;
      91             : 
      92             :   std::unique_ptr<DecodingState> Next(StreamingDecoder* streaming) override;
      93             : 
      94             :   virtual std::unique_ptr<DecodingState> NextWithValue(
      95             :       StreamingDecoder* streaming) = 0;
      96             : 
      97             :   size_t value() const { return value_; }
      98             :   size_t bytes_needed() const { return bytes_needed_; }
      99             : 
     100             :  private:
     101             :   uint8_t byte_buffer_[kMaxVarInt32Size];
     102             :   // The maximum valid value decoded in this state. {Next} returns an error if
     103             :   // this value is exceeded.
     104             :   size_t max_value_;
     105             :   const char* field_name_;
     106             :   size_t value_ = 0;
     107             :   size_t bytes_needed_ = 0;
     108             : };
     109             : 
     110        4422 : class StreamingDecoder::DecodeModuleHeader : public DecodingState {
     111             :  public:
     112        5695 :   size_t size() const override { return kModuleHeaderSize; }
     113        3563 :   uint8_t* buffer() override { return byte_buffer_; }
     114             : 
     115             :   std::unique_ptr<DecodingState> Next(StreamingDecoder* streaming) override;
     116             : 
     117             :  private:
     118             :   // Checks if the magic bytes of the module header are correct.
     119             :   void CheckHeader(Decoder* decoder);
     120             : 
     121             :   // The size of the module header.
     122             :   static constexpr size_t kModuleHeaderSize = 8;
     123             :   uint8_t byte_buffer_[kModuleHeaderSize];
     124             : };
     125             : 
     126        4092 : class StreamingDecoder::DecodeSectionID : public DecodingState {
     127             :  public:
     128             :   explicit DecodeSectionID(uint32_t module_offset)
     129        2046 :       : module_offset_(module_offset) {}
     130             : 
     131        3344 :   size_t size() const override { return 1; }
     132        1672 :   uint8_t* buffer() override { return &id_; }
     133         344 :   bool is_finishing_allowed() const override { return true; }
     134             : 
     135             :   uint8_t id() const { return id_; }
     136             : 
     137             :   uint32_t module_offset() const { return module_offset_; }
     138             : 
     139             :   std::unique_ptr<DecodingState> Next(StreamingDecoder* streaming) override;
     140             : 
     141             :  private:
     142             :   uint8_t id_ = 0;
     143             :   // The start offset of this section in the module.
     144             :   uint32_t module_offset_;
     145             : };
     146             : 
     147        3344 : class StreamingDecoder::DecodeSectionLength : public DecodeVarInt32 {
     148             :  public:
     149             :   explicit DecodeSectionLength(uint8_t id, uint32_t module_offset)
     150             :       : DecodeVarInt32(kV8MaxWasmModuleSize, "section length"),
     151             :         section_id_(id),
     152        1672 :         module_offset_(module_offset) {}
     153             : 
     154             :   uint8_t section_id() const { return section_id_; }
     155             : 
     156             :   uint32_t module_offset() const { return module_offset_; }
     157             : 
     158             :   std::unique_ptr<DecodingState> NextWithValue(
     159             :       StreamingDecoder* streaming) override;
     160             : 
     161             :  private:
     162             :   uint8_t section_id_;
     163             :   // The start offset of this section in the module.
     164             :   uint32_t module_offset_;
     165             : };
     166             : 
     167        1980 : class StreamingDecoder::DecodeSectionPayload : public DecodingState {
     168             :  public:
     169             :   explicit DecodeSectionPayload(SectionBuffer* section_buffer)
     170         990 :       : section_buffer_(section_buffer) {}
     171             : 
     172        4208 :   size_t size() const override { return section_buffer_->payload_length(); }
     173        1052 :   uint8_t* buffer() override {
     174        2104 :     return section_buffer_->bytes() + section_buffer_->payload_offset();
     175             :   }
     176             : 
     177             :   std::unique_ptr<DecodingState> Next(StreamingDecoder* streaming) override;
     178             : 
     179             :   SectionBuffer* section_buffer() const { return section_buffer_; }
     180             : 
     181             :  private:
     182             :   SectionBuffer* section_buffer_;
     183             : };
     184             : 
     185        1056 : class StreamingDecoder::DecodeNumberOfFunctions : public DecodeVarInt32 {
     186             :  public:
     187             :   explicit DecodeNumberOfFunctions(SectionBuffer* section_buffer)
     188             :       : DecodeVarInt32(kV8MaxWasmFunctions, "functions count"),
     189         528 :         section_buffer_(section_buffer) {}
     190             : 
     191             :   SectionBuffer* section_buffer() const { return section_buffer_; }
     192             : 
     193             :   std::unique_ptr<DecodingState> NextWithValue(
     194             :       StreamingDecoder* streaming) override;
     195             : 
     196             :  private:
     197             :   SectionBuffer* section_buffer_;
     198             : };
     199             : 
     200        1900 : class StreamingDecoder::DecodeFunctionLength : public DecodeVarInt32 {
     201             :  public:
     202             :   explicit DecodeFunctionLength(SectionBuffer* section_buffer,
     203             :                                 size_t buffer_offset,
     204             :                                 size_t num_remaining_functions)
     205             :       : DecodeVarInt32(kV8MaxWasmFunctionSize, "body size"),
     206             :         section_buffer_(section_buffer),
     207             :         buffer_offset_(buffer_offset),
     208             :         // We are reading a new function, so one function less is remaining.
     209         950 :         num_remaining_functions_(num_remaining_functions - 1) {
     210             :     DCHECK_GT(num_remaining_functions, 0);
     211             :   }
     212             : 
     213             :   size_t num_remaining_functions() const { return num_remaining_functions_; }
     214             :   size_t buffer_offset() const { return buffer_offset_; }
     215             :   SectionBuffer* section_buffer() const { return section_buffer_; }
     216             : 
     217             :   std::unique_ptr<DecodingState> NextWithValue(
     218             :       StreamingDecoder* streaming) override;
     219             : 
     220             :  private:
     221             :   SectionBuffer* section_buffer_;
     222             :   size_t buffer_offset_;
     223             :   size_t num_remaining_functions_;
     224             : };
     225             : 
     226        1582 : class StreamingDecoder::DecodeFunctionBody : public DecodingState {
     227             :  public:
     228             :   explicit DecodeFunctionBody(SectionBuffer* section_buffer,
     229             :                               size_t buffer_offset, size_t function_length,
     230             :                               size_t num_remaining_functions,
     231             :                               uint32_t module_offset)
     232             :       : section_buffer_(section_buffer),
     233             :         buffer_offset_(buffer_offset),
     234             :         size_(function_length),
     235             :         num_remaining_functions_(num_remaining_functions),
     236         791 :         module_offset_(module_offset) {}
     237             : 
     238             :   size_t buffer_offset() const { return buffer_offset_; }
     239        3246 :   size_t size() const override { return size_; }
     240        1623 :   uint8_t* buffer() override {
     241        3246 :     return section_buffer_->bytes() + buffer_offset_;
     242             :   }
     243             :   size_t num_remaining_functions() const { return num_remaining_functions_; }
     244             :   uint32_t module_offset() const { return module_offset_; }
     245             :   SectionBuffer* section_buffer() const { return section_buffer_; }
     246             : 
     247             :   std::unique_ptr<DecodingState> Next(StreamingDecoder* streaming) override;
     248             : 
     249             :  private:
     250             :   SectionBuffer* section_buffer_;
     251             :   size_t buffer_offset_;
     252             :   size_t size_;
     253             :   size_t num_remaining_functions_;
     254             :   uint32_t module_offset_;
     255             : };
     256             : 
     257        3123 : size_t StreamingDecoder::DecodeVarInt32::ReadBytes(
     258        3123 :     StreamingDecoder* streaming, Vector<const uint8_t> bytes) {
     259       18808 :   size_t bytes_read = std::min(bytes.size(), remaining());
     260        6246 :   memcpy(buffer() + offset(), &bytes.first(), bytes_read);
     261        6246 :   Decoder decoder(buffer(), buffer() + offset() + bytes_read,
     262             :                   streaming->module_offset());
     263        6246 :   value_ = decoder.consume_u32v(field_name_);
     264             :   // The number of bytes we actually needed to read.
     265             :   DCHECK_GT(decoder.pc(), buffer());
     266        3123 :   bytes_needed_ = static_cast<size_t>(decoder.pc() - buffer());
     267             : 
     268        3123 :   if (decoder.failed()) {
     269          70 :     if (offset() + bytes_read == size()) {
     270             :       // We only report an error if we read all bytes.
     271         225 :       streaming->Error(decoder.toResult(nullptr));
     272             :     }
     273          70 :     set_offset(offset() + bytes_read);
     274          70 :     return bytes_read;
     275             :   } else {
     276             :     DCHECK_GT(bytes_needed_, offset());
     277        3053 :     size_t result = bytes_needed_ - offset();
     278             :     // We read all the bytes we needed.
     279        3053 :     set_offset(size());
     280        3053 :     return result;
     281             :   }
     282             : }
     283             : 
     284             : std::unique_ptr<StreamingDecoder::DecodingState>
     285        6199 : StreamingDecoder::DecodeVarInt32::Next(StreamingDecoder* streaming) {
     286        3098 :   if (!streaming->ok()) {
     287             :     return nullptr;
     288             :   }
     289        3053 :   if (value() > max_value_) {
     290          48 :     std::ostringstream oss;
     291          96 :     oss << "function size > maximum function size: " << value() << " < "
     292          48 :         << max_value_;
     293          96 :     return streaming->Error(oss.str());
     294             :   }
     295             : 
     296        3005 :   return NextWithValue(streaming);
     297             : }
     298             : 
     299             : std::unique_ptr<StreamingDecoder::DecodingState>
     300        3697 : StreamingDecoder::DecodeModuleHeader::Next(StreamingDecoder* streaming) {
     301        1431 :   streaming->ProcessModuleHeader();
     302        1431 :   if (streaming->ok()) {
     303        1670 :     return base::make_unique<DecodeSectionID>(streaming->module_offset());
     304             :   }
     305             :   return nullptr;
     306             : }
     307             : 
     308             : std::unique_ptr<StreamingDecoder::DecodingState>
     309        3344 : StreamingDecoder::DecodeSectionID::Next(StreamingDecoder* streaming) {
     310        5016 :   return base::make_unique<DecodeSectionLength>(id(), module_offset());
     311             : }
     312             : 
     313             : std::unique_ptr<StreamingDecoder::DecodingState>
     314        1619 : StreamingDecoder::DecodeSectionLength::NextWithValue(
     315        4888 :     StreamingDecoder* streaming) {
     316             :   SectionBuffer* buf = streaming->CreateNewBuffer(
     317             :       module_offset(), section_id(), value(),
     318        8052 :       Vector<const uint8_t>(buffer(), static_cast<int>(bytes_needed())));
     319        1619 :   if (!buf) return nullptr;
     320        1576 :   if (value() == 0) {
     321          58 :     if (section_id() == SectionCode::kCodeSectionCode) {
     322          42 :       return streaming->Error("Code section cannot have size 0");
     323             :     } else {
     324          37 :       streaming->ProcessSection(buf);
     325          37 :       if (streaming->ok()) {
     326             :         // There is no payload, we go to the next section immediately.
     327          74 :         return base::make_unique<DecodeSectionID>(streaming->module_offset());
     328             :       } else {
     329             :         return nullptr;
     330             :       }
     331             :     }
     332             :   } else {
     333        1518 :     if (section_id() == SectionCode::kCodeSectionCode) {
     334             :       // We reached the code section. All functions of the code section are put
     335             :       // into the same SectionBuffer.
     336        1056 :       return base::make_unique<DecodeNumberOfFunctions>(buf);
     337             :     } else {
     338             :       return base::make_unique<DecodeSectionPayload>(buf);
     339             :     }
     340             :   }
     341             : }
     342             : 
     343             : std::unique_ptr<StreamingDecoder::DecodingState>
     344        2822 : StreamingDecoder::DecodeSectionPayload::Next(StreamingDecoder* streaming) {
     345         950 :   streaming->ProcessSection(section_buffer());
     346         950 :   if (streaming->ok()) {
     347        1844 :     return base::make_unique<DecodeSectionID>(streaming->module_offset());
     348             :   }
     349             :   return nullptr;
     350             : }
     351             : 
     352             : std::unique_ptr<StreamingDecoder::DecodingState>
     353         508 : StreamingDecoder::DecodeNumberOfFunctions::NextWithValue(
     354         952 :     StreamingDecoder* streaming) {
     355             :   // Copy the bytes we read into the section buffer.
     356        2920 :   if (section_buffer_->payload_length() >= bytes_needed()) {
     357         968 :     memcpy(section_buffer_->bytes() + section_buffer_->payload_offset(),
     358         484 :            buffer(), bytes_needed());
     359             :   } else {
     360          48 :     return streaming->Error("Invalid code section length");
     361             :   }
     362             : 
     363             :   // {value} is the number of functions.
     364         484 :   if (value() > 0) {
     365         484 :     streaming->StartCodeSection(value());
     366         484 :     if (!streaming->ok()) return nullptr;
     367             :     return base::make_unique<DecodeFunctionLength>(
     368         936 :         section_buffer(), section_buffer()->payload_offset() + bytes_needed(),
     369        1404 :         value());
     370             :   } else {
     371           0 :     return base::make_unique<DecodeSectionID>(streaming->module_offset());
     372             :   }
     373             : }
     374             : 
     375             : std::unique_ptr<StreamingDecoder::DecodingState>
     376         878 : StreamingDecoder::DecodeFunctionLength::NextWithValue(
     377        3196 :     StreamingDecoder* streaming) {
     378             :   // Copy the bytes we read into the section buffer.
     379        2515 :   if (section_buffer_->length() >= buffer_offset_ + bytes_needed()) {
     380        1660 :     memcpy(section_buffer_->bytes() + buffer_offset_, buffer(), bytes_needed());
     381             :   } else {
     382          96 :     return streaming->Error("Invalid code section length");
     383             :   }
     384             : 
     385             :   // {value} is the length of the function.
     386         830 :   if (value() == 0) {
     387          46 :     return streaming->Error("Invalid function length (0)");
     388        1614 :   } else if (buffer_offset() + bytes_needed() + value() >
     389         807 :              section_buffer()->length()) {
     390          48 :     streaming->Error("not enough code section bytes");
     391             :     return nullptr;
     392             :   }
     393             : 
     394             :   return base::make_unique<DecodeFunctionBody>(
     395             :       section_buffer(), buffer_offset() + bytes_needed(), value(),
     396        2373 :       num_remaining_functions(), streaming->module_offset());
     397             : }
     398             : 
     399             : std::unique_ptr<StreamingDecoder::DecodingState>
     400        4207 : StreamingDecoder::DecodeFunctionBody::Next(StreamingDecoder* streaming) {
     401             :   streaming->ProcessFunctionBody(
     402        1582 :       Vector<const uint8_t>(buffer(), static_cast<int>(size())),
     403         791 :       module_offset());
     404         791 :   if (!streaming->ok()) {
     405             :     return nullptr;
     406             :   }
     407         791 :   if (num_remaining_functions() != 0) {
     408             :     return base::make_unique<DecodeFunctionLength>(
     409        1928 :         section_buffer(), buffer_offset() + size(), num_remaining_functions());
     410             :   } else {
     411         618 :     if (buffer_offset() + size() != section_buffer()->length()) {
     412         114 :       return streaming->Error("not all code section bytes were used");
     413             :     }
     414         504 :     return base::make_unique<DecodeSectionID>(streaming->module_offset());
     415             :   }
     416             : }
     417             : 
     418        1474 : StreamingDecoder::StreamingDecoder(
     419             :     std::unique_ptr<StreamingProcessor> processor)
     420             :     : processor_(std::move(processor)),
     421             :       // A module always starts with a module header.
     422        2948 :       state_(new DecodeModuleHeader()) {}
     423             : }  // namespace wasm
     424             : }  // namespace internal
     425             : }  // namespace v8

Generated by: LCOV version 1.10