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#ifndef V8_BOOTSTRAPPER_H_
6#define V8_BOOTSTRAPPER_H_
7
8#include "src/factory.h"
9
10namespace v8 {
11namespace internal {
12
13// A SourceCodeCache uses a FixedArray to store pairs of
14// (OneByteString*, JSFunction*), mapping names of native code files
15// (runtime.js, etc.) to precompiled functions. Instead of mapping
16// names to functions it might make sense to let the JS2C tool
17// generate an index for each native JS file.
18class SourceCodeCache final BASE_EMBEDDED {
19 public:
20  explicit SourceCodeCache(Script::Type type): type_(type), cache_(NULL) { }
21
22  void Initialize(Isolate* isolate, bool create_heap_objects) {
23    cache_ = create_heap_objects ? isolate->heap()->empty_fixed_array() : NULL;
24  }
25
26  void Iterate(ObjectVisitor* v) {
27    v->VisitPointer(bit_cast<Object**, FixedArray**>(&cache_));
28  }
29
30  bool Lookup(Vector<const char> name, Handle<SharedFunctionInfo>* handle) {
31    for (int i = 0; i < cache_->length(); i+=2) {
32      SeqOneByteString* str = SeqOneByteString::cast(cache_->get(i));
33      if (str->IsUtf8EqualTo(name)) {
34        *handle = Handle<SharedFunctionInfo>(
35            SharedFunctionInfo::cast(cache_->get(i + 1)));
36        return true;
37      }
38    }
39    return false;
40  }
41
42  void Add(Vector<const char> name, Handle<SharedFunctionInfo> shared) {
43    Isolate* isolate = shared->GetIsolate();
44    Factory* factory = isolate->factory();
45    HandleScope scope(isolate);
46    int length = cache_->length();
47    Handle<FixedArray> new_array = factory->NewFixedArray(length + 2, TENURED);
48    cache_->CopyTo(0, *new_array, 0, cache_->length());
49    cache_ = *new_array;
50    Handle<String> str =
51        factory->NewStringFromAscii(name, TENURED).ToHandleChecked();
52    DCHECK(!str.is_null());
53    cache_->set(length, *str);
54    cache_->set(length + 1, *shared);
55    Script::cast(shared->script())->set_type(type_);
56  }
57
58 private:
59  Script::Type type_;
60  FixedArray* cache_;
61  DISALLOW_COPY_AND_ASSIGN(SourceCodeCache);
62};
63
64enum GlobalContextType { FULL_CONTEXT, DEBUG_CONTEXT };
65
66// The Boostrapper is the public interface for creating a JavaScript global
67// context.
68class Bootstrapper final {
69 public:
70  static void InitializeOncePerProcess();
71  static void TearDownExtensions();
72
73  // Requires: Heap::SetUp has been called.
74  void Initialize(bool create_heap_objects);
75  void TearDown();
76
77  // Creates a JavaScript Global Context with initial object graph.
78  // The returned value is a global handle casted to V8Environment*.
79  Handle<Context> CreateEnvironment(
80      MaybeHandle<JSGlobalProxy> maybe_global_proxy,
81      v8::Local<v8::ObjectTemplate> global_object_template,
82      v8::ExtensionConfiguration* extensions, size_t context_snapshot_index,
83      GlobalContextType context_type = FULL_CONTEXT);
84
85  Handle<JSGlobalProxy> NewRemoteContext(
86      MaybeHandle<JSGlobalProxy> maybe_global_proxy,
87      v8::Local<v8::ObjectTemplate> global_object_template);
88
89  // Detach the environment from its outer global object.
90  void DetachGlobal(Handle<Context> env);
91
92  // Traverses the pointers for memory management.
93  void Iterate(ObjectVisitor* v);
94
95  // Accessor for the native scripts source code.
96  template <class Source>
97  Handle<String> SourceLookup(int index);
98
99  // Tells whether bootstrapping is active.
100  bool IsActive() const { return nesting_ != 0; }
101
102  // Support for thread preemption.
103  static int ArchiveSpacePerThread();
104  char* ArchiveState(char* to);
105  char* RestoreState(char* from);
106  void FreeThreadResources();
107
108  // Used for new context creation.
109  bool InstallExtensions(Handle<Context> native_context,
110                         v8::ExtensionConfiguration* extensions);
111
112  SourceCodeCache* extensions_cache() { return &extensions_cache_; }
113
114  static bool CompileNative(Isolate* isolate, Vector<const char> name,
115                            Handle<String> source, int argc,
116                            Handle<Object> argv[], NativesFlag natives_flag);
117  static bool CompileBuiltin(Isolate* isolate, int index);
118  static bool CompileExperimentalBuiltin(Isolate* isolate, int index);
119  static bool CompileExtraBuiltin(Isolate* isolate, int index);
120  static bool CompileExperimentalExtraBuiltin(Isolate* isolate, int index);
121
122  static void ExportFromRuntime(Isolate* isolate, Handle<JSObject> container);
123  static void ExportExperimentalFromRuntime(Isolate* isolate,
124                                            Handle<JSObject> container);
125
126 private:
127  Isolate* isolate_;
128  typedef int NestingCounterType;
129  NestingCounterType nesting_;
130  SourceCodeCache extensions_cache_;
131
132  friend class BootstrapperActive;
133  friend class Isolate;
134  friend class NativesExternalStringResource;
135
136  explicit Bootstrapper(Isolate* isolate);
137
138  static v8::Extension* free_buffer_extension_;
139  static v8::Extension* gc_extension_;
140  static v8::Extension* externalize_string_extension_;
141  static v8::Extension* statistics_extension_;
142  static v8::Extension* trigger_failure_extension_;
143  static v8::Extension* ignition_statistics_extension_;
144
145  DISALLOW_COPY_AND_ASSIGN(Bootstrapper);
146};
147
148
149class BootstrapperActive final BASE_EMBEDDED {
150 public:
151  explicit BootstrapperActive(Bootstrapper* bootstrapper)
152      : bootstrapper_(bootstrapper) {
153    ++bootstrapper_->nesting_;
154  }
155
156  ~BootstrapperActive() {
157    --bootstrapper_->nesting_;
158  }
159
160 private:
161  Bootstrapper* bootstrapper_;
162
163  DISALLOW_COPY_AND_ASSIGN(BootstrapperActive);
164};
165
166
167class NativesExternalStringResource final
168    : public v8::String::ExternalOneByteStringResource {
169 public:
170  NativesExternalStringResource(const char* source, size_t length)
171      : data_(source), length_(length) {}
172  const char* data() const override { return data_; }
173  size_t length() const override { return length_; }
174
175 private:
176  const char* data_;
177  size_t length_;
178};
179
180}  // namespace internal
181}  // namespace v8
182
183#endif  // V8_BOOTSTRAPPER_H_
184