natives-external.cc 5.68 KB
Newer Older
1 2 3 4 5 6
// Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/natives.h"

7
#include "src/base/logging.h"
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
#include "src/list.h"
#include "src/list-inl.h"
#include "src/snapshot-source-sink.h"
#include "src/vector.h"

namespace v8 {
namespace internal {


/**
 * NativesStore stores the 'native' (builtin) JS libraries.
 *
 * NativesStore needs to be initialized before using V8, usually by the
 * embedder calling v8::SetNativesDataBlob, which calls SetNativesFromFile
 * below.
 */
class NativesStore {
 public:
  ~NativesStore() {}

  int GetBuiltinsCount() { return native_names_.length(); }
  int GetDebuggerCount() { return debugger_count_; }
  Vector<const char> GetScriptName(int index) { return native_names_[index]; }
  Vector<const char> GetRawScriptSource(int index) {
    return native_source_[index];
  }

  int GetIndex(const char* name) {
    for (int i = 0; i < native_names_.length(); ++i) {
37 38 39
      int native_name_length = native_names_[i].length();
      if ((static_cast<int>(strlen(name)) == native_name_length) &&
          (strncmp(name, native_names_[i].start(), native_name_length) == 0)) {
40 41 42
        return i;
      }
    }
43
    DCHECK(false);
44 45 46 47
    return -1;
  }

  int GetRawScriptsSize() {
48
    DCHECK(false);  // Used for compression. Doesn't really make sense here.
49 50 51 52
    return 0;
  }

  Vector<const byte> GetScriptsSource() {
53
    DCHECK(false);  // Used for compression. Doesn't really make sense here.
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
    return Vector<const byte>();
  }

  static NativesStore* MakeFromScriptsSource(SnapshotByteSource* source) {
    NativesStore* store = new NativesStore;

    // We expect the libraries in the following format:
    //   int: # of debugger sources.
    //   2N blobs: N pairs of source name + actual source.
    //   then, repeat for non-debugger sources.
    int debugger_count = source->GetInt();
    for (int i = 0; i < debugger_count; ++i)
      store->ReadNameAndContentPair(source);
    int library_count = source->GetInt();
    for (int i = 0; i < library_count; ++i)
      store->ReadNameAndContentPair(source);

    store->debugger_count_ = debugger_count;
    return store;
  }

 private:
  NativesStore() : debugger_count_(0) {}

  bool ReadNameAndContentPair(SnapshotByteSource* bytes) {
    const byte* name;
    int name_length;
    const byte* source;
    int source_length;
    bool success = bytes->GetBlob(&name, &name_length) &&
                   bytes->GetBlob(&source, &source_length);
    if (success) {
      Vector<const char> name_vector(
          reinterpret_cast<const char*>(name), name_length);
      Vector<const char> source_vector(
          reinterpret_cast<const char*>(source), source_length);
      native_names_.Add(name_vector);
      native_source_.Add(source_vector);
    }
    return success;
  }

  List<Vector<const char> > native_names_;
  List<Vector<const char> > native_source_;
  int debugger_count_;

  DISALLOW_COPY_AND_ASSIGN(NativesStore);
};


template<NativeType type>
class NativesHolder {
 public:
  static NativesStore* get() {
108
    DCHECK(holder_);
109 110 111
    return holder_;
  }
  static void set(NativesStore* store) {
112
    DCHECK(store);
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
    holder_ = store;
  }

 private:
  static NativesStore* holder_;
};

template<NativeType type>
NativesStore* NativesHolder<type>::holder_ = NULL;


/**
 * Read the Natives (library sources) blob, as generated by js2c + the build
 * system.
 */
void SetNativesFromFile(StartupData* natives_blob) {
129 130 131
  DCHECK(natives_blob);
  DCHECK(natives_blob->data);
  DCHECK(natives_blob->raw_size > 0);
132 133 134 135 136 137

  SnapshotByteSource bytes(
      reinterpret_cast<const byte*>(natives_blob->data),
      natives_blob->raw_size);
  NativesHolder<CORE>::set(NativesStore::MakeFromScriptsSource(&bytes));
  NativesHolder<EXPERIMENTAL>::set(NativesStore::MakeFromScriptsSource(&bytes));
138
  DCHECK(!bytes.HasMore());
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198
}


// Implement NativesCollection<T> bsaed on NativesHolder + NativesStore.
//
// (The callers expect a purely static interface, since this is how the
//  natives are usually compiled in. Since we implement them based on
//  runtime content, we have to implement this indirection to offer
//  a static interface.)
template<NativeType type>
int NativesCollection<type>::GetBuiltinsCount() {
  return NativesHolder<type>::get()->GetBuiltinsCount();
}

template<NativeType type>
int NativesCollection<type>::GetDebuggerCount() {
  return NativesHolder<type>::get()->GetDebuggerCount();
}

template<NativeType type>
int NativesCollection<type>::GetIndex(const char* name) {
  return NativesHolder<type>::get()->GetIndex(name);
}

template<NativeType type>
int NativesCollection<type>::GetRawScriptsSize() {
  return NativesHolder<type>::get()->GetRawScriptsSize();
}

template<NativeType type>
Vector<const char> NativesCollection<type>::GetRawScriptSource(int index) {
  return NativesHolder<type>::get()->GetRawScriptSource(index);
}

template<NativeType type>
Vector<const char> NativesCollection<type>::GetScriptName(int index) {
  return NativesHolder<type>::get()->GetScriptName(index);
}

template<NativeType type>
Vector<const byte> NativesCollection<type>::GetScriptsSource() {
  return NativesHolder<type>::get()->GetScriptsSource();
}

template<NativeType type>
void NativesCollection<type>::SetRawScriptsSource(
    Vector<const char> raw_source) {
  CHECK(false);  // Use SetNativesFromFile for this implementation.
}


// The compiler can't 'see' all uses of the static methods and hence
// my chose to elide them. This we'll explicitly instantiate these.
template class NativesCollection<CORE>;
template class NativesCollection<EXPERIMENTAL>;
template class NativesCollection<D8>;
template class NativesCollection<TEST>;

}  // namespace v8::internal
}  // namespace v8