LCOV - code coverage report
Current view: top level - src/snapshot - natives-external.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 54 67 80.6 %
Date: 2019-03-21 Functions: 12 16 75.0 %

          Line data    Source code
       1             : // Copyright 2014 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/snapshot/natives.h"
       6             : 
       7             : #include "src/base/logging.h"
       8             : #include "src/snapshot/snapshot-source-sink.h"
       9             : #include "src/vector.h"
      10             : 
      11             : #ifndef V8_USE_EXTERNAL_STARTUP_DATA
      12             : #error natives-external.cc is used only for the external snapshot build.
      13             : #endif  // V8_USE_EXTERNAL_STARTUP_DATA
      14             : 
      15             : 
      16             : namespace v8 {
      17             : namespace internal {
      18             : 
      19             : 
      20             : /**
      21             :  * NativesStore stores the 'native' (builtin) JS libraries.
      22             :  *
      23             :  * NativesStore needs to be initialized before using V8, usually by the
      24             :  * embedder calling v8::SetNativesDataBlob, which calls SetNativesFromFile
      25             :  * below.
      26             :  */
      27             : class NativesStore {
      28             :  public:
      29      117912 :   ~NativesStore() {
      30      176868 :     for (size_t i = 0; i < native_names_.size(); i++) {
      31             :       native_names_[i].Dispose();
      32             :     }
      33       58956 :   }
      34             : 
      35         220 :   int GetBuiltinsCount() { return static_cast<int>(native_ids_.size()); }
      36             : 
      37             :   Vector<const char> GetScriptSource(int index) {
      38      123086 :     return native_source_[index];
      39             :   }
      40             : 
      41         220 :   Vector<const char> GetScriptName(int index) { return native_names_[index]; }
      42             : 
      43           0 :   int GetIndex(const char* id) {
      44           0 :     for (int i = 0; i < static_cast<int>(native_ids_.size()); ++i) {
      45           0 :       int native_id_length = native_ids_[i].length();
      46           0 :       if ((static_cast<int>(strlen(id)) == native_id_length) &&
      47           0 :           (strncmp(id, native_ids_[i].start(), native_id_length) == 0)) {
      48           0 :         return i;
      49             :       }
      50             :     }
      51           0 :     UNREACHABLE();
      52             :   }
      53             : 
      54           0 :   Vector<const char> GetScriptsSource() {
      55           0 :     UNREACHABLE();  // Not implemented.
      56             :   }
      57             : 
      58       60117 :   static NativesStore* MakeFromScriptsSource(SnapshotByteSource* source) {
      59       60117 :     NativesStore* store = new NativesStore;
      60             : 
      61             :     // We expect the libraries in the following format:
      62             :     //   int: # of sources.
      63             :     //   2N blobs: N pairs of source name + actual source.
      64       60117 :     int library_count = source->GetInt();
      65      180351 :     for (int i = 0; i < library_count; ++i)
      66       60117 :       store->ReadNameAndContentPair(source);
      67             : 
      68       60117 :     return store;
      69             :   }
      70             : 
      71             :  private:
      72             :   NativesStore() = default;
      73             : 
      74       60117 :   Vector<const char> NameFromId(const byte* id, int id_length) {
      75       60117 :     const char native[] = "native ";
      76       60117 :     const char extension[] = ".js";
      77             :     Vector<char> name(Vector<char>::New(id_length + sizeof(native) - 1 +
      78       60117 :                                         sizeof(extension) - 1));
      79             :     memcpy(name.start(), native, sizeof(native) - 1);
      80       60117 :     memcpy(name.start() + sizeof(native) - 1, id, id_length);
      81       60117 :     memcpy(name.start() + sizeof(native) - 1 + id_length, extension,
      82             :            sizeof(extension) - 1);
      83       60117 :     return Vector<const char>::cast(name);
      84             :   }
      85             : 
      86       60117 :   void ReadNameAndContentPair(SnapshotByteSource* bytes) {
      87             :     const byte* id;
      88             :     const byte* source;
      89       60117 :     int id_length = bytes->GetBlob(&id);
      90       60117 :     int source_length = bytes->GetBlob(&source);
      91       60117 :     native_ids_.emplace_back(reinterpret_cast<const char*>(id), id_length);
      92      120234 :     native_source_.emplace_back(reinterpret_cast<const char*>(source),
      93       60117 :                                 source_length);
      94      120234 :     native_names_.push_back(NameFromId(id, id_length));
      95       60117 :   }
      96             : 
      97             :   std::vector<Vector<const char>> native_ids_;
      98             :   std::vector<Vector<const char>> native_names_;
      99             :   std::vector<Vector<const char>> native_source_;
     100             : 
     101             :   DISALLOW_COPY_AND_ASSIGN(NativesStore);
     102             : };
     103             : 
     104             : 
     105             : template<NativeType type>
     106             : class NativesHolder {
     107             :  public:
     108             :   static NativesStore* get() {
     109       61873 :     CHECK(holder_);
     110             :     return holder_;
     111             :   }
     112             :   static void set(NativesStore* store) {
     113       60117 :     CHECK(store);
     114       60117 :     holder_ = store;
     115             :   }
     116       64662 :   static bool empty() { return holder_ == nullptr; }
     117       58996 :   static void Dispose() {
     118       58996 :     delete holder_;
     119       58996 :     holder_ = nullptr;
     120       58996 :   }
     121             : 
     122             :  private:
     123             :   static NativesStore* holder_;
     124             : };
     125             : 
     126             : template <NativeType type>
     127             : NativesStore* NativesHolder<type>::holder_ = nullptr;
     128             : 
     129             : // The natives blob. Memory is owned by caller.
     130             : static StartupData* natives_blob_ = nullptr;
     131             : 
     132             : /**
     133             :  * Read the Natives blob, as previously set by SetNativesFromFile.
     134             :  */
     135      120528 : void ReadNatives() {
     136      185190 :   if (natives_blob_ && NativesHolder<EXTRAS>::empty()) {
     137       60117 :     SnapshotByteSource bytes(natives_blob_->data, natives_blob_->raw_size);
     138       60117 :     NativesHolder<EXTRAS>::set(NativesStore::MakeFromScriptsSource(&bytes));
     139             :     DCHECK(!bytes.HasMore());
     140             :   }
     141      120528 : }
     142             : 
     143             : 
     144             : /**
     145             :  * Set the Natives (library sources) blob, as generated by js2c + the build
     146             :  * system.
     147             :  */
     148       60107 : void SetNativesFromFile(StartupData* natives_blob) {
     149             :   DCHECK(!natives_blob_);
     150             :   DCHECK(natives_blob);
     151             :   DCHECK(natives_blob->data);
     152             :   DCHECK_GT(natives_blob->raw_size, 0);
     153             : 
     154       60107 :   natives_blob_ = natives_blob;
     155       60107 :   ReadNatives();
     156       60107 : }
     157             : 
     158             : 
     159             : /**
     160             :  * Release memory allocated by SetNativesFromFile.
     161             :  */
     162       58996 : void DisposeNatives() {
     163       58996 :   NativesHolder<EXTRAS>::Dispose();
     164       58996 : }
     165             : 
     166             : 
     167             : // Implement NativesCollection<T> bsaed on NativesHolder + NativesStore.
     168             : //
     169             : // (The callers expect a purely static interface, since this is how the
     170             : //  natives are usually compiled in. Since we implement them based on
     171             : //  runtime content, we have to implement this indirection to offer
     172             : //  a static interface.)
     173             : template<NativeType type>
     174         220 : int NativesCollection<type>::GetBuiltinsCount() {
     175         220 :   return NativesHolder<type>::get()->GetBuiltinsCount();
     176             : }
     177             : 
     178             : template<NativeType type>
     179           0 : int NativesCollection<type>::GetIndex(const char* name) {
     180           0 :   return NativesHolder<type>::get()->GetIndex(name);
     181             : }
     182             : 
     183             : template <NativeType type>
     184       61543 : Vector<const char> NativesCollection<type>::GetScriptSource(int index) {
     185       61543 :   return NativesHolder<type>::get()->GetScriptSource(index);
     186             : }
     187             : 
     188             : template<NativeType type>
     189         110 : Vector<const char> NativesCollection<type>::GetScriptName(int index) {
     190         110 :   return NativesHolder<type>::get()->GetScriptName(index);
     191             : }
     192             : 
     193             : template <NativeType type>
     194           0 : Vector<const char> NativesCollection<type>::GetScriptsSource() {
     195           0 :   return NativesHolder<type>::get()->GetScriptsSource();
     196             : }
     197             : 
     198             : 
     199             : // Explicit template instantiations.
     200             : #define INSTANTIATE_TEMPLATES(T)                                            \
     201             :   template int NativesCollection<T>::GetBuiltinsCount();                    \
     202             :   template int NativesCollection<T>::GetIndex(const char* name);            \
     203             :   template Vector<const char> NativesCollection<T>::GetScriptSource(int i); \
     204             :   template Vector<const char> NativesCollection<T>::GetScriptName(int i);   \
     205             :   template Vector<const char> NativesCollection<T>::GetScriptsSource();
     206             : INSTANTIATE_TEMPLATES(EXTRAS)
     207             : #undef INSTANTIATE_TEMPLATES
     208             : 
     209             : }  // namespace internal
     210      120214 : }  // namespace v8

Generated by: LCOV version 1.10