// 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" #include "src/base/logging.h" #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 GetScriptName(int index) { return native_names_[index]; } Vector GetRawScriptSource(int index) { return native_source_[index]; } int GetIndex(const char* name) { for (int i = 0; i < native_names_.length(); ++i) { int native_name_length = native_names_[i].length(); if ((static_cast(strlen(name)) == native_name_length) && (strncmp(name, native_names_[i].start(), native_name_length) == 0)) { return i; } } DCHECK(false); return -1; } int GetRawScriptsSize() { DCHECK(false); // Used for compression. Doesn't really make sense here. return 0; } Vector GetScriptsSource() { DCHECK(false); // Used for compression. Doesn't really make sense here. return Vector(); } 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 name_vector( reinterpret_cast(name), name_length); Vector source_vector( reinterpret_cast(source), source_length); native_names_.Add(name_vector); native_source_.Add(source_vector); } return success; } List > native_names_; List > native_source_; int debugger_count_; DISALLOW_COPY_AND_ASSIGN(NativesStore); }; template class NativesHolder { public: static NativesStore* get() { DCHECK(holder_); return holder_; } static void set(NativesStore* store) { DCHECK(store); holder_ = store; } private: static NativesStore* holder_; }; template NativesStore* NativesHolder::holder_ = NULL; /** * Read the Natives (library sources) blob, as generated by js2c + the build * system. */ void SetNativesFromFile(StartupData* natives_blob) { DCHECK(natives_blob); DCHECK(natives_blob->data); DCHECK(natives_blob->raw_size > 0); SnapshotByteSource bytes( reinterpret_cast(natives_blob->data), natives_blob->raw_size); NativesHolder::set(NativesStore::MakeFromScriptsSource(&bytes)); NativesHolder::set(NativesStore::MakeFromScriptsSource(&bytes)); DCHECK(!bytes.HasMore()); } // Implement NativesCollection 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 int NativesCollection::GetBuiltinsCount() { return NativesHolder::get()->GetBuiltinsCount(); } template int NativesCollection::GetDebuggerCount() { return NativesHolder::get()->GetDebuggerCount(); } template int NativesCollection::GetIndex(const char* name) { return NativesHolder::get()->GetIndex(name); } template int NativesCollection::GetRawScriptsSize() { return NativesHolder::get()->GetRawScriptsSize(); } template Vector NativesCollection::GetRawScriptSource(int index) { return NativesHolder::get()->GetRawScriptSource(index); } template Vector NativesCollection::GetScriptName(int index) { return NativesHolder::get()->GetScriptName(index); } template Vector NativesCollection::GetScriptsSource() { return NativesHolder::get()->GetScriptsSource(); } template void NativesCollection::SetRawScriptsSource( Vector 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; template class NativesCollection; template class NativesCollection; template class NativesCollection; } // namespace v8::internal } // namespace v8