blob: f68a12ab14c9c68391cfee29cceeae98e3f3c1ea [file] [log] [blame]
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001// 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.
Steve Blocka7e24c12009-10-30 11:49:00 +00004
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005#include "src/bootstrapper.h"
Steve Blocka7e24c12009-10-30 11:49:00 +00006
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007#include "src/accessors.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008#include "src/api-natives.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009#include "src/code-stubs.h"
10#include "src/extensions/externalize-string-extension.h"
11#include "src/extensions/free-buffer-extension.h"
12#include "src/extensions/gc-extension.h"
13#include "src/extensions/statistics-extension.h"
14#include "src/extensions/trigger-failure-extension.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000015#include "src/heap/heap.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000016#include "src/isolate-inl.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000017#include "src/snapshot/natives.h"
18#include "src/snapshot/snapshot.h"
19#include "src/wasm/wasm-js.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000020
21namespace v8 {
22namespace internal {
23
Ben Murdochb8a8cc12014-11-26 15:28:44 +000024Bootstrapper::Bootstrapper(Isolate* isolate)
25 : isolate_(isolate),
26 nesting_(0),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000027 extensions_cache_(Script::TYPE_EXTENSION) {}
Steve Block44f0eee2011-05-26 01:26:41 +010028
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000029template <class Source>
30Handle<String> Bootstrapper::SourceLookup(int index) {
31 DCHECK(0 <= index && index < Source::GetBuiltinsCount());
Ben Murdochb8a8cc12014-11-26 15:28:44 +000032 Heap* heap = isolate_->heap();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000033 if (Source::GetSourceCache(heap)->get(index)->IsUndefined()) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +010034 // We can use external strings for the natives.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000035 Vector<const char> source = Source::GetScriptSource(index);
Ben Murdoch3ef787d2012-04-12 10:51:47 +010036 NativesExternalStringResource* resource =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000037 new NativesExternalStringResource(source.start(), source.length());
Ben Murdochb8a8cc12014-11-26 15:28:44 +000038 // We do not expect this to throw an exception. Change this if it does.
39 Handle<String> source_code = isolate_->factory()
40 ->NewExternalStringFromOneByte(resource)
41 .ToHandleChecked();
Emily Bernierd0a1eb72015-03-24 16:35:39 -040042 // Mark this external string with a special map.
43 source_code->set_map(isolate_->heap()->native_source_string_map());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000044 Source::GetSourceCache(heap)->set(index, *source_code);
Steve Blocka7e24c12009-10-30 11:49:00 +000045 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000046 Handle<Object> cached_source(Source::GetSourceCache(heap)->get(index),
Ben Murdochb8a8cc12014-11-26 15:28:44 +000047 isolate_);
Steve Blocka7e24c12009-10-30 11:49:00 +000048 return Handle<String>::cast(cached_source);
49}
50
51
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000052template Handle<String> Bootstrapper::SourceLookup<Natives>(int index);
53template Handle<String> Bootstrapper::SourceLookup<ExperimentalNatives>(
54 int index);
55template Handle<String> Bootstrapper::SourceLookup<ExperimentalExtraNatives>(
56 int index);
57template Handle<String> Bootstrapper::SourceLookup<ExtraNatives>(int index);
58
59
Steve Blocka7e24c12009-10-30 11:49:00 +000060void Bootstrapper::Initialize(bool create_heap_objects) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000061 extensions_cache_.Initialize(isolate_, create_heap_objects);
62}
63
64
65static const char* GCFunctionName() {
66 bool flag_given = FLAG_expose_gc_as != NULL && strlen(FLAG_expose_gc_as) != 0;
67 return flag_given ? FLAG_expose_gc_as : "gc";
68}
69
70
71v8::Extension* Bootstrapper::free_buffer_extension_ = NULL;
72v8::Extension* Bootstrapper::gc_extension_ = NULL;
73v8::Extension* Bootstrapper::externalize_string_extension_ = NULL;
74v8::Extension* Bootstrapper::statistics_extension_ = NULL;
75v8::Extension* Bootstrapper::trigger_failure_extension_ = NULL;
76
77
78void Bootstrapper::InitializeOncePerProcess() {
79 free_buffer_extension_ = new FreeBufferExtension;
80 v8::RegisterExtension(free_buffer_extension_);
81 gc_extension_ = new GCExtension(GCFunctionName());
82 v8::RegisterExtension(gc_extension_);
83 externalize_string_extension_ = new ExternalizeStringExtension;
84 v8::RegisterExtension(externalize_string_extension_);
85 statistics_extension_ = new StatisticsExtension;
86 v8::RegisterExtension(statistics_extension_);
87 trigger_failure_extension_ = new TriggerFailureExtension;
88 v8::RegisterExtension(trigger_failure_extension_);
89}
90
91
92void Bootstrapper::TearDownExtensions() {
93 delete free_buffer_extension_;
94 free_buffer_extension_ = NULL;
95 delete gc_extension_;
96 gc_extension_ = NULL;
97 delete externalize_string_extension_;
98 externalize_string_extension_ = NULL;
99 delete statistics_extension_;
100 statistics_extension_ = NULL;
101 delete trigger_failure_extension_;
102 trigger_failure_extension_ = NULL;
Steve Blocka7e24c12009-10-30 11:49:00 +0000103}
104
105
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000106void DeleteNativeSources(Object* maybe_array) {
107 if (maybe_array->IsFixedArray()) {
108 FixedArray* array = FixedArray::cast(maybe_array);
109 for (int i = 0; i < array->length(); i++) {
110 Object* natives_source = array->get(i);
111 if (!natives_source->IsUndefined()) {
112 const NativesExternalStringResource* resource =
113 reinterpret_cast<const NativesExternalStringResource*>(
114 ExternalOneByteString::cast(natives_source)->resource());
115 delete resource;
116 }
Leon Clarkee46be812010-01-19 14:06:41 +0000117 }
Leon Clarkee46be812010-01-19 14:06:41 +0000118 }
Leon Clarkee46be812010-01-19 14:06:41 +0000119}
120
121
Steve Blocka7e24c12009-10-30 11:49:00 +0000122void Bootstrapper::TearDown() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000123 DeleteNativeSources(Natives::GetSourceCache(isolate_->heap()));
124 DeleteNativeSources(ExperimentalNatives::GetSourceCache(isolate_->heap()));
125 DeleteNativeSources(ExtraNatives::GetSourceCache(isolate_->heap()));
126 DeleteNativeSources(
127 ExperimentalExtraNatives::GetSourceCache(isolate_->heap()));
Leon Clarkee46be812010-01-19 14:06:41 +0000128
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000129 extensions_cache_.Initialize(isolate_, false); // Yes, symmetrical
Steve Blocka7e24c12009-10-30 11:49:00 +0000130}
131
132
Steve Blocka7e24c12009-10-30 11:49:00 +0000133class Genesis BASE_EMBEDDED {
134 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000135 Genesis(Isolate* isolate, MaybeHandle<JSGlobalProxy> maybe_global_proxy,
136 v8::Local<v8::ObjectTemplate> global_proxy_template,
137 v8::ExtensionConfiguration* extensions, ContextType context_type);
Andrei Popescu31002712010-02-23 13:46:05 +0000138 ~Genesis() { }
Steve Blocka7e24c12009-10-30 11:49:00 +0000139
Ben Murdoch257744e2011-11-30 15:57:28 +0000140 Isolate* isolate() const { return isolate_; }
141 Factory* factory() const { return isolate_->factory(); }
142 Heap* heap() const { return isolate_->heap(); }
143
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000144 Handle<Context> result() { return result_; }
145
Steve Blocka7e24c12009-10-30 11:49:00 +0000146 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000147 Handle<Context> native_context() { return native_context_; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000148
Andrei Popescu31002712010-02-23 13:46:05 +0000149 // Creates some basic objects. Used for creating a context from scratch.
150 void CreateRoots();
151 // Creates the empty function. Used for creating a context from scratch.
Ben Murdoch257744e2011-11-30 15:57:28 +0000152 Handle<JSFunction> CreateEmptyFunction(Isolate* isolate);
Steve Block44f0eee2011-05-26 01:26:41 +0100153 // Creates the ThrowTypeError function. ECMA 5th Ed. 13.2.3
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000154 Handle<JSFunction> GetRestrictedFunctionPropertiesThrower();
155 Handle<JSFunction> GetStrictArgumentsPoisonFunction();
156 Handle<JSFunction> GetThrowTypeErrorIntrinsic(Builtins::Name builtin_name);
Steve Block44f0eee2011-05-26 01:26:41 +0100157
158 void CreateStrictModeFunctionMaps(Handle<JSFunction> empty);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000159 void CreateStrongModeFunctionMaps(Handle<JSFunction> empty);
160 void CreateIteratorMaps();
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100161
162 // Make the "arguments" and "caller" properties throw a TypeError on access.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000163 void AddRestrictedFunctionProperties(Handle<Map> map);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100164
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000165 // Creates the global objects using the global proxy and the template passed
166 // in through the API. We call this regardless of whether we are building a
Andrei Popescu31002712010-02-23 13:46:05 +0000167 // context from scratch or using a deserialized one from the partial snapshot
168 // but in the latter case we don't use the objects it produces directly, as
169 // we have to used the deserialized ones that are linked together with the
170 // rest of the context snapshot.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000171 Handle<JSGlobalObject> CreateNewGlobals(
172 v8::Local<v8::ObjectTemplate> global_proxy_template,
173 Handle<JSGlobalProxy> global_proxy);
Andrei Popescu31002712010-02-23 13:46:05 +0000174 // Hooks the given global proxy into the context. If the context was created
175 // by deserialization then this will unhook the global proxy that was
176 // deserialized, leaving the GC to pick it up.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000177 void HookUpGlobalProxy(Handle<JSGlobalObject> global_object,
Andrei Popescu31002712010-02-23 13:46:05 +0000178 Handle<JSGlobalProxy> global_proxy);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000179 // Similarly, we want to use the global that has been created by the templates
180 // passed through the API. The global from the snapshot is detached from the
181 // other objects in the snapshot.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000182 void HookUpGlobalObject(Handle<JSGlobalObject> global_object);
183 // The native context has a ScriptContextTable that store declarative bindings
184 // made in script scopes. Add a "this" binding to that table pointing to the
185 // global proxy.
186 void InstallGlobalThisBinding();
Andrei Popescu31002712010-02-23 13:46:05 +0000187 // New context initialization. Used for creating a context from scratch.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000188 void InitializeGlobal(Handle<JSGlobalObject> global_object,
189 Handle<JSFunction> empty_function,
190 ContextType context_type);
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000191 void InitializeExperimentalGlobal();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000192 // Depending on the situation, expose and/or get rid of the utils object.
193 void ConfigureUtilsObject(ContextType context_type);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400194
195#define DECLARE_FEATURE_INITIALIZATION(id, descr) \
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400196 void InitializeGlobal_##id();
197
198 HARMONY_INPROGRESS(DECLARE_FEATURE_INITIALIZATION)
199 HARMONY_STAGED(DECLARE_FEATURE_INITIALIZATION)
200 HARMONY_SHIPPING(DECLARE_FEATURE_INITIALIZATION)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000201 DECLARE_FEATURE_INITIALIZATION(promise_extra, "")
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400202#undef DECLARE_FEATURE_INITIALIZATION
203
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000204 Handle<JSFunction> InstallArrayBuffer(Handle<JSObject> target,
205 const char* name);
206 Handle<JSFunction> InstallInternalArray(Handle<JSObject> target,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000207 const char* name,
208 ElementsKind elements_kind);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000209 bool InstallNatives(ContextType context_type);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000210
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000211 void InstallTypedArray(const char* name, ElementsKind elements_kind,
212 Handle<JSFunction>* fun);
Ben Murdoch257744e2011-11-30 15:57:28 +0000213 bool InstallExperimentalNatives();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000214 bool InstallExtraNatives();
215 bool InstallExperimentalExtraNatives();
216 bool InstallDebuggerNatives();
Ben Murdochb0fe1622011-05-05 13:52:32 +0100217 void InstallBuiltinFunctionIds();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000218 void InstallExperimentalBuiltinFunctionIds();
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100219 void InitializeNormalizedMapCaches();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000220 void InstallJSProxyMaps();
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100221
222 enum ExtensionTraversalState {
223 UNVISITED, VISITED, INSTALLED
224 };
225
226 class ExtensionStates {
227 public:
228 ExtensionStates();
229 ExtensionTraversalState get_state(RegisteredExtension* extension);
230 void set_state(RegisteredExtension* extension,
231 ExtensionTraversalState state);
232 private:
233 HashMap map_;
234 DISALLOW_COPY_AND_ASSIGN(ExtensionStates);
235 };
236
Andrei Popescu31002712010-02-23 13:46:05 +0000237 // Used both for deserialized and from-scratch contexts to add the extensions
238 // provided.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000239 static bool InstallExtensions(Handle<Context> native_context,
Andrei Popescu31002712010-02-23 13:46:05 +0000240 v8::ExtensionConfiguration* extensions);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000241 static bool InstallAutoExtensions(Isolate* isolate,
242 ExtensionStates* extension_states);
243 static bool InstallRequestedExtensions(Isolate* isolate,
244 v8::ExtensionConfiguration* extensions,
245 ExtensionStates* extension_states);
246 static bool InstallExtension(Isolate* isolate,
247 const char* name,
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100248 ExtensionStates* extension_states);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000249 static bool InstallExtension(Isolate* isolate,
250 v8::RegisteredExtension* current,
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100251 ExtensionStates* extension_states);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000252 static bool InstallSpecialObjects(Handle<Context> native_context);
Steve Blocka7e24c12009-10-30 11:49:00 +0000253 bool ConfigureApiObject(Handle<JSObject> object,
254 Handle<ObjectTemplateInfo> object_template);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000255 bool ConfigureGlobalObjects(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000256 v8::Local<v8::ObjectTemplate> global_proxy_template);
Steve Blocka7e24c12009-10-30 11:49:00 +0000257
258 // Migrates all properties from the 'from' object to the 'to'
259 // object and overrides the prototype in 'to' with the one from
260 // 'from'.
261 void TransferObject(Handle<JSObject> from, Handle<JSObject> to);
262 void TransferNamedProperties(Handle<JSObject> from, Handle<JSObject> to);
263 void TransferIndexedProperties(Handle<JSObject> from, Handle<JSObject> to);
264
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000265 enum FunctionMode {
266 // With prototype.
267 FUNCTION_WITH_WRITEABLE_PROTOTYPE,
268 FUNCTION_WITH_READONLY_PROTOTYPE,
269 // Without prototype.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000270 FUNCTION_WITHOUT_PROTOTYPE
Steve Block6ded16b2010-05-10 14:33:55 +0100271 };
Steve Block44f0eee2011-05-26 01:26:41 +0100272
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000273 static bool IsFunctionModeWithPrototype(FunctionMode function_mode) {
274 return (function_mode == FUNCTION_WITH_WRITEABLE_PROTOTYPE ||
275 function_mode == FUNCTION_WITH_READONLY_PROTOTYPE);
276 }
Steve Block44f0eee2011-05-26 01:26:41 +0100277
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000278 Handle<Map> CreateSloppyFunctionMap(FunctionMode function_mode);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000279
280 void SetFunctionInstanceDescriptor(Handle<Map> map,
281 FunctionMode function_mode);
Steve Blocka7e24c12009-10-30 11:49:00 +0000282 void MakeFunctionInstancePrototypeWritable();
283
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000284 Handle<Map> CreateStrictFunctionMap(FunctionMode function_mode,
285 Handle<JSFunction> empty_function);
286 Handle<Map> CreateStrongFunctionMap(Handle<JSFunction> empty_function,
287 bool is_constructor);
288
Steve Block44f0eee2011-05-26 01:26:41 +0100289
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000290 void SetStrictFunctionInstanceDescriptor(Handle<Map> map,
291 FunctionMode function_mode);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000292 void SetStrongFunctionInstanceDescriptor(Handle<Map> map);
Steve Block44f0eee2011-05-26 01:26:41 +0100293
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000294 static bool CallUtilsFunction(Isolate* isolate, const char* name);
295
296 static bool CompileExtension(Isolate* isolate, v8::Extension* extension);
Steve Blocka7e24c12009-10-30 11:49:00 +0000297
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000298 Isolate* isolate_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000299 Handle<Context> result_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000300 Handle<Context> native_context_;
Steve Block44f0eee2011-05-26 01:26:41 +0100301
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000302 // Function maps. Function maps are created initially with a read only
303 // prototype for the processing of JS builtins. Later the function maps are
304 // replaced in order to make prototype writable. These are the final, writable
305 // prototype, maps.
306 Handle<Map> sloppy_function_map_writable_prototype_;
307 Handle<Map> strict_function_map_writable_prototype_;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000308 Handle<JSFunction> strict_poison_function_;
309 Handle<JSFunction> restricted_function_properties_thrower_;
Steve Block44f0eee2011-05-26 01:26:41 +0100310
Andrei Popescu31002712010-02-23 13:46:05 +0000311 BootstrapperActive active_;
312 friend class Bootstrapper;
Steve Blocka7e24c12009-10-30 11:49:00 +0000313};
314
Steve Blocka7e24c12009-10-30 11:49:00 +0000315
316void Bootstrapper::Iterate(ObjectVisitor* v) {
Steve Block44f0eee2011-05-26 01:26:41 +0100317 extensions_cache_.Iterate(v);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100318 v->Synchronize(VisitorSynchronization::kExtensions);
Steve Blocka7e24c12009-10-30 11:49:00 +0000319}
320
321
Steve Blocka7e24c12009-10-30 11:49:00 +0000322Handle<Context> Bootstrapper::CreateEnvironment(
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000323 MaybeHandle<JSGlobalProxy> maybe_global_proxy,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000324 v8::Local<v8::ObjectTemplate> global_proxy_template,
325 v8::ExtensionConfiguration* extensions, ContextType context_type) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000326 HandleScope scope(isolate_);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000327 Genesis genesis(isolate_, maybe_global_proxy, global_proxy_template,
328 extensions, context_type);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000329 Handle<Context> env = genesis.result();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000330 if (env.is_null() ||
331 (context_type != THIN_CONTEXT && !InstallExtensions(env, extensions))) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000332 return Handle<Context>();
Andrei Popescu31002712010-02-23 13:46:05 +0000333 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000334 return scope.CloseAndEscape(env);
Steve Blocka7e24c12009-10-30 11:49:00 +0000335}
336
337
338static void SetObjectPrototype(Handle<JSObject> object, Handle<Object> proto) {
339 // object.__proto__ = proto;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000340 Handle<Map> old_map = Handle<Map>(object->map());
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400341 Handle<Map> new_map = Map::Copy(old_map, "SetObjectPrototype");
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000342 Map::SetPrototype(new_map, proto, FAST_PROTOTYPE);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000343 JSObject::MigrateToMap(object, new_map);
Steve Blocka7e24c12009-10-30 11:49:00 +0000344}
345
346
347void Bootstrapper::DetachGlobal(Handle<Context> env) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000348 env->GetIsolate()->counters()->errors_thrown_per_context()->AddSample(
349 env->GetErrorsThrown());
350
Ben Murdoch257744e2011-11-30 15:57:28 +0000351 Factory* factory = env->GetIsolate()->factory();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000352 Handle<JSGlobalProxy> global_proxy(JSGlobalProxy::cast(env->global_proxy()));
353 global_proxy->set_native_context(*factory->null_value());
354 SetObjectPrototype(global_proxy, factory->null_value());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000355 global_proxy->map()->SetConstructor(*factory->null_value());
356 if (FLAG_track_detached_contexts) {
357 env->GetIsolate()->AddDetachedContext(env);
358 }
Andrei Popescu74b3c142010-03-29 12:03:09 +0100359}
360
361
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000362namespace {
363
364void InstallFunction(Handle<JSObject> target, Handle<Name> property_name,
365 Handle<JSFunction> function, Handle<String> function_name,
366 PropertyAttributes attributes = DONT_ENUM) {
367 JSObject::AddProperty(target, property_name, function, attributes);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000368 if (target->IsJSGlobalObject()) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000369 function->shared()->set_instance_class_name(*function_name);
Steve Blocka7e24c12009-10-30 11:49:00 +0000370 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100371 function->shared()->set_native(true);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000372}
373
374
375static void InstallFunction(Handle<JSObject> target,
376 Handle<JSFunction> function, Handle<Name> name,
377 PropertyAttributes attributes = DONT_ENUM) {
378 Handle<String> name_string = Name::ToFunctionName(name).ToHandleChecked();
379 InstallFunction(target, name, function, name_string, attributes);
380}
381
382
383static Handle<JSFunction> CreateFunction(Isolate* isolate, Handle<String> name,
384 InstanceType type, int instance_size,
385 MaybeHandle<JSObject> maybe_prototype,
386 Builtins::Name call,
387 bool strict_function_map = false) {
388 Factory* factory = isolate->factory();
389 Handle<Code> call_code(isolate->builtins()->builtin(call));
390 Handle<JSObject> prototype;
391 static const bool kReadOnlyPrototype = false;
392 static const bool kInstallConstructor = false;
393 return maybe_prototype.ToHandle(&prototype)
394 ? factory->NewFunction(name, call_code, prototype, type,
395 instance_size, kReadOnlyPrototype,
396 kInstallConstructor, strict_function_map)
397 : factory->NewFunctionWithoutPrototype(name, call_code,
398 strict_function_map);
399}
400
401
402Handle<JSFunction> InstallFunction(Handle<JSObject> target, Handle<Name> name,
403 InstanceType type, int instance_size,
404 MaybeHandle<JSObject> maybe_prototype,
405 Builtins::Name call,
406 PropertyAttributes attributes,
407 bool strict_function_map = false) {
408 Handle<String> name_string = Name::ToFunctionName(name).ToHandleChecked();
409 Handle<JSFunction> function =
410 CreateFunction(target->GetIsolate(), name_string, type, instance_size,
411 maybe_prototype, call, strict_function_map);
412 InstallFunction(target, name, function, name_string, attributes);
Steve Blocka7e24c12009-10-30 11:49:00 +0000413 return function;
414}
415
416
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000417Handle<JSFunction> InstallFunction(Handle<JSObject> target, const char* name,
418 InstanceType type, int instance_size,
419 MaybeHandle<JSObject> maybe_prototype,
420 Builtins::Name call,
421 bool strict_function_map = false) {
422 Factory* const factory = target->GetIsolate()->factory();
423 PropertyAttributes attributes = DONT_ENUM;
424 return InstallFunction(target, factory->InternalizeUtf8String(name), type,
425 instance_size, maybe_prototype, call, attributes,
426 strict_function_map);
427}
428
429} // namespace
430
431
432void Genesis::SetFunctionInstanceDescriptor(Handle<Map> map,
433 FunctionMode function_mode) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000434 int size = IsFunctionModeWithPrototype(function_mode) ? 5 : 4;
435 Map::EnsureDescriptorSlack(map, size);
436
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000437 PropertyAttributes ro_attribs =
438 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
439 PropertyAttributes roc_attribs =
440 static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100441
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000442 Handle<AccessorInfo> length =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000443 Accessors::FunctionLengthInfo(isolate(), roc_attribs);
Steve Block44f0eee2011-05-26 01:26:41 +0100444 { // Add length.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000445 AccessorConstantDescriptor d(Handle<Name>(Name::cast(length->name())),
446 length, roc_attribs);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000447 map->AppendDescriptor(&d);
Steve Block44f0eee2011-05-26 01:26:41 +0100448 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000449 Handle<AccessorInfo> name =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000450 Accessors::FunctionNameInfo(isolate(), ro_attribs);
Steve Block44f0eee2011-05-26 01:26:41 +0100451 { // Add name.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000452 AccessorConstantDescriptor d(Handle<Name>(Name::cast(name->name())), name,
453 roc_attribs);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000454 map->AppendDescriptor(&d);
Steve Block44f0eee2011-05-26 01:26:41 +0100455 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000456 Handle<AccessorInfo> args =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000457 Accessors::FunctionArgumentsInfo(isolate(), ro_attribs);
Steve Block44f0eee2011-05-26 01:26:41 +0100458 { // Add arguments.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000459 AccessorConstantDescriptor d(Handle<Name>(Name::cast(args->name())), args,
460 ro_attribs);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000461 map->AppendDescriptor(&d);
Steve Block44f0eee2011-05-26 01:26:41 +0100462 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000463 Handle<AccessorInfo> caller =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000464 Accessors::FunctionCallerInfo(isolate(), ro_attribs);
Steve Block44f0eee2011-05-26 01:26:41 +0100465 { // Add caller.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000466 AccessorConstantDescriptor d(Handle<Name>(Name::cast(caller->name())),
467 caller, ro_attribs);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000468 map->AppendDescriptor(&d);
Steve Block44f0eee2011-05-26 01:26:41 +0100469 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000470 if (IsFunctionModeWithPrototype(function_mode)) {
471 if (function_mode == FUNCTION_WITH_WRITEABLE_PROTOTYPE) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000472 ro_attribs = static_cast<PropertyAttributes>(ro_attribs & ~READ_ONLY);
Steve Block44f0eee2011-05-26 01:26:41 +0100473 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000474 Handle<AccessorInfo> prototype =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000475 Accessors::FunctionPrototypeInfo(isolate(), ro_attribs);
476 AccessorConstantDescriptor d(Handle<Name>(Name::cast(prototype->name())),
477 prototype, ro_attribs);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000478 map->AppendDescriptor(&d);
Steve Block44f0eee2011-05-26 01:26:41 +0100479 }
Steve Block44f0eee2011-05-26 01:26:41 +0100480}
Steve Blocka7e24c12009-10-30 11:49:00 +0000481
Steve Blocka7e24c12009-10-30 11:49:00 +0000482
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000483Handle<Map> Genesis::CreateSloppyFunctionMap(FunctionMode function_mode) {
Ben Murdoch257744e2011-11-30 15:57:28 +0000484 Handle<Map> map = factory()->NewMap(JS_FUNCTION_TYPE, JSFunction::kSize);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000485 SetFunctionInstanceDescriptor(map, function_mode);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000486 if (IsFunctionModeWithPrototype(function_mode)) map->set_is_constructor();
487 map->set_is_callable();
Steve Block44f0eee2011-05-26 01:26:41 +0100488 return map;
Steve Blocka7e24c12009-10-30 11:49:00 +0000489}
490
491
Ben Murdoch257744e2011-11-30 15:57:28 +0000492Handle<JSFunction> Genesis::CreateEmptyFunction(Isolate* isolate) {
Steve Block44f0eee2011-05-26 01:26:41 +0100493 // Allocate the map for function instances. Maps are allocated first and their
494 // prototypes patched later, once empty function is created.
495
Steve Block6ded16b2010-05-10 14:33:55 +0100496 // Functions with this map will not have a 'prototype' property, and
497 // can not be used as constructors.
Ben Murdoch8b112d22011-06-08 16:22:53 +0100498 Handle<Map> function_without_prototype_map =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000499 CreateSloppyFunctionMap(FUNCTION_WITHOUT_PROTOTYPE);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000500 native_context()->set_sloppy_function_without_prototype_map(
Ben Murdoch8b112d22011-06-08 16:22:53 +0100501 *function_without_prototype_map);
Steve Blocka7e24c12009-10-30 11:49:00 +0000502
Steve Block44f0eee2011-05-26 01:26:41 +0100503 // Allocate the function map. This map is temporary, used only for processing
504 // of builtins.
505 // Later the map is replaced with writable prototype map, allocated below.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000506 Handle<Map> function_map =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000507 CreateSloppyFunctionMap(FUNCTION_WITH_READONLY_PROTOTYPE);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000508 native_context()->set_sloppy_function_map(*function_map);
509 native_context()->set_sloppy_function_with_readonly_prototype_map(
510 *function_map);
Steve Blocka7e24c12009-10-30 11:49:00 +0000511
Steve Block44f0eee2011-05-26 01:26:41 +0100512 // The final map for functions. Writeable prototype.
513 // This map is installed in MakeFunctionInstancePrototypeWritable.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000514 sloppy_function_map_writable_prototype_ =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000515 CreateSloppyFunctionMap(FUNCTION_WITH_WRITEABLE_PROTOTYPE);
Steve Block44f0eee2011-05-26 01:26:41 +0100516 Factory* factory = isolate->factory();
Steve Block44f0eee2011-05-26 01:26:41 +0100517
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000518 Handle<String> object_name = factory->Object_string();
Steve Blocka7e24c12009-10-30 11:49:00 +0000519
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400520 Handle<JSObject> object_function_prototype;
521
Steve Blocka7e24c12009-10-30 11:49:00 +0000522 { // --- O b j e c t ---
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000523 Handle<JSFunction> object_fun = factory->NewFunction(object_name);
524 int unused = JSObject::kInitialGlobalObjectUnusedPropertiesCount;
525 int instance_size = JSObject::kHeaderSize + kPointerSize * unused;
Steve Blocka7e24c12009-10-30 11:49:00 +0000526 Handle<Map> object_function_map =
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000527 factory->NewMap(JS_OBJECT_TYPE, instance_size);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000528 object_function_map->SetInObjectProperties(unused);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000529 JSFunction::SetInitialMap(object_fun, object_function_map,
530 isolate->factory()->null_value());
531 object_function_map->set_unused_property_fields(unused);
Steve Blocka7e24c12009-10-30 11:49:00 +0000532
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000533 native_context()->set_object_function(*object_fun);
Steve Blocka7e24c12009-10-30 11:49:00 +0000534
535 // Allocate a new prototype for the object function.
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400536 object_function_prototype =
537 factory->NewJSObject(isolate->object_function(), TENURED);
538 Handle<Map> map = Map::Copy(handle(object_function_prototype->map()),
539 "EmptyObjectPrototype");
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000540 map->set_is_prototype_map(true);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400541 object_function_prototype->set_map(*map);
Steve Blocka7e24c12009-10-30 11:49:00 +0000542
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400543 native_context()->set_initial_object_prototype(*object_function_prototype);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000544 // For bootstrapping set the array prototype to be the same as the object
545 // prototype, otherwise the missing initial_array_prototype will cause
546 // assertions during startup.
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400547 native_context()->set_initial_array_prototype(*object_function_prototype);
548 Accessors::FunctionSetPrototype(object_fun, object_function_prototype)
549 .Assert();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000550
551 // Allocate initial strong object map.
552 Handle<Map> strong_object_map =
553 Map::Copy(Handle<Map>(object_fun->initial_map()), "EmptyStrongObject");
554 strong_object_map->set_is_strong();
555 native_context()->set_js_object_strong_map(*strong_object_map);
Steve Blocka7e24c12009-10-30 11:49:00 +0000556 }
557
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000558 // Allocate the empty function as the prototype for function - ES6 19.2.3
559 Handle<Code> code(isolate->builtins()->EmptyFunction());
560 Handle<JSFunction> empty_function =
561 factory->NewFunctionWithoutPrototype(factory->empty_string(), code);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000562
563 // Allocate the function map first and then patch the prototype later
564 Handle<Map> empty_function_map =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000565 CreateSloppyFunctionMap(FUNCTION_WITHOUT_PROTOTYPE);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000566 DCHECK(!empty_function_map->is_dictionary_map());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000567 Map::SetPrototype(empty_function_map, object_function_prototype);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000568 empty_function_map->set_is_prototype_map(true);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000569
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000570 empty_function->set_map(*empty_function_map);
Steve Blocka7e24c12009-10-30 11:49:00 +0000571
Andrei Popescu31002712010-02-23 13:46:05 +0000572 // --- E m p t y ---
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000573 Handle<String> source = factory->NewStringFromStaticChars("() {}");
Steve Block44f0eee2011-05-26 01:26:41 +0100574 Handle<Script> script = factory->NewScript(source);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000575 script->set_type(Script::TYPE_NATIVE);
Andrei Popescu31002712010-02-23 13:46:05 +0000576 empty_function->shared()->set_start_position(0);
577 empty_function->shared()->set_end_position(source->length());
578 empty_function->shared()->DontAdaptArguments();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000579 SharedFunctionInfo::SetScript(handle(empty_function->shared()), script);
Steve Block44f0eee2011-05-26 01:26:41 +0100580
581 // Set prototypes for the function maps.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000582 Handle<Map> sloppy_function_map(native_context()->sloppy_function_map(),
583 isolate);
584 Handle<Map> sloppy_function_without_prototype_map(
585 native_context()->sloppy_function_without_prototype_map(), isolate);
586 Map::SetPrototype(sloppy_function_map, empty_function);
587 Map::SetPrototype(sloppy_function_without_prototype_map, empty_function);
588 Map::SetPrototype(sloppy_function_map_writable_prototype_, empty_function);
589
590 // ES6 draft 03-17-2015, section 8.2.2 step 12
591 AddRestrictedFunctionProperties(empty_function_map);
592
Andrei Popescu31002712010-02-23 13:46:05 +0000593 return empty_function;
594}
595
596
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000597void Genesis::SetStrictFunctionInstanceDescriptor(Handle<Map> map,
598 FunctionMode function_mode) {
599 int size = IsFunctionModeWithPrototype(function_mode) ? 3 : 2;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000600 Map::EnsureDescriptorSlack(map, size);
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000601
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000602 PropertyAttributes rw_attribs =
603 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE);
604 PropertyAttributes ro_attribs =
605 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000606 PropertyAttributes roc_attribs =
607 static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100608
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000609 DCHECK(function_mode == FUNCTION_WITH_WRITEABLE_PROTOTYPE ||
610 function_mode == FUNCTION_WITH_READONLY_PROTOTYPE ||
611 function_mode == FUNCTION_WITHOUT_PROTOTYPE);
612 { // Add length.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000613 Handle<AccessorInfo> length =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000614 Accessors::FunctionLengthInfo(isolate(), roc_attribs);
615 AccessorConstantDescriptor d(Handle<Name>(Name::cast(length->name())),
616 length, roc_attribs);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000617 map->AppendDescriptor(&d);
Steve Block44f0eee2011-05-26 01:26:41 +0100618 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100619 { // Add name.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000620 Handle<AccessorInfo> name =
621 Accessors::FunctionNameInfo(isolate(), roc_attribs);
622 AccessorConstantDescriptor d(Handle<Name>(Name::cast(name->name())), name,
623 roc_attribs);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000624 map->AppendDescriptor(&d);
Steve Block44f0eee2011-05-26 01:26:41 +0100625 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000626 if (IsFunctionModeWithPrototype(function_mode)) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100627 // Add prototype.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000628 PropertyAttributes attribs =
629 function_mode == FUNCTION_WITH_WRITEABLE_PROTOTYPE ? rw_attribs
630 : ro_attribs;
631 Handle<AccessorInfo> prototype =
632 Accessors::FunctionPrototypeInfo(isolate(), attribs);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000633 AccessorConstantDescriptor d(Handle<Name>(Name::cast(prototype->name())),
634 prototype, attribs);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000635 map->AppendDescriptor(&d);
Steve Block44f0eee2011-05-26 01:26:41 +0100636 }
Steve Block44f0eee2011-05-26 01:26:41 +0100637}
638
639
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000640void Genesis::SetStrongFunctionInstanceDescriptor(Handle<Map> map) {
641 Map::EnsureDescriptorSlack(map, 2);
Steve Block053d10c2011-06-13 19:13:29 +0100642
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000643 PropertyAttributes ro_attribs =
644 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
645
646 Handle<AccessorInfo> length =
647 Accessors::FunctionLengthInfo(isolate(), ro_attribs);
648 { // Add length.
649 AccessorConstantDescriptor d(Handle<Name>(Name::cast(length->name())),
650 length, ro_attribs);
651 map->AppendDescriptor(&d);
Ben Murdoch257744e2011-11-30 15:57:28 +0000652 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000653 Handle<AccessorInfo> name =
654 Accessors::FunctionNameInfo(isolate(), ro_attribs);
655 { // Add name.
656 AccessorConstantDescriptor d(Handle<Name>(Name::cast(name->name())), name,
657 ro_attribs);
658 map->AppendDescriptor(&d);
659 }
Steve Block44f0eee2011-05-26 01:26:41 +0100660}
661
662
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000663// Creates the %ThrowTypeError% function.
664Handle<JSFunction> Genesis::GetThrowTypeErrorIntrinsic(
665 Builtins::Name builtin_name) {
666 Handle<String> name =
667 factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("ThrowTypeError"));
668 Handle<Code> code(isolate()->builtins()->builtin(builtin_name));
669 Handle<JSFunction> function =
670 factory()->NewFunctionWithoutPrototype(name, code);
671 function->shared()->DontAdaptArguments();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000672
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000673 // %ThrowTypeError% must not have a name property.
674 if (JSReceiver::DeleteProperty(function, factory()->name_string())
675 .IsNothing()) {
676 DCHECK(false);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000677 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000678
679 // length needs to be non configurable.
680 Handle<Object> value(Smi::FromInt(function->shared()->length()), isolate());
681 JSObject::SetOwnPropertyIgnoreAttributes(
682 function, factory()->length_string(), value,
683 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY))
684 .Assert();
685
686 if (JSObject::PreventExtensions(function, Object::THROW_ON_ERROR)
687 .IsNothing()) {
688 DCHECK(false);
689 }
690
691 return function;
692}
693
694
695// ECMAScript 5th Edition, 13.2.3
696Handle<JSFunction> Genesis::GetRestrictedFunctionPropertiesThrower() {
697 if (restricted_function_properties_thrower_.is_null()) {
698 restricted_function_properties_thrower_ = GetThrowTypeErrorIntrinsic(
699 Builtins::kRestrictedFunctionPropertiesThrower);
700 }
701 return restricted_function_properties_thrower_;
702}
703
704
705Handle<JSFunction> Genesis::GetStrictArgumentsPoisonFunction() {
706 if (strict_poison_function_.is_null()) {
707 strict_poison_function_ = GetThrowTypeErrorIntrinsic(
708 Builtins::kRestrictedStrictArgumentsPropertiesThrower);
709 }
710 return strict_poison_function_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000711}
712
713
714Handle<Map> Genesis::CreateStrictFunctionMap(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000715 FunctionMode function_mode, Handle<JSFunction> empty_function) {
Ben Murdoch257744e2011-11-30 15:57:28 +0000716 Handle<Map> map = factory()->NewMap(JS_FUNCTION_TYPE, JSFunction::kSize);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000717 SetStrictFunctionInstanceDescriptor(map, function_mode);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000718 if (IsFunctionModeWithPrototype(function_mode)) map->set_is_constructor();
719 map->set_is_callable();
720 Map::SetPrototype(map, empty_function);
721 return map;
722}
723
724
725Handle<Map> Genesis::CreateStrongFunctionMap(
726 Handle<JSFunction> empty_function, bool is_constructor) {
727 Handle<Map> map = factory()->NewMap(JS_FUNCTION_TYPE, JSFunction::kSize);
728 SetStrongFunctionInstanceDescriptor(map);
729 if (is_constructor) map->set_is_constructor();
730 Map::SetPrototype(map, empty_function);
731 map->set_is_callable();
732 map->set_is_extensible(is_constructor);
733 map->set_is_strong();
Steve Block44f0eee2011-05-26 01:26:41 +0100734 return map;
735}
736
737
738void Genesis::CreateStrictModeFunctionMaps(Handle<JSFunction> empty) {
Steve Block44f0eee2011-05-26 01:26:41 +0100739 // Allocate map for the prototype-less strict mode instances.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000740 Handle<Map> strict_function_without_prototype_map =
741 CreateStrictFunctionMap(FUNCTION_WITHOUT_PROTOTYPE, empty);
742 native_context()->set_strict_function_without_prototype_map(
743 *strict_function_without_prototype_map);
Steve Block44f0eee2011-05-26 01:26:41 +0100744
745 // Allocate map for the strict mode functions. This map is temporary, used
746 // only for processing of builtins.
747 // Later the map is replaced with writable prototype map, allocated below.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000748 Handle<Map> strict_function_map =
749 CreateStrictFunctionMap(FUNCTION_WITH_READONLY_PROTOTYPE, empty);
750 native_context()->set_strict_function_map(*strict_function_map);
Steve Block44f0eee2011-05-26 01:26:41 +0100751
752 // The final map for the strict mode functions. Writeable prototype.
753 // This map is installed in MakeFunctionInstancePrototypeWritable.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000754 strict_function_map_writable_prototype_ =
755 CreateStrictFunctionMap(FUNCTION_WITH_WRITEABLE_PROTOTYPE, empty);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100756}
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +0100757
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100758
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000759void Genesis::CreateStrongModeFunctionMaps(Handle<JSFunction> empty) {
760 // Allocate map for strong mode instances, which never have prototypes.
761 Handle<Map> strong_function_map = CreateStrongFunctionMap(empty, false);
762 native_context()->set_strong_function_map(*strong_function_map);
763 // Constructors do, though.
764 Handle<Map> strong_constructor_map = CreateStrongFunctionMap(empty, true);
765 native_context()->set_strong_constructor_map(*strong_constructor_map);
766}
767
768
769void Genesis::CreateIteratorMaps() {
770 // Create iterator-related meta-objects.
771 Handle<JSObject> iterator_prototype =
772 factory()->NewJSObject(isolate()->object_function(), TENURED);
773 Handle<JSObject> generator_object_prototype =
774 factory()->NewJSObject(isolate()->object_function(), TENURED);
775 Handle<JSObject> generator_function_prototype =
776 factory()->NewJSObject(isolate()->object_function(), TENURED);
777 SetObjectPrototype(generator_object_prototype, iterator_prototype);
778
779 JSObject::AddProperty(generator_function_prototype,
780 factory()->InternalizeUtf8String("prototype"),
781 generator_object_prototype,
782 static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
783
784 // Create maps for generator functions and their prototypes. Store those
785 // maps in the native context. The "prototype" property descriptor is
786 // writable, non-enumerable, and non-configurable (as per ES6 draft
787 // 04-14-15, section 25.2.4.3).
788 Handle<Map> strict_function_map(strict_function_map_writable_prototype_);
789 // Generator functions do not have "caller" or "arguments" accessors.
790 Handle<Map> sloppy_generator_function_map =
791 Map::Copy(strict_function_map, "SloppyGeneratorFunction");
792 Map::SetPrototype(sloppy_generator_function_map,
793 generator_function_prototype);
794 native_context()->set_sloppy_generator_function_map(
795 *sloppy_generator_function_map);
796
797 Handle<Map> strict_generator_function_map =
798 Map::Copy(strict_function_map, "StrictGeneratorFunction");
799 Map::SetPrototype(strict_generator_function_map,
800 generator_function_prototype);
801 native_context()->set_strict_generator_function_map(
802 *strict_generator_function_map);
803
804 Handle<Map> strong_function_map(native_context()->strong_function_map());
805 Handle<Map> strong_generator_function_map =
806 Map::Copy(strong_function_map, "StrongGeneratorFunction");
807 Map::SetPrototype(strong_generator_function_map,
808 generator_function_prototype);
809 native_context()->set_strong_generator_function_map(
810 *strong_generator_function_map);
811
812 Handle<JSFunction> object_function(native_context()->object_function());
813 Handle<Map> generator_object_prototype_map = Map::Create(isolate(), 0);
814 Map::SetPrototype(generator_object_prototype_map, generator_object_prototype);
815 native_context()->set_generator_object_prototype_map(
816 *generator_object_prototype_map);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100817}
818
819
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000820static void ReplaceAccessors(Handle<Map> map,
821 Handle<String> name,
822 PropertyAttributes attributes,
823 Handle<AccessorPair> accessor_pair) {
824 DescriptorArray* descriptors = map->instance_descriptors();
825 int idx = descriptors->SearchWithCache(*name, *map);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000826 AccessorConstantDescriptor descriptor(name, accessor_pair, attributes);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000827 descriptors->Replace(idx, &descriptor);
Steve Block44f0eee2011-05-26 01:26:41 +0100828}
829
830
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000831void Genesis::AddRestrictedFunctionProperties(Handle<Map> map) {
832 PropertyAttributes rw_attribs = static_cast<PropertyAttributes>(DONT_ENUM);
833 Handle<JSFunction> thrower = GetRestrictedFunctionPropertiesThrower();
834 Handle<AccessorPair> accessors = factory()->NewAccessorPair();
835 accessors->set_getter(*thrower);
836 accessors->set_setter(*thrower);
837
838 ReplaceAccessors(map, factory()->arguments_string(), rw_attribs, accessors);
839 ReplaceAccessors(map, factory()->caller_string(), rw_attribs, accessors);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000840}
841
842
843static void AddToWeakNativeContextList(Context* context) {
844 DCHECK(context->IsNativeContext());
Ben Murdoch257744e2011-11-30 15:57:28 +0000845 Heap* heap = context->GetIsolate()->heap();
Ben Murdochb0fe1622011-05-05 13:52:32 +0100846#ifdef DEBUG
847 { // NOLINT
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000848 DCHECK(context->get(Context::NEXT_CONTEXT_LINK)->IsUndefined());
Ben Murdochb0fe1622011-05-05 13:52:32 +0100849 // Check that context is not in the list yet.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000850 for (Object* current = heap->native_contexts_list();
Ben Murdochb0fe1622011-05-05 13:52:32 +0100851 !current->IsUndefined();
852 current = Context::cast(current)->get(Context::NEXT_CONTEXT_LINK)) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000853 DCHECK(current != context);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100854 }
855 }
856#endif
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000857 context->set(Context::NEXT_CONTEXT_LINK, heap->native_contexts_list(),
858 UPDATE_WEAK_WRITE_BARRIER);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000859 heap->set_native_contexts_list(context);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100860}
861
862
Andrei Popescu31002712010-02-23 13:46:05 +0000863void Genesis::CreateRoots() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000864 // Allocate the native context FixedArray first and then patch the
Andrei Popescu31002712010-02-23 13:46:05 +0000865 // closure and extension object later (we need the empty function
866 // and the global object, but in order to create those, we need the
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000867 // native context).
868 native_context_ = factory()->NewNativeContext();
869 AddToWeakNativeContextList(*native_context());
870 isolate()->set_context(*native_context());
Andrei Popescu31002712010-02-23 13:46:05 +0000871
872 // Allocate the message listeners object.
873 {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000874 v8::NeanderArray listeners(isolate());
875 native_context()->set_message_listeners(*listeners.value());
Andrei Popescu31002712010-02-23 13:46:05 +0000876 }
877}
878
879
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000880void Genesis::InstallGlobalThisBinding() {
881 Handle<ScriptContextTable> script_contexts(
882 native_context()->script_context_table());
883 Handle<ScopeInfo> scope_info = ScopeInfo::CreateGlobalThisBinding(isolate());
884 Handle<JSFunction> closure(native_context()->closure());
885 Handle<Context> context = factory()->NewScriptContext(closure, scope_info);
886
887 // Go ahead and hook it up while we're at it.
888 int slot = scope_info->ReceiverContextSlotIndex();
889 DCHECK_EQ(slot, Context::MIN_CONTEXT_SLOTS);
890 context->set(slot, native_context()->global_proxy());
891
892 Handle<ScriptContextTable> new_script_contexts =
893 ScriptContextTable::Extend(script_contexts, context);
894 native_context()->set_script_context_table(*new_script_contexts);
895}
896
897
898Handle<JSGlobalObject> Genesis::CreateNewGlobals(
899 v8::Local<v8::ObjectTemplate> global_proxy_template,
900 Handle<JSGlobalProxy> global_proxy) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000901 // The argument global_proxy_template aka data is an ObjectTemplateInfo.
Andrei Popescu31002712010-02-23 13:46:05 +0000902 // It has a constructor pointer that points at global_constructor which is a
903 // FunctionTemplateInfo.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000904 // The global_proxy_constructor is used to (re)initialize the
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000905 // global_proxy. The global_proxy_constructor also has a prototype_template
906 // pointer that points at js_global_object_template which is an
907 // ObjectTemplateInfo.
Andrei Popescu31002712010-02-23 13:46:05 +0000908 // That in turn has a constructor pointer that points at
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000909 // js_global_object_constructor which is a FunctionTemplateInfo.
910 // js_global_object_constructor is used to make js_global_object_function
911 // js_global_object_function is used to make the new global_object.
Andrei Popescu31002712010-02-23 13:46:05 +0000912 //
913 // --- G l o b a l ---
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000914 // Step 1: Create a fresh JSGlobalObject.
915 Handle<JSFunction> js_global_object_function;
916 Handle<ObjectTemplateInfo> js_global_object_template;
917 if (!global_proxy_template.IsEmpty()) {
918 // Get prototype template of the global_proxy_template.
Andrei Popescu31002712010-02-23 13:46:05 +0000919 Handle<ObjectTemplateInfo> data =
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000920 v8::Utils::OpenHandle(*global_proxy_template);
Andrei Popescu31002712010-02-23 13:46:05 +0000921 Handle<FunctionTemplateInfo> global_constructor =
922 Handle<FunctionTemplateInfo>(
923 FunctionTemplateInfo::cast(data->constructor()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000924 Handle<Object> proto_template(global_constructor->prototype_template(),
925 isolate());
Andrei Popescu31002712010-02-23 13:46:05 +0000926 if (!proto_template->IsUndefined()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000927 js_global_object_template =
Andrei Popescu31002712010-02-23 13:46:05 +0000928 Handle<ObjectTemplateInfo>::cast(proto_template);
929 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000930 }
931
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000932 if (js_global_object_template.is_null()) {
933 Handle<String> name = Handle<String>(heap()->empty_string());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000934 Handle<Code> code = isolate()->builtins()->Illegal();
Andrei Popescu31002712010-02-23 13:46:05 +0000935 Handle<JSObject> prototype =
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000936 factory()->NewFunctionPrototype(isolate()->object_function());
937 js_global_object_function = factory()->NewFunction(
938 name, code, prototype, JS_GLOBAL_OBJECT_TYPE, JSGlobalObject::kSize);
939#ifdef DEBUG
940 LookupIterator it(prototype, factory()->constructor_string(),
941 LookupIterator::OWN_SKIP_INTERCEPTOR);
942 Handle<Object> value = JSReceiver::GetProperty(&it).ToHandleChecked();
943 DCHECK(it.IsFound());
944 DCHECK_EQ(*isolate()->object_function(), *value);
945#endif
Andrei Popescu31002712010-02-23 13:46:05 +0000946 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000947 Handle<FunctionTemplateInfo> js_global_object_constructor(
948 FunctionTemplateInfo::cast(js_global_object_template->constructor()));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000949 js_global_object_function = ApiNatives::CreateApiFunction(
950 isolate(), js_global_object_constructor, factory()->the_hole_value(),
951 ApiNatives::GlobalObjectType);
Steve Blocka7e24c12009-10-30 11:49:00 +0000952 }
953
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000954 js_global_object_function->initial_map()->set_is_prototype_map(true);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000955 js_global_object_function->initial_map()->set_is_hidden_prototype();
956 js_global_object_function->initial_map()->set_dictionary_map(true);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000957 Handle<JSGlobalObject> global_object =
958 factory()->NewJSGlobalObject(js_global_object_function);
Andrei Popescu31002712010-02-23 13:46:05 +0000959
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000960 // Step 2: (re)initialize the global proxy object.
Andrei Popescu31002712010-02-23 13:46:05 +0000961 Handle<JSFunction> global_proxy_function;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000962 if (global_proxy_template.IsEmpty()) {
963 Handle<String> name = Handle<String>(heap()->empty_string());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000964 Handle<Code> code = isolate()->builtins()->Illegal();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000965 global_proxy_function = factory()->NewFunction(
966 name, code, JS_GLOBAL_PROXY_TYPE, JSGlobalProxy::kSize);
Andrei Popescu31002712010-02-23 13:46:05 +0000967 } else {
968 Handle<ObjectTemplateInfo> data =
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000969 v8::Utils::OpenHandle(*global_proxy_template);
Andrei Popescu31002712010-02-23 13:46:05 +0000970 Handle<FunctionTemplateInfo> global_constructor(
971 FunctionTemplateInfo::cast(data->constructor()));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000972 global_proxy_function = ApiNatives::CreateApiFunction(
973 isolate(), global_constructor, factory()->the_hole_value(),
974 ApiNatives::GlobalProxyType);
Andrei Popescu31002712010-02-23 13:46:05 +0000975 }
976
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000977 Handle<String> global_name = factory()->global_string();
Andrei Popescu31002712010-02-23 13:46:05 +0000978 global_proxy_function->shared()->set_instance_class_name(*global_name);
979 global_proxy_function->initial_map()->set_is_access_check_needed(true);
980
981 // Set global_proxy.__proto__ to js_global after ConfigureGlobalObjects
982 // Return the global proxy.
983
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000984 factory()->ReinitializeJSGlobalProxy(global_proxy, global_proxy_function);
985 return global_object;
Andrei Popescu31002712010-02-23 13:46:05 +0000986}
987
988
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000989void Genesis::HookUpGlobalProxy(Handle<JSGlobalObject> global_object,
Andrei Popescu31002712010-02-23 13:46:05 +0000990 Handle<JSGlobalProxy> global_proxy) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000991 // Set the native context for the global object.
992 global_object->set_native_context(*native_context());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000993 global_object->set_global_proxy(*global_proxy);
994 global_proxy->set_native_context(*native_context());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000995 // If we deserialized the context, the global proxy is already
996 // correctly set up. Otherwise it's undefined.
997 DCHECK(native_context()->get(Context::GLOBAL_PROXY_INDEX)->IsUndefined() ||
998 native_context()->global_proxy() == *global_proxy);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000999 native_context()->set_global_proxy(*global_proxy);
Andrei Popescu31002712010-02-23 13:46:05 +00001000}
1001
1002
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001003void Genesis::HookUpGlobalObject(Handle<JSGlobalObject> global_object) {
1004 Handle<JSGlobalObject> global_object_from_snapshot(
1005 JSGlobalObject::cast(native_context()->extension()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001006 native_context()->set_extension(*global_object);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001007 native_context()->set_security_token(*global_object);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001008
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001009 TransferNamedProperties(global_object_from_snapshot, global_object);
1010 TransferIndexedProperties(global_object_from_snapshot, global_object);
Andrei Popescu402d9372010-02-26 13:31:12 +00001011}
1012
1013
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001014static Handle<JSFunction> SimpleCreateFunction(Isolate* isolate,
1015 Handle<String> name,
1016 Builtins::Name call, int len,
1017 bool adapt) {
1018 Handle<JSFunction> fun =
1019 CreateFunction(isolate, name, JS_OBJECT_TYPE, JSObject::kHeaderSize,
1020 MaybeHandle<JSObject>(), call);
1021 if (adapt) {
1022 fun->shared()->set_internal_formal_parameter_count(len);
1023 } else {
1024 fun->shared()->DontAdaptArguments();
1025 }
1026 fun->shared()->set_length(len);
1027 return fun;
1028}
1029
1030
1031static Handle<JSFunction> SimpleInstallFunction(Handle<JSObject> base,
1032 Handle<String> name,
1033 Builtins::Name call, int len,
1034 bool adapt) {
1035 Handle<JSFunction> fun =
1036 SimpleCreateFunction(base->GetIsolate(), name, call, len, adapt);
1037 InstallFunction(base, fun, name, DONT_ENUM);
1038 return fun;
1039}
1040
1041
1042static Handle<JSFunction> SimpleInstallFunction(Handle<JSObject> base,
1043 const char* name,
1044 Builtins::Name call, int len,
1045 bool adapt) {
1046 Factory* const factory = base->GetIsolate()->factory();
1047 return SimpleInstallFunction(base, factory->InternalizeUtf8String(name), call,
1048 len, adapt);
1049}
1050
1051
1052static void InstallWithIntrinsicDefaultProto(Isolate* isolate,
1053 Handle<JSFunction> function,
1054 int context_index) {
1055 Handle<Smi> index(Smi::FromInt(context_index), isolate);
1056 JSObject::AddProperty(
1057 function, isolate->factory()->native_context_index_symbol(), index, NONE);
1058 isolate->native_context()->set(context_index, *function);
1059}
1060
1061
Andrei Popescu402d9372010-02-26 13:31:12 +00001062// This is only called if we are not using snapshots. The equivalent
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001063// work in the snapshot case is done in HookUpGlobalObject.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001064void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
1065 Handle<JSFunction> empty_function,
1066 ContextType context_type) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001067 // --- N a t i v e C o n t e x t ---
Andrei Popescu31002712010-02-23 13:46:05 +00001068 // Use the empty function as closure (no scope info).
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001069 native_context()->set_closure(*empty_function);
1070 native_context()->set_previous(NULL);
Andrei Popescu31002712010-02-23 13:46:05 +00001071 // Set extension and global object.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001072 native_context()->set_extension(*global_object);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001073 // Security setup: Set the security token of the native context to the global
1074 // object. This makes the security check between two different contexts fail
1075 // by default even in case of global object reinitialization.
1076 native_context()->set_security_token(*global_object);
Andrei Popescu31002712010-02-23 13:46:05 +00001077
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001078 Isolate* isolate = global_object->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01001079 Factory* factory = isolate->factory();
Steve Block44f0eee2011-05-26 01:26:41 +01001080
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001081 Handle<ScriptContextTable> script_context_table =
1082 factory->NewScriptContextTable();
1083 native_context()->set_script_context_table(*script_context_table);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001084 InstallGlobalThisBinding();
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001085
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001086 { // --- O b j e c t ---
1087 Handle<String> object_name = factory->Object_string();
1088 Handle<JSFunction> object_function = isolate->object_function();
1089 JSObject::AddProperty(global_object, object_name, object_function,
1090 DONT_ENUM);
1091 SimpleInstallFunction(object_function, factory->assign_string(),
1092 Builtins::kObjectAssign, 2, false);
1093 SimpleInstallFunction(object_function, factory->create_string(),
1094 Builtins::kObjectCreate, 2, false);
1095 Handle<JSFunction> object_freeze = SimpleInstallFunction(
1096 object_function, "freeze", Builtins::kObjectFreeze, 1, false);
1097 native_context()->set_object_freeze(*object_freeze);
1098 Handle<JSFunction> object_is_extensible =
1099 SimpleInstallFunction(object_function, "isExtensible",
1100 Builtins::kObjectIsExtensible, 1, false);
1101 native_context()->set_object_is_extensible(*object_is_extensible);
1102 Handle<JSFunction> object_is_frozen = SimpleInstallFunction(
1103 object_function, "isFrozen", Builtins::kObjectIsFrozen, 1, false);
1104 native_context()->set_object_is_frozen(*object_is_frozen);
1105 Handle<JSFunction> object_is_sealed = SimpleInstallFunction(
1106 object_function, "isSealed", Builtins::kObjectIsSealed, 1, false);
1107 native_context()->set_object_is_sealed(*object_is_sealed);
1108 Handle<JSFunction> object_keys = SimpleInstallFunction(
1109 object_function, "keys", Builtins::kObjectKeys, 1, false);
1110 native_context()->set_object_keys(*object_keys);
1111 SimpleInstallFunction(object_function, "preventExtensions",
1112 Builtins::kObjectPreventExtensions, 1, false);
1113 SimpleInstallFunction(object_function, "seal", Builtins::kObjectSeal, 1,
1114 false);
1115 }
Andrei Popescu31002712010-02-23 13:46:05 +00001116
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001117 Handle<JSObject> global(native_context()->global_object());
Steve Blocka7e24c12009-10-30 11:49:00 +00001118
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001119 { // --- F u n c t i o n ---
1120 Handle<JSFunction> prototype = empty_function;
1121 Handle<JSFunction> function_fun =
1122 InstallFunction(global, "Function", JS_FUNCTION_TYPE, JSFunction::kSize,
1123 prototype, Builtins::kFunctionConstructor);
1124 function_fun->set_prototype_or_initial_map(
1125 *sloppy_function_map_writable_prototype_);
1126 function_fun->shared()->DontAdaptArguments();
1127 function_fun->shared()->set_construct_stub(
1128 *isolate->builtins()->FunctionConstructor());
1129 function_fun->shared()->set_length(1);
1130 InstallWithIntrinsicDefaultProto(isolate, function_fun,
1131 Context::FUNCTION_FUNCTION_INDEX);
1132
1133 // Setup the methods on the %FunctionPrototype%.
1134 SimpleInstallFunction(prototype, factory->apply_string(),
1135 Builtins::kFunctionPrototypeApply, 2, false);
1136 SimpleInstallFunction(prototype, factory->bind_string(),
1137 Builtins::kFunctionPrototypeBind, 1, false);
1138 SimpleInstallFunction(prototype, factory->call_string(),
1139 Builtins::kFunctionPrototypeCall, 1, false);
1140 SimpleInstallFunction(prototype, factory->toString_string(),
1141 Builtins::kFunctionPrototypeToString, 0, false);
1142
1143 // Install the "constructor" property on the %FunctionPrototype%.
1144 JSObject::AddProperty(prototype, factory->constructor_string(),
1145 function_fun, DONT_ENUM);
1146
1147 sloppy_function_map_writable_prototype_->SetConstructor(*function_fun);
1148 strict_function_map_writable_prototype_->SetConstructor(*function_fun);
1149 native_context()->strong_function_map()->SetConstructor(*function_fun);
1150 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001151
1152 { // --- A r r a y ---
1153 Handle<JSFunction> array_function =
1154 InstallFunction(global, "Array", JS_ARRAY_TYPE, JSArray::kSize,
Steve Block44f0eee2011-05-26 01:26:41 +01001155 isolate->initial_object_prototype(),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001156 Builtins::kArrayCode);
Steve Blocka7e24c12009-10-30 11:49:00 +00001157 array_function->shared()->DontAdaptArguments();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001158 array_function->shared()->set_function_data(Smi::FromInt(kArrayCode));
Steve Blocka7e24c12009-10-30 11:49:00 +00001159
1160 // This seems a bit hackish, but we need to make sure Array.length
1161 // is 1.
1162 array_function->shared()->set_length(1);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001163
1164 Handle<Map> initial_map(array_function->initial_map());
1165
1166 // This assert protects an optimization in
1167 // HGraphBuilder::JSArrayBuilder::EmitMapCode()
1168 DCHECK(initial_map->elements_kind() == GetInitialFastElementsKind());
1169 Map::EnsureDescriptorSlack(initial_map, 1);
1170
1171 PropertyAttributes attribs = static_cast<PropertyAttributes>(
1172 DONT_ENUM | DONT_DELETE);
1173
1174 Handle<AccessorInfo> array_length =
1175 Accessors::ArrayLengthInfo(isolate, attribs);
1176 { // Add length.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001177 AccessorConstantDescriptor d(
1178 Handle<Name>(Name::cast(array_length->name())), array_length,
1179 attribs);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001180 initial_map->AppendDescriptor(&d);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001181 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001182
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001183 InstallWithIntrinsicDefaultProto(isolate, array_function,
1184 Context::ARRAY_FUNCTION_INDEX);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001185
1186 // Cache the array maps, needed by ArrayConstructorStub
1187 CacheInitialJSArrayMaps(native_context(), initial_map);
1188 ArrayConstructorStub array_constructor_stub(isolate);
1189 Handle<Code> code = array_constructor_stub.GetCode();
1190 array_function->shared()->set_construct_stub(*code);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001191
1192 Handle<Map> initial_strong_map =
1193 Map::Copy(initial_map, "SetInstancePrototype");
1194 initial_strong_map->set_is_strong();
1195 CacheInitialJSArrayMaps(native_context(), initial_strong_map);
1196
1197 Handle<JSFunction> is_arraylike = SimpleInstallFunction(
1198 array_function, isolate->factory()->InternalizeUtf8String("isArray"),
1199 Builtins::kArrayIsArray, 1, true);
1200 native_context()->set_is_arraylike(*is_arraylike);
Steve Blocka7e24c12009-10-30 11:49:00 +00001201 }
1202
1203 { // --- N u m b e r ---
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001204 Handle<JSFunction> number_fun = InstallFunction(
1205 global, "Number", JS_VALUE_TYPE, JSValue::kSize,
1206 isolate->initial_object_prototype(), Builtins::kNumberConstructor);
1207 number_fun->shared()->DontAdaptArguments();
1208 number_fun->shared()->set_construct_stub(
1209 *isolate->builtins()->NumberConstructor_ConstructStub());
1210 number_fun->shared()->set_length(1);
1211 InstallWithIntrinsicDefaultProto(isolate, number_fun,
1212 Context::NUMBER_FUNCTION_INDEX);
Steve Blocka7e24c12009-10-30 11:49:00 +00001213 }
1214
1215 { // --- B o o l e a n ---
1216 Handle<JSFunction> boolean_fun =
1217 InstallFunction(global, "Boolean", JS_VALUE_TYPE, JSValue::kSize,
Steve Block44f0eee2011-05-26 01:26:41 +01001218 isolate->initial_object_prototype(),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001219 Builtins::kIllegal);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001220 InstallWithIntrinsicDefaultProto(isolate, boolean_fun,
1221 Context::BOOLEAN_FUNCTION_INDEX);
Steve Blocka7e24c12009-10-30 11:49:00 +00001222 }
1223
1224 { // --- S t r i n g ---
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001225 Handle<JSFunction> string_fun = InstallFunction(
1226 global, "String", JS_VALUE_TYPE, JSValue::kSize,
1227 isolate->initial_object_prototype(), Builtins::kStringConstructor);
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001228 string_fun->shared()->set_construct_stub(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001229 *isolate->builtins()->StringConstructor_ConstructStub());
1230 string_fun->shared()->DontAdaptArguments();
1231 string_fun->shared()->set_length(1);
1232 InstallWithIntrinsicDefaultProto(isolate, string_fun,
1233 Context::STRING_FUNCTION_INDEX);
Steve Blocka7e24c12009-10-30 11:49:00 +00001234
1235 Handle<Map> string_map =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001236 Handle<Map>(native_context()->string_function()->initial_map());
1237 Map::EnsureDescriptorSlack(string_map, 1);
1238
1239 PropertyAttributes attribs = static_cast<PropertyAttributes>(
1240 DONT_ENUM | DONT_DELETE | READ_ONLY);
1241 Handle<AccessorInfo> string_length(
1242 Accessors::StringLengthInfo(isolate, attribs));
1243
1244 { // Add length.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001245 AccessorConstantDescriptor d(factory->length_string(), string_length,
1246 attribs);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001247 string_map->AppendDescriptor(&d);
1248 }
1249 }
1250
1251 {
1252 // --- S y m b o l ---
1253 Handle<JSFunction> symbol_fun = InstallFunction(
1254 global, "Symbol", JS_VALUE_TYPE, JSValue::kSize,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001255 isolate->initial_object_prototype(), Builtins::kSymbolConstructor);
1256 symbol_fun->shared()->set_construct_stub(
1257 *isolate->builtins()->SymbolConstructor_ConstructStub());
1258 symbol_fun->shared()->set_length(1);
1259 symbol_fun->shared()->DontAdaptArguments();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001260 native_context()->set_symbol_function(*symbol_fun);
Steve Blocka7e24c12009-10-30 11:49:00 +00001261 }
1262
1263 { // --- D a t e ---
1264 // Builtin functions for Date.prototype.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001265 Handle<JSObject> prototype =
1266 factory->NewJSObject(isolate->object_function(), TENURED);
Steve Blocka7e24c12009-10-30 11:49:00 +00001267 Handle<JSFunction> date_fun =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001268 InstallFunction(global, "Date", JS_DATE_TYPE, JSDate::kSize, prototype,
1269 Builtins::kDateConstructor);
1270 InstallWithIntrinsicDefaultProto(isolate, date_fun,
1271 Context::DATE_FUNCTION_INDEX);
1272 date_fun->shared()->set_construct_stub(
1273 *isolate->builtins()->DateConstructor_ConstructStub());
1274 date_fun->shared()->set_length(7);
1275 date_fun->shared()->DontAdaptArguments();
Steve Blocka7e24c12009-10-30 11:49:00 +00001276
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001277 // Install the Date.now, Date.parse and Date.UTC functions.
1278 SimpleInstallFunction(date_fun, "now", Builtins::kDateNow, 0, false);
1279 SimpleInstallFunction(date_fun, "parse", Builtins::kDateParse, 1, false);
1280 SimpleInstallFunction(date_fun, "UTC", Builtins::kDateUTC, 7, false);
1281
1282 // Install the "constructor" property on the {prototype}.
1283 JSObject::AddProperty(prototype, factory->constructor_string(), date_fun,
1284 DONT_ENUM);
1285
1286 // Install the Date.prototype methods.
1287 SimpleInstallFunction(prototype, "toString",
1288 Builtins::kDatePrototypeToString, 0, false);
1289 SimpleInstallFunction(prototype, "toDateString",
1290 Builtins::kDatePrototypeToDateString, 0, false);
1291 SimpleInstallFunction(prototype, "toTimeString",
1292 Builtins::kDatePrototypeToTimeString, 0, false);
1293 SimpleInstallFunction(prototype, "toGMTString",
1294 Builtins::kDatePrototypeToUTCString, 0, false);
1295 SimpleInstallFunction(prototype, "toISOString",
1296 Builtins::kDatePrototypeToISOString, 0, false);
1297 SimpleInstallFunction(prototype, "toUTCString",
1298 Builtins::kDatePrototypeToUTCString, 0, false);
1299 SimpleInstallFunction(prototype, "getDate", Builtins::kDatePrototypeGetDate,
1300 0, true);
1301 SimpleInstallFunction(prototype, "setDate", Builtins::kDatePrototypeSetDate,
1302 1, false);
1303 SimpleInstallFunction(prototype, "getDay", Builtins::kDatePrototypeGetDay,
1304 0, true);
1305 SimpleInstallFunction(prototype, "getFullYear",
1306 Builtins::kDatePrototypeGetFullYear, 0, true);
1307 SimpleInstallFunction(prototype, "setFullYear",
1308 Builtins::kDatePrototypeSetFullYear, 3, false);
1309 SimpleInstallFunction(prototype, "getHours",
1310 Builtins::kDatePrototypeGetHours, 0, true);
1311 SimpleInstallFunction(prototype, "setHours",
1312 Builtins::kDatePrototypeSetHours, 4, false);
1313 SimpleInstallFunction(prototype, "getMilliseconds",
1314 Builtins::kDatePrototypeGetMilliseconds, 0, true);
1315 SimpleInstallFunction(prototype, "setMilliseconds",
1316 Builtins::kDatePrototypeSetMilliseconds, 1, false);
1317 SimpleInstallFunction(prototype, "getMinutes",
1318 Builtins::kDatePrototypeGetMinutes, 0, true);
1319 SimpleInstallFunction(prototype, "setMinutes",
1320 Builtins::kDatePrototypeSetMinutes, 3, false);
1321 SimpleInstallFunction(prototype, "getMonth",
1322 Builtins::kDatePrototypeGetMonth, 0, true);
1323 SimpleInstallFunction(prototype, "setMonth",
1324 Builtins::kDatePrototypeSetMonth, 2, false);
1325 SimpleInstallFunction(prototype, "getSeconds",
1326 Builtins::kDatePrototypeGetSeconds, 0, true);
1327 SimpleInstallFunction(prototype, "setSeconds",
1328 Builtins::kDatePrototypeSetSeconds, 2, false);
1329 SimpleInstallFunction(prototype, "getTime", Builtins::kDatePrototypeGetTime,
1330 0, true);
1331 SimpleInstallFunction(prototype, "setTime", Builtins::kDatePrototypeSetTime,
1332 1, false);
1333 SimpleInstallFunction(prototype, "getTimezoneOffset",
1334 Builtins::kDatePrototypeGetTimezoneOffset, 0, true);
1335 SimpleInstallFunction(prototype, "getUTCDate",
1336 Builtins::kDatePrototypeGetUTCDate, 0, true);
1337 SimpleInstallFunction(prototype, "setUTCDate",
1338 Builtins::kDatePrototypeSetUTCDate, 1, false);
1339 SimpleInstallFunction(prototype, "getUTCDay",
1340 Builtins::kDatePrototypeGetUTCDay, 0, true);
1341 SimpleInstallFunction(prototype, "getUTCFullYear",
1342 Builtins::kDatePrototypeGetUTCFullYear, 0, true);
1343 SimpleInstallFunction(prototype, "setUTCFullYear",
1344 Builtins::kDatePrototypeSetUTCFullYear, 3, false);
1345 SimpleInstallFunction(prototype, "getUTCHours",
1346 Builtins::kDatePrototypeGetUTCHours, 0, true);
1347 SimpleInstallFunction(prototype, "setUTCHours",
1348 Builtins::kDatePrototypeSetUTCHours, 4, false);
1349 SimpleInstallFunction(prototype, "getUTCMilliseconds",
1350 Builtins::kDatePrototypeGetUTCMilliseconds, 0, true);
1351 SimpleInstallFunction(prototype, "setUTCMilliseconds",
1352 Builtins::kDatePrototypeSetUTCMilliseconds, 1, false);
1353 SimpleInstallFunction(prototype, "getUTCMinutes",
1354 Builtins::kDatePrototypeGetUTCMinutes, 0, true);
1355 SimpleInstallFunction(prototype, "setUTCMinutes",
1356 Builtins::kDatePrototypeSetUTCMinutes, 3, false);
1357 SimpleInstallFunction(prototype, "getUTCMonth",
1358 Builtins::kDatePrototypeGetUTCMonth, 0, true);
1359 SimpleInstallFunction(prototype, "setUTCMonth",
1360 Builtins::kDatePrototypeSetUTCMonth, 2, false);
1361 SimpleInstallFunction(prototype, "getUTCSeconds",
1362 Builtins::kDatePrototypeGetUTCSeconds, 0, true);
1363 SimpleInstallFunction(prototype, "setUTCSeconds",
1364 Builtins::kDatePrototypeSetUTCSeconds, 2, false);
1365 SimpleInstallFunction(prototype, "valueOf", Builtins::kDatePrototypeValueOf,
1366 0, false);
1367 SimpleInstallFunction(prototype, "getYear", Builtins::kDatePrototypeGetYear,
1368 0, true);
1369 SimpleInstallFunction(prototype, "setYear", Builtins::kDatePrototypeSetYear,
1370 1, false);
1371
1372 // Install i18n fallback functions.
1373 SimpleInstallFunction(prototype, "toLocaleString",
1374 Builtins::kDatePrototypeToString, 0, false);
1375 SimpleInstallFunction(prototype, "toLocaleDateString",
1376 Builtins::kDatePrototypeToDateString, 0, false);
1377 SimpleInstallFunction(prototype, "toLocaleTimeString",
1378 Builtins::kDatePrototypeToTimeString, 0, false);
1379
1380 // Install the @@toPrimitive function.
1381 Handle<JSFunction> to_primitive = InstallFunction(
1382 prototype, factory->to_primitive_symbol(), JS_OBJECT_TYPE,
1383 JSObject::kHeaderSize, MaybeHandle<JSObject>(),
1384 Builtins::kDatePrototypeToPrimitive,
1385 static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
1386
1387 // Set the expected parameters for @@toPrimitive to 1; required by builtin.
1388 to_primitive->shared()->set_internal_formal_parameter_count(1);
1389
1390 // Set the length for the function to satisfy ECMA-262.
1391 to_primitive->shared()->set_length(1);
Steve Blocka7e24c12009-10-30 11:49:00 +00001392 }
1393
Steve Blocka7e24c12009-10-30 11:49:00 +00001394 { // -- R e g E x p
1395 // Builtin functions for RegExp.prototype.
1396 Handle<JSFunction> regexp_fun =
1397 InstallFunction(global, "RegExp", JS_REGEXP_TYPE, JSRegExp::kSize,
Steve Block44f0eee2011-05-26 01:26:41 +01001398 isolate->initial_object_prototype(),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001399 Builtins::kIllegal);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001400 InstallWithIntrinsicDefaultProto(isolate, regexp_fun,
1401 Context::REGEXP_FUNCTION_INDEX);
1402 regexp_fun->shared()->set_construct_stub(
1403 *isolate->builtins()->JSBuiltinsConstructStub());
Steve Block6ded16b2010-05-10 14:33:55 +01001404
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001405 DCHECK(regexp_fun->has_initial_map());
Steve Block6ded16b2010-05-10 14:33:55 +01001406 Handle<Map> initial_map(regexp_fun->initial_map());
1407
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001408 DCHECK_EQ(0, initial_map->GetInObjectProperties());
Steve Block6ded16b2010-05-10 14:33:55 +01001409
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001410 Map::EnsureDescriptorSlack(initial_map, 1);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001411
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001412 // ECMA-262, section 15.10.7.5.
1413 PropertyAttributes writable =
1414 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE);
1415 DataDescriptor field(factory->last_index_string(),
1416 JSRegExp::kLastIndexFieldIndex, writable,
1417 Representation::Tagged());
1418 initial_map->AppendDescriptor(&field);
Steve Block6ded16b2010-05-10 14:33:55 +01001419
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001420 static const int num_fields = JSRegExp::kInObjectFieldCount;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001421 initial_map->SetInObjectProperties(num_fields);
Steve Block6ded16b2010-05-10 14:33:55 +01001422 initial_map->set_unused_property_fields(0);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001423 initial_map->set_instance_size(initial_map->instance_size() +
1424 num_fields * kPointerSize);
Steve Blocka7e24c12009-10-30 11:49:00 +00001425 }
1426
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001427 { // -- E r r o r
1428 Handle<JSFunction> error_fun = InstallFunction(
1429 global, "Error", JS_OBJECT_TYPE, JSObject::kHeaderSize,
1430 isolate->initial_object_prototype(), Builtins::kIllegal);
1431 InstallWithIntrinsicDefaultProto(isolate, error_fun,
1432 Context::ERROR_FUNCTION_INDEX);
1433 }
1434
1435 { // -- E v a l E r r o r
1436 Handle<JSFunction> eval_error_fun = InstallFunction(
1437 global, "EvalError", JS_OBJECT_TYPE, JSObject::kHeaderSize,
1438 isolate->initial_object_prototype(), Builtins::kIllegal);
1439 InstallWithIntrinsicDefaultProto(isolate, eval_error_fun,
1440 Context::EVAL_ERROR_FUNCTION_INDEX);
1441 }
1442
1443 { // -- R a n g e E r r o r
1444 Handle<JSFunction> range_error_fun = InstallFunction(
1445 global, "RangeError", JS_OBJECT_TYPE, JSObject::kHeaderSize,
1446 isolate->initial_object_prototype(), Builtins::kIllegal);
1447 InstallWithIntrinsicDefaultProto(isolate, range_error_fun,
1448 Context::RANGE_ERROR_FUNCTION_INDEX);
1449 }
1450
1451 { // -- R e f e r e n c e E r r o r
1452 Handle<JSFunction> reference_error_fun = InstallFunction(
1453 global, "ReferenceError", JS_OBJECT_TYPE, JSObject::kHeaderSize,
1454 isolate->initial_object_prototype(), Builtins::kIllegal);
1455 InstallWithIntrinsicDefaultProto(isolate, reference_error_fun,
1456 Context::REFERENCE_ERROR_FUNCTION_INDEX);
1457 }
1458
1459 { // -- S y n t a x E r r o r
1460 Handle<JSFunction> syntax_error_fun = InstallFunction(
1461 global, "SyntaxError", JS_OBJECT_TYPE, JSObject::kHeaderSize,
1462 isolate->initial_object_prototype(), Builtins::kIllegal);
1463 InstallWithIntrinsicDefaultProto(isolate, syntax_error_fun,
1464 Context::SYNTAX_ERROR_FUNCTION_INDEX);
1465 }
1466
1467 { // -- T y p e E r r o r
1468 Handle<JSFunction> type_error_fun = InstallFunction(
1469 global, "TypeError", JS_OBJECT_TYPE, JSObject::kHeaderSize,
1470 isolate->initial_object_prototype(), Builtins::kIllegal);
1471 InstallWithIntrinsicDefaultProto(isolate, type_error_fun,
1472 Context::TYPE_ERROR_FUNCTION_INDEX);
1473 }
1474
1475 { // -- U R I E r r o r
1476 Handle<JSFunction> uri_error_fun = InstallFunction(
1477 global, "URIError", JS_OBJECT_TYPE, JSObject::kHeaderSize,
1478 isolate->initial_object_prototype(), Builtins::kIllegal);
1479 InstallWithIntrinsicDefaultProto(isolate, uri_error_fun,
1480 Context::URI_ERROR_FUNCTION_INDEX);
1481 }
1482
1483 // Initialize the embedder data slot.
1484 Handle<FixedArray> embedder_data = factory->NewFixedArray(3);
1485 native_context()->set_embedder_data(*embedder_data);
1486
1487 if (context_type == THIN_CONTEXT) return;
1488
Steve Blocka7e24c12009-10-30 11:49:00 +00001489 { // -- J S O N
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001490 Handle<String> name = factory->InternalizeUtf8String("JSON");
1491 Handle<JSFunction> cons = factory->NewFunction(name);
1492 JSFunction::SetInstancePrototype(cons,
1493 Handle<Object>(native_context()->initial_object_prototype(), isolate));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001494 cons->shared()->set_instance_class_name(*name);
Steve Block44f0eee2011-05-26 01:26:41 +01001495 Handle<JSObject> json_object = factory->NewJSObject(cons, TENURED);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001496 DCHECK(json_object->IsJSObject());
1497 JSObject::AddProperty(global, name, json_object, DONT_ENUM);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001498 }
1499
1500 { // -- M a t h
1501 Handle<String> name = factory->InternalizeUtf8String("Math");
1502 Handle<JSFunction> cons = factory->NewFunction(name);
1503 JSFunction::SetInstancePrototype(
1504 cons,
1505 Handle<Object>(native_context()->initial_object_prototype(), isolate));
1506 cons->shared()->set_instance_class_name(*name);
1507 Handle<JSObject> json_object = factory->NewJSObject(cons, TENURED);
1508 DCHECK(json_object->IsJSObject());
1509 JSObject::AddProperty(global, name, json_object, DONT_ENUM);
Steve Blocka7e24c12009-10-30 11:49:00 +00001510 }
1511
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001512 { // -- A r r a y B u f f e r
1513 Handle<JSFunction> array_buffer_fun =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001514 InstallArrayBuffer(global, "ArrayBuffer");
1515 InstallWithIntrinsicDefaultProto(isolate, array_buffer_fun,
1516 Context::ARRAY_BUFFER_FUN_INDEX);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001517 }
1518
1519 { // -- T y p e d A r r a y s
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001520#define INSTALL_TYPED_ARRAY(Type, type, TYPE, ctype, size) \
1521 { \
1522 Handle<JSFunction> fun; \
1523 InstallTypedArray(#Type "Array", TYPE##_ELEMENTS, &fun); \
1524 InstallWithIntrinsicDefaultProto(isolate, fun, \
1525 Context::TYPE##_ARRAY_FUN_INDEX); \
1526 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001527 TYPED_ARRAYS(INSTALL_TYPED_ARRAY)
1528#undef INSTALL_TYPED_ARRAY
1529
1530 Handle<JSFunction> data_view_fun =
1531 InstallFunction(
1532 global, "DataView", JS_DATA_VIEW_TYPE,
1533 JSDataView::kSizeWithInternalFields,
1534 isolate->initial_object_prototype(),
1535 Builtins::kIllegal);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001536 InstallWithIntrinsicDefaultProto(isolate, data_view_fun,
1537 Context::DATA_VIEW_FUN_INDEX);
1538 data_view_fun->shared()->set_construct_stub(
1539 *isolate->builtins()->JSBuiltinsConstructStub());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001540 }
1541
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001542 { // -- M a p
1543 Handle<JSFunction> js_map_fun = InstallFunction(
1544 global, "Map", JS_MAP_TYPE, JSMap::kSize,
1545 isolate->initial_object_prototype(), Builtins::kIllegal);
1546 InstallWithIntrinsicDefaultProto(isolate, js_map_fun,
1547 Context::JS_MAP_FUN_INDEX);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001548 }
1549
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001550 { // -- S e t
1551 Handle<JSFunction> js_set_fun = InstallFunction(
1552 global, "Set", JS_SET_TYPE, JSSet::kSize,
1553 isolate->initial_object_prototype(), Builtins::kIllegal);
1554 InstallWithIntrinsicDefaultProto(isolate, js_set_fun,
1555 Context::JS_SET_FUN_INDEX);
1556 }
1557
1558 { // -- I t e r a t o r R e s u l t
1559 Handle<Map> map =
1560 factory->NewMap(JS_ITERATOR_RESULT_TYPE, JSIteratorResult::kSize);
1561 Map::SetPrototype(map, isolate->initial_object_prototype());
1562 Map::EnsureDescriptorSlack(map, 2);
1563
1564 { // value
1565 DataDescriptor d(factory->value_string(), JSIteratorResult::kValueIndex,
1566 NONE, Representation::Tagged());
1567 map->AppendDescriptor(&d);
1568 }
1569
1570 { // done
1571 DataDescriptor d(factory->done_string(), JSIteratorResult::kDoneIndex,
1572 NONE, Representation::Tagged());
1573 map->AppendDescriptor(&d);
1574 }
1575
1576 map->SetInObjectProperties(2);
1577 native_context()->set_iterator_result_map(*map);
1578 }
1579
1580 { // -- W e a k M a p
1581 Handle<JSFunction> js_weak_map_fun = InstallFunction(
1582 global, "WeakMap", JS_WEAK_MAP_TYPE, JSWeakMap::kSize,
1583 isolate->initial_object_prototype(), Builtins::kIllegal);
1584 InstallWithIntrinsicDefaultProto(isolate, js_weak_map_fun,
1585 Context::JS_WEAK_MAP_FUN_INDEX);
1586 }
1587
1588 { // -- W e a k S e t
1589 Handle<JSFunction> js_weak_set_fun = InstallFunction(
1590 global, "WeakSet", JS_WEAK_SET_TYPE, JSWeakSet::kSize,
1591 isolate->initial_object_prototype(), Builtins::kIllegal);
1592 InstallWithIntrinsicDefaultProto(isolate, js_weak_set_fun,
1593 Context::JS_WEAK_SET_FUN_INDEX);
1594 }
1595
1596 { // --- B o u n d F u n c t i o n
1597 Handle<Map> map =
1598 factory->NewMap(JS_BOUND_FUNCTION_TYPE, JSBoundFunction::kSize);
1599 map->set_is_callable();
1600 Map::SetPrototype(map, empty_function);
1601
1602 PropertyAttributes roc_attribs =
1603 static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY);
1604 Map::EnsureDescriptorSlack(map, 2);
1605
1606 { // length
1607 DataDescriptor d(factory->length_string(), JSBoundFunction::kLengthIndex,
1608 roc_attribs, Representation::Tagged());
1609 map->AppendDescriptor(&d);
1610 }
1611 { // name
1612 DataDescriptor d(factory->name_string(), JSBoundFunction::kNameIndex,
1613 roc_attribs, Representation::Tagged());
1614 map->AppendDescriptor(&d);
1615 }
1616
1617 map->SetInObjectProperties(2);
1618 native_context()->set_bound_function_without_constructor_map(*map);
1619
1620 map = Map::Copy(map, "IsConstructor");
1621 map->set_is_constructor();
1622 native_context()->set_bound_function_with_constructor_map(*map);
1623 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001624
1625 { // --- sloppy arguments map
Steve Blocka7e24c12009-10-30 11:49:00 +00001626 // Make sure we can recognize argument objects at runtime.
1627 // This is done by introducing an anonymous function with
1628 // class_name equals 'Arguments'.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001629 Handle<String> arguments_string = factory->Arguments_string();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001630 Handle<Code> code = isolate->builtins()->Illegal();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001631 Handle<JSFunction> function = factory->NewFunctionWithoutPrototype(
1632 arguments_string, code);
1633 function->shared()->set_instance_class_name(*arguments_string);
Steve Blocka7e24c12009-10-30 11:49:00 +00001634
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001635 Handle<Map> map = factory->NewMap(
1636 JS_OBJECT_TYPE, Heap::kSloppyArgumentsObjectSize, FAST_ELEMENTS);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001637 // Create the descriptor array for the arguments object.
1638 Map::EnsureDescriptorSlack(map, 2);
Steve Blocka7e24c12009-10-30 11:49:00 +00001639
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001640 { // length
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001641 DataDescriptor d(factory->length_string(), Heap::kArgumentsLengthIndex,
1642 DONT_ENUM, Representation::Tagged());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001643 map->AppendDescriptor(&d);
1644 }
1645 { // callee
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001646 DataDescriptor d(factory->callee_string(), Heap::kArgumentsCalleeIndex,
1647 DONT_ENUM, Representation::Tagged());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001648 map->AppendDescriptor(&d);
1649 }
1650 // @@iterator method is added later.
Steve Blocka7e24c12009-10-30 11:49:00 +00001651
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001652 map->SetInObjectProperties(2);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001653 native_context()->set_sloppy_arguments_map(*map);
Steve Blocka7e24c12009-10-30 11:49:00 +00001654
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001655 DCHECK(!function->has_initial_map());
1656 JSFunction::SetInitialMap(function, map,
1657 isolate->initial_object_prototype());
Steve Blocka7e24c12009-10-30 11:49:00 +00001658
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001659 DCHECK(map->GetInObjectProperties() > Heap::kArgumentsCalleeIndex);
1660 DCHECK(map->GetInObjectProperties() > Heap::kArgumentsLengthIndex);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001661 DCHECK(!map->is_dictionary_map());
1662 DCHECK(IsFastObjectElementsKind(map->elements_kind()));
Steve Block44f0eee2011-05-26 01:26:41 +01001663 }
1664
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001665 { // --- fast and slow aliased arguments map
1666 Handle<Map> map = isolate->sloppy_arguments_map();
1667 map = Map::Copy(map, "FastAliasedArguments");
1668 map->set_elements_kind(FAST_SLOPPY_ARGUMENTS_ELEMENTS);
1669 DCHECK_EQ(2, map->GetInObjectProperties());
1670 native_context()->set_fast_aliased_arguments_map(*map);
1671
1672 map = Map::Copy(map, "SlowAliasedArguments");
1673 map->set_elements_kind(SLOW_SLOPPY_ARGUMENTS_ELEMENTS);
1674 DCHECK_EQ(2, map->GetInObjectProperties());
1675 native_context()->set_slow_aliased_arguments_map(*map);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001676 }
1677
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001678 { // --- strict mode arguments map
Steve Block44f0eee2011-05-26 01:26:41 +01001679 const PropertyAttributes attributes =
1680 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
1681
1682 // Create the ThrowTypeError functions.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001683 Handle<AccessorPair> callee = factory->NewAccessorPair();
1684 Handle<AccessorPair> caller = factory->NewAccessorPair();
Steve Block44f0eee2011-05-26 01:26:41 +01001685
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001686 Handle<JSFunction> poison = GetStrictArgumentsPoisonFunction();
Steve Block44f0eee2011-05-26 01:26:41 +01001687
1688 // Install the ThrowTypeError functions.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001689 callee->set_getter(*poison);
1690 callee->set_setter(*poison);
1691 caller->set_getter(*poison);
1692 caller->set_setter(*poison);
Steve Block44f0eee2011-05-26 01:26:41 +01001693
1694 // Create the map. Allocate one in-object field for length.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001695 Handle<Map> map = factory->NewMap(
1696 JS_OBJECT_TYPE, Heap::kStrictArgumentsObjectSize, FAST_ELEMENTS);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001697 // Create the descriptor array for the arguments object.
1698 Map::EnsureDescriptorSlack(map, 3);
1699
1700 { // length
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001701 DataDescriptor d(factory->length_string(), Heap::kArgumentsLengthIndex,
1702 DONT_ENUM, Representation::Tagged());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001703 map->AppendDescriptor(&d);
1704 }
1705 { // callee
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001706 AccessorConstantDescriptor d(factory->callee_string(), callee,
1707 attributes);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001708 map->AppendDescriptor(&d);
1709 }
1710 { // caller
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001711 AccessorConstantDescriptor d(factory->caller_string(), caller,
1712 attributes);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001713 map->AppendDescriptor(&d);
1714 }
1715 // @@iterator method is added later.
1716
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001717 DCHECK_EQ(native_context()->object_function()->prototype(),
1718 *isolate->initial_object_prototype());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001719 Map::SetPrototype(map, isolate->initial_object_prototype());
1720 map->SetInObjectProperties(1);
Steve Block44f0eee2011-05-26 01:26:41 +01001721
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001722 // Copy constructor from the sloppy arguments boilerplate.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001723 map->SetConstructor(
1724 native_context()->sloppy_arguments_map()->GetConstructor());
Steve Block44f0eee2011-05-26 01:26:41 +01001725
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001726 native_context()->set_strict_arguments_map(*map);
Steve Block44f0eee2011-05-26 01:26:41 +01001727
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001728 DCHECK(map->GetInObjectProperties() > Heap::kArgumentsLengthIndex);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001729 DCHECK(!map->is_dictionary_map());
1730 DCHECK(IsFastObjectElementsKind(map->elements_kind()));
Steve Blocka7e24c12009-10-30 11:49:00 +00001731 }
1732
1733 { // --- context extension
1734 // Create a function for the context extension objects.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001735 Handle<Code> code = isolate->builtins()->Illegal();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001736 Handle<JSFunction> context_extension_fun = factory->NewFunction(
1737 factory->empty_string(), code, JS_CONTEXT_EXTENSION_OBJECT_TYPE,
1738 JSObject::kHeaderSize);
Steve Blocka7e24c12009-10-30 11:49:00 +00001739
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001740 Handle<String> name = factory->InternalizeOneByteString(
1741 STATIC_CHAR_VECTOR("context_extension"));
Steve Blocka7e24c12009-10-30 11:49:00 +00001742 context_extension_fun->shared()->set_instance_class_name(*name);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001743 native_context()->set_context_extension_function(*context_extension_fun);
Steve Blocka7e24c12009-10-30 11:49:00 +00001744 }
1745
1746
1747 {
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001748 // Set up the call-as-function delegate.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001749 Handle<Code> code = isolate->builtins()->HandleApiCallAsFunction();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001750 Handle<JSFunction> delegate = factory->NewFunction(
1751 factory->empty_string(), code, JS_OBJECT_TYPE, JSObject::kHeaderSize);
1752 native_context()->set_call_as_function_delegate(*delegate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001753 delegate->shared()->DontAdaptArguments();
1754 }
1755
1756 {
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001757 // Set up the call-as-constructor delegate.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001758 Handle<Code> code = isolate->builtins()->HandleApiCallAsConstructor();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001759 Handle<JSFunction> delegate = factory->NewFunction(
1760 factory->empty_string(), code, JS_OBJECT_TYPE, JSObject::kHeaderSize);
1761 native_context()->set_call_as_constructor_delegate(*delegate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001762 delegate->shared()->DontAdaptArguments();
1763 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001764} // NOLINT(readability/fn_size)
Steve Blocka7e24c12009-10-30 11:49:00 +00001765
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001766
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001767void Genesis::InstallTypedArray(const char* name, ElementsKind elements_kind,
1768 Handle<JSFunction>* fun) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001769 Handle<JSObject> global = Handle<JSObject>(native_context()->global_object());
1770 Handle<JSFunction> result = InstallFunction(
1771 global, name, JS_TYPED_ARRAY_TYPE, JSTypedArray::kSize,
1772 isolate()->initial_object_prototype(), Builtins::kIllegal);
1773
1774 Handle<Map> initial_map = isolate()->factory()->NewMap(
1775 JS_TYPED_ARRAY_TYPE,
1776 JSTypedArray::kSizeWithInternalFields,
1777 elements_kind);
1778 JSFunction::SetInitialMap(result, initial_map,
1779 handle(initial_map->prototype(), isolate()));
1780 *fun = result;
Steve Blocka7e24c12009-10-30 11:49:00 +00001781}
1782
1783
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001784void Genesis::InitializeExperimentalGlobal() {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001785#define FEATURE_INITIALIZE_GLOBAL(id, descr) InitializeGlobal_##id();
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001786
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001787 HARMONY_INPROGRESS(FEATURE_INITIALIZE_GLOBAL)
1788 HARMONY_STAGED(FEATURE_INITIALIZE_GLOBAL)
1789 HARMONY_SHIPPING(FEATURE_INITIALIZE_GLOBAL)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001790 FEATURE_INITIALIZE_GLOBAL(promise_extra, "")
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001791#undef FEATURE_INITIALIZE_GLOBAL
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001792}
1793
1794
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001795bool Bootstrapper::CompileBuiltin(Isolate* isolate, int index) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001796 Vector<const char> name = Natives::GetScriptName(index);
Steve Block44f0eee2011-05-26 01:26:41 +01001797 Handle<String> source_code =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001798 isolate->bootstrapper()->SourceLookup<Natives>(index);
1799
1800 // We pass in extras_utils so that builtin code can set it up for later use
1801 // by actual extras code, compiled with CompileExtraBuiltin.
1802 Handle<Object> global = isolate->global_object();
1803 Handle<Object> utils = isolate->natives_utils_object();
1804 Handle<Object> extras_utils = isolate->extras_utils_object();
1805 Handle<Object> args[] = {global, utils, extras_utils};
1806
1807 return Bootstrapper::CompileNative(isolate, name, source_code,
1808 arraysize(args), args);
Ben Murdoch257744e2011-11-30 15:57:28 +00001809}
1810
1811
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001812bool Bootstrapper::CompileExperimentalBuiltin(Isolate* isolate, int index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001813 HandleScope scope(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001814 Vector<const char> name = ExperimentalNatives::GetScriptName(index);
1815 Handle<String> source_code =
1816 isolate->bootstrapper()->SourceLookup<ExperimentalNatives>(index);
1817 Handle<Object> global = isolate->global_object();
1818 Handle<Object> utils = isolate->natives_utils_object();
1819 Handle<Object> args[] = {global, utils};
1820 return Bootstrapper::CompileNative(isolate, name, source_code,
1821 arraysize(args), args);
1822}
1823
1824
1825bool Bootstrapper::CompileExtraBuiltin(Isolate* isolate, int index) {
1826 HandleScope scope(isolate);
1827 Vector<const char> name = ExtraNatives::GetScriptName(index);
1828 Handle<String> source_code =
1829 isolate->bootstrapper()->SourceLookup<ExtraNatives>(index);
1830 Handle<Object> global = isolate->global_object();
1831 Handle<Object> binding = isolate->extras_binding_object();
1832 Handle<Object> extras_utils = isolate->extras_utils_object();
1833 Handle<Object> args[] = {global, binding, extras_utils};
1834 return Bootstrapper::CompileNative(isolate, name, source_code,
1835 arraysize(args), args);
1836}
1837
1838
1839bool Bootstrapper::CompileExperimentalExtraBuiltin(Isolate* isolate,
1840 int index) {
1841 HandleScope scope(isolate);
1842 Vector<const char> name = ExperimentalExtraNatives::GetScriptName(index);
1843 Handle<String> source_code =
1844 isolate->bootstrapper()->SourceLookup<ExperimentalExtraNatives>(index);
1845 Handle<Object> global = isolate->global_object();
1846 Handle<Object> binding = isolate->extras_binding_object();
1847 Handle<Object> extras_utils = isolate->extras_utils_object();
1848 Handle<Object> args[] = {global, binding, extras_utils};
1849 return Bootstrapper::CompileNative(isolate, name, source_code,
1850 arraysize(args), args);
1851}
1852
1853
1854bool Bootstrapper::CompileNative(Isolate* isolate, Vector<const char> name,
1855 Handle<String> source, int argc,
1856 Handle<Object> argv[]) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001857 SuppressDebug compiling_natives(isolate->debug());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001858 // During genesis, the boilerplate for stack overflow won't work until the
1859 // environment has been at least partially initialized. Add a stack check
1860 // before entering JS code to catch overflow early.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001861 StackLimitCheck check(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001862 if (check.JsHasOverflowed(1 * KB)) {
1863 isolate->StackOverflow();
1864 return false;
1865 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001866
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001867 Handle<Context> context(isolate->context());
1868
1869 Handle<String> script_name =
1870 isolate->factory()->NewStringFromUtf8(name).ToHandleChecked();
1871 Handle<SharedFunctionInfo> function_info = Compiler::CompileScript(
1872 source, script_name, 0, 0, ScriptOriginOptions(), Handle<Object>(),
1873 context, NULL, NULL, ScriptCompiler::kNoCompileOptions, NATIVES_CODE,
1874 false);
1875 if (function_info.is_null()) return false;
1876
1877 DCHECK(context->IsNativeContext());
1878
1879 Handle<JSFunction> fun =
1880 isolate->factory()->NewFunctionFromSharedFunctionInfo(function_info,
1881 context);
1882 Handle<Object> receiver = isolate->factory()->undefined_value();
1883
1884 // For non-extension scripts, run script to get the function wrapper.
1885 Handle<Object> wrapper;
1886 if (!Execution::Call(isolate, fun, receiver, 0, NULL).ToHandle(&wrapper)) {
1887 return false;
1888 }
1889 // Then run the function wrapper.
1890 return !Execution::Call(isolate, Handle<JSFunction>::cast(wrapper), receiver,
1891 argc, argv).is_null();
Steve Blocka7e24c12009-10-30 11:49:00 +00001892}
1893
1894
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001895bool Genesis::CallUtilsFunction(Isolate* isolate, const char* name) {
1896 Handle<JSObject> utils =
1897 Handle<JSObject>::cast(isolate->natives_utils_object());
1898 Handle<String> name_string =
1899 isolate->factory()->NewStringFromAsciiChecked(name);
1900 Handle<Object> fun = JSObject::GetDataProperty(utils, name_string);
1901 Handle<Object> receiver = isolate->factory()->undefined_value();
1902 Handle<Object> args[] = {utils};
1903 return !Execution::Call(isolate, fun, receiver, 1, args).is_null();
1904}
1905
1906
1907bool Genesis::CompileExtension(Isolate* isolate, v8::Extension* extension) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001908 Factory* factory = isolate->factory();
1909 HandleScope scope(isolate);
Steve Block6ded16b2010-05-10 14:33:55 +01001910 Handle<SharedFunctionInfo> function_info;
Steve Blocka7e24c12009-10-30 11:49:00 +00001911
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001912 Handle<String> source =
1913 isolate->factory()
1914 ->NewExternalStringFromOneByte(extension->source())
1915 .ToHandleChecked();
1916 DCHECK(source->IsOneByteRepresentation());
1917
Steve Blocka7e24c12009-10-30 11:49:00 +00001918 // If we can't find the function in the cache, we compile a new
1919 // function and insert it into the cache.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001920 Vector<const char> name = CStrVector(extension->name());
1921 SourceCodeCache* cache = isolate->bootstrapper()->extensions_cache();
1922 Handle<Context> context(isolate->context());
1923 DCHECK(context->IsNativeContext());
1924
1925 if (!cache->Lookup(name, &function_info)) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001926 Handle<String> script_name =
1927 factory->NewStringFromUtf8(name).ToHandleChecked();
1928 function_info = Compiler::CompileScript(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001929 source, script_name, 0, 0, ScriptOriginOptions(), Handle<Object>(),
1930 context, extension, NULL, ScriptCompiler::kNoCompileOptions,
1931 NOT_NATIVES_CODE, false);
Steve Block6ded16b2010-05-10 14:33:55 +01001932 if (function_info.is_null()) return false;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001933 cache->Add(name, function_info);
Steve Blocka7e24c12009-10-30 11:49:00 +00001934 }
1935
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001936 // Set up the function context. Conceptually, we should clone the
Steve Blocka7e24c12009-10-30 11:49:00 +00001937 // function before overwriting the context but since we're in a
1938 // single-threaded environment it is not strictly necessary.
Steve Blocka7e24c12009-10-30 11:49:00 +00001939 Handle<JSFunction> fun =
Steve Block44f0eee2011-05-26 01:26:41 +01001940 factory->NewFunctionFromSharedFunctionInfo(function_info, context);
Steve Blocka7e24c12009-10-30 11:49:00 +00001941
Leon Clarke4515c472010-02-03 11:58:03 +00001942 // Call function using either the runtime object or the global
Steve Blocka7e24c12009-10-30 11:49:00 +00001943 // object as the receiver. Provide no parameters.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001944 Handle<Object> receiver = isolate->global_object();
1945 return !Execution::Call(isolate, fun, receiver, 0, NULL).is_null();
Steve Blocka7e24c12009-10-30 11:49:00 +00001946}
1947
1948
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001949static Handle<JSObject> ResolveBuiltinIdHolder(Handle<Context> native_context,
1950 const char* holder_expr) {
1951 Isolate* isolate = native_context->GetIsolate();
1952 Factory* factory = isolate->factory();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001953 Handle<JSGlobalObject> global(native_context->global_object());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001954 const char* period_pos = strchr(holder_expr, '.');
1955 if (period_pos == NULL) {
1956 return Handle<JSObject>::cast(
1957 Object::GetPropertyOrElement(
1958 global, factory->InternalizeUtf8String(holder_expr))
1959 .ToHandleChecked());
1960 }
1961 const char* inner = period_pos + 1;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001962 DCHECK(!strchr(inner, '.'));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001963 Vector<const char> property(holder_expr,
1964 static_cast<int>(period_pos - holder_expr));
1965 Handle<String> property_string = factory->InternalizeUtf8String(property);
1966 DCHECK(!property_string.is_null());
1967 Handle<JSObject> object = Handle<JSObject>::cast(
1968 Object::GetProperty(global, property_string).ToHandleChecked());
1969 if (strcmp("prototype", inner) == 0) {
1970 Handle<JSFunction> function = Handle<JSFunction>::cast(object);
1971 return Handle<JSObject>(JSObject::cast(function->prototype()));
1972 }
1973 Handle<String> inner_string = factory->InternalizeUtf8String(inner);
1974 DCHECK(!inner_string.is_null());
1975 Handle<Object> value =
1976 Object::GetProperty(object, inner_string).ToHandleChecked();
1977 return Handle<JSObject>::cast(value);
1978}
Steve Blocka7e24c12009-10-30 11:49:00 +00001979
Steve Block44f0eee2011-05-26 01:26:41 +01001980
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001981void Genesis::ConfigureUtilsObject(ContextType context_type) {
1982 switch (context_type) {
1983 // We still need the utils object to find debug functions.
1984 case DEBUG_CONTEXT:
1985 return;
1986 // Expose the natives in global if a valid name for it is specified.
1987 case FULL_CONTEXT: {
1988 // We still need the utils object after deserialization.
1989 if (isolate()->serializer_enabled()) return;
1990 if (FLAG_expose_natives_as == NULL) break;
1991 if (strlen(FLAG_expose_natives_as) == 0) break;
1992 HandleScope scope(isolate());
1993 Handle<String> natives_key =
1994 factory()->InternalizeUtf8String(FLAG_expose_natives_as);
1995 uint32_t dummy_index;
1996 if (natives_key->AsArrayIndex(&dummy_index)) break;
1997 Handle<Object> utils = isolate()->natives_utils_object();
1998 Handle<JSObject> global = isolate()->global_object();
1999 JSObject::AddProperty(global, natives_key, utils, DONT_ENUM);
2000 break;
2001 }
2002 case THIN_CONTEXT:
2003 break;
Ben Murdoch257744e2011-11-30 15:57:28 +00002004 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002005
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002006 // The utils object can be removed for cases that reach this point.
2007 native_context()->set_natives_utils_object(heap()->undefined_value());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002008}
2009
2010
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002011void Bootstrapper::ExportFromRuntime(Isolate* isolate,
2012 Handle<JSObject> container) {
2013 Factory* factory = isolate->factory();
2014 HandleScope scope(isolate);
2015 Handle<Context> native_context = isolate->native_context();
2016#define EXPORT_PRIVATE_SYMBOL(NAME) \
2017 Handle<String> NAME##_name = factory->NewStringFromAsciiChecked(#NAME); \
2018 JSObject::AddProperty(container, NAME##_name, factory->NAME(), NONE);
2019 PRIVATE_SYMBOL_LIST(EXPORT_PRIVATE_SYMBOL)
2020#undef EXPORT_PRIVATE_SYMBOL
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002021
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002022#define EXPORT_PUBLIC_SYMBOL(NAME, DESCRIPTION) \
2023 Handle<String> NAME##_name = factory->NewStringFromAsciiChecked(#NAME); \
2024 JSObject::AddProperty(container, NAME##_name, factory->NAME(), NONE);
2025 PUBLIC_SYMBOL_LIST(EXPORT_PUBLIC_SYMBOL)
2026 WELL_KNOWN_SYMBOL_LIST(EXPORT_PUBLIC_SYMBOL)
2027#undef EXPORT_PUBLIC_SYMBOL
2028
2029 {
2030 Handle<JSFunction> apply = InstallFunction(
2031 container, "reflect_apply", JS_OBJECT_TYPE, JSObject::kHeaderSize,
2032 MaybeHandle<JSObject>(), Builtins::kReflectApply);
2033 apply->shared()->DontAdaptArguments();
2034 apply->shared()->set_length(3);
2035 native_context->set_reflect_apply(*apply);
2036 }
2037
2038 {
2039 Handle<JSFunction> construct = InstallFunction(
2040 container, "reflect_construct", JS_OBJECT_TYPE, JSObject::kHeaderSize,
2041 MaybeHandle<JSObject>(), Builtins::kReflectConstruct);
2042 construct->shared()->DontAdaptArguments();
2043 construct->shared()->set_length(2);
2044 native_context->set_reflect_construct(*construct);
2045 }
2046
2047 {
2048 Handle<JSFunction> to_string = InstallFunction(
2049 container, "object_to_string", JS_OBJECT_TYPE, JSObject::kHeaderSize,
2050 MaybeHandle<JSObject>(), Builtins::kObjectProtoToString);
2051 to_string->shared()->DontAdaptArguments();
2052 to_string->shared()->set_length(0);
2053 native_context->set_object_to_string(*to_string);
2054 }
2055
2056 Handle<JSObject> iterator_prototype;
2057
2058 {
2059 PrototypeIterator iter(native_context->generator_object_prototype_map());
2060 iter.Advance(); // Advance to the prototype of generator_object_prototype.
2061 iterator_prototype = Handle<JSObject>(iter.GetCurrent<JSObject>());
2062
2063 JSObject::AddProperty(container,
2064 factory->InternalizeUtf8String("IteratorPrototype"),
2065 iterator_prototype, NONE);
2066 }
2067
2068 {
2069 PrototypeIterator iter(native_context->sloppy_generator_function_map());
2070 Handle<JSObject> generator_function_prototype(iter.GetCurrent<JSObject>());
2071
2072 JSObject::AddProperty(
2073 container, factory->InternalizeUtf8String("GeneratorFunctionPrototype"),
2074 generator_function_prototype, NONE);
2075
2076 static const bool kUseStrictFunctionMap = true;
2077 Handle<JSFunction> generator_function_function = InstallFunction(
2078 container, "GeneratorFunction", JS_FUNCTION_TYPE, JSFunction::kSize,
2079 generator_function_prototype, Builtins::kGeneratorFunctionConstructor,
2080 kUseStrictFunctionMap);
2081 generator_function_function->set_prototype_or_initial_map(
2082 native_context->sloppy_generator_function_map());
2083 generator_function_function->shared()->DontAdaptArguments();
2084 generator_function_function->shared()->set_construct_stub(
2085 *isolate->builtins()->GeneratorFunctionConstructor());
2086 generator_function_function->shared()->set_length(1);
2087 InstallWithIntrinsicDefaultProto(
2088 isolate, generator_function_function,
2089 Context::GENERATOR_FUNCTION_FUNCTION_INDEX);
2090
2091 native_context->sloppy_generator_function_map()->SetConstructor(
2092 *generator_function_function);
2093 native_context->strict_generator_function_map()->SetConstructor(
2094 *generator_function_function);
2095 native_context->strong_generator_function_map()->SetConstructor(
2096 *generator_function_function);
2097 }
2098
2099 { // -- S e t I t e r a t o r
2100 Handle<JSObject> set_iterator_prototype =
2101 isolate->factory()->NewJSObject(isolate->object_function(), TENURED);
2102 SetObjectPrototype(set_iterator_prototype, iterator_prototype);
2103 Handle<JSFunction> set_iterator_function = InstallFunction(
2104 container, "SetIterator", JS_SET_ITERATOR_TYPE, JSSetIterator::kSize,
2105 set_iterator_prototype, Builtins::kIllegal);
2106 native_context->set_set_iterator_map(set_iterator_function->initial_map());
2107 }
2108
2109 { // -- M a p I t e r a t o r
2110 Handle<JSObject> map_iterator_prototype =
2111 isolate->factory()->NewJSObject(isolate->object_function(), TENURED);
2112 SetObjectPrototype(map_iterator_prototype, iterator_prototype);
2113 Handle<JSFunction> map_iterator_function = InstallFunction(
2114 container, "MapIterator", JS_MAP_ITERATOR_TYPE, JSMapIterator::kSize,
2115 map_iterator_prototype, Builtins::kIllegal);
2116 native_context->set_map_iterator_map(map_iterator_function->initial_map());
2117 }
2118
2119 { // -- S c r i p t
2120 // Builtin functions for Script.
2121 Handle<JSFunction> script_fun = InstallFunction(
2122 container, "Script", JS_VALUE_TYPE, JSValue::kSize,
2123 isolate->initial_object_prototype(), Builtins::kIllegal);
2124 Handle<JSObject> prototype =
2125 factory->NewJSObject(isolate->object_function(), TENURED);
2126 Accessors::FunctionSetPrototype(script_fun, prototype).Assert();
2127 native_context->set_script_function(*script_fun);
2128
2129 Handle<Map> script_map = Handle<Map>(script_fun->initial_map());
2130 Map::EnsureDescriptorSlack(script_map, 15);
2131
2132 PropertyAttributes attribs =
2133 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
2134
2135 Handle<AccessorInfo> script_column =
2136 Accessors::ScriptColumnOffsetInfo(isolate, attribs);
2137 {
2138 AccessorConstantDescriptor d(
2139 Handle<Name>(Name::cast(script_column->name())), script_column,
2140 attribs);
2141 script_map->AppendDescriptor(&d);
2142 }
2143
2144 Handle<AccessorInfo> script_id = Accessors::ScriptIdInfo(isolate, attribs);
2145 {
2146 AccessorConstantDescriptor d(Handle<Name>(Name::cast(script_id->name())),
2147 script_id, attribs);
2148 script_map->AppendDescriptor(&d);
2149 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002150
2151
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002152 Handle<AccessorInfo> script_name =
2153 Accessors::ScriptNameInfo(isolate, attribs);
2154 {
2155 AccessorConstantDescriptor d(
2156 Handle<Name>(Name::cast(script_name->name())), script_name, attribs);
2157 script_map->AppendDescriptor(&d);
2158 }
2159
2160 Handle<AccessorInfo> script_line =
2161 Accessors::ScriptLineOffsetInfo(isolate, attribs);
2162 {
2163 AccessorConstantDescriptor d(
2164 Handle<Name>(Name::cast(script_line->name())), script_line, attribs);
2165 script_map->AppendDescriptor(&d);
2166 }
2167
2168 Handle<AccessorInfo> script_source =
2169 Accessors::ScriptSourceInfo(isolate, attribs);
2170 {
2171 AccessorConstantDescriptor d(
2172 Handle<Name>(Name::cast(script_source->name())), script_source,
2173 attribs);
2174 script_map->AppendDescriptor(&d);
2175 }
2176
2177 Handle<AccessorInfo> script_type =
2178 Accessors::ScriptTypeInfo(isolate, attribs);
2179 {
2180 AccessorConstantDescriptor d(
2181 Handle<Name>(Name::cast(script_type->name())), script_type, attribs);
2182 script_map->AppendDescriptor(&d);
2183 }
2184
2185 Handle<AccessorInfo> script_compilation_type =
2186 Accessors::ScriptCompilationTypeInfo(isolate, attribs);
2187 {
2188 AccessorConstantDescriptor d(
2189 Handle<Name>(Name::cast(script_compilation_type->name())),
2190 script_compilation_type, attribs);
2191 script_map->AppendDescriptor(&d);
2192 }
2193
2194 Handle<AccessorInfo> script_line_ends =
2195 Accessors::ScriptLineEndsInfo(isolate, attribs);
2196 {
2197 AccessorConstantDescriptor d(
2198 Handle<Name>(Name::cast(script_line_ends->name())), script_line_ends,
2199 attribs);
2200 script_map->AppendDescriptor(&d);
2201 }
2202
2203 Handle<AccessorInfo> script_context_data =
2204 Accessors::ScriptContextDataInfo(isolate, attribs);
2205 {
2206 AccessorConstantDescriptor d(
2207 Handle<Name>(Name::cast(script_context_data->name())),
2208 script_context_data, attribs);
2209 script_map->AppendDescriptor(&d);
2210 }
2211
2212 Handle<AccessorInfo> script_eval_from_script =
2213 Accessors::ScriptEvalFromScriptInfo(isolate, attribs);
2214 {
2215 AccessorConstantDescriptor d(
2216 Handle<Name>(Name::cast(script_eval_from_script->name())),
2217 script_eval_from_script, attribs);
2218 script_map->AppendDescriptor(&d);
2219 }
2220
2221 Handle<AccessorInfo> script_eval_from_script_position =
2222 Accessors::ScriptEvalFromScriptPositionInfo(isolate, attribs);
2223 {
2224 AccessorConstantDescriptor d(
2225 Handle<Name>(Name::cast(script_eval_from_script_position->name())),
2226 script_eval_from_script_position, attribs);
2227 script_map->AppendDescriptor(&d);
2228 }
2229
2230 Handle<AccessorInfo> script_eval_from_function_name =
2231 Accessors::ScriptEvalFromFunctionNameInfo(isolate, attribs);
2232 {
2233 AccessorConstantDescriptor d(
2234 Handle<Name>(Name::cast(script_eval_from_function_name->name())),
2235 script_eval_from_function_name, attribs);
2236 script_map->AppendDescriptor(&d);
2237 }
2238
2239 Handle<AccessorInfo> script_source_url =
2240 Accessors::ScriptSourceUrlInfo(isolate, attribs);
2241 {
2242 AccessorConstantDescriptor d(
2243 Handle<Name>(Name::cast(script_source_url->name())),
2244 script_source_url, attribs);
2245 script_map->AppendDescriptor(&d);
2246 }
2247
2248 Handle<AccessorInfo> script_source_mapping_url =
2249 Accessors::ScriptSourceMappingUrlInfo(isolate, attribs);
2250 {
2251 AccessorConstantDescriptor d(
2252 Handle<Name>(Name::cast(script_source_mapping_url->name())),
2253 script_source_mapping_url, attribs);
2254 script_map->AppendDescriptor(&d);
2255 }
2256
2257 Handle<AccessorInfo> script_is_embedder_debug_script =
2258 Accessors::ScriptIsEmbedderDebugScriptInfo(isolate, attribs);
2259 {
2260 AccessorConstantDescriptor d(
2261 Handle<Name>(Name::cast(script_is_embedder_debug_script->name())),
2262 script_is_embedder_debug_script, attribs);
2263 script_map->AppendDescriptor(&d);
2264 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002265 }
Ben Murdoch257744e2011-11-30 15:57:28 +00002266}
2267
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002268
2269void Bootstrapper::ExportExperimentalFromRuntime(Isolate* isolate,
2270 Handle<JSObject> container) {
2271 HandleScope scope(isolate);
2272
2273#define INITIALIZE_FLAG(FLAG) \
2274 { \
2275 Handle<String> name = \
2276 isolate->factory()->NewStringFromAsciiChecked(#FLAG); \
2277 JSObject::AddProperty(container, name, \
2278 isolate->factory()->ToBoolean(FLAG), NONE); \
2279 }
2280
2281 INITIALIZE_FLAG(FLAG_harmony_tostring)
2282 INITIALIZE_FLAG(FLAG_harmony_tolength)
2283 INITIALIZE_FLAG(FLAG_harmony_species)
2284
2285#undef INITIALIZE_FLAG
2286}
2287
Steve Blocka7e24c12009-10-30 11:49:00 +00002288
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002289#define EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(id) \
2290 void Genesis::InitializeGlobal_##id() {}
2291
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002292EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_modules)
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002293EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_sloppy)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002294EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_sloppy_function)
2295EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_sloppy_let)
2296EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_default_parameters)
2297EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_destructuring_bind)
2298EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_destructuring_assignment)
2299EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_object_observe)
2300EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_regexps)
2301EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_unicode_regexps)
2302EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_completion)
2303EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_tolength)
2304EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_do_expressions)
2305EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_regexp_lookbehind)
2306EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_function_name)
2307EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(promise_extra)
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002308
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002309
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002310void InstallPublicSymbol(Factory* factory, Handle<Context> native_context,
2311 const char* name, Handle<Symbol> value) {
2312 Handle<JSGlobalObject> global(
2313 JSGlobalObject::cast(native_context->global_object()));
2314 Handle<String> symbol_string = factory->InternalizeUtf8String("Symbol");
2315 Handle<JSObject> symbol = Handle<JSObject>::cast(
2316 JSObject::GetProperty(global, symbol_string).ToHandleChecked());
2317 Handle<String> name_string = factory->InternalizeUtf8String(name);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002318 PropertyAttributes attributes =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002319 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
2320 JSObject::AddProperty(symbol, name_string, value, attributes);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002321}
2322
Steve Blocka7e24c12009-10-30 11:49:00 +00002323
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002324void Genesis::InitializeGlobal_harmony_tostring() {
2325 if (!FLAG_harmony_tostring) return;
2326 InstallPublicSymbol(factory(), native_context(), "toStringTag",
2327 factory()->to_string_tag_symbol());
2328}
2329
2330
2331void Genesis::InitializeGlobal_harmony_concat_spreadable() {
2332 if (!FLAG_harmony_concat_spreadable) return;
2333 InstallPublicSymbol(factory(), native_context(), "isConcatSpreadable",
2334 factory()->is_concat_spreadable_symbol());
2335}
2336
2337
2338void Genesis::InitializeGlobal_harmony_regexp_subclass() {
2339 if (!FLAG_harmony_regexp_subclass) return;
2340 InstallPublicSymbol(factory(), native_context(), "match",
2341 factory()->match_symbol());
2342 InstallPublicSymbol(factory(), native_context(), "replace",
2343 factory()->replace_symbol());
2344 InstallPublicSymbol(factory(), native_context(), "search",
2345 factory()->search_symbol());
2346 InstallPublicSymbol(factory(), native_context(), "split",
2347 factory()->split_symbol());
2348}
2349
2350
2351void Genesis::InitializeGlobal_harmony_reflect() {
2352 Factory* factory = isolate()->factory();
2353
2354 // We currently use some of the Reflect functions internally, even when
2355 // the --harmony-reflect flag is not given.
2356
2357 Handle<JSFunction> define_property =
2358 SimpleCreateFunction(isolate(), factory->defineProperty_string(),
2359 Builtins::kReflectDefineProperty, 3, true);
2360 native_context()->set_reflect_define_property(*define_property);
2361
2362 Handle<JSFunction> delete_property =
2363 SimpleCreateFunction(isolate(), factory->deleteProperty_string(),
2364 Builtins::kReflectDeleteProperty, 2, true);
2365 native_context()->set_reflect_delete_property(*delete_property);
2366
2367 if (!FLAG_harmony_reflect) return;
2368
2369 Handle<JSGlobalObject> global(JSGlobalObject::cast(
2370 native_context()->global_object()));
2371 Handle<String> reflect_string = factory->NewStringFromStaticChars("Reflect");
2372 Handle<JSObject> reflect =
2373 factory->NewJSObject(isolate()->object_function(), TENURED);
2374 JSObject::AddProperty(global, reflect_string, reflect, DONT_ENUM);
2375
2376 InstallFunction(reflect, define_property, factory->defineProperty_string());
2377 InstallFunction(reflect, delete_property, factory->deleteProperty_string());
2378
2379 SimpleInstallFunction(reflect, factory->get_string(),
2380 Builtins::kReflectGet, 2, false);
2381 SimpleInstallFunction(reflect, factory->getOwnPropertyDescriptor_string(),
2382 Builtins::kReflectGetOwnPropertyDescriptor, 2, true);
2383 SimpleInstallFunction(reflect, factory->getPrototypeOf_string(),
2384 Builtins::kReflectGetPrototypeOf, 1, true);
2385 SimpleInstallFunction(reflect, factory->has_string(),
2386 Builtins::kReflectHas, 2, true);
2387 SimpleInstallFunction(reflect, factory->isExtensible_string(),
2388 Builtins::kReflectIsExtensible, 1, true);
2389 SimpleInstallFunction(reflect, factory->ownKeys_string(),
2390 Builtins::kReflectOwnKeys, 1, true);
2391 SimpleInstallFunction(reflect, factory->preventExtensions_string(),
2392 Builtins::kReflectPreventExtensions, 1, true);
2393 SimpleInstallFunction(reflect, factory->set_string(),
2394 Builtins::kReflectSet, 3, false);
2395 SimpleInstallFunction(reflect, factory->setPrototypeOf_string(),
2396 Builtins::kReflectSetPrototypeOf, 2, true);
2397}
2398
2399
2400void Genesis::InitializeGlobal_harmony_sharedarraybuffer() {
2401 if (!FLAG_harmony_sharedarraybuffer) return;
2402
2403 Handle<JSGlobalObject> global(native_context()->global_object());
2404 Handle<JSFunction> shared_array_buffer_fun =
2405 InstallArrayBuffer(global, "SharedArrayBuffer");
2406 native_context()->set_shared_array_buffer_fun(*shared_array_buffer_fun);
2407}
2408
2409
2410void Genesis::InitializeGlobal_harmony_simd() {
2411 if (!FLAG_harmony_simd) return;
2412
2413 Handle<JSGlobalObject> global(
2414 JSGlobalObject::cast(native_context()->global_object()));
2415 Isolate* isolate = global->GetIsolate();
2416 Factory* factory = isolate->factory();
2417
2418 Handle<String> name = factory->InternalizeUtf8String("SIMD");
2419 Handle<JSFunction> cons = factory->NewFunction(name);
2420 JSFunction::SetInstancePrototype(
2421 cons,
2422 Handle<Object>(native_context()->initial_object_prototype(), isolate));
2423 cons->shared()->set_instance_class_name(*name);
2424 Handle<JSObject> simd_object = factory->NewJSObject(cons, TENURED);
2425 DCHECK(simd_object->IsJSObject());
2426 JSObject::AddProperty(global, name, simd_object, DONT_ENUM);
2427
2428// Install SIMD type functions. Set the instance class names since
2429// InstallFunction only does this when we install on the JSGlobalObject.
2430#define SIMD128_INSTALL_FUNCTION(TYPE, Type, type, lane_count, lane_type) \
2431 Handle<JSFunction> type##_function = InstallFunction( \
2432 simd_object, #Type, JS_VALUE_TYPE, JSValue::kSize, \
2433 isolate->initial_object_prototype(), Builtins::kIllegal); \
2434 native_context()->set_##type##_function(*type##_function); \
2435 type##_function->shared()->set_instance_class_name(*factory->Type##_string());
2436 SIMD128_TYPES(SIMD128_INSTALL_FUNCTION)
2437#undef SIMD128_INSTALL_FUNCTION
2438}
2439
2440
2441void Genesis::InstallJSProxyMaps() {
2442 // Allocate the different maps for all Proxy types.
2443 // Next to the default proxy, we need maps indicating callable and
2444 // constructable proxies.
2445
2446 Handle<Map> proxy_function_map =
2447 Map::Copy(isolate()->sloppy_function_without_prototype_map(), "Proxy");
2448 proxy_function_map->set_is_constructor();
2449 native_context()->set_proxy_function_map(*proxy_function_map);
2450
2451 Handle<Map> proxy_map =
2452 factory()->NewMap(JS_PROXY_TYPE, JSProxy::kSize, FAST_ELEMENTS);
2453 proxy_map->set_dictionary_map(true);
2454 native_context()->set_proxy_map(*proxy_map);
2455
2456 Handle<Map> proxy_callable_map = Map::Copy(proxy_map, "callable Proxy");
2457 proxy_callable_map->set_is_callable();
2458 native_context()->set_proxy_callable_map(*proxy_callable_map);
2459 proxy_callable_map->SetConstructor(native_context()->function_function());
2460
2461 Handle<Map> proxy_constructor_map =
2462 Map::Copy(proxy_callable_map, "constructor Proxy");
2463 proxy_constructor_map->set_is_constructor();
2464 native_context()->set_proxy_constructor_map(*proxy_constructor_map);
2465}
2466
2467
2468void Genesis::InitializeGlobal_harmony_proxies() {
2469 if (!FLAG_harmony_proxies) return;
2470 Handle<JSGlobalObject> global(
2471 JSGlobalObject::cast(native_context()->global_object()));
2472 Isolate* isolate = global->GetIsolate();
2473 Factory* factory = isolate->factory();
2474
2475 InstallJSProxyMaps();
2476
2477 // Create the Proxy object.
2478 Handle<String> name = factory->Proxy_string();
2479 Handle<Code> code(isolate->builtins()->ProxyConstructor());
2480
2481 Handle<JSFunction> proxy_function = factory->NewFunction(
2482 isolate->proxy_function_map(), factory->Proxy_string(), code);
2483
2484 JSFunction::SetInitialMap(proxy_function,
2485 Handle<Map>(native_context()->proxy_map(), isolate),
2486 factory->null_value());
2487
2488 proxy_function->shared()->set_construct_stub(
2489 *isolate->builtins()->ProxyConstructor_ConstructStub());
2490 proxy_function->shared()->set_internal_formal_parameter_count(2);
2491 proxy_function->shared()->set_length(2);
2492
2493 native_context()->set_proxy_function(*proxy_function);
2494 InstallFunction(global, name, proxy_function, factory->Object_string());
2495}
2496
2497
2498Handle<JSFunction> Genesis::InstallArrayBuffer(Handle<JSObject> target,
2499 const char* name) {
2500 // Setup the {prototype} with the given {name} for @@toStringTag.
2501 Handle<JSObject> prototype =
2502 factory()->NewJSObject(isolate()->object_function(), TENURED);
2503 JSObject::AddProperty(prototype, factory()->to_string_tag_symbol(),
2504 factory()->NewStringFromAsciiChecked(name),
2505 static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
2506
2507 // Allocate the constructor with the given {prototype}.
2508 Handle<JSFunction> array_buffer_fun =
2509 InstallFunction(target, name, JS_ARRAY_BUFFER_TYPE,
2510 JSArrayBuffer::kSizeWithInternalFields, prototype,
2511 Builtins::kArrayBufferConstructor);
2512 array_buffer_fun->shared()->set_construct_stub(
2513 *isolate()->builtins()->ArrayBufferConstructor_ConstructStub());
2514 array_buffer_fun->shared()->DontAdaptArguments();
2515 array_buffer_fun->shared()->set_length(1);
2516
2517 // Install the "constructor" property on the {prototype}.
2518 JSObject::AddProperty(prototype, factory()->constructor_string(),
2519 array_buffer_fun, DONT_ENUM);
2520
2521 SimpleInstallFunction(array_buffer_fun, factory()->isView_string(),
2522 Builtins::kArrayBufferIsView, 1, true);
2523
2524 return array_buffer_fun;
2525}
2526
2527
2528void Genesis::InitializeGlobal_harmony_species() {
2529 if (!FLAG_harmony_species) return;
2530 InstallPublicSymbol(factory(), native_context(), "species",
2531 factory()->species_symbol());
2532}
2533
2534
2535Handle<JSFunction> Genesis::InstallInternalArray(Handle<JSObject> target,
2536 const char* name,
2537 ElementsKind elements_kind) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002538 // --- I n t e r n a l A r r a y ---
2539 // An array constructor on the builtins object that works like
2540 // the public Array constructor, except that its prototype
2541 // doesn't inherit from Object.prototype.
2542 // To be used only for internal work by builtins. Instances
2543 // must not be leaked to user code.
2544 Handle<JSObject> prototype =
2545 factory()->NewJSObject(isolate()->object_function(), TENURED);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002546 Handle<JSFunction> array_function =
2547 InstallFunction(target, name, JS_ARRAY_TYPE, JSArray::kSize, prototype,
2548 Builtins::kInternalArrayCode);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002549
2550 InternalArrayConstructorStub internal_array_constructor_stub(isolate());
2551 Handle<Code> code = internal_array_constructor_stub.GetCode();
2552 array_function->shared()->set_construct_stub(*code);
2553 array_function->shared()->DontAdaptArguments();
2554
2555 Handle<Map> original_map(array_function->initial_map());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002556 Handle<Map> initial_map = Map::Copy(original_map, "InternalArray");
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002557 initial_map->set_elements_kind(elements_kind);
2558 JSFunction::SetInitialMap(array_function, initial_map, prototype);
2559
2560 // Make "length" magic on instances.
2561 Map::EnsureDescriptorSlack(initial_map, 1);
2562
2563 PropertyAttributes attribs = static_cast<PropertyAttributes>(
2564 DONT_ENUM | DONT_DELETE);
2565
2566 Handle<AccessorInfo> array_length =
2567 Accessors::ArrayLengthInfo(isolate(), attribs);
2568 { // Add length.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002569 AccessorConstantDescriptor d(Handle<Name>(Name::cast(array_length->name())),
2570 array_length, attribs);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002571 initial_map->AppendDescriptor(&d);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002572 }
2573
2574 return array_function;
2575}
2576
2577
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002578bool Genesis::InstallNatives(ContextType context_type) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002579 HandleScope scope(isolate());
Steve Blocka7e24c12009-10-30 11:49:00 +00002580
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002581 // Set up the utils object as shared container between native scripts.
2582 Handle<JSObject> utils = factory()->NewJSObject(isolate()->object_function());
2583 JSObject::NormalizeProperties(utils, CLEAR_INOBJECT_PROPERTIES, 16,
2584 "utils container for native scripts");
2585 native_context()->set_natives_utils_object(*utils);
Steve Blocka7e24c12009-10-30 11:49:00 +00002586
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002587 // Set up the extras utils object as a shared container between native
2588 // scripts and extras. (Extras consume things added there by native scripts.)
2589 Handle<JSObject> extras_utils =
2590 factory()->NewJSObject(isolate()->object_function());
2591 native_context()->set_extras_utils_object(*extras_utils);
Steve Blocka7e24c12009-10-30 11:49:00 +00002592
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002593 InstallInternalArray(extras_utils, "InternalPackedArray", FAST_ELEMENTS);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002594
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002595 int builtin_index = Natives::GetDebuggerCount();
2596 // Only run prologue.js and runtime.js at this point.
2597 DCHECK_EQ(builtin_index, Natives::GetIndex("prologue"));
2598 if (!Bootstrapper::CompileBuiltin(isolate(), builtin_index++)) return false;
2599 DCHECK_EQ(builtin_index, Natives::GetIndex("runtime"));
2600 if (!Bootstrapper::CompileBuiltin(isolate(), builtin_index++)) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00002601
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002602 // A thin context is ready at this point.
2603 if (context_type == THIN_CONTEXT) return true;
Steve Blocka7e24c12009-10-30 11:49:00 +00002604
Steve Block6ded16b2010-05-10 14:33:55 +01002605 {
2606 // Builtin function for OpaqueReference -- a JSValue-based object,
2607 // that keeps its field isolated from JavaScript code. It may store
2608 // objects, that JavaScript code may not access.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002609 Handle<JSFunction> opaque_reference_fun = factory()->NewFunction(
2610 factory()->empty_string(), isolate()->builtins()->Illegal(),
2611 isolate()->initial_object_prototype(), JS_VALUE_TYPE, JSValue::kSize);
Steve Block6ded16b2010-05-10 14:33:55 +01002612 Handle<JSObject> prototype =
Ben Murdoch257744e2011-11-30 15:57:28 +00002613 factory()->NewJSObject(isolate()->object_function(), TENURED);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002614 Accessors::FunctionSetPrototype(opaque_reference_fun, prototype).Assert();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002615 native_context()->set_opaque_reference_function(*opaque_reference_fun);
Steve Block6ded16b2010-05-10 14:33:55 +01002616 }
2617
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002618 // InternalArrays should not use Smi-Only array optimizations. There are too
2619 // many places in the C++ runtime code (e.g. RegEx) that assume that
2620 // elements in InternalArrays can be set to non-Smi values without going
2621 // through a common bottleneck that would make the SMI_ONLY -> FAST_ELEMENT
2622 // transition easy to trap. Moreover, they rarely are smi-only.
2623 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002624 HandleScope scope(isolate());
2625 Handle<JSObject> utils =
2626 Handle<JSObject>::cast(isolate()->natives_utils_object());
Ben Murdoche0cee9b2011-05-25 10:26:03 +01002627 Handle<JSFunction> array_function =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002628 InstallInternalArray(utils, "InternalArray", FAST_HOLEY_ELEMENTS);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002629 native_context()->set_internal_array_function(*array_function);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002630 InstallInternalArray(utils, "InternalPackedArray", FAST_ELEMENTS);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002631 }
2632
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002633 // Run the rest of the native scripts.
2634 while (builtin_index < Natives::GetBuiltinsCount()) {
2635 if (!Bootstrapper::CompileBuiltin(isolate(), builtin_index++)) return false;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002636 }
2637
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002638 if (!CallUtilsFunction(isolate(), "PostNatives")) return false;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002639
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002640 auto function_cache =
2641 ObjectHashTable::New(isolate(), ApiNatives::kInitialFunctionCacheSize,
2642 USE_CUSTOM_MINIMUM_CAPACITY);
2643 native_context()->set_function_cache(*function_cache);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002644
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002645 // Store the map for the %ObjectPrototype% after the natives has been compiled
2646 // and the Object function has been set up.
2647 Handle<JSFunction> object_function(native_context()->object_function());
2648 DCHECK(JSObject::cast(object_function->initial_map()->prototype())
2649 ->HasFastProperties());
2650 native_context()->set_object_function_prototype_map(
2651 HeapObject::cast(object_function->initial_map()->prototype())->map());
Ben Murdoche0cee9b2011-05-25 10:26:03 +01002652
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002653 // Store the map for the %StringPrototype% after the natives has been compiled
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002654 // and the String function has been set up.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002655 Handle<JSFunction> string_function(native_context()->string_function());
2656 DCHECK(JSObject::cast(
Iain Merrick75681382010-08-19 15:07:18 +01002657 string_function->initial_map()->prototype())->HasFastProperties());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002658 native_context()->set_string_function_prototype_map(
Iain Merrick75681382010-08-19 15:07:18 +01002659 HeapObject::cast(string_function->initial_map()->prototype())->map());
2660
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002661 // Install Global.eval.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002662 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002663 Handle<JSFunction> eval = SimpleInstallFunction(
2664 handle(native_context()->global_object()), factory()->eval_string(),
2665 Builtins::kGlobalEval, 1, false);
2666 native_context()->set_global_eval_fun(*eval);
2667 }
Steve Blocka7e24c12009-10-30 11:49:00 +00002668
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002669 // Install Array.prototype.concat
2670 {
2671 Handle<JSFunction> array_constructor(native_context()->array_function());
2672 Handle<JSObject> proto(JSObject::cast(array_constructor->prototype()));
2673 Handle<JSFunction> concat =
2674 InstallFunction(proto, "concat", JS_OBJECT_TYPE, JSObject::kHeaderSize,
2675 MaybeHandle<JSObject>(), Builtins::kArrayConcat);
Steve Blocka7e24c12009-10-30 11:49:00 +00002676
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002677 // Make sure that Array.prototype.concat appears to be compiled.
Steve Blocka7e24c12009-10-30 11:49:00 +00002678 // The code will never be called, but inline caching for call will
2679 // only work if it appears to be compiled.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002680 concat->shared()->DontAdaptArguments();
2681 DCHECK(concat->is_compiled());
Steve Blocka7e24c12009-10-30 11:49:00 +00002682 // Set the lengths for the functions to satisfy ECMA-262.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002683 concat->shared()->set_length(1);
2684 }
2685
2686 // Install InternalArray.prototype.concat
2687 {
2688 Handle<JSFunction> array_constructor(
2689 native_context()->internal_array_function());
2690 Handle<JSObject> proto(JSObject::cast(array_constructor->prototype()));
2691 Handle<JSFunction> concat =
2692 InstallFunction(proto, "concat", JS_OBJECT_TYPE, JSObject::kHeaderSize,
2693 MaybeHandle<JSObject>(), Builtins::kArrayConcat);
2694
2695 // Make sure that InternalArray.prototype.concat appears to be compiled.
2696 // The code will never be called, but inline caching for call will
2697 // only work if it appears to be compiled.
2698 concat->shared()->DontAdaptArguments();
2699 DCHECK(concat->is_compiled());
2700 // Set the lengths for the functions to satisfy ECMA-262.
2701 concat->shared()->set_length(1);
2702 }
2703
2704 // Set up the Promise constructor.
2705 {
2706 Handle<String> key = factory()->Promise_string();
2707 Handle<JSFunction> function = Handle<JSFunction>::cast(
2708 Object::GetProperty(handle(native_context()->global_object()), key)
2709 .ToHandleChecked());
2710 JSFunction::EnsureHasInitialMap(function);
2711 function->initial_map()->set_instance_type(JS_PROMISE_TYPE);
2712 function->shared()->set_construct_stub(
2713 *isolate()->builtins()->JSBuiltinsConstructStub());
2714 InstallWithIntrinsicDefaultProto(isolate(), function,
2715 Context::PROMISE_FUNCTION_INDEX);
Steve Blocka7e24c12009-10-30 11:49:00 +00002716 }
2717
Ben Murdoch42effa52011-08-19 16:40:31 +01002718 InstallBuiltinFunctionIds();
2719
Steve Block6ded16b2010-05-10 14:33:55 +01002720 // Create a constructor for RegExp results (a variant of Array that
2721 // predefines the two properties index and match).
2722 {
2723 // RegExpResult initial map.
2724
2725 // Find global.Array.prototype to inherit from.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002726 Handle<JSFunction> array_constructor(native_context()->array_function());
Steve Block6ded16b2010-05-10 14:33:55 +01002727 Handle<JSObject> array_prototype(
2728 JSObject::cast(array_constructor->instance_prototype()));
2729
2730 // Add initial map.
2731 Handle<Map> initial_map =
Ben Murdoch257744e2011-11-30 15:57:28 +00002732 factory()->NewMap(JS_ARRAY_TYPE, JSRegExpResult::kSize);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002733 initial_map->SetConstructor(*array_constructor);
Steve Block6ded16b2010-05-10 14:33:55 +01002734
2735 // Set prototype on map.
2736 initial_map->set_non_instance_prototype(false);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002737 Map::SetPrototype(initial_map, array_prototype);
Steve Block6ded16b2010-05-10 14:33:55 +01002738
2739 // Update map with length accessor from Array and add "index" and "input".
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002740 Map::EnsureDescriptorSlack(initial_map, 3);
Ben Murdoch592a9fc2012-03-05 11:04:45 +00002741
Steve Block6ded16b2010-05-10 14:33:55 +01002742 {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002743 JSFunction* array_function = native_context()->array_function();
2744 Handle<DescriptorArray> array_descriptors(
2745 array_function->initial_map()->instance_descriptors());
2746 Handle<String> length = factory()->length_string();
2747 int old = array_descriptors->SearchWithCache(
2748 *length, array_function->initial_map());
2749 DCHECK(old != DescriptorArray::kNotFound);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002750 AccessorConstantDescriptor desc(
2751 length, handle(array_descriptors->GetValue(old), isolate()),
2752 array_descriptors->GetDetails(old).attributes());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002753 initial_map->AppendDescriptor(&desc);
2754 }
2755 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002756 DataDescriptor index_field(factory()->index_string(),
2757 JSRegExpResult::kIndexIndex, NONE,
2758 Representation::Tagged());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002759 initial_map->AppendDescriptor(&index_field);
Steve Block6ded16b2010-05-10 14:33:55 +01002760 }
2761
2762 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002763 DataDescriptor input_field(factory()->input_string(),
2764 JSRegExpResult::kInputIndex, NONE,
2765 Representation::Tagged());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002766 initial_map->AppendDescriptor(&input_field);
Steve Block6ded16b2010-05-10 14:33:55 +01002767 }
Steve Block6ded16b2010-05-10 14:33:55 +01002768
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002769 initial_map->SetInObjectProperties(2);
Steve Block6ded16b2010-05-10 14:33:55 +01002770 initial_map->set_unused_property_fields(0);
Steve Block6ded16b2010-05-10 14:33:55 +01002771
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002772 native_context()->set_regexp_result_map(*initial_map);
Steve Block6ded16b2010-05-10 14:33:55 +01002773 }
2774
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002775 // Add @@iterator method to the arguments object maps.
2776 {
2777 PropertyAttributes attribs = DONT_ENUM;
2778 Handle<AccessorInfo> arguments_iterator =
2779 Accessors::ArgumentsIteratorInfo(isolate(), attribs);
2780 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002781 AccessorConstantDescriptor d(factory()->iterator_symbol(),
2782 arguments_iterator, attribs);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002783 Handle<Map> map(native_context()->sloppy_arguments_map());
2784 Map::EnsureDescriptorSlack(map, 1);
2785 map->AppendDescriptor(&d);
2786 }
2787 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002788 AccessorConstantDescriptor d(factory()->iterator_symbol(),
2789 arguments_iterator, attribs);
2790 Handle<Map> map(native_context()->fast_aliased_arguments_map());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002791 Map::EnsureDescriptorSlack(map, 1);
2792 map->AppendDescriptor(&d);
2793 }
2794 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002795 AccessorConstantDescriptor d(factory()->iterator_symbol(),
2796 arguments_iterator, attribs);
2797 Handle<Map> map(native_context()->slow_aliased_arguments_map());
2798 Map::EnsureDescriptorSlack(map, 1);
2799 map->AppendDescriptor(&d);
2800 }
2801 {
2802 AccessorConstantDescriptor d(factory()->iterator_symbol(),
2803 arguments_iterator, attribs);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002804 Handle<Map> map(native_context()->strict_arguments_map());
2805 Map::EnsureDescriptorSlack(map, 1);
2806 map->AppendDescriptor(&d);
2807 }
2808 }
2809
Steve Blocka7e24c12009-10-30 11:49:00 +00002810 return true;
2811}
2812
2813
Ben Murdoch257744e2011-11-30 15:57:28 +00002814bool Genesis::InstallExperimentalNatives() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002815 static const char* harmony_proxies_natives[] = {"native proxy.js", nullptr};
2816 static const char* harmony_modules_natives[] = {nullptr};
2817 static const char* harmony_regexps_natives[] = {"native harmony-regexp.js",
2818 nullptr};
2819 static const char* harmony_tostring_natives[] = {nullptr};
2820 static const char* harmony_sloppy_natives[] = {nullptr};
2821 static const char* harmony_sloppy_function_natives[] = {nullptr};
2822 static const char* harmony_sloppy_let_natives[] = {nullptr};
2823 static const char* harmony_species_natives[] = {"native harmony-species.js",
2824 nullptr};
2825 static const char* harmony_unicode_regexps_natives[] = {
2826 "native harmony-unicode-regexps.js", nullptr};
2827 static const char* harmony_default_parameters_natives[] = {nullptr};
2828 static const char* harmony_reflect_natives[] = {"native harmony-reflect.js",
2829 nullptr};
2830 static const char* harmony_destructuring_bind_natives[] = {nullptr};
2831 static const char* harmony_destructuring_assignment_natives[] = {nullptr};
2832 static const char* harmony_object_observe_natives[] = {
2833 "native harmony-object-observe.js", nullptr};
2834 static const char* harmony_sharedarraybuffer_natives[] = {
2835 "native harmony-sharedarraybuffer.js", "native harmony-atomics.js", NULL};
2836 static const char* harmony_concat_spreadable_natives[] = {nullptr};
2837 static const char* harmony_simd_natives[] = {"native harmony-simd.js",
2838 nullptr};
2839 static const char* harmony_tolength_natives[] = {nullptr};
2840 static const char* harmony_completion_natives[] = {nullptr};
2841 static const char* harmony_do_expressions_natives[] = {nullptr};
2842 static const char* harmony_regexp_subclass_natives[] = {nullptr};
2843 static const char* harmony_regexp_lookbehind_natives[] = {nullptr};
2844 static const char* harmony_function_name_natives[] = {nullptr};
2845 static const char* promise_extra_natives[] = {"native promise-extra.js",
2846 nullptr};
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002847
Ben Murdoch257744e2011-11-30 15:57:28 +00002848 for (int i = ExperimentalNatives::GetDebuggerCount();
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002849 i < ExperimentalNatives::GetBuiltinsCount(); i++) {
2850#define INSTALL_EXPERIMENTAL_NATIVES(id, desc) \
2851 if (FLAG_##id) { \
2852 for (size_t j = 0; id##_natives[j] != NULL; j++) { \
2853 Vector<const char> script_name = ExperimentalNatives::GetScriptName(i); \
2854 if (strncmp(script_name.start(), id##_natives[j], \
2855 script_name.length()) == 0) { \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002856 if (!Bootstrapper::CompileExperimentalBuiltin(isolate(), i)) { \
2857 return false; \
2858 } \
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002859 } \
2860 } \
2861 }
2862 HARMONY_INPROGRESS(INSTALL_EXPERIMENTAL_NATIVES);
2863 HARMONY_STAGED(INSTALL_EXPERIMENTAL_NATIVES);
2864 HARMONY_SHIPPING(INSTALL_EXPERIMENTAL_NATIVES);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002865 INSTALL_EXPERIMENTAL_NATIVES(promise_extra, "");
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002866#undef INSTALL_EXPERIMENTAL_NATIVES
Ben Murdoch257744e2011-11-30 15:57:28 +00002867 }
2868
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002869 if (!CallUtilsFunction(isolate(), "PostExperimentals")) return false;
2870
2871 InstallExperimentalBuiltinFunctionIds();
Ben Murdoch257744e2011-11-30 15:57:28 +00002872 return true;
2873}
2874
2875
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002876bool Genesis::InstallExtraNatives() {
2877 HandleScope scope(isolate());
2878
2879 Handle<JSObject> extras_binding =
2880 factory()->NewJSObject(isolate()->object_function());
2881 native_context()->set_extras_binding_object(*extras_binding);
2882
2883 for (int i = ExtraNatives::GetDebuggerCount();
2884 i < ExtraNatives::GetBuiltinsCount(); i++) {
2885 if (!Bootstrapper::CompileExtraBuiltin(isolate(), i)) return false;
2886 }
2887
2888 return true;
2889}
2890
2891
2892bool Genesis::InstallExperimentalExtraNatives() {
2893 for (int i = ExperimentalExtraNatives::GetDebuggerCount();
2894 i < ExperimentalExtraNatives::GetBuiltinsCount(); i++) {
2895 if (!Bootstrapper::CompileExperimentalExtraBuiltin(isolate(), i))
2896 return false;
2897 }
2898
2899 return true;
2900}
2901
2902
2903bool Genesis::InstallDebuggerNatives() {
2904 for (int i = 0; i < Natives::GetDebuggerCount(); ++i) {
2905 if (!Bootstrapper::CompileBuiltin(isolate(), i)) return false;
2906 }
2907 return CallUtilsFunction(isolate(), "PostDebug");
2908}
2909
2910
Ben Murdochb0fe1622011-05-05 13:52:32 +01002911static void InstallBuiltinFunctionId(Handle<JSObject> holder,
2912 const char* function_name,
2913 BuiltinFunctionId id) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002914 Isolate* isolate = holder->GetIsolate();
2915 Handle<Object> function_object =
2916 Object::GetProperty(isolate, holder, function_name).ToHandleChecked();
2917 Handle<JSFunction> function = Handle<JSFunction>::cast(function_object);
Kristian Monsen25f61362010-05-21 11:50:48 +01002918 function->shared()->set_function_data(Smi::FromInt(id));
2919}
2920
2921
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002922#define INSTALL_BUILTIN_ID(holder_expr, fun_name, name) \
2923 { #holder_expr, #fun_name, k##name } \
2924 ,
2925
2926
Ben Murdochb0fe1622011-05-05 13:52:32 +01002927void Genesis::InstallBuiltinFunctionIds() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002928 HandleScope scope(isolate());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002929 struct BuiltinFunctionIds {
2930 const char* holder_expr;
2931 const char* fun_name;
2932 BuiltinFunctionId id;
2933 };
2934
2935 const BuiltinFunctionIds builtins[] = {
2936 FUNCTIONS_WITH_ID_LIST(INSTALL_BUILTIN_ID)};
2937
2938 for (const BuiltinFunctionIds& builtin : builtins) {
2939 Handle<JSObject> holder =
2940 ResolveBuiltinIdHolder(native_context(), builtin.holder_expr);
2941 InstallBuiltinFunctionId(holder, builtin.fun_name, builtin.id);
Kristian Monsen25f61362010-05-21 11:50:48 +01002942 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002943}
2944
2945
2946void Genesis::InstallExperimentalBuiltinFunctionIds() {
2947 if (FLAG_harmony_sharedarraybuffer) {
2948 struct BuiltinFunctionIds {
2949 const char* holder_expr;
2950 const char* fun_name;
2951 BuiltinFunctionId id;
2952 };
2953
2954 const BuiltinFunctionIds atomic_builtins[] = {
2955 ATOMIC_FUNCTIONS_WITH_ID_LIST(INSTALL_BUILTIN_ID)};
2956
2957 for (const BuiltinFunctionIds& builtin : atomic_builtins) {
2958 Handle<JSObject> holder =
2959 ResolveBuiltinIdHolder(native_context(), builtin.holder_expr);
2960 InstallBuiltinFunctionId(holder, builtin.fun_name, builtin.id);
2961 }
2962 }
2963}
2964
2965
Ben Murdochb0fe1622011-05-05 13:52:32 +01002966#undef INSTALL_BUILTIN_ID
Steve Block6ded16b2010-05-10 14:33:55 +01002967
2968
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002969void Genesis::InitializeNormalizedMapCaches() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002970 Handle<NormalizedMapCache> cache = NormalizedMapCache::New(isolate());
2971 native_context()->set_normalized_map_cache(*cache);
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002972}
2973
2974
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002975bool Bootstrapper::InstallExtensions(Handle<Context> native_context,
Andrei Popescu31002712010-02-23 13:46:05 +00002976 v8::ExtensionConfiguration* extensions) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002977 BootstrapperActive active(this);
2978 SaveContext saved_context(isolate_);
2979 isolate_->set_context(*native_context);
2980 return Genesis::InstallExtensions(native_context, extensions) &&
2981 Genesis::InstallSpecialObjects(native_context);
2982}
2983
2984
2985bool Genesis::InstallSpecialObjects(Handle<Context> native_context) {
2986 Isolate* isolate = native_context->GetIsolate();
2987 // Don't install extensions into the snapshot.
2988 if (isolate->serializer_enabled()) return true;
2989
2990 Factory* factory = isolate->factory();
2991 HandleScope scope(isolate);
2992 Handle<JSGlobalObject> global(JSGlobalObject::cast(
2993 native_context->global_object()));
2994
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002995 Handle<JSObject> Error = isolate->error_function();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002996 Handle<String> name =
2997 factory->InternalizeOneByteString(STATIC_CHAR_VECTOR("stackTraceLimit"));
2998 Handle<Smi> stack_trace_limit(Smi::FromInt(FLAG_stack_trace_limit), isolate);
2999 JSObject::AddProperty(Error, name, stack_trace_limit, NONE);
3000
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003001 // Expose the debug global object in global if a name for it is specified.
3002 if (FLAG_expose_debug_as != NULL && strlen(FLAG_expose_debug_as) != 0) {
3003 // If loading fails we just bail out without installing the
3004 // debugger but without tanking the whole context.
3005 Debug* debug = isolate->debug();
3006 if (!debug->Load()) return true;
3007 Handle<Context> debug_context = debug->debug_context();
3008 // Set the security token for the debugger context to the same as
3009 // the shell native context to allow calling between these (otherwise
3010 // exposing debug global object doesn't make much sense).
3011 debug_context->set_security_token(native_context->security_token());
3012 Handle<String> debug_string =
3013 factory->InternalizeUtf8String(FLAG_expose_debug_as);
3014 uint32_t index;
3015 if (debug_string->AsArrayIndex(&index)) return true;
3016 Handle<Object> global_proxy(debug_context->global_proxy(), isolate);
3017 JSObject::AddProperty(global, debug_string, global_proxy, DONT_ENUM);
3018 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003019
3020 if (FLAG_expose_wasm) {
3021 WasmJs::Install(isolate, global);
3022 }
3023
Andrei Popescu31002712010-02-23 13:46:05 +00003024 return true;
3025}
3026
3027
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003028static uint32_t Hash(RegisteredExtension* extension) {
3029 return v8::internal::ComputePointerHash(extension);
3030}
3031
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003032
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003033Genesis::ExtensionStates::ExtensionStates() : map_(HashMap::PointersMatch, 8) {}
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003034
3035Genesis::ExtensionTraversalState Genesis::ExtensionStates::get_state(
3036 RegisteredExtension* extension) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003037 i::HashMap::Entry* entry = map_.Lookup(extension, Hash(extension));
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003038 if (entry == NULL) {
3039 return UNVISITED;
3040 }
3041 return static_cast<ExtensionTraversalState>(
3042 reinterpret_cast<intptr_t>(entry->value));
3043}
3044
3045void Genesis::ExtensionStates::set_state(RegisteredExtension* extension,
3046 ExtensionTraversalState state) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003047 map_.LookupOrInsert(extension, Hash(extension))->value =
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003048 reinterpret_cast<void*>(static_cast<intptr_t>(state));
3049}
Steve Blocka7e24c12009-10-30 11:49:00 +00003050
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003051
3052bool Genesis::InstallExtensions(Handle<Context> native_context,
Andrei Popescu31002712010-02-23 13:46:05 +00003053 v8::ExtensionConfiguration* extensions) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003054 Isolate* isolate = native_context->GetIsolate();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003055 ExtensionStates extension_states; // All extensions have state UNVISITED.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003056 return InstallAutoExtensions(isolate, &extension_states) &&
3057 (!FLAG_expose_free_buffer ||
3058 InstallExtension(isolate, "v8/free-buffer", &extension_states)) &&
3059 (!FLAG_expose_gc ||
3060 InstallExtension(isolate, "v8/gc", &extension_states)) &&
3061 (!FLAG_expose_externalize_string ||
3062 InstallExtension(isolate, "v8/externalize", &extension_states)) &&
3063 (!FLAG_track_gc_object_stats ||
3064 InstallExtension(isolate, "v8/statistics", &extension_states)) &&
3065 (!FLAG_expose_trigger_failure ||
3066 InstallExtension(isolate, "v8/trigger-failure", &extension_states)) &&
3067 InstallRequestedExtensions(isolate, extensions, &extension_states);
3068}
Steve Blocka7e24c12009-10-30 11:49:00 +00003069
Steve Blocka7e24c12009-10-30 11:49:00 +00003070
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003071bool Genesis::InstallAutoExtensions(Isolate* isolate,
3072 ExtensionStates* extension_states) {
3073 for (v8::RegisteredExtension* it = v8::RegisteredExtension::first_extension();
3074 it != NULL;
3075 it = it->next()) {
3076 if (it->extension()->auto_enable() &&
3077 !InstallExtension(isolate, it, extension_states)) {
Steve Blocka7e24c12009-10-30 11:49:00 +00003078 return false;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003079 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003080 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003081 return true;
3082}
Steve Blocka7e24c12009-10-30 11:49:00 +00003083
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003084
3085bool Genesis::InstallRequestedExtensions(Isolate* isolate,
3086 v8::ExtensionConfiguration* extensions,
3087 ExtensionStates* extension_states) {
3088 for (const char** it = extensions->begin(); it != extensions->end(); ++it) {
3089 if (!InstallExtension(isolate, *it, extension_states)) return false;
3090 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003091 return true;
3092}
3093
3094
3095// Installs a named extension. This methods is unoptimized and does
3096// not scale well if we want to support a large number of extensions.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003097bool Genesis::InstallExtension(Isolate* isolate,
3098 const char* name,
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003099 ExtensionStates* extension_states) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003100 for (v8::RegisteredExtension* it = v8::RegisteredExtension::first_extension();
3101 it != NULL;
3102 it = it->next()) {
3103 if (strcmp(name, it->extension()->name()) == 0) {
3104 return InstallExtension(isolate, it, extension_states);
3105 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003106 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003107 return Utils::ApiCheck(false,
3108 "v8::Context::New()",
3109 "Cannot find required extension");
Steve Blocka7e24c12009-10-30 11:49:00 +00003110}
3111
3112
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003113bool Genesis::InstallExtension(Isolate* isolate,
3114 v8::RegisteredExtension* current,
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003115 ExtensionStates* extension_states) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003116 HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003117
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003118 if (extension_states->get_state(current) == INSTALLED) return true;
Steve Blocka7e24c12009-10-30 11:49:00 +00003119 // The current node has already been visited so there must be a
3120 // cycle in the dependency graph; fail.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003121 if (!Utils::ApiCheck(extension_states->get_state(current) != VISITED,
3122 "v8::Context::New()",
3123 "Circular extension dependency")) {
Steve Blocka7e24c12009-10-30 11:49:00 +00003124 return false;
3125 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003126 DCHECK(extension_states->get_state(current) == UNVISITED);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003127 extension_states->set_state(current, VISITED);
Steve Blocka7e24c12009-10-30 11:49:00 +00003128 v8::Extension* extension = current->extension();
3129 // Install the extension's dependencies
3130 for (int i = 0; i < extension->dependency_count(); i++) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003131 if (!InstallExtension(isolate,
3132 extension->dependencies()[i],
3133 extension_states)) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003134 return false;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003135 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003136 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003137 // We do not expect this to throw an exception. Change this if it does.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003138 bool result = CompileExtension(isolate, extension);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003139 DCHECK(isolate->has_pending_exception() != result);
Steve Blocka7e24c12009-10-30 11:49:00 +00003140 if (!result) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003141 // We print out the name of the extension that fail to install.
3142 // When an error is thrown during bootstrapping we automatically print
3143 // the line number at which this happened to the console in the isolate
3144 // error throwing functionality.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003145 base::OS::PrintError("Error installing extension '%s'.\n",
3146 current->extension()->name());
Steve Block44f0eee2011-05-26 01:26:41 +01003147 isolate->clear_pending_exception();
Steve Blocka7e24c12009-10-30 11:49:00 +00003148 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003149 extension_states->set_state(current, INSTALLED);
3150 isolate->NotifyExtensionInstalled();
Steve Blocka7e24c12009-10-30 11:49:00 +00003151 return result;
3152}
3153
3154
3155bool Genesis::ConfigureGlobalObjects(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003156 v8::Local<v8::ObjectTemplate> global_proxy_template) {
Steve Blocka7e24c12009-10-30 11:49:00 +00003157 Handle<JSObject> global_proxy(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003158 JSObject::cast(native_context()->global_proxy()));
3159 Handle<JSObject> global_object(
3160 JSObject::cast(native_context()->global_object()));
Steve Blocka7e24c12009-10-30 11:49:00 +00003161
3162 if (!global_proxy_template.IsEmpty()) {
3163 // Configure the global proxy object.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003164 Handle<ObjectTemplateInfo> global_proxy_data =
Steve Blocka7e24c12009-10-30 11:49:00 +00003165 v8::Utils::OpenHandle(*global_proxy_template);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003166 if (!ConfigureApiObject(global_proxy, global_proxy_data)) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00003167
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003168 // Configure the global object.
Steve Blocka7e24c12009-10-30 11:49:00 +00003169 Handle<FunctionTemplateInfo> proxy_constructor(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003170 FunctionTemplateInfo::cast(global_proxy_data->constructor()));
Steve Blocka7e24c12009-10-30 11:49:00 +00003171 if (!proxy_constructor->prototype_template()->IsUndefined()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003172 Handle<ObjectTemplateInfo> global_object_data(
Steve Blocka7e24c12009-10-30 11:49:00 +00003173 ObjectTemplateInfo::cast(proxy_constructor->prototype_template()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003174 if (!ConfigureApiObject(global_object, global_object_data)) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00003175 }
3176 }
3177
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003178 SetObjectPrototype(global_proxy, global_object);
3179
3180 native_context()->set_initial_array_prototype(
3181 JSArray::cast(native_context()->array_function()->prototype()));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003182 native_context()->set_array_buffer_map(
3183 native_context()->array_buffer_fun()->initial_map());
3184 native_context()->set_js_map_map(
3185 native_context()->js_map_fun()->initial_map());
3186 native_context()->set_js_set_map(
3187 native_context()->js_set_fun()->initial_map());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003188
Steve Blocka7e24c12009-10-30 11:49:00 +00003189 return true;
3190}
3191
3192
3193bool Genesis::ConfigureApiObject(Handle<JSObject> object,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003194 Handle<ObjectTemplateInfo> object_template) {
3195 DCHECK(!object_template.is_null());
3196 DCHECK(FunctionTemplateInfo::cast(object_template->constructor())
3197 ->IsTemplateFor(object->map()));;
Steve Blocka7e24c12009-10-30 11:49:00 +00003198
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003199 MaybeHandle<JSObject> maybe_obj =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003200 ApiNatives::InstantiateObject(object_template);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003201 Handle<JSObject> obj;
3202 if (!maybe_obj.ToHandle(&obj)) {
3203 DCHECK(isolate()->has_pending_exception());
Ben Murdoch257744e2011-11-30 15:57:28 +00003204 isolate()->clear_pending_exception();
Steve Blocka7e24c12009-10-30 11:49:00 +00003205 return false;
3206 }
3207 TransferObject(obj, object);
3208 return true;
3209}
3210
3211
3212void Genesis::TransferNamedProperties(Handle<JSObject> from,
3213 Handle<JSObject> to) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003214 // If JSObject::AddProperty asserts due to already existing property,
3215 // it is likely due to both global objects sharing property name(s).
3216 // Merging those two global objects is impossible.
3217 // The global template must not create properties that already exist
3218 // in the snapshotted global object.
Steve Blocka7e24c12009-10-30 11:49:00 +00003219 if (from->HasFastProperties()) {
3220 Handle<DescriptorArray> descs =
3221 Handle<DescriptorArray>(from->map()->instance_descriptors());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003222 for (int i = 0; i < from->map()->NumberOfOwnDescriptors(); i++) {
3223 PropertyDetails details = descs->GetDetails(i);
Steve Blocka7e24c12009-10-30 11:49:00 +00003224 switch (details.type()) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003225 case DATA: {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003226 HandleScope inner(isolate());
3227 Handle<Name> key = Handle<Name>(descs->GetKey(i));
3228 FieldIndex index = FieldIndex::ForDescriptor(from->map(), i);
3229 DCHECK(!descs->GetDetails(i).representation().IsDouble());
3230 Handle<Object> value = Handle<Object>(from->RawFastPropertyAt(index),
3231 isolate());
3232 JSObject::AddProperty(to, key, value, details.attributes());
Steve Blocka7e24c12009-10-30 11:49:00 +00003233 break;
3234 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003235 case DATA_CONSTANT: {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003236 HandleScope inner(isolate());
3237 Handle<Name> key = Handle<Name>(descs->GetKey(i));
3238 Handle<Object> constant(descs->GetConstant(i), isolate());
3239 JSObject::AddProperty(to, key, constant, details.attributes());
Steve Blocka7e24c12009-10-30 11:49:00 +00003240 break;
3241 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003242 case ACCESSOR:
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003243 UNREACHABLE();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003244 case ACCESSOR_CONSTANT: {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003245 Handle<Name> key(descs->GetKey(i));
3246 LookupIterator it(to, key, LookupIterator::OWN_SKIP_INTERCEPTOR);
3247 CHECK_NE(LookupIterator::ACCESS_CHECK, it.state());
Steve Blocka7e24c12009-10-30 11:49:00 +00003248 // If the property is already there we skip it
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003249 if (it.IsFound()) continue;
3250 HandleScope inner(isolate());
3251 DCHECK(!to->HasFastProperties());
Andrei Popescu31002712010-02-23 13:46:05 +00003252 // Add to dictionary.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003253 Handle<Object> callbacks(descs->GetCallbacksObject(i), isolate());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003254 PropertyDetails d(details.attributes(), ACCESSOR_CONSTANT, i + 1,
3255 PropertyCellType::kMutable);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003256 JSObject::SetNormalizedProperty(to, key, callbacks, d);
Steve Blocka7e24c12009-10-30 11:49:00 +00003257 break;
3258 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003259 }
3260 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003261 } else if (from->IsJSGlobalObject()) {
3262 Handle<GlobalDictionary> properties =
3263 Handle<GlobalDictionary>(from->global_dictionary());
3264 int capacity = properties->Capacity();
3265 for (int i = 0; i < capacity; i++) {
3266 Object* raw_key(properties->KeyAt(i));
3267 if (properties->IsKey(raw_key)) {
3268 DCHECK(raw_key->IsName());
3269 // If the property is already there we skip it.
3270 Handle<Name> key(Name::cast(raw_key));
3271 LookupIterator it(to, key, LookupIterator::OWN_SKIP_INTERCEPTOR);
3272 CHECK_NE(LookupIterator::ACCESS_CHECK, it.state());
3273 if (it.IsFound()) continue;
3274 // Set the property.
3275 DCHECK(properties->ValueAt(i)->IsPropertyCell());
3276 Handle<PropertyCell> cell(PropertyCell::cast(properties->ValueAt(i)));
3277 Handle<Object> value(cell->value(), isolate());
3278 if (value->IsTheHole()) continue;
3279 PropertyDetails details = cell->property_details();
3280 DCHECK_EQ(kData, details.kind());
3281 JSObject::AddProperty(to, key, value, details.attributes());
3282 }
3283 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003284 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003285 Handle<NameDictionary> properties =
3286 Handle<NameDictionary>(from->property_dictionary());
Steve Blocka7e24c12009-10-30 11:49:00 +00003287 int capacity = properties->Capacity();
3288 for (int i = 0; i < capacity; i++) {
3289 Object* raw_key(properties->KeyAt(i));
3290 if (properties->IsKey(raw_key)) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003291 DCHECK(raw_key->IsName());
Steve Blocka7e24c12009-10-30 11:49:00 +00003292 // If the property is already there we skip it.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003293 Handle<Name> key(Name::cast(raw_key));
3294 LookupIterator it(to, key, LookupIterator::OWN_SKIP_INTERCEPTOR);
3295 CHECK_NE(LookupIterator::ACCESS_CHECK, it.state());
3296 if (it.IsFound()) continue;
Steve Blocka7e24c12009-10-30 11:49:00 +00003297 // Set the property.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003298 Handle<Object> value = Handle<Object>(properties->ValueAt(i),
3299 isolate());
3300 DCHECK(!value->IsCell());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003301 DCHECK(!value->IsTheHole());
Steve Blocka7e24c12009-10-30 11:49:00 +00003302 PropertyDetails details = properties->DetailsAt(i);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003303 DCHECK_EQ(kData, details.kind());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003304 JSObject::AddProperty(to, key, value, details.attributes());
Steve Blocka7e24c12009-10-30 11:49:00 +00003305 }
3306 }
3307 }
3308}
3309
3310
3311void Genesis::TransferIndexedProperties(Handle<JSObject> from,
3312 Handle<JSObject> to) {
3313 // Cloning the elements array is sufficient.
3314 Handle<FixedArray> from_elements =
3315 Handle<FixedArray>(FixedArray::cast(from->elements()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003316 Handle<FixedArray> to_elements = factory()->CopyFixedArray(from_elements);
Steve Blocka7e24c12009-10-30 11:49:00 +00003317 to->set_elements(*to_elements);
3318}
3319
3320
3321void Genesis::TransferObject(Handle<JSObject> from, Handle<JSObject> to) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003322 HandleScope outer(isolate());
Steve Blocka7e24c12009-10-30 11:49:00 +00003323
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003324 DCHECK(!from->IsJSArray());
3325 DCHECK(!to->IsJSArray());
Steve Blocka7e24c12009-10-30 11:49:00 +00003326
3327 TransferNamedProperties(from, to);
3328 TransferIndexedProperties(from, to);
3329
3330 // Transfer the prototype (new map is needed).
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003331 Handle<Object> proto(from->map()->prototype(), isolate());
3332 SetObjectPrototype(to, proto);
Steve Blocka7e24c12009-10-30 11:49:00 +00003333}
3334
3335
3336void Genesis::MakeFunctionInstancePrototypeWritable() {
Steve Block44f0eee2011-05-26 01:26:41 +01003337 // The maps with writable prototype are created in CreateEmptyFunction
3338 // and CreateStrictModeFunctionMaps respectively. Initially the maps are
3339 // created with read-only prototype for JS builtins processing.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003340 DCHECK(!sloppy_function_map_writable_prototype_.is_null());
3341 DCHECK(!strict_function_map_writable_prototype_.is_null());
Steve Blocka7e24c12009-10-30 11:49:00 +00003342
Steve Block44f0eee2011-05-26 01:26:41 +01003343 // Replace function instance maps to make prototype writable.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003344 native_context()->set_sloppy_function_map(
3345 *sloppy_function_map_writable_prototype_);
3346 native_context()->set_strict_function_map(
3347 *strict_function_map_writable_prototype_);
Steve Blocka7e24c12009-10-30 11:49:00 +00003348}
3349
3350
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003351class NoTrackDoubleFieldsForSerializerScope {
3352 public:
3353 explicit NoTrackDoubleFieldsForSerializerScope(Isolate* isolate)
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003354 : flag_(FLAG_track_double_fields), enabled_(false) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003355 if (isolate->serializer_enabled()) {
3356 // Disable tracking double fields because heap numbers treated as
3357 // immutable by the serializer.
3358 FLAG_track_double_fields = false;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003359 enabled_ = true;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003360 }
3361 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003362
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003363 ~NoTrackDoubleFieldsForSerializerScope() {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003364 if (enabled_) {
3365 FLAG_track_double_fields = flag_;
3366 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003367 }
3368
3369 private:
3370 bool flag_;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003371 bool enabled_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003372};
3373
3374
3375Genesis::Genesis(Isolate* isolate,
3376 MaybeHandle<JSGlobalProxy> maybe_global_proxy,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003377 v8::Local<v8::ObjectTemplate> global_proxy_template,
3378 v8::ExtensionConfiguration* extensions,
3379 ContextType context_type)
3380 : isolate_(isolate), active_(isolate->bootstrapper()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003381 NoTrackDoubleFieldsForSerializerScope disable_scope(isolate);
3382 result_ = Handle<Context>::null();
Steve Blocka7e24c12009-10-30 11:49:00 +00003383 // Before creating the roots we must save the context and restore it
3384 // on all function exits.
Steve Block44f0eee2011-05-26 01:26:41 +01003385 SaveContext saved_context(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003386
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003387 // During genesis, the boilerplate for stack overflow won't work until the
3388 // environment has been at least partially initialized. Add a stack check
3389 // before entering JS code to catch overflow early.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003390 StackLimitCheck check(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003391 if (check.HasOverflowed()) {
3392 isolate->StackOverflow();
3393 return;
3394 }
3395
3396 // The deserializer needs to hook up references to the global proxy.
3397 // Create an uninitialized global proxy now if we don't have one
3398 // and initialize it later in CreateNewGlobals.
3399 Handle<JSGlobalProxy> global_proxy;
3400 if (!maybe_global_proxy.ToHandle(&global_proxy)) {
3401 global_proxy = isolate->factory()->NewUninitializedJSGlobalProxy();
3402 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003403
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003404 // We can only de-serialize a context if the isolate was initialized from
3405 // a snapshot. Otherwise we have to build the context from scratch.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003406 // Also create a context from scratch to expose natives, if required by flag.
3407 if (!isolate->initialized_from_snapshot() ||
3408 !Snapshot::NewContextFromSnapshot(isolate, global_proxy)
3409 .ToHandle(&native_context_)) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003410 native_context_ = Handle<Context>();
3411 }
3412
3413 if (!native_context().is_null()) {
3414 AddToWeakNativeContextList(*native_context());
3415 isolate->set_context(*native_context());
Steve Block44f0eee2011-05-26 01:26:41 +01003416 isolate->counters()->contexts_created_by_snapshot()->Increment();
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003417#if TRACE_MAPS
3418 if (FLAG_trace_maps) {
3419 Handle<JSFunction> object_fun = isolate->object_function();
3420 PrintF("[TraceMap: InitialMap map= %p SFI= %d_Object ]\n",
3421 reinterpret_cast<void*>(object_fun->initial_map()),
3422 object_fun->shared()->unique_id());
3423 Map::TraceAllTransitions(object_fun->initial_map());
3424 }
3425#endif
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003426 Handle<JSGlobalObject> global_object =
3427 CreateNewGlobals(global_proxy_template, global_proxy);
Andrei Popescu402d9372010-02-26 13:31:12 +00003428
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003429 HookUpGlobalProxy(global_object, global_proxy);
3430 HookUpGlobalObject(global_object);
Andrei Popescu402d9372010-02-26 13:31:12 +00003431
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003432 if (!ConfigureGlobalObjects(global_proxy_template)) return;
Andrei Popescu31002712010-02-23 13:46:05 +00003433 } else {
3434 // We get here if there was no context snapshot.
3435 CreateRoots();
Ben Murdoch257744e2011-11-30 15:57:28 +00003436 Handle<JSFunction> empty_function = CreateEmptyFunction(isolate);
Steve Block44f0eee2011-05-26 01:26:41 +01003437 CreateStrictModeFunctionMaps(empty_function);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003438 CreateStrongModeFunctionMaps(empty_function);
3439 CreateIteratorMaps();
3440 Handle<JSGlobalObject> global_object =
3441 CreateNewGlobals(global_proxy_template, global_proxy);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003442 HookUpGlobalProxy(global_object, global_proxy);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003443 InitializeGlobal(global_object, empty_function, context_type);
Kristian Monsen80d68ea2010-09-08 11:05:35 +01003444 InitializeNormalizedMapCaches();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003445
3446 if (!InstallNatives(context_type)) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00003447
Andrei Popescu31002712010-02-23 13:46:05 +00003448 MakeFunctionInstancePrototypeWritable();
Steve Blocka7e24c12009-10-30 11:49:00 +00003449
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003450 if (context_type != THIN_CONTEXT) {
3451 if (!InstallExtraNatives()) return;
3452 if (!ConfigureGlobalObjects(global_proxy_template)) return;
3453 }
Steve Block44f0eee2011-05-26 01:26:41 +01003454 isolate->counters()->contexts_created_from_scratch()->Increment();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003455 // Re-initialize the counter because it got incremented during snapshot
3456 // creation.
3457 isolate->native_context()->set_errors_thrown(Smi::FromInt(0));
Andrei Popescu31002712010-02-23 13:46:05 +00003458 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003459
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003460 // Install experimental natives. Do not include them into the
3461 // snapshot as we should be able to turn them off at runtime. Re-installing
3462 // them after they have already been deserialized would also fail.
3463 if (context_type == FULL_CONTEXT) {
3464 if (!isolate->serializer_enabled()) {
3465 InitializeExperimentalGlobal();
3466 if (!InstallExperimentalNatives()) return;
Ben Murdoch257744e2011-11-30 15:57:28 +00003467
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003468 if (FLAG_experimental_extras) {
3469 if (!InstallExperimentalExtraNatives()) return;
3470 }
3471 }
3472 // The serializer cannot serialize typed arrays. Reset those typed arrays
3473 // for each new context.
3474 } else if (context_type == DEBUG_CONTEXT) {
3475 DCHECK(!isolate->serializer_enabled());
3476 InitializeExperimentalGlobal();
3477 if (!InstallDebuggerNatives()) return;
3478 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003479
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003480 ConfigureUtilsObject(context_type);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003481
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003482 // Check that the script context table is empty except for the 'this' binding.
3483 // We do not need script contexts for native scripts.
3484 if (!FLAG_global_var_shortcuts) {
3485 DCHECK_EQ(1, native_context()->script_context_table()->used());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003486 }
3487
3488 result_ = native_context();
Steve Blocka7e24c12009-10-30 11:49:00 +00003489}
3490
3491
3492// Support for thread preemption.
3493
3494// Reserve space for statics needing saving and restoring.
3495int Bootstrapper::ArchiveSpacePerThread() {
Steve Block44f0eee2011-05-26 01:26:41 +01003496 return sizeof(NestingCounterType);
Steve Blocka7e24c12009-10-30 11:49:00 +00003497}
3498
3499
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003500// Archive statics that are thread-local.
Steve Blocka7e24c12009-10-30 11:49:00 +00003501char* Bootstrapper::ArchiveState(char* to) {
Steve Block44f0eee2011-05-26 01:26:41 +01003502 *reinterpret_cast<NestingCounterType*>(to) = nesting_;
3503 nesting_ = 0;
3504 return to + sizeof(NestingCounterType);
Steve Blocka7e24c12009-10-30 11:49:00 +00003505}
3506
3507
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003508// Restore statics that are thread-local.
Steve Blocka7e24c12009-10-30 11:49:00 +00003509char* Bootstrapper::RestoreState(char* from) {
Steve Block44f0eee2011-05-26 01:26:41 +01003510 nesting_ = *reinterpret_cast<NestingCounterType*>(from);
3511 return from + sizeof(NestingCounterType);
Steve Blocka7e24c12009-10-30 11:49:00 +00003512}
3513
3514
3515// Called when the top-level V8 mutex is destroyed.
3516void Bootstrapper::FreeThreadResources() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003517 DCHECK(!IsActive());
Steve Blocka7e24c12009-10-30 11:49:00 +00003518}
3519
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003520} // namespace internal
3521} // namespace v8