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