test: remove obsolete harmony flags
[platform/upstream/nodejs.git] / deps / v8 / src / natives-external.cc
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/natives.h"
6
7 #include "src/base/logging.h"
8 #include "src/list.h"
9 #include "src/list-inl.h"
10 #include "src/snapshot-source-sink.h"
11 #include "src/vector.h"
12
13 #ifndef V8_USE_EXTERNAL_STARTUP_DATA
14 #error natives-external.cc is used only for the external snapshot build.
15 #endif  // V8_USE_EXTERNAL_STARTUP_DATA
16
17
18 namespace v8 {
19 namespace internal {
20
21
22 /**
23  * NativesStore stores the 'native' (builtin) JS libraries.
24  *
25  * NativesStore needs to be initialized before using V8, usually by the
26  * embedder calling v8::SetNativesDataBlob, which calls SetNativesFromFile
27  * below.
28  */
29 class NativesStore {
30  public:
31   ~NativesStore() {
32     for (int i = 0; i < native_names_.length(); i++) {
33       native_names_[i].Dispose();
34     }
35   }
36
37   int GetBuiltinsCount() { return native_ids_.length(); }
38   int GetDebuggerCount() { return debugger_count_; }
39
40   Vector<const char> GetScriptSource(int index) {
41     return native_source_[index];
42   }
43
44   Vector<const char> GetScriptName(int index) { return native_names_[index]; }
45
46   int GetIndex(const char* id) {
47     for (int i = 0; i < native_ids_.length(); ++i) {
48       int native_id_length = native_ids_[i].length();
49       if ((static_cast<int>(strlen(id)) == native_id_length) &&
50           (strncmp(id, native_ids_[i].start(), native_id_length) == 0)) {
51         return i;
52       }
53     }
54     DCHECK(false);
55     return -1;
56   }
57
58   Vector<const char> GetScriptsSource() {
59     DCHECK(false);  // Not implemented.
60     return Vector<const char>();
61   }
62
63   static NativesStore* MakeFromScriptsSource(SnapshotByteSource* source) {
64     NativesStore* store = new NativesStore;
65
66     // We expect the libraries in the following format:
67     //   int: # of debugger sources.
68     //   2N blobs: N pairs of source name + actual source.
69     //   then, repeat for non-debugger sources.
70     int debugger_count = source->GetInt();
71     for (int i = 0; i < debugger_count; ++i)
72       store->ReadNameAndContentPair(source);
73     int library_count = source->GetInt();
74     for (int i = 0; i < library_count; ++i)
75       store->ReadNameAndContentPair(source);
76
77     store->debugger_count_ = debugger_count;
78     return store;
79   }
80
81  private:
82   NativesStore() : debugger_count_(0) {}
83
84   Vector<const char> NameFromId(const byte* id, int id_length) {
85     const char native[] = "native ";
86     const char extension[] = ".js";
87     Vector<char> name(Vector<char>::New(id_length + sizeof(native) - 1 +
88                                         sizeof(extension) - 1));
89     memcpy(name.start(), native, sizeof(native) - 1);
90     memcpy(name.start() + sizeof(native) - 1, id, id_length);
91     memcpy(name.start() + sizeof(native) - 1 + id_length, extension,
92            sizeof(extension) - 1);
93     return Vector<const char>::cast(name);
94   }
95
96   bool ReadNameAndContentPair(SnapshotByteSource* bytes) {
97     const byte* id;
98     int id_length;
99     const byte* source;
100     int source_length;
101     bool success = bytes->GetBlob(&id, &id_length) &&
102                    bytes->GetBlob(&source, &source_length);
103     if (success) {
104       Vector<const char> id_vector(reinterpret_cast<const char*>(id),
105                                    id_length);
106       Vector<const char> source_vector(
107           reinterpret_cast<const char*>(source), source_length);
108       native_ids_.Add(id_vector);
109       native_source_.Add(source_vector);
110       native_names_.Add(NameFromId(id, id_length));
111     }
112     return success;
113   }
114
115   List<Vector<const char> > native_ids_;
116   List<Vector<const char> > native_names_;
117   List<Vector<const char> > native_source_;
118   int debugger_count_;
119
120   DISALLOW_COPY_AND_ASSIGN(NativesStore);
121 };
122
123
124 template<NativeType type>
125 class NativesHolder {
126  public:
127   static NativesStore* get() {
128     DCHECK(holder_);
129     return holder_;
130   }
131   static void set(NativesStore* store) {
132     DCHECK(store);
133     holder_ = store;
134   }
135
136  private:
137   static NativesStore* holder_;
138 };
139
140 template<NativeType type>
141 NativesStore* NativesHolder<type>::holder_ = NULL;
142
143
144 /**
145  * Read the Natives (library sources) blob, as generated by js2c + the build
146  * system.
147  */
148 void SetNativesFromFile(StartupData* natives_blob) {
149   DCHECK(natives_blob);
150   DCHECK(natives_blob->data);
151   DCHECK(natives_blob->raw_size > 0);
152
153   SnapshotByteSource bytes(natives_blob->data, natives_blob->raw_size);
154   NativesHolder<CORE>::set(NativesStore::MakeFromScriptsSource(&bytes));
155   NativesHolder<EXPERIMENTAL>::set(NativesStore::MakeFromScriptsSource(&bytes));
156   DCHECK(!bytes.HasMore());
157 }
158
159
160 // Implement NativesCollection<T> bsaed on NativesHolder + NativesStore.
161 //
162 // (The callers expect a purely static interface, since this is how the
163 //  natives are usually compiled in. Since we implement them based on
164 //  runtime content, we have to implement this indirection to offer
165 //  a static interface.)
166 template<NativeType type>
167 int NativesCollection<type>::GetBuiltinsCount() {
168   return NativesHolder<type>::get()->GetBuiltinsCount();
169 }
170
171 template<NativeType type>
172 int NativesCollection<type>::GetDebuggerCount() {
173   return NativesHolder<type>::get()->GetDebuggerCount();
174 }
175
176 template<NativeType type>
177 int NativesCollection<type>::GetIndex(const char* name) {
178   return NativesHolder<type>::get()->GetIndex(name);
179 }
180
181 template <NativeType type>
182 Vector<const char> NativesCollection<type>::GetScriptSource(int index) {
183   return NativesHolder<type>::get()->GetScriptSource(index);
184 }
185
186 template<NativeType type>
187 Vector<const char> NativesCollection<type>::GetScriptName(int index) {
188   return NativesHolder<type>::get()->GetScriptName(index);
189 }
190
191 template <NativeType type>
192 Vector<const char> NativesCollection<type>::GetScriptsSource() {
193   return NativesHolder<type>::get()->GetScriptsSource();
194 }
195
196
197 // The compiler can't 'see' all uses of the static methods and hence
198 // my choice to elide them. This we'll explicitly instantiate these.
199 template class NativesCollection<CORE>;
200 template class NativesCollection<EXPERIMENTAL>;
201
202 }  // namespace v8::internal
203 }  // namespace v8