blob: 252c51cae4deb756dba58b500ae658fc5b872702 [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,
Ben Murdoch097c5b22016-05-18 11:27:45 +0100137 v8::ExtensionConfiguration* extensions,
138 GlobalContextType context_type);
Andrei Popescu31002712010-02-23 13:46:05 +0000139 ~Genesis() { }
Steve Blocka7e24c12009-10-30 11:49:00 +0000140
Ben Murdoch257744e2011-11-30 15:57:28 +0000141 Isolate* isolate() const { return isolate_; }
142 Factory* factory() const { return isolate_->factory(); }
143 Heap* heap() const { return isolate_->heap(); }
144
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000145 Handle<Context> result() { return result_; }
146
Steve Blocka7e24c12009-10-30 11:49:00 +0000147 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000148 Handle<Context> native_context() { return native_context_; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000149
Andrei Popescu31002712010-02-23 13:46:05 +0000150 // Creates some basic objects. Used for creating a context from scratch.
151 void CreateRoots();
152 // Creates the empty function. Used for creating a context from scratch.
Ben Murdoch257744e2011-11-30 15:57:28 +0000153 Handle<JSFunction> CreateEmptyFunction(Isolate* isolate);
Steve Block44f0eee2011-05-26 01:26:41 +0100154 // Creates the ThrowTypeError function. ECMA 5th Ed. 13.2.3
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000155 Handle<JSFunction> GetRestrictedFunctionPropertiesThrower();
156 Handle<JSFunction> GetStrictArgumentsPoisonFunction();
157 Handle<JSFunction> GetThrowTypeErrorIntrinsic(Builtins::Name builtin_name);
Steve Block44f0eee2011-05-26 01:26:41 +0100158
159 void CreateStrictModeFunctionMaps(Handle<JSFunction> empty);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000160 void CreateStrongModeFunctionMaps(Handle<JSFunction> empty);
161 void CreateIteratorMaps();
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100162
163 // Make the "arguments" and "caller" properties throw a TypeError on access.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000164 void AddRestrictedFunctionProperties(Handle<Map> map);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100165
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000166 // Creates the global objects using the global proxy and the template passed
167 // in through the API. We call this regardless of whether we are building a
Andrei Popescu31002712010-02-23 13:46:05 +0000168 // context from scratch or using a deserialized one from the partial snapshot
169 // but in the latter case we don't use the objects it produces directly, as
170 // we have to used the deserialized ones that are linked together with the
171 // rest of the context snapshot.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000172 Handle<JSGlobalObject> CreateNewGlobals(
173 v8::Local<v8::ObjectTemplate> global_proxy_template,
174 Handle<JSGlobalProxy> global_proxy);
Andrei Popescu31002712010-02-23 13:46:05 +0000175 // Hooks the given global proxy into the context. If the context was created
176 // by deserialization then this will unhook the global proxy that was
177 // deserialized, leaving the GC to pick it up.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000178 void HookUpGlobalProxy(Handle<JSGlobalObject> global_object,
Andrei Popescu31002712010-02-23 13:46:05 +0000179 Handle<JSGlobalProxy> global_proxy);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000180 // Similarly, we want to use the global that has been created by the templates
181 // passed through the API. The global from the snapshot is detached from the
182 // other objects in the snapshot.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000183 void HookUpGlobalObject(Handle<JSGlobalObject> global_object);
184 // The native context has a ScriptContextTable that store declarative bindings
185 // made in script scopes. Add a "this" binding to that table pointing to the
186 // global proxy.
187 void InstallGlobalThisBinding();
Andrei Popescu31002712010-02-23 13:46:05 +0000188 // New context initialization. Used for creating a context from scratch.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000189 void InitializeGlobal(Handle<JSGlobalObject> global_object,
190 Handle<JSFunction> empty_function,
Ben Murdoch097c5b22016-05-18 11:27:45 +0100191 GlobalContextType context_type);
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000192 void InitializeExperimentalGlobal();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000193 // Depending on the situation, expose and/or get rid of the utils object.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100194 void ConfigureUtilsObject(GlobalContextType context_type);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400195
196#define DECLARE_FEATURE_INITIALIZATION(id, descr) \
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400197 void InitializeGlobal_##id();
198
199 HARMONY_INPROGRESS(DECLARE_FEATURE_INITIALIZATION)
200 HARMONY_STAGED(DECLARE_FEATURE_INITIALIZATION)
201 HARMONY_SHIPPING(DECLARE_FEATURE_INITIALIZATION)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000202 DECLARE_FEATURE_INITIALIZATION(promise_extra, "")
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400203#undef DECLARE_FEATURE_INITIALIZATION
204
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000205 Handle<JSFunction> InstallArrayBuffer(Handle<JSObject> target,
206 const char* name);
207 Handle<JSFunction> InstallInternalArray(Handle<JSObject> target,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000208 const char* name,
209 ElementsKind elements_kind);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100210 bool InstallNatives(GlobalContextType context_type);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000211
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000212 void InstallTypedArray(const char* name, ElementsKind elements_kind,
213 Handle<JSFunction>* fun);
Ben Murdoch257744e2011-11-30 15:57:28 +0000214 bool InstallExperimentalNatives();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000215 bool InstallExtraNatives();
216 bool InstallExperimentalExtraNatives();
217 bool InstallDebuggerNatives();
Ben Murdochb0fe1622011-05-05 13:52:32 +0100218 void InstallBuiltinFunctionIds();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000219 void InstallExperimentalBuiltinFunctionIds();
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100220 void InitializeNormalizedMapCaches();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000221 void InstallJSProxyMaps();
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100222
223 enum ExtensionTraversalState {
224 UNVISITED, VISITED, INSTALLED
225 };
226
227 class ExtensionStates {
228 public:
229 ExtensionStates();
230 ExtensionTraversalState get_state(RegisteredExtension* extension);
231 void set_state(RegisteredExtension* extension,
232 ExtensionTraversalState state);
233 private:
234 HashMap map_;
235 DISALLOW_COPY_AND_ASSIGN(ExtensionStates);
236 };
237
Andrei Popescu31002712010-02-23 13:46:05 +0000238 // Used both for deserialized and from-scratch contexts to add the extensions
239 // provided.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000240 static bool InstallExtensions(Handle<Context> native_context,
Andrei Popescu31002712010-02-23 13:46:05 +0000241 v8::ExtensionConfiguration* extensions);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000242 static bool InstallAutoExtensions(Isolate* isolate,
243 ExtensionStates* extension_states);
244 static bool InstallRequestedExtensions(Isolate* isolate,
245 v8::ExtensionConfiguration* extensions,
246 ExtensionStates* extension_states);
247 static bool InstallExtension(Isolate* isolate,
248 const char* name,
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100249 ExtensionStates* extension_states);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000250 static bool InstallExtension(Isolate* isolate,
251 v8::RegisteredExtension* current,
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100252 ExtensionStates* extension_states);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000253 static bool InstallSpecialObjects(Handle<Context> native_context);
Steve Blocka7e24c12009-10-30 11:49:00 +0000254 bool ConfigureApiObject(Handle<JSObject> object,
255 Handle<ObjectTemplateInfo> object_template);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000256 bool ConfigureGlobalObjects(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000257 v8::Local<v8::ObjectTemplate> global_proxy_template);
Steve Blocka7e24c12009-10-30 11:49:00 +0000258
259 // Migrates all properties from the 'from' object to the 'to'
260 // object and overrides the prototype in 'to' with the one from
261 // 'from'.
262 void TransferObject(Handle<JSObject> from, Handle<JSObject> to);
263 void TransferNamedProperties(Handle<JSObject> from, Handle<JSObject> to);
264 void TransferIndexedProperties(Handle<JSObject> from, Handle<JSObject> to);
265
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000266 enum FunctionMode {
267 // With prototype.
268 FUNCTION_WITH_WRITEABLE_PROTOTYPE,
269 FUNCTION_WITH_READONLY_PROTOTYPE,
270 // Without prototype.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000271 FUNCTION_WITHOUT_PROTOTYPE
Steve Block6ded16b2010-05-10 14:33:55 +0100272 };
Steve Block44f0eee2011-05-26 01:26:41 +0100273
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000274 static bool IsFunctionModeWithPrototype(FunctionMode function_mode) {
275 return (function_mode == FUNCTION_WITH_WRITEABLE_PROTOTYPE ||
276 function_mode == FUNCTION_WITH_READONLY_PROTOTYPE);
277 }
Steve Block44f0eee2011-05-26 01:26:41 +0100278
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000279 Handle<Map> CreateSloppyFunctionMap(FunctionMode function_mode);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000280
281 void SetFunctionInstanceDescriptor(Handle<Map> map,
282 FunctionMode function_mode);
Steve Blocka7e24c12009-10-30 11:49:00 +0000283 void MakeFunctionInstancePrototypeWritable();
284
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000285 Handle<Map> CreateStrictFunctionMap(FunctionMode function_mode,
286 Handle<JSFunction> empty_function);
287 Handle<Map> CreateStrongFunctionMap(Handle<JSFunction> empty_function,
288 bool is_constructor);
289
Steve Block44f0eee2011-05-26 01:26:41 +0100290
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000291 void SetStrictFunctionInstanceDescriptor(Handle<Map> map,
292 FunctionMode function_mode);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000293 void SetStrongFunctionInstanceDescriptor(Handle<Map> map);
Steve Block44f0eee2011-05-26 01:26:41 +0100294
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000295 static bool CallUtilsFunction(Isolate* isolate, const char* name);
296
297 static bool CompileExtension(Isolate* isolate, v8::Extension* extension);
Steve Blocka7e24c12009-10-30 11:49:00 +0000298
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000299 Isolate* isolate_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000300 Handle<Context> result_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000301 Handle<Context> native_context_;
Steve Block44f0eee2011-05-26 01:26:41 +0100302
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000303 // Function maps. Function maps are created initially with a read only
304 // prototype for the processing of JS builtins. Later the function maps are
305 // replaced in order to make prototype writable. These are the final, writable
306 // prototype, maps.
307 Handle<Map> sloppy_function_map_writable_prototype_;
308 Handle<Map> strict_function_map_writable_prototype_;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000309 Handle<JSFunction> strict_poison_function_;
310 Handle<JSFunction> restricted_function_properties_thrower_;
Steve Block44f0eee2011-05-26 01:26:41 +0100311
Andrei Popescu31002712010-02-23 13:46:05 +0000312 BootstrapperActive active_;
313 friend class Bootstrapper;
Steve Blocka7e24c12009-10-30 11:49:00 +0000314};
315
Steve Blocka7e24c12009-10-30 11:49:00 +0000316
317void Bootstrapper::Iterate(ObjectVisitor* v) {
Steve Block44f0eee2011-05-26 01:26:41 +0100318 extensions_cache_.Iterate(v);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100319 v->Synchronize(VisitorSynchronization::kExtensions);
Steve Blocka7e24c12009-10-30 11:49:00 +0000320}
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,
Ben Murdoch097c5b22016-05-18 11:27:45 +0100325 v8::ExtensionConfiguration* extensions, GlobalContextType 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 Murdoch097c5b22016-05-18 11:27:45 +0100486 map->set_is_constructor(IsFunctionModeWithPrototype(function_mode));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000487 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 Murdoch097c5b22016-05-18 11:27:45 +0100718 map->set_is_constructor(IsFunctionModeWithPrototype(function_mode));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000719 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);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100729 map->set_is_constructor(is_constructor);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000730 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");
Ben Murdoch097c5b22016-05-18 11:27:45 +0100792 sloppy_generator_function_map->set_is_constructor(false);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000793 Map::SetPrototype(sloppy_generator_function_map,
794 generator_function_prototype);
795 native_context()->set_sloppy_generator_function_map(
796 *sloppy_generator_function_map);
797
798 Handle<Map> strict_generator_function_map =
799 Map::Copy(strict_function_map, "StrictGeneratorFunction");
Ben Murdoch097c5b22016-05-18 11:27:45 +0100800 strict_generator_function_map->set_is_constructor(false);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000801 Map::SetPrototype(strict_generator_function_map,
802 generator_function_prototype);
803 native_context()->set_strict_generator_function_map(
804 *strict_generator_function_map);
805
806 Handle<Map> strong_function_map(native_context()->strong_function_map());
807 Handle<Map> strong_generator_function_map =
808 Map::Copy(strong_function_map, "StrongGeneratorFunction");
Ben Murdoch097c5b22016-05-18 11:27:45 +0100809 strong_generator_function_map->set_is_constructor(false);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000810 Map::SetPrototype(strong_generator_function_map,
811 generator_function_prototype);
812 native_context()->set_strong_generator_function_map(
813 *strong_generator_function_map);
814
815 Handle<JSFunction> object_function(native_context()->object_function());
816 Handle<Map> generator_object_prototype_map = Map::Create(isolate(), 0);
817 Map::SetPrototype(generator_object_prototype_map, generator_object_prototype);
818 native_context()->set_generator_object_prototype_map(
819 *generator_object_prototype_map);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100820}
821
822
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000823static void ReplaceAccessors(Handle<Map> map,
824 Handle<String> name,
825 PropertyAttributes attributes,
826 Handle<AccessorPair> accessor_pair) {
827 DescriptorArray* descriptors = map->instance_descriptors();
Ben Murdoch097c5b22016-05-18 11:27:45 +0100828 int idx = descriptors->SearchWithCache(map->GetIsolate(), *name, *map);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000829 AccessorConstantDescriptor descriptor(name, accessor_pair, attributes);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000830 descriptors->Replace(idx, &descriptor);
Steve Block44f0eee2011-05-26 01:26:41 +0100831}
832
833
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000834void Genesis::AddRestrictedFunctionProperties(Handle<Map> map) {
835 PropertyAttributes rw_attribs = static_cast<PropertyAttributes>(DONT_ENUM);
836 Handle<JSFunction> thrower = GetRestrictedFunctionPropertiesThrower();
837 Handle<AccessorPair> accessors = factory()->NewAccessorPair();
838 accessors->set_getter(*thrower);
839 accessors->set_setter(*thrower);
840
841 ReplaceAccessors(map, factory()->arguments_string(), rw_attribs, accessors);
842 ReplaceAccessors(map, factory()->caller_string(), rw_attribs, accessors);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000843}
844
845
846static void AddToWeakNativeContextList(Context* context) {
847 DCHECK(context->IsNativeContext());
Ben Murdoch257744e2011-11-30 15:57:28 +0000848 Heap* heap = context->GetIsolate()->heap();
Ben Murdochb0fe1622011-05-05 13:52:32 +0100849#ifdef DEBUG
850 { // NOLINT
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000851 DCHECK(context->get(Context::NEXT_CONTEXT_LINK)->IsUndefined());
Ben Murdochb0fe1622011-05-05 13:52:32 +0100852 // Check that context is not in the list yet.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000853 for (Object* current = heap->native_contexts_list();
Ben Murdochb0fe1622011-05-05 13:52:32 +0100854 !current->IsUndefined();
855 current = Context::cast(current)->get(Context::NEXT_CONTEXT_LINK)) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000856 DCHECK(current != context);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100857 }
858 }
859#endif
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000860 context->set(Context::NEXT_CONTEXT_LINK, heap->native_contexts_list(),
861 UPDATE_WEAK_WRITE_BARRIER);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000862 heap->set_native_contexts_list(context);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100863}
864
865
Andrei Popescu31002712010-02-23 13:46:05 +0000866void Genesis::CreateRoots() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000867 // Allocate the native context FixedArray first and then patch the
Andrei Popescu31002712010-02-23 13:46:05 +0000868 // closure and extension object later (we need the empty function
869 // and the global object, but in order to create those, we need the
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000870 // native context).
871 native_context_ = factory()->NewNativeContext();
872 AddToWeakNativeContextList(*native_context());
873 isolate()->set_context(*native_context());
Andrei Popescu31002712010-02-23 13:46:05 +0000874
875 // Allocate the message listeners object.
876 {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000877 v8::NeanderArray listeners(isolate());
878 native_context()->set_message_listeners(*listeners.value());
Andrei Popescu31002712010-02-23 13:46:05 +0000879 }
880}
881
882
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000883void Genesis::InstallGlobalThisBinding() {
884 Handle<ScriptContextTable> script_contexts(
885 native_context()->script_context_table());
886 Handle<ScopeInfo> scope_info = ScopeInfo::CreateGlobalThisBinding(isolate());
887 Handle<JSFunction> closure(native_context()->closure());
888 Handle<Context> context = factory()->NewScriptContext(closure, scope_info);
889
890 // Go ahead and hook it up while we're at it.
891 int slot = scope_info->ReceiverContextSlotIndex();
892 DCHECK_EQ(slot, Context::MIN_CONTEXT_SLOTS);
893 context->set(slot, native_context()->global_proxy());
894
895 Handle<ScriptContextTable> new_script_contexts =
896 ScriptContextTable::Extend(script_contexts, context);
897 native_context()->set_script_context_table(*new_script_contexts);
898}
899
900
901Handle<JSGlobalObject> Genesis::CreateNewGlobals(
902 v8::Local<v8::ObjectTemplate> global_proxy_template,
903 Handle<JSGlobalProxy> global_proxy) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000904 // The argument global_proxy_template aka data is an ObjectTemplateInfo.
Andrei Popescu31002712010-02-23 13:46:05 +0000905 // It has a constructor pointer that points at global_constructor which is a
906 // FunctionTemplateInfo.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000907 // The global_proxy_constructor is used to (re)initialize the
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000908 // global_proxy. The global_proxy_constructor also has a prototype_template
909 // pointer that points at js_global_object_template which is an
910 // ObjectTemplateInfo.
Andrei Popescu31002712010-02-23 13:46:05 +0000911 // That in turn has a constructor pointer that points at
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000912 // js_global_object_constructor which is a FunctionTemplateInfo.
913 // js_global_object_constructor is used to make js_global_object_function
914 // js_global_object_function is used to make the new global_object.
Andrei Popescu31002712010-02-23 13:46:05 +0000915 //
916 // --- G l o b a l ---
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000917 // Step 1: Create a fresh JSGlobalObject.
918 Handle<JSFunction> js_global_object_function;
919 Handle<ObjectTemplateInfo> js_global_object_template;
920 if (!global_proxy_template.IsEmpty()) {
921 // Get prototype template of the global_proxy_template.
Andrei Popescu31002712010-02-23 13:46:05 +0000922 Handle<ObjectTemplateInfo> data =
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000923 v8::Utils::OpenHandle(*global_proxy_template);
Andrei Popescu31002712010-02-23 13:46:05 +0000924 Handle<FunctionTemplateInfo> global_constructor =
925 Handle<FunctionTemplateInfo>(
926 FunctionTemplateInfo::cast(data->constructor()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000927 Handle<Object> proto_template(global_constructor->prototype_template(),
928 isolate());
Andrei Popescu31002712010-02-23 13:46:05 +0000929 if (!proto_template->IsUndefined()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000930 js_global_object_template =
Andrei Popescu31002712010-02-23 13:46:05 +0000931 Handle<ObjectTemplateInfo>::cast(proto_template);
932 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000933 }
934
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000935 if (js_global_object_template.is_null()) {
936 Handle<String> name = Handle<String>(heap()->empty_string());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000937 Handle<Code> code = isolate()->builtins()->Illegal();
Andrei Popescu31002712010-02-23 13:46:05 +0000938 Handle<JSObject> prototype =
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000939 factory()->NewFunctionPrototype(isolate()->object_function());
940 js_global_object_function = factory()->NewFunction(
941 name, code, prototype, JS_GLOBAL_OBJECT_TYPE, JSGlobalObject::kSize);
942#ifdef DEBUG
943 LookupIterator it(prototype, factory()->constructor_string(),
944 LookupIterator::OWN_SKIP_INTERCEPTOR);
945 Handle<Object> value = JSReceiver::GetProperty(&it).ToHandleChecked();
946 DCHECK(it.IsFound());
947 DCHECK_EQ(*isolate()->object_function(), *value);
948#endif
Andrei Popescu31002712010-02-23 13:46:05 +0000949 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000950 Handle<FunctionTemplateInfo> js_global_object_constructor(
951 FunctionTemplateInfo::cast(js_global_object_template->constructor()));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000952 js_global_object_function = ApiNatives::CreateApiFunction(
953 isolate(), js_global_object_constructor, factory()->the_hole_value(),
954 ApiNatives::GlobalObjectType);
Steve Blocka7e24c12009-10-30 11:49:00 +0000955 }
956
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000957 js_global_object_function->initial_map()->set_is_prototype_map(true);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000958 js_global_object_function->initial_map()->set_dictionary_map(true);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000959 Handle<JSGlobalObject> global_object =
960 factory()->NewJSGlobalObject(js_global_object_function);
Andrei Popescu31002712010-02-23 13:46:05 +0000961
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000962 // Step 2: (re)initialize the global proxy object.
Andrei Popescu31002712010-02-23 13:46:05 +0000963 Handle<JSFunction> global_proxy_function;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000964 if (global_proxy_template.IsEmpty()) {
965 Handle<String> name = Handle<String>(heap()->empty_string());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000966 Handle<Code> code = isolate()->builtins()->Illegal();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000967 global_proxy_function = factory()->NewFunction(
968 name, code, JS_GLOBAL_PROXY_TYPE, JSGlobalProxy::kSize);
Andrei Popescu31002712010-02-23 13:46:05 +0000969 } else {
970 Handle<ObjectTemplateInfo> data =
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000971 v8::Utils::OpenHandle(*global_proxy_template);
Andrei Popescu31002712010-02-23 13:46:05 +0000972 Handle<FunctionTemplateInfo> global_constructor(
973 FunctionTemplateInfo::cast(data->constructor()));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000974 global_proxy_function = ApiNatives::CreateApiFunction(
975 isolate(), global_constructor, factory()->the_hole_value(),
976 ApiNatives::GlobalProxyType);
Andrei Popescu31002712010-02-23 13:46:05 +0000977 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000978 Handle<String> global_name = factory()->global_string();
Andrei Popescu31002712010-02-23 13:46:05 +0000979 global_proxy_function->shared()->set_instance_class_name(*global_name);
980 global_proxy_function->initial_map()->set_is_access_check_needed(true);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100981 global_proxy_function->initial_map()->set_has_hidden_prototype(true);
Andrei Popescu31002712010-02-23 13:46:05 +0000982
983 // Set global_proxy.__proto__ to js_global after ConfigureGlobalObjects
984 // Return the global proxy.
985
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000986 factory()->ReinitializeJSGlobalProxy(global_proxy, global_proxy_function);
987 return global_object;
Andrei Popescu31002712010-02-23 13:46:05 +0000988}
989
990
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000991void Genesis::HookUpGlobalProxy(Handle<JSGlobalObject> global_object,
Andrei Popescu31002712010-02-23 13:46:05 +0000992 Handle<JSGlobalProxy> global_proxy) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000993 // Set the native context for the global object.
994 global_object->set_native_context(*native_context());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000995 global_object->set_global_proxy(*global_proxy);
996 global_proxy->set_native_context(*native_context());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000997 // If we deserialized the context, the global proxy is already
998 // correctly set up. Otherwise it's undefined.
999 DCHECK(native_context()->get(Context::GLOBAL_PROXY_INDEX)->IsUndefined() ||
1000 native_context()->global_proxy() == *global_proxy);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001001 native_context()->set_global_proxy(*global_proxy);
Andrei Popescu31002712010-02-23 13:46:05 +00001002}
1003
1004
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001005void Genesis::HookUpGlobalObject(Handle<JSGlobalObject> global_object) {
1006 Handle<JSGlobalObject> global_object_from_snapshot(
1007 JSGlobalObject::cast(native_context()->extension()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001008 native_context()->set_extension(*global_object);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001009 native_context()->set_security_token(*global_object);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001010
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001011 TransferNamedProperties(global_object_from_snapshot, global_object);
1012 TransferIndexedProperties(global_object_from_snapshot, global_object);
Andrei Popescu402d9372010-02-26 13:31:12 +00001013}
1014
1015
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001016static Handle<JSFunction> SimpleCreateFunction(Isolate* isolate,
1017 Handle<String> name,
1018 Builtins::Name call, int len,
1019 bool adapt) {
1020 Handle<JSFunction> fun =
1021 CreateFunction(isolate, name, JS_OBJECT_TYPE, JSObject::kHeaderSize,
1022 MaybeHandle<JSObject>(), call);
1023 if (adapt) {
1024 fun->shared()->set_internal_formal_parameter_count(len);
1025 } else {
1026 fun->shared()->DontAdaptArguments();
1027 }
1028 fun->shared()->set_length(len);
1029 return fun;
1030}
1031
1032
1033static Handle<JSFunction> SimpleInstallFunction(Handle<JSObject> base,
1034 Handle<String> name,
1035 Builtins::Name call, int len,
1036 bool adapt) {
1037 Handle<JSFunction> fun =
1038 SimpleCreateFunction(base->GetIsolate(), name, call, len, adapt);
1039 InstallFunction(base, fun, name, DONT_ENUM);
1040 return fun;
1041}
1042
1043
1044static Handle<JSFunction> SimpleInstallFunction(Handle<JSObject> base,
1045 const char* name,
1046 Builtins::Name call, int len,
1047 bool adapt) {
1048 Factory* const factory = base->GetIsolate()->factory();
1049 return SimpleInstallFunction(base, factory->InternalizeUtf8String(name), call,
1050 len, adapt);
1051}
1052
1053
1054static void InstallWithIntrinsicDefaultProto(Isolate* isolate,
1055 Handle<JSFunction> function,
1056 int context_index) {
1057 Handle<Smi> index(Smi::FromInt(context_index), isolate);
1058 JSObject::AddProperty(
1059 function, isolate->factory()->native_context_index_symbol(), index, NONE);
1060 isolate->native_context()->set(context_index, *function);
1061}
1062
1063
Andrei Popescu402d9372010-02-26 13:31:12 +00001064// This is only called if we are not using snapshots. The equivalent
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001065// work in the snapshot case is done in HookUpGlobalObject.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001066void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
1067 Handle<JSFunction> empty_function,
Ben Murdoch097c5b22016-05-18 11:27:45 +01001068 GlobalContextType context_type) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001069 // --- N a t i v e C o n t e x t ---
Andrei Popescu31002712010-02-23 13:46:05 +00001070 // Use the empty function as closure (no scope info).
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001071 native_context()->set_closure(*empty_function);
1072 native_context()->set_previous(NULL);
Andrei Popescu31002712010-02-23 13:46:05 +00001073 // Set extension and global object.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001074 native_context()->set_extension(*global_object);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001075 // Security setup: Set the security token of the native context to the global
1076 // object. This makes the security check between two different contexts fail
1077 // by default even in case of global object reinitialization.
1078 native_context()->set_security_token(*global_object);
Andrei Popescu31002712010-02-23 13:46:05 +00001079
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001080 Isolate* isolate = global_object->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01001081 Factory* factory = isolate->factory();
Steve Block44f0eee2011-05-26 01:26:41 +01001082
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001083 Handle<ScriptContextTable> script_context_table =
1084 factory->NewScriptContextTable();
1085 native_context()->set_script_context_table(*script_context_table);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001086 InstallGlobalThisBinding();
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001087
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001088 { // --- O b j e c t ---
1089 Handle<String> object_name = factory->Object_string();
1090 Handle<JSFunction> object_function = isolate->object_function();
1091 JSObject::AddProperty(global_object, object_name, object_function,
1092 DONT_ENUM);
1093 SimpleInstallFunction(object_function, factory->assign_string(),
1094 Builtins::kObjectAssign, 2, false);
1095 SimpleInstallFunction(object_function, factory->create_string(),
1096 Builtins::kObjectCreate, 2, false);
1097 Handle<JSFunction> object_freeze = SimpleInstallFunction(
1098 object_function, "freeze", Builtins::kObjectFreeze, 1, false);
1099 native_context()->set_object_freeze(*object_freeze);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001100 SimpleInstallFunction(object_function, "getOwnPropertyDescriptor",
1101 Builtins::kObjectGetOwnPropertyDescriptor, 2, false);
1102 SimpleInstallFunction(object_function, "getOwnPropertyNames",
1103 Builtins::kObjectGetOwnPropertyNames, 1, false);
1104 SimpleInstallFunction(object_function, "getOwnPropertySymbols",
1105 Builtins::kObjectGetOwnPropertySymbols, 1, false);
1106 SimpleInstallFunction(object_function, "is", Builtins::kObjectIs, 2, true);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001107 Handle<JSFunction> object_is_extensible =
1108 SimpleInstallFunction(object_function, "isExtensible",
1109 Builtins::kObjectIsExtensible, 1, false);
1110 native_context()->set_object_is_extensible(*object_is_extensible);
1111 Handle<JSFunction> object_is_frozen = SimpleInstallFunction(
1112 object_function, "isFrozen", Builtins::kObjectIsFrozen, 1, false);
1113 native_context()->set_object_is_frozen(*object_is_frozen);
1114 Handle<JSFunction> object_is_sealed = SimpleInstallFunction(
1115 object_function, "isSealed", Builtins::kObjectIsSealed, 1, false);
1116 native_context()->set_object_is_sealed(*object_is_sealed);
1117 Handle<JSFunction> object_keys = SimpleInstallFunction(
1118 object_function, "keys", Builtins::kObjectKeys, 1, false);
1119 native_context()->set_object_keys(*object_keys);
1120 SimpleInstallFunction(object_function, "preventExtensions",
1121 Builtins::kObjectPreventExtensions, 1, false);
1122 SimpleInstallFunction(object_function, "seal", Builtins::kObjectSeal, 1,
1123 false);
1124 }
Andrei Popescu31002712010-02-23 13:46:05 +00001125
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001126 Handle<JSObject> global(native_context()->global_object());
Steve Blocka7e24c12009-10-30 11:49:00 +00001127
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001128 { // --- F u n c t i o n ---
1129 Handle<JSFunction> prototype = empty_function;
1130 Handle<JSFunction> function_fun =
1131 InstallFunction(global, "Function", JS_FUNCTION_TYPE, JSFunction::kSize,
1132 prototype, Builtins::kFunctionConstructor);
1133 function_fun->set_prototype_or_initial_map(
1134 *sloppy_function_map_writable_prototype_);
1135 function_fun->shared()->DontAdaptArguments();
1136 function_fun->shared()->set_construct_stub(
1137 *isolate->builtins()->FunctionConstructor());
1138 function_fun->shared()->set_length(1);
1139 InstallWithIntrinsicDefaultProto(isolate, function_fun,
1140 Context::FUNCTION_FUNCTION_INDEX);
1141
1142 // Setup the methods on the %FunctionPrototype%.
1143 SimpleInstallFunction(prototype, factory->apply_string(),
1144 Builtins::kFunctionPrototypeApply, 2, false);
1145 SimpleInstallFunction(prototype, factory->bind_string(),
1146 Builtins::kFunctionPrototypeBind, 1, false);
1147 SimpleInstallFunction(prototype, factory->call_string(),
1148 Builtins::kFunctionPrototypeCall, 1, false);
1149 SimpleInstallFunction(prototype, factory->toString_string(),
1150 Builtins::kFunctionPrototypeToString, 0, false);
1151
Ben Murdoch097c5b22016-05-18 11:27:45 +01001152 // Install the @@hasInstance function.
1153 Handle<JSFunction> has_instance = InstallFunction(
1154 prototype, factory->has_instance_symbol(), JS_OBJECT_TYPE,
1155 JSObject::kHeaderSize, MaybeHandle<JSObject>(),
1156 Builtins::kFunctionHasInstance,
1157 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY));
1158
1159 // Set the expected parameters for @@hasInstance to 1; required by builtin.
1160 has_instance->shared()->set_internal_formal_parameter_count(1);
1161
1162 // Set the length for the function to satisfy ECMA-262.
1163 has_instance->shared()->set_length(1);
1164
1165 // Install in the native context
1166 native_context()->set_ordinary_has_instance(*has_instance);
1167
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001168 // Install the "constructor" property on the %FunctionPrototype%.
1169 JSObject::AddProperty(prototype, factory->constructor_string(),
1170 function_fun, DONT_ENUM);
1171
1172 sloppy_function_map_writable_prototype_->SetConstructor(*function_fun);
1173 strict_function_map_writable_prototype_->SetConstructor(*function_fun);
1174 native_context()->strong_function_map()->SetConstructor(*function_fun);
1175 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001176
1177 { // --- A r r a y ---
1178 Handle<JSFunction> array_function =
1179 InstallFunction(global, "Array", JS_ARRAY_TYPE, JSArray::kSize,
Steve Block44f0eee2011-05-26 01:26:41 +01001180 isolate->initial_object_prototype(),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001181 Builtins::kArrayCode);
Steve Blocka7e24c12009-10-30 11:49:00 +00001182 array_function->shared()->DontAdaptArguments();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001183 array_function->shared()->set_function_data(Smi::FromInt(kArrayCode));
Steve Blocka7e24c12009-10-30 11:49:00 +00001184
1185 // This seems a bit hackish, but we need to make sure Array.length
1186 // is 1.
1187 array_function->shared()->set_length(1);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001188
1189 Handle<Map> initial_map(array_function->initial_map());
1190
1191 // This assert protects an optimization in
1192 // HGraphBuilder::JSArrayBuilder::EmitMapCode()
1193 DCHECK(initial_map->elements_kind() == GetInitialFastElementsKind());
1194 Map::EnsureDescriptorSlack(initial_map, 1);
1195
1196 PropertyAttributes attribs = static_cast<PropertyAttributes>(
1197 DONT_ENUM | DONT_DELETE);
1198
1199 Handle<AccessorInfo> array_length =
1200 Accessors::ArrayLengthInfo(isolate, attribs);
1201 { // Add length.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001202 AccessorConstantDescriptor d(
1203 Handle<Name>(Name::cast(array_length->name())), array_length,
1204 attribs);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001205 initial_map->AppendDescriptor(&d);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001206 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001207
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001208 InstallWithIntrinsicDefaultProto(isolate, array_function,
1209 Context::ARRAY_FUNCTION_INDEX);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001210
1211 // Cache the array maps, needed by ArrayConstructorStub
1212 CacheInitialJSArrayMaps(native_context(), initial_map);
1213 ArrayConstructorStub array_constructor_stub(isolate);
1214 Handle<Code> code = array_constructor_stub.GetCode();
1215 array_function->shared()->set_construct_stub(*code);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001216
1217 Handle<Map> initial_strong_map =
1218 Map::Copy(initial_map, "SetInstancePrototype");
1219 initial_strong_map->set_is_strong();
1220 CacheInitialJSArrayMaps(native_context(), initial_strong_map);
1221
1222 Handle<JSFunction> is_arraylike = SimpleInstallFunction(
1223 array_function, isolate->factory()->InternalizeUtf8String("isArray"),
1224 Builtins::kArrayIsArray, 1, true);
1225 native_context()->set_is_arraylike(*is_arraylike);
Steve Blocka7e24c12009-10-30 11:49:00 +00001226 }
1227
1228 { // --- N u m b e r ---
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001229 Handle<JSFunction> number_fun = InstallFunction(
1230 global, "Number", JS_VALUE_TYPE, JSValue::kSize,
1231 isolate->initial_object_prototype(), Builtins::kNumberConstructor);
1232 number_fun->shared()->DontAdaptArguments();
1233 number_fun->shared()->set_construct_stub(
1234 *isolate->builtins()->NumberConstructor_ConstructStub());
1235 number_fun->shared()->set_length(1);
1236 InstallWithIntrinsicDefaultProto(isolate, number_fun,
1237 Context::NUMBER_FUNCTION_INDEX);
Steve Blocka7e24c12009-10-30 11:49:00 +00001238 }
1239
1240 { // --- B o o l e a n ---
1241 Handle<JSFunction> boolean_fun =
1242 InstallFunction(global, "Boolean", JS_VALUE_TYPE, JSValue::kSize,
Steve Block44f0eee2011-05-26 01:26:41 +01001243 isolate->initial_object_prototype(),
Ben Murdoch097c5b22016-05-18 11:27:45 +01001244 Builtins::kBooleanConstructor);
1245 boolean_fun->shared()->DontAdaptArguments();
1246 boolean_fun->shared()->set_construct_stub(
1247 *isolate->builtins()->BooleanConstructor_ConstructStub());
1248 boolean_fun->shared()->set_length(1);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001249 InstallWithIntrinsicDefaultProto(isolate, boolean_fun,
1250 Context::BOOLEAN_FUNCTION_INDEX);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001251
1252 // Create the %BooleanPrototype%
1253 Handle<JSValue> prototype =
1254 Handle<JSValue>::cast(factory->NewJSObject(boolean_fun, TENURED));
1255 prototype->set_value(isolate->heap()->false_value());
1256 Accessors::FunctionSetPrototype(boolean_fun, prototype).Assert();
1257
1258 // Install the "constructor" property on the {prototype}.
1259 JSObject::AddProperty(prototype, factory->constructor_string(), boolean_fun,
1260 DONT_ENUM);
1261
1262 // Install the Boolean.prototype methods.
1263 SimpleInstallFunction(prototype, "toString",
1264 Builtins::kBooleanPrototypeToString, 0, false);
1265 SimpleInstallFunction(prototype, "valueOf",
1266 Builtins::kBooleanPrototypeValueOf, 0, false);
Steve Blocka7e24c12009-10-30 11:49:00 +00001267 }
1268
1269 { // --- S t r i n g ---
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001270 Handle<JSFunction> string_fun = InstallFunction(
1271 global, "String", JS_VALUE_TYPE, JSValue::kSize,
1272 isolate->initial_object_prototype(), Builtins::kStringConstructor);
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001273 string_fun->shared()->set_construct_stub(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001274 *isolate->builtins()->StringConstructor_ConstructStub());
1275 string_fun->shared()->DontAdaptArguments();
1276 string_fun->shared()->set_length(1);
1277 InstallWithIntrinsicDefaultProto(isolate, string_fun,
1278 Context::STRING_FUNCTION_INDEX);
Steve Blocka7e24c12009-10-30 11:49:00 +00001279
1280 Handle<Map> string_map =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001281 Handle<Map>(native_context()->string_function()->initial_map());
Ben Murdoch097c5b22016-05-18 11:27:45 +01001282 string_map->set_elements_kind(FAST_STRING_WRAPPER_ELEMENTS);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001283 Map::EnsureDescriptorSlack(string_map, 1);
1284
1285 PropertyAttributes attribs = static_cast<PropertyAttributes>(
1286 DONT_ENUM | DONT_DELETE | READ_ONLY);
1287 Handle<AccessorInfo> string_length(
1288 Accessors::StringLengthInfo(isolate, attribs));
1289
1290 { // Add length.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001291 AccessorConstantDescriptor d(factory->length_string(), string_length,
1292 attribs);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001293 string_map->AppendDescriptor(&d);
1294 }
1295 }
1296
1297 {
1298 // --- S y m b o l ---
Ben Murdoch097c5b22016-05-18 11:27:45 +01001299 Handle<JSObject> prototype =
1300 factory->NewJSObject(isolate->object_function(), TENURED);
1301 Handle<JSFunction> symbol_fun =
1302 InstallFunction(global, "Symbol", JS_VALUE_TYPE, JSValue::kSize,
1303 prototype, Builtins::kSymbolConstructor);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001304 symbol_fun->shared()->set_construct_stub(
1305 *isolate->builtins()->SymbolConstructor_ConstructStub());
1306 symbol_fun->shared()->set_length(1);
1307 symbol_fun->shared()->DontAdaptArguments();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001308 native_context()->set_symbol_function(*symbol_fun);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001309
1310 // Install the "constructor" property on the {prototype}.
1311 JSObject::AddProperty(prototype, factory->constructor_string(), symbol_fun,
1312 DONT_ENUM);
Steve Blocka7e24c12009-10-30 11:49:00 +00001313 }
1314
1315 { // --- D a t e ---
1316 // Builtin functions for Date.prototype.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001317 Handle<JSObject> prototype =
1318 factory->NewJSObject(isolate->object_function(), TENURED);
Steve Blocka7e24c12009-10-30 11:49:00 +00001319 Handle<JSFunction> date_fun =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001320 InstallFunction(global, "Date", JS_DATE_TYPE, JSDate::kSize, prototype,
1321 Builtins::kDateConstructor);
1322 InstallWithIntrinsicDefaultProto(isolate, date_fun,
1323 Context::DATE_FUNCTION_INDEX);
1324 date_fun->shared()->set_construct_stub(
1325 *isolate->builtins()->DateConstructor_ConstructStub());
1326 date_fun->shared()->set_length(7);
1327 date_fun->shared()->DontAdaptArguments();
Steve Blocka7e24c12009-10-30 11:49:00 +00001328
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001329 // Install the Date.now, Date.parse and Date.UTC functions.
1330 SimpleInstallFunction(date_fun, "now", Builtins::kDateNow, 0, false);
1331 SimpleInstallFunction(date_fun, "parse", Builtins::kDateParse, 1, false);
1332 SimpleInstallFunction(date_fun, "UTC", Builtins::kDateUTC, 7, false);
1333
1334 // Install the "constructor" property on the {prototype}.
1335 JSObject::AddProperty(prototype, factory->constructor_string(), date_fun,
1336 DONT_ENUM);
1337
1338 // Install the Date.prototype methods.
1339 SimpleInstallFunction(prototype, "toString",
1340 Builtins::kDatePrototypeToString, 0, false);
1341 SimpleInstallFunction(prototype, "toDateString",
1342 Builtins::kDatePrototypeToDateString, 0, false);
1343 SimpleInstallFunction(prototype, "toTimeString",
1344 Builtins::kDatePrototypeToTimeString, 0, false);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001345 SimpleInstallFunction(prototype, "toISOString",
1346 Builtins::kDatePrototypeToISOString, 0, false);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001347 Handle<JSFunction> to_utc_string =
1348 SimpleInstallFunction(prototype, "toUTCString",
1349 Builtins::kDatePrototypeToUTCString, 0, false);
1350 InstallFunction(prototype, to_utc_string,
1351 factory->InternalizeUtf8String("toGMTString"), DONT_ENUM);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001352 SimpleInstallFunction(prototype, "getDate", Builtins::kDatePrototypeGetDate,
1353 0, true);
1354 SimpleInstallFunction(prototype, "setDate", Builtins::kDatePrototypeSetDate,
1355 1, false);
1356 SimpleInstallFunction(prototype, "getDay", Builtins::kDatePrototypeGetDay,
1357 0, true);
1358 SimpleInstallFunction(prototype, "getFullYear",
1359 Builtins::kDatePrototypeGetFullYear, 0, true);
1360 SimpleInstallFunction(prototype, "setFullYear",
1361 Builtins::kDatePrototypeSetFullYear, 3, false);
1362 SimpleInstallFunction(prototype, "getHours",
1363 Builtins::kDatePrototypeGetHours, 0, true);
1364 SimpleInstallFunction(prototype, "setHours",
1365 Builtins::kDatePrototypeSetHours, 4, false);
1366 SimpleInstallFunction(prototype, "getMilliseconds",
1367 Builtins::kDatePrototypeGetMilliseconds, 0, true);
1368 SimpleInstallFunction(prototype, "setMilliseconds",
1369 Builtins::kDatePrototypeSetMilliseconds, 1, false);
1370 SimpleInstallFunction(prototype, "getMinutes",
1371 Builtins::kDatePrototypeGetMinutes, 0, true);
1372 SimpleInstallFunction(prototype, "setMinutes",
1373 Builtins::kDatePrototypeSetMinutes, 3, false);
1374 SimpleInstallFunction(prototype, "getMonth",
1375 Builtins::kDatePrototypeGetMonth, 0, true);
1376 SimpleInstallFunction(prototype, "setMonth",
1377 Builtins::kDatePrototypeSetMonth, 2, false);
1378 SimpleInstallFunction(prototype, "getSeconds",
1379 Builtins::kDatePrototypeGetSeconds, 0, true);
1380 SimpleInstallFunction(prototype, "setSeconds",
1381 Builtins::kDatePrototypeSetSeconds, 2, false);
1382 SimpleInstallFunction(prototype, "getTime", Builtins::kDatePrototypeGetTime,
1383 0, true);
1384 SimpleInstallFunction(prototype, "setTime", Builtins::kDatePrototypeSetTime,
1385 1, false);
1386 SimpleInstallFunction(prototype, "getTimezoneOffset",
1387 Builtins::kDatePrototypeGetTimezoneOffset, 0, true);
1388 SimpleInstallFunction(prototype, "getUTCDate",
1389 Builtins::kDatePrototypeGetUTCDate, 0, true);
1390 SimpleInstallFunction(prototype, "setUTCDate",
1391 Builtins::kDatePrototypeSetUTCDate, 1, false);
1392 SimpleInstallFunction(prototype, "getUTCDay",
1393 Builtins::kDatePrototypeGetUTCDay, 0, true);
1394 SimpleInstallFunction(prototype, "getUTCFullYear",
1395 Builtins::kDatePrototypeGetUTCFullYear, 0, true);
1396 SimpleInstallFunction(prototype, "setUTCFullYear",
1397 Builtins::kDatePrototypeSetUTCFullYear, 3, false);
1398 SimpleInstallFunction(prototype, "getUTCHours",
1399 Builtins::kDatePrototypeGetUTCHours, 0, true);
1400 SimpleInstallFunction(prototype, "setUTCHours",
1401 Builtins::kDatePrototypeSetUTCHours, 4, false);
1402 SimpleInstallFunction(prototype, "getUTCMilliseconds",
1403 Builtins::kDatePrototypeGetUTCMilliseconds, 0, true);
1404 SimpleInstallFunction(prototype, "setUTCMilliseconds",
1405 Builtins::kDatePrototypeSetUTCMilliseconds, 1, false);
1406 SimpleInstallFunction(prototype, "getUTCMinutes",
1407 Builtins::kDatePrototypeGetUTCMinutes, 0, true);
1408 SimpleInstallFunction(prototype, "setUTCMinutes",
1409 Builtins::kDatePrototypeSetUTCMinutes, 3, false);
1410 SimpleInstallFunction(prototype, "getUTCMonth",
1411 Builtins::kDatePrototypeGetUTCMonth, 0, true);
1412 SimpleInstallFunction(prototype, "setUTCMonth",
1413 Builtins::kDatePrototypeSetUTCMonth, 2, false);
1414 SimpleInstallFunction(prototype, "getUTCSeconds",
1415 Builtins::kDatePrototypeGetUTCSeconds, 0, true);
1416 SimpleInstallFunction(prototype, "setUTCSeconds",
1417 Builtins::kDatePrototypeSetUTCSeconds, 2, false);
1418 SimpleInstallFunction(prototype, "valueOf", Builtins::kDatePrototypeValueOf,
1419 0, false);
1420 SimpleInstallFunction(prototype, "getYear", Builtins::kDatePrototypeGetYear,
1421 0, true);
1422 SimpleInstallFunction(prototype, "setYear", Builtins::kDatePrototypeSetYear,
1423 1, false);
1424
1425 // Install i18n fallback functions.
1426 SimpleInstallFunction(prototype, "toLocaleString",
1427 Builtins::kDatePrototypeToString, 0, false);
1428 SimpleInstallFunction(prototype, "toLocaleDateString",
1429 Builtins::kDatePrototypeToDateString, 0, false);
1430 SimpleInstallFunction(prototype, "toLocaleTimeString",
1431 Builtins::kDatePrototypeToTimeString, 0, false);
1432
1433 // Install the @@toPrimitive function.
1434 Handle<JSFunction> to_primitive = InstallFunction(
1435 prototype, factory->to_primitive_symbol(), JS_OBJECT_TYPE,
1436 JSObject::kHeaderSize, MaybeHandle<JSObject>(),
1437 Builtins::kDatePrototypeToPrimitive,
1438 static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
1439
1440 // Set the expected parameters for @@toPrimitive to 1; required by builtin.
1441 to_primitive->shared()->set_internal_formal_parameter_count(1);
1442
1443 // Set the length for the function to satisfy ECMA-262.
1444 to_primitive->shared()->set_length(1);
Steve Blocka7e24c12009-10-30 11:49:00 +00001445 }
1446
Steve Blocka7e24c12009-10-30 11:49:00 +00001447 { // -- R e g E x p
1448 // Builtin functions for RegExp.prototype.
1449 Handle<JSFunction> regexp_fun =
1450 InstallFunction(global, "RegExp", JS_REGEXP_TYPE, JSRegExp::kSize,
Steve Block44f0eee2011-05-26 01:26:41 +01001451 isolate->initial_object_prototype(),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001452 Builtins::kIllegal);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001453 InstallWithIntrinsicDefaultProto(isolate, regexp_fun,
1454 Context::REGEXP_FUNCTION_INDEX);
1455 regexp_fun->shared()->set_construct_stub(
1456 *isolate->builtins()->JSBuiltinsConstructStub());
Steve Block6ded16b2010-05-10 14:33:55 +01001457
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001458 DCHECK(regexp_fun->has_initial_map());
Steve Block6ded16b2010-05-10 14:33:55 +01001459 Handle<Map> initial_map(regexp_fun->initial_map());
1460
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001461 DCHECK_EQ(0, initial_map->GetInObjectProperties());
Steve Block6ded16b2010-05-10 14:33:55 +01001462
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001463 Map::EnsureDescriptorSlack(initial_map, 1);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001464
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001465 // ECMA-262, section 15.10.7.5.
1466 PropertyAttributes writable =
1467 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE);
1468 DataDescriptor field(factory->last_index_string(),
1469 JSRegExp::kLastIndexFieldIndex, writable,
1470 Representation::Tagged());
1471 initial_map->AppendDescriptor(&field);
Steve Block6ded16b2010-05-10 14:33:55 +01001472
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001473 static const int num_fields = JSRegExp::kInObjectFieldCount;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001474 initial_map->SetInObjectProperties(num_fields);
Steve Block6ded16b2010-05-10 14:33:55 +01001475 initial_map->set_unused_property_fields(0);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001476 initial_map->set_instance_size(initial_map->instance_size() +
1477 num_fields * kPointerSize);
Steve Blocka7e24c12009-10-30 11:49:00 +00001478 }
1479
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001480 { // -- E r r o r
1481 Handle<JSFunction> error_fun = InstallFunction(
1482 global, "Error", JS_OBJECT_TYPE, JSObject::kHeaderSize,
1483 isolate->initial_object_prototype(), Builtins::kIllegal);
1484 InstallWithIntrinsicDefaultProto(isolate, error_fun,
1485 Context::ERROR_FUNCTION_INDEX);
1486 }
1487
1488 { // -- E v a l E r r o r
1489 Handle<JSFunction> eval_error_fun = InstallFunction(
1490 global, "EvalError", JS_OBJECT_TYPE, JSObject::kHeaderSize,
1491 isolate->initial_object_prototype(), Builtins::kIllegal);
1492 InstallWithIntrinsicDefaultProto(isolate, eval_error_fun,
1493 Context::EVAL_ERROR_FUNCTION_INDEX);
1494 }
1495
1496 { // -- R a n g e E r r o r
1497 Handle<JSFunction> range_error_fun = InstallFunction(
1498 global, "RangeError", JS_OBJECT_TYPE, JSObject::kHeaderSize,
1499 isolate->initial_object_prototype(), Builtins::kIllegal);
1500 InstallWithIntrinsicDefaultProto(isolate, range_error_fun,
1501 Context::RANGE_ERROR_FUNCTION_INDEX);
1502 }
1503
1504 { // -- R e f e r e n c e E r r o r
1505 Handle<JSFunction> reference_error_fun = InstallFunction(
1506 global, "ReferenceError", JS_OBJECT_TYPE, JSObject::kHeaderSize,
1507 isolate->initial_object_prototype(), Builtins::kIllegal);
1508 InstallWithIntrinsicDefaultProto(isolate, reference_error_fun,
1509 Context::REFERENCE_ERROR_FUNCTION_INDEX);
1510 }
1511
1512 { // -- S y n t a x E r r o r
1513 Handle<JSFunction> syntax_error_fun = InstallFunction(
1514 global, "SyntaxError", JS_OBJECT_TYPE, JSObject::kHeaderSize,
1515 isolate->initial_object_prototype(), Builtins::kIllegal);
1516 InstallWithIntrinsicDefaultProto(isolate, syntax_error_fun,
1517 Context::SYNTAX_ERROR_FUNCTION_INDEX);
1518 }
1519
1520 { // -- T y p e E r r o r
1521 Handle<JSFunction> type_error_fun = InstallFunction(
1522 global, "TypeError", JS_OBJECT_TYPE, JSObject::kHeaderSize,
1523 isolate->initial_object_prototype(), Builtins::kIllegal);
1524 InstallWithIntrinsicDefaultProto(isolate, type_error_fun,
1525 Context::TYPE_ERROR_FUNCTION_INDEX);
1526 }
1527
1528 { // -- U R I E r r o r
1529 Handle<JSFunction> uri_error_fun = InstallFunction(
1530 global, "URIError", JS_OBJECT_TYPE, JSObject::kHeaderSize,
1531 isolate->initial_object_prototype(), Builtins::kIllegal);
1532 InstallWithIntrinsicDefaultProto(isolate, uri_error_fun,
1533 Context::URI_ERROR_FUNCTION_INDEX);
1534 }
1535
1536 // Initialize the embedder data slot.
1537 Handle<FixedArray> embedder_data = factory->NewFixedArray(3);
1538 native_context()->set_embedder_data(*embedder_data);
1539
1540 if (context_type == THIN_CONTEXT) return;
1541
Steve Blocka7e24c12009-10-30 11:49:00 +00001542 { // -- J S O N
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001543 Handle<String> name = factory->InternalizeUtf8String("JSON");
1544 Handle<JSFunction> cons = factory->NewFunction(name);
1545 JSFunction::SetInstancePrototype(cons,
1546 Handle<Object>(native_context()->initial_object_prototype(), isolate));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001547 cons->shared()->set_instance_class_name(*name);
Steve Block44f0eee2011-05-26 01:26:41 +01001548 Handle<JSObject> json_object = factory->NewJSObject(cons, TENURED);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001549 DCHECK(json_object->IsJSObject());
1550 JSObject::AddProperty(global, name, json_object, DONT_ENUM);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001551 }
1552
1553 { // -- M a t h
1554 Handle<String> name = factory->InternalizeUtf8String("Math");
1555 Handle<JSFunction> cons = factory->NewFunction(name);
1556 JSFunction::SetInstancePrototype(
1557 cons,
1558 Handle<Object>(native_context()->initial_object_prototype(), isolate));
1559 cons->shared()->set_instance_class_name(*name);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001560 Handle<JSObject> math = factory->NewJSObject(cons, TENURED);
1561 DCHECK(math->IsJSObject());
1562 JSObject::AddProperty(global, name, math, DONT_ENUM);
1563 SimpleInstallFunction(math, "max", Builtins::kMathMax, 2, false);
1564 SimpleInstallFunction(math, "min", Builtins::kMathMin, 2, false);
Steve Blocka7e24c12009-10-30 11:49:00 +00001565 }
1566
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001567 { // -- A r r a y B u f f e r
1568 Handle<JSFunction> array_buffer_fun =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001569 InstallArrayBuffer(global, "ArrayBuffer");
1570 InstallWithIntrinsicDefaultProto(isolate, array_buffer_fun,
1571 Context::ARRAY_BUFFER_FUN_INDEX);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001572 }
1573
1574 { // -- T y p e d A r r a y s
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001575#define INSTALL_TYPED_ARRAY(Type, type, TYPE, ctype, size) \
1576 { \
1577 Handle<JSFunction> fun; \
1578 InstallTypedArray(#Type "Array", TYPE##_ELEMENTS, &fun); \
1579 InstallWithIntrinsicDefaultProto(isolate, fun, \
1580 Context::TYPE##_ARRAY_FUN_INDEX); \
1581 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001582 TYPED_ARRAYS(INSTALL_TYPED_ARRAY)
1583#undef INSTALL_TYPED_ARRAY
1584
Ben Murdoch097c5b22016-05-18 11:27:45 +01001585 Handle<JSFunction> data_view_fun = InstallFunction(
1586 global, "DataView", JS_DATA_VIEW_TYPE,
1587 JSDataView::kSizeWithInternalFields,
1588 isolate->initial_object_prototype(), Builtins::kDataViewConstructor);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001589 InstallWithIntrinsicDefaultProto(isolate, data_view_fun,
1590 Context::DATA_VIEW_FUN_INDEX);
1591 data_view_fun->shared()->set_construct_stub(
Ben Murdoch097c5b22016-05-18 11:27:45 +01001592 *isolate->builtins()->DataViewConstructor_ConstructStub());
1593 data_view_fun->shared()->set_length(3);
1594 data_view_fun->shared()->DontAdaptArguments();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001595 }
1596
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001597 { // -- M a p
1598 Handle<JSFunction> js_map_fun = InstallFunction(
1599 global, "Map", JS_MAP_TYPE, JSMap::kSize,
1600 isolate->initial_object_prototype(), Builtins::kIllegal);
1601 InstallWithIntrinsicDefaultProto(isolate, js_map_fun,
1602 Context::JS_MAP_FUN_INDEX);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001603 }
1604
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001605 { // -- S e t
1606 Handle<JSFunction> js_set_fun = InstallFunction(
1607 global, "Set", JS_SET_TYPE, JSSet::kSize,
1608 isolate->initial_object_prototype(), Builtins::kIllegal);
1609 InstallWithIntrinsicDefaultProto(isolate, js_set_fun,
1610 Context::JS_SET_FUN_INDEX);
1611 }
1612
1613 { // -- I t e r a t o r R e s u l t
1614 Handle<Map> map =
Ben Murdoch097c5b22016-05-18 11:27:45 +01001615 factory->NewMap(JS_OBJECT_TYPE, JSIteratorResult::kSize);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001616 Map::SetPrototype(map, isolate->initial_object_prototype());
1617 Map::EnsureDescriptorSlack(map, 2);
1618
1619 { // value
1620 DataDescriptor d(factory->value_string(), JSIteratorResult::kValueIndex,
1621 NONE, Representation::Tagged());
1622 map->AppendDescriptor(&d);
1623 }
1624
1625 { // done
1626 DataDescriptor d(factory->done_string(), JSIteratorResult::kDoneIndex,
1627 NONE, Representation::Tagged());
1628 map->AppendDescriptor(&d);
1629 }
1630
Ben Murdoch097c5b22016-05-18 11:27:45 +01001631 map->SetConstructor(native_context()->object_function());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001632 map->SetInObjectProperties(2);
1633 native_context()->set_iterator_result_map(*map);
1634 }
1635
1636 { // -- W e a k M a p
1637 Handle<JSFunction> js_weak_map_fun = InstallFunction(
1638 global, "WeakMap", JS_WEAK_MAP_TYPE, JSWeakMap::kSize,
1639 isolate->initial_object_prototype(), Builtins::kIllegal);
1640 InstallWithIntrinsicDefaultProto(isolate, js_weak_map_fun,
1641 Context::JS_WEAK_MAP_FUN_INDEX);
1642 }
1643
1644 { // -- W e a k S e t
1645 Handle<JSFunction> js_weak_set_fun = InstallFunction(
1646 global, "WeakSet", JS_WEAK_SET_TYPE, JSWeakSet::kSize,
1647 isolate->initial_object_prototype(), Builtins::kIllegal);
1648 InstallWithIntrinsicDefaultProto(isolate, js_weak_set_fun,
1649 Context::JS_WEAK_SET_FUN_INDEX);
1650 }
1651
1652 { // --- B o u n d F u n c t i o n
1653 Handle<Map> map =
1654 factory->NewMap(JS_BOUND_FUNCTION_TYPE, JSBoundFunction::kSize);
1655 map->set_is_callable();
1656 Map::SetPrototype(map, empty_function);
1657
1658 PropertyAttributes roc_attribs =
1659 static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY);
1660 Map::EnsureDescriptorSlack(map, 2);
1661
1662 { // length
1663 DataDescriptor d(factory->length_string(), JSBoundFunction::kLengthIndex,
1664 roc_attribs, Representation::Tagged());
1665 map->AppendDescriptor(&d);
1666 }
1667 { // name
1668 DataDescriptor d(factory->name_string(), JSBoundFunction::kNameIndex,
1669 roc_attribs, Representation::Tagged());
1670 map->AppendDescriptor(&d);
1671 }
1672
1673 map->SetInObjectProperties(2);
1674 native_context()->set_bound_function_without_constructor_map(*map);
1675
1676 map = Map::Copy(map, "IsConstructor");
Ben Murdoch097c5b22016-05-18 11:27:45 +01001677 map->set_is_constructor(true);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001678 native_context()->set_bound_function_with_constructor_map(*map);
1679 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001680
1681 { // --- sloppy arguments map
Steve Blocka7e24c12009-10-30 11:49:00 +00001682 // Make sure we can recognize argument objects at runtime.
1683 // This is done by introducing an anonymous function with
1684 // class_name equals 'Arguments'.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001685 Handle<String> arguments_string = factory->Arguments_string();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001686 Handle<Code> code = isolate->builtins()->Illegal();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001687 Handle<JSFunction> function = factory->NewFunctionWithoutPrototype(
1688 arguments_string, code);
1689 function->shared()->set_instance_class_name(*arguments_string);
Steve Blocka7e24c12009-10-30 11:49:00 +00001690
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001691 Handle<Map> map = factory->NewMap(
Ben Murdoch097c5b22016-05-18 11:27:45 +01001692 JS_OBJECT_TYPE, JSSloppyArgumentsObject::kSize, FAST_ELEMENTS);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001693 // Create the descriptor array for the arguments object.
1694 Map::EnsureDescriptorSlack(map, 2);
Steve Blocka7e24c12009-10-30 11:49:00 +00001695
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001696 { // length
Ben Murdoch097c5b22016-05-18 11:27:45 +01001697 DataDescriptor d(factory->length_string(),
1698 JSSloppyArgumentsObject::kLengthIndex, DONT_ENUM,
1699 Representation::Tagged());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001700 map->AppendDescriptor(&d);
1701 }
1702 { // callee
Ben Murdoch097c5b22016-05-18 11:27:45 +01001703 DataDescriptor d(factory->callee_string(),
1704 JSSloppyArgumentsObject::kCalleeIndex, DONT_ENUM,
1705 Representation::Tagged());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001706 map->AppendDescriptor(&d);
1707 }
1708 // @@iterator method is added later.
Steve Blocka7e24c12009-10-30 11:49:00 +00001709
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001710 map->SetInObjectProperties(2);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001711 native_context()->set_sloppy_arguments_map(*map);
Steve Blocka7e24c12009-10-30 11:49:00 +00001712
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001713 DCHECK(!function->has_initial_map());
1714 JSFunction::SetInitialMap(function, map,
1715 isolate->initial_object_prototype());
Steve Blocka7e24c12009-10-30 11:49:00 +00001716
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001717 DCHECK(!map->is_dictionary_map());
1718 DCHECK(IsFastObjectElementsKind(map->elements_kind()));
Steve Block44f0eee2011-05-26 01:26:41 +01001719 }
1720
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001721 { // --- fast and slow aliased arguments map
1722 Handle<Map> map = isolate->sloppy_arguments_map();
1723 map = Map::Copy(map, "FastAliasedArguments");
1724 map->set_elements_kind(FAST_SLOPPY_ARGUMENTS_ELEMENTS);
1725 DCHECK_EQ(2, map->GetInObjectProperties());
1726 native_context()->set_fast_aliased_arguments_map(*map);
1727
1728 map = Map::Copy(map, "SlowAliasedArguments");
1729 map->set_elements_kind(SLOW_SLOPPY_ARGUMENTS_ELEMENTS);
1730 DCHECK_EQ(2, map->GetInObjectProperties());
1731 native_context()->set_slow_aliased_arguments_map(*map);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001732 }
1733
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001734 { // --- strict mode arguments map
Steve Block44f0eee2011-05-26 01:26:41 +01001735 const PropertyAttributes attributes =
1736 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
1737
1738 // Create the ThrowTypeError functions.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001739 Handle<AccessorPair> callee = factory->NewAccessorPair();
1740 Handle<AccessorPair> caller = factory->NewAccessorPair();
Steve Block44f0eee2011-05-26 01:26:41 +01001741
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001742 Handle<JSFunction> poison = GetStrictArgumentsPoisonFunction();
Steve Block44f0eee2011-05-26 01:26:41 +01001743
1744 // Install the ThrowTypeError functions.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001745 callee->set_getter(*poison);
1746 callee->set_setter(*poison);
1747 caller->set_getter(*poison);
1748 caller->set_setter(*poison);
Steve Block44f0eee2011-05-26 01:26:41 +01001749
1750 // Create the map. Allocate one in-object field for length.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001751 Handle<Map> map = factory->NewMap(
Ben Murdoch097c5b22016-05-18 11:27:45 +01001752 JS_OBJECT_TYPE, JSStrictArgumentsObject::kSize, FAST_ELEMENTS);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001753 // Create the descriptor array for the arguments object.
1754 Map::EnsureDescriptorSlack(map, 3);
1755
1756 { // length
Ben Murdoch097c5b22016-05-18 11:27:45 +01001757 DataDescriptor d(factory->length_string(),
1758 JSStrictArgumentsObject::kLengthIndex, DONT_ENUM,
1759 Representation::Tagged());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001760 map->AppendDescriptor(&d);
1761 }
1762 { // callee
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001763 AccessorConstantDescriptor d(factory->callee_string(), callee,
1764 attributes);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001765 map->AppendDescriptor(&d);
1766 }
1767 { // caller
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001768 AccessorConstantDescriptor d(factory->caller_string(), caller,
1769 attributes);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001770 map->AppendDescriptor(&d);
1771 }
1772 // @@iterator method is added later.
1773
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001774 DCHECK_EQ(native_context()->object_function()->prototype(),
1775 *isolate->initial_object_prototype());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001776 Map::SetPrototype(map, isolate->initial_object_prototype());
1777 map->SetInObjectProperties(1);
Steve Block44f0eee2011-05-26 01:26:41 +01001778
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001779 // Copy constructor from the sloppy arguments boilerplate.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001780 map->SetConstructor(
1781 native_context()->sloppy_arguments_map()->GetConstructor());
Steve Block44f0eee2011-05-26 01:26:41 +01001782
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001783 native_context()->set_strict_arguments_map(*map);
Steve Block44f0eee2011-05-26 01:26:41 +01001784
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001785 DCHECK(!map->is_dictionary_map());
1786 DCHECK(IsFastObjectElementsKind(map->elements_kind()));
Steve Blocka7e24c12009-10-30 11:49:00 +00001787 }
1788
1789 { // --- context extension
1790 // Create a function for the context extension objects.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001791 Handle<Code> code = isolate->builtins()->Illegal();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001792 Handle<JSFunction> context_extension_fun = factory->NewFunction(
1793 factory->empty_string(), code, JS_CONTEXT_EXTENSION_OBJECT_TYPE,
1794 JSObject::kHeaderSize);
Steve Blocka7e24c12009-10-30 11:49:00 +00001795
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001796 Handle<String> name = factory->InternalizeOneByteString(
1797 STATIC_CHAR_VECTOR("context_extension"));
Steve Blocka7e24c12009-10-30 11:49:00 +00001798 context_extension_fun->shared()->set_instance_class_name(*name);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001799 native_context()->set_context_extension_function(*context_extension_fun);
Steve Blocka7e24c12009-10-30 11:49:00 +00001800 }
1801
1802
1803 {
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001804 // Set up the call-as-function delegate.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001805 Handle<Code> code = isolate->builtins()->HandleApiCallAsFunction();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001806 Handle<JSFunction> delegate = factory->NewFunction(
1807 factory->empty_string(), code, JS_OBJECT_TYPE, JSObject::kHeaderSize);
1808 native_context()->set_call_as_function_delegate(*delegate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001809 delegate->shared()->DontAdaptArguments();
1810 }
1811
1812 {
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001813 // Set up the call-as-constructor delegate.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001814 Handle<Code> code = isolate->builtins()->HandleApiCallAsConstructor();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001815 Handle<JSFunction> delegate = factory->NewFunction(
1816 factory->empty_string(), code, JS_OBJECT_TYPE, JSObject::kHeaderSize);
1817 native_context()->set_call_as_constructor_delegate(*delegate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001818 delegate->shared()->DontAdaptArguments();
1819 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001820} // NOLINT(readability/fn_size)
Steve Blocka7e24c12009-10-30 11:49:00 +00001821
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001822
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001823void Genesis::InstallTypedArray(const char* name, ElementsKind elements_kind,
1824 Handle<JSFunction>* fun) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001825 Handle<JSObject> global = Handle<JSObject>(native_context()->global_object());
1826 Handle<JSFunction> result = InstallFunction(
1827 global, name, JS_TYPED_ARRAY_TYPE, JSTypedArray::kSize,
1828 isolate()->initial_object_prototype(), Builtins::kIllegal);
1829
1830 Handle<Map> initial_map = isolate()->factory()->NewMap(
1831 JS_TYPED_ARRAY_TYPE,
1832 JSTypedArray::kSizeWithInternalFields,
1833 elements_kind);
1834 JSFunction::SetInitialMap(result, initial_map,
1835 handle(initial_map->prototype(), isolate()));
1836 *fun = result;
Steve Blocka7e24c12009-10-30 11:49:00 +00001837}
1838
1839
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001840void Genesis::InitializeExperimentalGlobal() {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001841#define FEATURE_INITIALIZE_GLOBAL(id, descr) InitializeGlobal_##id();
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001842
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001843 HARMONY_INPROGRESS(FEATURE_INITIALIZE_GLOBAL)
1844 HARMONY_STAGED(FEATURE_INITIALIZE_GLOBAL)
1845 HARMONY_SHIPPING(FEATURE_INITIALIZE_GLOBAL)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001846 FEATURE_INITIALIZE_GLOBAL(promise_extra, "")
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001847#undef FEATURE_INITIALIZE_GLOBAL
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001848}
1849
1850
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001851bool Bootstrapper::CompileBuiltin(Isolate* isolate, int index) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001852 Vector<const char> name = Natives::GetScriptName(index);
Steve Block44f0eee2011-05-26 01:26:41 +01001853 Handle<String> source_code =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001854 isolate->bootstrapper()->SourceLookup<Natives>(index);
1855
1856 // We pass in extras_utils so that builtin code can set it up for later use
1857 // by actual extras code, compiled with CompileExtraBuiltin.
1858 Handle<Object> global = isolate->global_object();
1859 Handle<Object> utils = isolate->natives_utils_object();
1860 Handle<Object> extras_utils = isolate->extras_utils_object();
1861 Handle<Object> args[] = {global, utils, extras_utils};
1862
1863 return Bootstrapper::CompileNative(isolate, name, source_code,
Ben Murdoch097c5b22016-05-18 11:27:45 +01001864 arraysize(args), args, NATIVES_CODE);
Ben Murdoch257744e2011-11-30 15:57:28 +00001865}
1866
1867
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001868bool Bootstrapper::CompileExperimentalBuiltin(Isolate* isolate, int index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001869 HandleScope scope(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001870 Vector<const char> name = ExperimentalNatives::GetScriptName(index);
1871 Handle<String> source_code =
1872 isolate->bootstrapper()->SourceLookup<ExperimentalNatives>(index);
1873 Handle<Object> global = isolate->global_object();
1874 Handle<Object> utils = isolate->natives_utils_object();
1875 Handle<Object> args[] = {global, utils};
1876 return Bootstrapper::CompileNative(isolate, name, source_code,
Ben Murdoch097c5b22016-05-18 11:27:45 +01001877 arraysize(args), args, NATIVES_CODE);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001878}
1879
1880
1881bool Bootstrapper::CompileExtraBuiltin(Isolate* isolate, int index) {
1882 HandleScope scope(isolate);
1883 Vector<const char> name = ExtraNatives::GetScriptName(index);
1884 Handle<String> source_code =
1885 isolate->bootstrapper()->SourceLookup<ExtraNatives>(index);
1886 Handle<Object> global = isolate->global_object();
1887 Handle<Object> binding = isolate->extras_binding_object();
1888 Handle<Object> extras_utils = isolate->extras_utils_object();
1889 Handle<Object> args[] = {global, binding, extras_utils};
1890 return Bootstrapper::CompileNative(isolate, name, source_code,
Ben Murdoch097c5b22016-05-18 11:27:45 +01001891 arraysize(args), args, EXTENSION_CODE);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001892}
1893
1894
1895bool Bootstrapper::CompileExperimentalExtraBuiltin(Isolate* isolate,
1896 int index) {
1897 HandleScope scope(isolate);
1898 Vector<const char> name = ExperimentalExtraNatives::GetScriptName(index);
1899 Handle<String> source_code =
1900 isolate->bootstrapper()->SourceLookup<ExperimentalExtraNatives>(index);
1901 Handle<Object> global = isolate->global_object();
1902 Handle<Object> binding = isolate->extras_binding_object();
1903 Handle<Object> extras_utils = isolate->extras_utils_object();
1904 Handle<Object> args[] = {global, binding, extras_utils};
1905 return Bootstrapper::CompileNative(isolate, name, source_code,
Ben Murdoch097c5b22016-05-18 11:27:45 +01001906 arraysize(args), args, EXTENSION_CODE);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001907}
1908
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001909bool Bootstrapper::CompileNative(Isolate* isolate, Vector<const char> name,
1910 Handle<String> source, int argc,
Ben Murdoch097c5b22016-05-18 11:27:45 +01001911 Handle<Object> argv[],
1912 NativesFlag natives_flag) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001913 SuppressDebug compiling_natives(isolate->debug());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001914 // During genesis, the boilerplate for stack overflow won't work until the
1915 // environment has been at least partially initialized. Add a stack check
1916 // before entering JS code to catch overflow early.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001917 StackLimitCheck check(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001918 if (check.JsHasOverflowed(1 * KB)) {
1919 isolate->StackOverflow();
1920 return false;
1921 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001922
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001923 Handle<Context> context(isolate->context());
1924
1925 Handle<String> script_name =
1926 isolate->factory()->NewStringFromUtf8(name).ToHandleChecked();
1927 Handle<SharedFunctionInfo> function_info = Compiler::CompileScript(
1928 source, script_name, 0, 0, ScriptOriginOptions(), Handle<Object>(),
Ben Murdoch097c5b22016-05-18 11:27:45 +01001929 context, NULL, NULL, ScriptCompiler::kNoCompileOptions, natives_flag,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001930 false);
1931 if (function_info.is_null()) return false;
1932
1933 DCHECK(context->IsNativeContext());
1934
1935 Handle<JSFunction> fun =
1936 isolate->factory()->NewFunctionFromSharedFunctionInfo(function_info,
1937 context);
1938 Handle<Object> receiver = isolate->factory()->undefined_value();
1939
1940 // For non-extension scripts, run script to get the function wrapper.
1941 Handle<Object> wrapper;
1942 if (!Execution::Call(isolate, fun, receiver, 0, NULL).ToHandle(&wrapper)) {
1943 return false;
1944 }
1945 // Then run the function wrapper.
1946 return !Execution::Call(isolate, Handle<JSFunction>::cast(wrapper), receiver,
1947 argc, argv).is_null();
Steve Blocka7e24c12009-10-30 11:49:00 +00001948}
1949
1950
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001951bool Genesis::CallUtilsFunction(Isolate* isolate, const char* name) {
1952 Handle<JSObject> utils =
1953 Handle<JSObject>::cast(isolate->natives_utils_object());
1954 Handle<String> name_string =
1955 isolate->factory()->NewStringFromAsciiChecked(name);
1956 Handle<Object> fun = JSObject::GetDataProperty(utils, name_string);
1957 Handle<Object> receiver = isolate->factory()->undefined_value();
1958 Handle<Object> args[] = {utils};
1959 return !Execution::Call(isolate, fun, receiver, 1, args).is_null();
1960}
1961
1962
1963bool Genesis::CompileExtension(Isolate* isolate, v8::Extension* extension) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001964 Factory* factory = isolate->factory();
1965 HandleScope scope(isolate);
Steve Block6ded16b2010-05-10 14:33:55 +01001966 Handle<SharedFunctionInfo> function_info;
Steve Blocka7e24c12009-10-30 11:49:00 +00001967
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001968 Handle<String> source =
1969 isolate->factory()
1970 ->NewExternalStringFromOneByte(extension->source())
1971 .ToHandleChecked();
1972 DCHECK(source->IsOneByteRepresentation());
1973
Steve Blocka7e24c12009-10-30 11:49:00 +00001974 // If we can't find the function in the cache, we compile a new
1975 // function and insert it into the cache.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001976 Vector<const char> name = CStrVector(extension->name());
1977 SourceCodeCache* cache = isolate->bootstrapper()->extensions_cache();
1978 Handle<Context> context(isolate->context());
1979 DCHECK(context->IsNativeContext());
1980
1981 if (!cache->Lookup(name, &function_info)) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001982 Handle<String> script_name =
1983 factory->NewStringFromUtf8(name).ToHandleChecked();
1984 function_info = Compiler::CompileScript(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001985 source, script_name, 0, 0, ScriptOriginOptions(), Handle<Object>(),
1986 context, extension, NULL, ScriptCompiler::kNoCompileOptions,
Ben Murdoch097c5b22016-05-18 11:27:45 +01001987 EXTENSION_CODE, false);
Steve Block6ded16b2010-05-10 14:33:55 +01001988 if (function_info.is_null()) return false;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001989 cache->Add(name, function_info);
Steve Blocka7e24c12009-10-30 11:49:00 +00001990 }
1991
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001992 // Set up the function context. Conceptually, we should clone the
Steve Blocka7e24c12009-10-30 11:49:00 +00001993 // function before overwriting the context but since we're in a
1994 // single-threaded environment it is not strictly necessary.
Steve Blocka7e24c12009-10-30 11:49:00 +00001995 Handle<JSFunction> fun =
Steve Block44f0eee2011-05-26 01:26:41 +01001996 factory->NewFunctionFromSharedFunctionInfo(function_info, context);
Steve Blocka7e24c12009-10-30 11:49:00 +00001997
Leon Clarke4515c472010-02-03 11:58:03 +00001998 // Call function using either the runtime object or the global
Steve Blocka7e24c12009-10-30 11:49:00 +00001999 // object as the receiver. Provide no parameters.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002000 Handle<Object> receiver = isolate->global_object();
2001 return !Execution::Call(isolate, fun, receiver, 0, NULL).is_null();
Steve Blocka7e24c12009-10-30 11:49:00 +00002002}
2003
2004
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002005static Handle<JSObject> ResolveBuiltinIdHolder(Handle<Context> native_context,
2006 const char* holder_expr) {
2007 Isolate* isolate = native_context->GetIsolate();
2008 Factory* factory = isolate->factory();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002009 Handle<JSGlobalObject> global(native_context->global_object());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002010 const char* period_pos = strchr(holder_expr, '.');
2011 if (period_pos == NULL) {
2012 return Handle<JSObject>::cast(
2013 Object::GetPropertyOrElement(
2014 global, factory->InternalizeUtf8String(holder_expr))
2015 .ToHandleChecked());
2016 }
2017 const char* inner = period_pos + 1;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002018 DCHECK(!strchr(inner, '.'));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002019 Vector<const char> property(holder_expr,
2020 static_cast<int>(period_pos - holder_expr));
2021 Handle<String> property_string = factory->InternalizeUtf8String(property);
2022 DCHECK(!property_string.is_null());
2023 Handle<JSObject> object = Handle<JSObject>::cast(
2024 Object::GetProperty(global, property_string).ToHandleChecked());
2025 if (strcmp("prototype", inner) == 0) {
2026 Handle<JSFunction> function = Handle<JSFunction>::cast(object);
2027 return Handle<JSObject>(JSObject::cast(function->prototype()));
2028 }
2029 Handle<String> inner_string = factory->InternalizeUtf8String(inner);
2030 DCHECK(!inner_string.is_null());
2031 Handle<Object> value =
2032 Object::GetProperty(object, inner_string).ToHandleChecked();
2033 return Handle<JSObject>::cast(value);
2034}
Steve Blocka7e24c12009-10-30 11:49:00 +00002035
Ben Murdoch097c5b22016-05-18 11:27:45 +01002036void Genesis::ConfigureUtilsObject(GlobalContextType context_type) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002037 switch (context_type) {
2038 // We still need the utils object to find debug functions.
2039 case DEBUG_CONTEXT:
2040 return;
2041 // Expose the natives in global if a valid name for it is specified.
2042 case FULL_CONTEXT: {
2043 // We still need the utils object after deserialization.
2044 if (isolate()->serializer_enabled()) return;
2045 if (FLAG_expose_natives_as == NULL) break;
2046 if (strlen(FLAG_expose_natives_as) == 0) break;
2047 HandleScope scope(isolate());
2048 Handle<String> natives_key =
2049 factory()->InternalizeUtf8String(FLAG_expose_natives_as);
2050 uint32_t dummy_index;
2051 if (natives_key->AsArrayIndex(&dummy_index)) break;
2052 Handle<Object> utils = isolate()->natives_utils_object();
2053 Handle<JSObject> global = isolate()->global_object();
2054 JSObject::AddProperty(global, natives_key, utils, DONT_ENUM);
2055 break;
2056 }
2057 case THIN_CONTEXT:
2058 break;
Ben Murdoch257744e2011-11-30 15:57:28 +00002059 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002060
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002061 // The utils object can be removed for cases that reach this point.
2062 native_context()->set_natives_utils_object(heap()->undefined_value());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002063}
2064
2065
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002066void Bootstrapper::ExportFromRuntime(Isolate* isolate,
2067 Handle<JSObject> container) {
2068 Factory* factory = isolate->factory();
2069 HandleScope scope(isolate);
2070 Handle<Context> native_context = isolate->native_context();
2071#define EXPORT_PRIVATE_SYMBOL(NAME) \
2072 Handle<String> NAME##_name = factory->NewStringFromAsciiChecked(#NAME); \
2073 JSObject::AddProperty(container, NAME##_name, factory->NAME(), NONE);
2074 PRIVATE_SYMBOL_LIST(EXPORT_PRIVATE_SYMBOL)
2075#undef EXPORT_PRIVATE_SYMBOL
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002076
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002077#define EXPORT_PUBLIC_SYMBOL(NAME, DESCRIPTION) \
2078 Handle<String> NAME##_name = factory->NewStringFromAsciiChecked(#NAME); \
2079 JSObject::AddProperty(container, NAME##_name, factory->NAME(), NONE);
2080 PUBLIC_SYMBOL_LIST(EXPORT_PUBLIC_SYMBOL)
2081 WELL_KNOWN_SYMBOL_LIST(EXPORT_PUBLIC_SYMBOL)
2082#undef EXPORT_PUBLIC_SYMBOL
2083
2084 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002085 Handle<JSFunction> to_string = InstallFunction(
2086 container, "object_to_string", JS_OBJECT_TYPE, JSObject::kHeaderSize,
2087 MaybeHandle<JSObject>(), Builtins::kObjectProtoToString);
2088 to_string->shared()->DontAdaptArguments();
2089 to_string->shared()->set_length(0);
2090 native_context->set_object_to_string(*to_string);
2091 }
2092
2093 Handle<JSObject> iterator_prototype;
2094
2095 {
2096 PrototypeIterator iter(native_context->generator_object_prototype_map());
2097 iter.Advance(); // Advance to the prototype of generator_object_prototype.
2098 iterator_prototype = Handle<JSObject>(iter.GetCurrent<JSObject>());
2099
2100 JSObject::AddProperty(container,
2101 factory->InternalizeUtf8String("IteratorPrototype"),
2102 iterator_prototype, NONE);
2103 }
2104
2105 {
2106 PrototypeIterator iter(native_context->sloppy_generator_function_map());
2107 Handle<JSObject> generator_function_prototype(iter.GetCurrent<JSObject>());
2108
2109 JSObject::AddProperty(
2110 container, factory->InternalizeUtf8String("GeneratorFunctionPrototype"),
2111 generator_function_prototype, NONE);
2112
2113 static const bool kUseStrictFunctionMap = true;
2114 Handle<JSFunction> generator_function_function = InstallFunction(
2115 container, "GeneratorFunction", JS_FUNCTION_TYPE, JSFunction::kSize,
2116 generator_function_prototype, Builtins::kGeneratorFunctionConstructor,
2117 kUseStrictFunctionMap);
2118 generator_function_function->set_prototype_or_initial_map(
2119 native_context->sloppy_generator_function_map());
2120 generator_function_function->shared()->DontAdaptArguments();
2121 generator_function_function->shared()->set_construct_stub(
2122 *isolate->builtins()->GeneratorFunctionConstructor());
2123 generator_function_function->shared()->set_length(1);
2124 InstallWithIntrinsicDefaultProto(
2125 isolate, generator_function_function,
2126 Context::GENERATOR_FUNCTION_FUNCTION_INDEX);
2127
2128 native_context->sloppy_generator_function_map()->SetConstructor(
2129 *generator_function_function);
2130 native_context->strict_generator_function_map()->SetConstructor(
2131 *generator_function_function);
2132 native_context->strong_generator_function_map()->SetConstructor(
2133 *generator_function_function);
2134 }
2135
2136 { // -- S e t I t e r a t o r
2137 Handle<JSObject> set_iterator_prototype =
2138 isolate->factory()->NewJSObject(isolate->object_function(), TENURED);
2139 SetObjectPrototype(set_iterator_prototype, iterator_prototype);
2140 Handle<JSFunction> set_iterator_function = InstallFunction(
2141 container, "SetIterator", JS_SET_ITERATOR_TYPE, JSSetIterator::kSize,
2142 set_iterator_prototype, Builtins::kIllegal);
2143 native_context->set_set_iterator_map(set_iterator_function->initial_map());
2144 }
2145
2146 { // -- M a p I t e r a t o r
2147 Handle<JSObject> map_iterator_prototype =
2148 isolate->factory()->NewJSObject(isolate->object_function(), TENURED);
2149 SetObjectPrototype(map_iterator_prototype, iterator_prototype);
2150 Handle<JSFunction> map_iterator_function = InstallFunction(
2151 container, "MapIterator", JS_MAP_ITERATOR_TYPE, JSMapIterator::kSize,
2152 map_iterator_prototype, Builtins::kIllegal);
2153 native_context->set_map_iterator_map(map_iterator_function->initial_map());
2154 }
2155
2156 { // -- S c r i p t
2157 // Builtin functions for Script.
2158 Handle<JSFunction> script_fun = InstallFunction(
2159 container, "Script", JS_VALUE_TYPE, JSValue::kSize,
2160 isolate->initial_object_prototype(), Builtins::kIllegal);
2161 Handle<JSObject> prototype =
2162 factory->NewJSObject(isolate->object_function(), TENURED);
2163 Accessors::FunctionSetPrototype(script_fun, prototype).Assert();
2164 native_context->set_script_function(*script_fun);
2165
2166 Handle<Map> script_map = Handle<Map>(script_fun->initial_map());
2167 Map::EnsureDescriptorSlack(script_map, 15);
2168
2169 PropertyAttributes attribs =
2170 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
2171
2172 Handle<AccessorInfo> script_column =
2173 Accessors::ScriptColumnOffsetInfo(isolate, attribs);
2174 {
2175 AccessorConstantDescriptor d(
2176 Handle<Name>(Name::cast(script_column->name())), script_column,
2177 attribs);
2178 script_map->AppendDescriptor(&d);
2179 }
2180
2181 Handle<AccessorInfo> script_id = Accessors::ScriptIdInfo(isolate, attribs);
2182 {
2183 AccessorConstantDescriptor d(Handle<Name>(Name::cast(script_id->name())),
2184 script_id, attribs);
2185 script_map->AppendDescriptor(&d);
2186 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002187
2188
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002189 Handle<AccessorInfo> script_name =
2190 Accessors::ScriptNameInfo(isolate, attribs);
2191 {
2192 AccessorConstantDescriptor d(
2193 Handle<Name>(Name::cast(script_name->name())), script_name, attribs);
2194 script_map->AppendDescriptor(&d);
2195 }
2196
2197 Handle<AccessorInfo> script_line =
2198 Accessors::ScriptLineOffsetInfo(isolate, attribs);
2199 {
2200 AccessorConstantDescriptor d(
2201 Handle<Name>(Name::cast(script_line->name())), script_line, attribs);
2202 script_map->AppendDescriptor(&d);
2203 }
2204
2205 Handle<AccessorInfo> script_source =
2206 Accessors::ScriptSourceInfo(isolate, attribs);
2207 {
2208 AccessorConstantDescriptor d(
2209 Handle<Name>(Name::cast(script_source->name())), script_source,
2210 attribs);
2211 script_map->AppendDescriptor(&d);
2212 }
2213
2214 Handle<AccessorInfo> script_type =
2215 Accessors::ScriptTypeInfo(isolate, attribs);
2216 {
2217 AccessorConstantDescriptor d(
2218 Handle<Name>(Name::cast(script_type->name())), script_type, attribs);
2219 script_map->AppendDescriptor(&d);
2220 }
2221
2222 Handle<AccessorInfo> script_compilation_type =
2223 Accessors::ScriptCompilationTypeInfo(isolate, attribs);
2224 {
2225 AccessorConstantDescriptor d(
2226 Handle<Name>(Name::cast(script_compilation_type->name())),
2227 script_compilation_type, attribs);
2228 script_map->AppendDescriptor(&d);
2229 }
2230
2231 Handle<AccessorInfo> script_line_ends =
2232 Accessors::ScriptLineEndsInfo(isolate, attribs);
2233 {
2234 AccessorConstantDescriptor d(
2235 Handle<Name>(Name::cast(script_line_ends->name())), script_line_ends,
2236 attribs);
2237 script_map->AppendDescriptor(&d);
2238 }
2239
2240 Handle<AccessorInfo> script_context_data =
2241 Accessors::ScriptContextDataInfo(isolate, attribs);
2242 {
2243 AccessorConstantDescriptor d(
2244 Handle<Name>(Name::cast(script_context_data->name())),
2245 script_context_data, attribs);
2246 script_map->AppendDescriptor(&d);
2247 }
2248
2249 Handle<AccessorInfo> script_eval_from_script =
2250 Accessors::ScriptEvalFromScriptInfo(isolate, attribs);
2251 {
2252 AccessorConstantDescriptor d(
2253 Handle<Name>(Name::cast(script_eval_from_script->name())),
2254 script_eval_from_script, attribs);
2255 script_map->AppendDescriptor(&d);
2256 }
2257
2258 Handle<AccessorInfo> script_eval_from_script_position =
2259 Accessors::ScriptEvalFromScriptPositionInfo(isolate, attribs);
2260 {
2261 AccessorConstantDescriptor d(
2262 Handle<Name>(Name::cast(script_eval_from_script_position->name())),
2263 script_eval_from_script_position, attribs);
2264 script_map->AppendDescriptor(&d);
2265 }
2266
2267 Handle<AccessorInfo> script_eval_from_function_name =
2268 Accessors::ScriptEvalFromFunctionNameInfo(isolate, attribs);
2269 {
2270 AccessorConstantDescriptor d(
2271 Handle<Name>(Name::cast(script_eval_from_function_name->name())),
2272 script_eval_from_function_name, attribs);
2273 script_map->AppendDescriptor(&d);
2274 }
2275
2276 Handle<AccessorInfo> script_source_url =
2277 Accessors::ScriptSourceUrlInfo(isolate, attribs);
2278 {
2279 AccessorConstantDescriptor d(
2280 Handle<Name>(Name::cast(script_source_url->name())),
2281 script_source_url, attribs);
2282 script_map->AppendDescriptor(&d);
2283 }
2284
2285 Handle<AccessorInfo> script_source_mapping_url =
2286 Accessors::ScriptSourceMappingUrlInfo(isolate, attribs);
2287 {
2288 AccessorConstantDescriptor d(
2289 Handle<Name>(Name::cast(script_source_mapping_url->name())),
2290 script_source_mapping_url, attribs);
2291 script_map->AppendDescriptor(&d);
2292 }
2293
2294 Handle<AccessorInfo> script_is_embedder_debug_script =
2295 Accessors::ScriptIsEmbedderDebugScriptInfo(isolate, attribs);
2296 {
2297 AccessorConstantDescriptor d(
2298 Handle<Name>(Name::cast(script_is_embedder_debug_script->name())),
2299 script_is_embedder_debug_script, attribs);
2300 script_map->AppendDescriptor(&d);
2301 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002302 }
Ben Murdoch257744e2011-11-30 15:57:28 +00002303}
2304
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002305
2306void Bootstrapper::ExportExperimentalFromRuntime(Isolate* isolate,
2307 Handle<JSObject> container) {
2308 HandleScope scope(isolate);
2309
2310#define INITIALIZE_FLAG(FLAG) \
2311 { \
2312 Handle<String> name = \
2313 isolate->factory()->NewStringFromAsciiChecked(#FLAG); \
2314 JSObject::AddProperty(container, name, \
2315 isolate->factory()->ToBoolean(FLAG), NONE); \
2316 }
2317
2318 INITIALIZE_FLAG(FLAG_harmony_tostring)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002319 INITIALIZE_FLAG(FLAG_harmony_species)
2320
2321#undef INITIALIZE_FLAG
2322}
2323
Steve Blocka7e24c12009-10-30 11:49:00 +00002324
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002325#define EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(id) \
2326 void Genesis::InitializeGlobal_##id() {}
2327
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002328EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_modules)
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002329EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_sloppy)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002330EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_sloppy_function)
2331EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_sloppy_let)
2332EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_default_parameters)
2333EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_destructuring_bind)
2334EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_destructuring_assignment)
2335EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_object_observe)
2336EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_regexps)
2337EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_unicode_regexps)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002338EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_do_expressions)
Ben Murdoch097c5b22016-05-18 11:27:45 +01002339EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_iterator_close)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002340EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_regexp_lookbehind)
Ben Murdoch097c5b22016-05-18 11:27:45 +01002341EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_regexp_property)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002342EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_function_name)
Ben Murdoch097c5b22016-05-18 11:27:45 +01002343EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_function_sent)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002344EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(promise_extra)
Ben Murdoch097c5b22016-05-18 11:27:45 +01002345EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_tailcalls)
2346EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_instanceof)
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002347
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002348void InstallPublicSymbol(Factory* factory, Handle<Context> native_context,
2349 const char* name, Handle<Symbol> value) {
2350 Handle<JSGlobalObject> global(
2351 JSGlobalObject::cast(native_context->global_object()));
2352 Handle<String> symbol_string = factory->InternalizeUtf8String("Symbol");
2353 Handle<JSObject> symbol = Handle<JSObject>::cast(
2354 JSObject::GetProperty(global, symbol_string).ToHandleChecked());
2355 Handle<String> name_string = factory->InternalizeUtf8String(name);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002356 PropertyAttributes attributes =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002357 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
2358 JSObject::AddProperty(symbol, name_string, value, attributes);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002359}
2360
Steve Blocka7e24c12009-10-30 11:49:00 +00002361
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002362void Genesis::InitializeGlobal_harmony_tostring() {
2363 if (!FLAG_harmony_tostring) return;
2364 InstallPublicSymbol(factory(), native_context(), "toStringTag",
2365 factory()->to_string_tag_symbol());
2366}
2367
2368
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002369void Genesis::InitializeGlobal_harmony_regexp_subclass() {
2370 if (!FLAG_harmony_regexp_subclass) return;
2371 InstallPublicSymbol(factory(), native_context(), "match",
2372 factory()->match_symbol());
2373 InstallPublicSymbol(factory(), native_context(), "replace",
2374 factory()->replace_symbol());
2375 InstallPublicSymbol(factory(), native_context(), "search",
2376 factory()->search_symbol());
2377 InstallPublicSymbol(factory(), native_context(), "split",
2378 factory()->split_symbol());
2379}
2380
2381
2382void Genesis::InitializeGlobal_harmony_reflect() {
2383 Factory* factory = isolate()->factory();
2384
2385 // We currently use some of the Reflect functions internally, even when
2386 // the --harmony-reflect flag is not given.
2387
2388 Handle<JSFunction> define_property =
2389 SimpleCreateFunction(isolate(), factory->defineProperty_string(),
2390 Builtins::kReflectDefineProperty, 3, true);
2391 native_context()->set_reflect_define_property(*define_property);
2392
2393 Handle<JSFunction> delete_property =
2394 SimpleCreateFunction(isolate(), factory->deleteProperty_string(),
2395 Builtins::kReflectDeleteProperty, 2, true);
2396 native_context()->set_reflect_delete_property(*delete_property);
2397
Ben Murdoch097c5b22016-05-18 11:27:45 +01002398 Handle<JSFunction> apply = SimpleCreateFunction(
2399 isolate(), factory->apply_string(), Builtins::kReflectApply, 3, false);
2400 native_context()->set_reflect_apply(*apply);
2401
2402 Handle<JSFunction> construct =
2403 SimpleCreateFunction(isolate(), factory->construct_string(),
2404 Builtins::kReflectConstruct, 2, false);
2405 native_context()->set_reflect_construct(*construct);
2406
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002407 if (!FLAG_harmony_reflect) return;
2408
2409 Handle<JSGlobalObject> global(JSGlobalObject::cast(
2410 native_context()->global_object()));
2411 Handle<String> reflect_string = factory->NewStringFromStaticChars("Reflect");
2412 Handle<JSObject> reflect =
2413 factory->NewJSObject(isolate()->object_function(), TENURED);
2414 JSObject::AddProperty(global, reflect_string, reflect, DONT_ENUM);
2415
2416 InstallFunction(reflect, define_property, factory->defineProperty_string());
2417 InstallFunction(reflect, delete_property, factory->deleteProperty_string());
Ben Murdoch097c5b22016-05-18 11:27:45 +01002418 InstallFunction(reflect, apply, factory->apply_string());
2419 InstallFunction(reflect, construct, factory->construct_string());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002420
2421 SimpleInstallFunction(reflect, factory->get_string(),
2422 Builtins::kReflectGet, 2, false);
2423 SimpleInstallFunction(reflect, factory->getOwnPropertyDescriptor_string(),
2424 Builtins::kReflectGetOwnPropertyDescriptor, 2, true);
2425 SimpleInstallFunction(reflect, factory->getPrototypeOf_string(),
2426 Builtins::kReflectGetPrototypeOf, 1, true);
2427 SimpleInstallFunction(reflect, factory->has_string(),
2428 Builtins::kReflectHas, 2, true);
2429 SimpleInstallFunction(reflect, factory->isExtensible_string(),
2430 Builtins::kReflectIsExtensible, 1, true);
2431 SimpleInstallFunction(reflect, factory->ownKeys_string(),
2432 Builtins::kReflectOwnKeys, 1, true);
2433 SimpleInstallFunction(reflect, factory->preventExtensions_string(),
2434 Builtins::kReflectPreventExtensions, 1, true);
2435 SimpleInstallFunction(reflect, factory->set_string(),
2436 Builtins::kReflectSet, 3, false);
2437 SimpleInstallFunction(reflect, factory->setPrototypeOf_string(),
2438 Builtins::kReflectSetPrototypeOf, 2, true);
2439}
2440
2441
2442void Genesis::InitializeGlobal_harmony_sharedarraybuffer() {
2443 if (!FLAG_harmony_sharedarraybuffer) return;
2444
2445 Handle<JSGlobalObject> global(native_context()->global_object());
2446 Handle<JSFunction> shared_array_buffer_fun =
2447 InstallArrayBuffer(global, "SharedArrayBuffer");
2448 native_context()->set_shared_array_buffer_fun(*shared_array_buffer_fun);
2449}
2450
2451
2452void Genesis::InitializeGlobal_harmony_simd() {
2453 if (!FLAG_harmony_simd) return;
2454
2455 Handle<JSGlobalObject> global(
2456 JSGlobalObject::cast(native_context()->global_object()));
2457 Isolate* isolate = global->GetIsolate();
2458 Factory* factory = isolate->factory();
2459
2460 Handle<String> name = factory->InternalizeUtf8String("SIMD");
2461 Handle<JSFunction> cons = factory->NewFunction(name);
2462 JSFunction::SetInstancePrototype(
2463 cons,
2464 Handle<Object>(native_context()->initial_object_prototype(), isolate));
2465 cons->shared()->set_instance_class_name(*name);
2466 Handle<JSObject> simd_object = factory->NewJSObject(cons, TENURED);
2467 DCHECK(simd_object->IsJSObject());
2468 JSObject::AddProperty(global, name, simd_object, DONT_ENUM);
2469
2470// Install SIMD type functions. Set the instance class names since
2471// InstallFunction only does this when we install on the JSGlobalObject.
2472#define SIMD128_INSTALL_FUNCTION(TYPE, Type, type, lane_count, lane_type) \
2473 Handle<JSFunction> type##_function = InstallFunction( \
2474 simd_object, #Type, JS_VALUE_TYPE, JSValue::kSize, \
2475 isolate->initial_object_prototype(), Builtins::kIllegal); \
2476 native_context()->set_##type##_function(*type##_function); \
2477 type##_function->shared()->set_instance_class_name(*factory->Type##_string());
2478 SIMD128_TYPES(SIMD128_INSTALL_FUNCTION)
2479#undef SIMD128_INSTALL_FUNCTION
2480}
2481
2482
Ben Murdoch097c5b22016-05-18 11:27:45 +01002483void Genesis::InitializeGlobal_harmony_object_values_entries() {
2484 if (!FLAG_harmony_object_values_entries) return;
2485
2486 Handle<JSGlobalObject> global(
2487 JSGlobalObject::cast(native_context()->global_object()));
2488 Isolate* isolate = global->GetIsolate();
2489 Factory* factory = isolate->factory();
2490
2491 Handle<JSFunction> object_function = isolate->object_function();
2492 SimpleInstallFunction(object_function, factory->entries_string(),
2493 Builtins::kObjectEntries, 1, false);
2494 SimpleInstallFunction(object_function, factory->values_string(),
2495 Builtins::kObjectValues, 1, false);
2496}
2497
2498void Genesis::InitializeGlobal_harmony_object_own_property_descriptors() {
2499 if (!FLAG_harmony_object_own_property_descriptors) return;
2500
2501 Handle<JSGlobalObject> global(
2502 JSGlobalObject::cast(native_context()->global_object()));
2503 Isolate* isolate = global->GetIsolate();
2504 Factory* factory = isolate->factory();
2505
2506 Handle<JSFunction> object_function = isolate->object_function();
2507 SimpleInstallFunction(object_function,
2508 factory->getOwnPropertyDescriptors_string(),
2509 Builtins::kObjectGetOwnPropertyDescriptors, 1, false);
2510}
2511
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002512void Genesis::InstallJSProxyMaps() {
2513 // Allocate the different maps for all Proxy types.
2514 // Next to the default proxy, we need maps indicating callable and
2515 // constructable proxies.
2516
2517 Handle<Map> proxy_function_map =
2518 Map::Copy(isolate()->sloppy_function_without_prototype_map(), "Proxy");
Ben Murdoch097c5b22016-05-18 11:27:45 +01002519 proxy_function_map->set_is_constructor(true);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002520 native_context()->set_proxy_function_map(*proxy_function_map);
2521
2522 Handle<Map> proxy_map =
2523 factory()->NewMap(JS_PROXY_TYPE, JSProxy::kSize, FAST_ELEMENTS);
2524 proxy_map->set_dictionary_map(true);
2525 native_context()->set_proxy_map(*proxy_map);
2526
2527 Handle<Map> proxy_callable_map = Map::Copy(proxy_map, "callable Proxy");
2528 proxy_callable_map->set_is_callable();
2529 native_context()->set_proxy_callable_map(*proxy_callable_map);
2530 proxy_callable_map->SetConstructor(native_context()->function_function());
2531
2532 Handle<Map> proxy_constructor_map =
2533 Map::Copy(proxy_callable_map, "constructor Proxy");
Ben Murdoch097c5b22016-05-18 11:27:45 +01002534 proxy_constructor_map->set_is_constructor(true);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002535 native_context()->set_proxy_constructor_map(*proxy_constructor_map);
2536}
2537
2538
2539void Genesis::InitializeGlobal_harmony_proxies() {
2540 if (!FLAG_harmony_proxies) return;
2541 Handle<JSGlobalObject> global(
2542 JSGlobalObject::cast(native_context()->global_object()));
2543 Isolate* isolate = global->GetIsolate();
2544 Factory* factory = isolate->factory();
2545
2546 InstallJSProxyMaps();
2547
2548 // Create the Proxy object.
2549 Handle<String> name = factory->Proxy_string();
2550 Handle<Code> code(isolate->builtins()->ProxyConstructor());
2551
Ben Murdoch097c5b22016-05-18 11:27:45 +01002552 Handle<JSFunction> proxy_function =
2553 factory->NewFunction(isolate->proxy_function_map(),
2554 factory->Proxy_string(), MaybeHandle<Code>(code));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002555
2556 JSFunction::SetInitialMap(proxy_function,
2557 Handle<Map>(native_context()->proxy_map(), isolate),
2558 factory->null_value());
2559
2560 proxy_function->shared()->set_construct_stub(
2561 *isolate->builtins()->ProxyConstructor_ConstructStub());
2562 proxy_function->shared()->set_internal_formal_parameter_count(2);
2563 proxy_function->shared()->set_length(2);
2564
2565 native_context()->set_proxy_function(*proxy_function);
2566 InstallFunction(global, name, proxy_function, factory->Object_string());
2567}
2568
2569
2570Handle<JSFunction> Genesis::InstallArrayBuffer(Handle<JSObject> target,
2571 const char* name) {
2572 // Setup the {prototype} with the given {name} for @@toStringTag.
2573 Handle<JSObject> prototype =
2574 factory()->NewJSObject(isolate()->object_function(), TENURED);
2575 JSObject::AddProperty(prototype, factory()->to_string_tag_symbol(),
2576 factory()->NewStringFromAsciiChecked(name),
2577 static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
2578
2579 // Allocate the constructor with the given {prototype}.
2580 Handle<JSFunction> array_buffer_fun =
2581 InstallFunction(target, name, JS_ARRAY_BUFFER_TYPE,
2582 JSArrayBuffer::kSizeWithInternalFields, prototype,
2583 Builtins::kArrayBufferConstructor);
2584 array_buffer_fun->shared()->set_construct_stub(
2585 *isolate()->builtins()->ArrayBufferConstructor_ConstructStub());
2586 array_buffer_fun->shared()->DontAdaptArguments();
2587 array_buffer_fun->shared()->set_length(1);
2588
2589 // Install the "constructor" property on the {prototype}.
2590 JSObject::AddProperty(prototype, factory()->constructor_string(),
2591 array_buffer_fun, DONT_ENUM);
2592
2593 SimpleInstallFunction(array_buffer_fun, factory()->isView_string(),
2594 Builtins::kArrayBufferIsView, 1, true);
2595
2596 return array_buffer_fun;
2597}
2598
2599
2600void Genesis::InitializeGlobal_harmony_species() {
2601 if (!FLAG_harmony_species) return;
2602 InstallPublicSymbol(factory(), native_context(), "species",
2603 factory()->species_symbol());
2604}
2605
2606
2607Handle<JSFunction> Genesis::InstallInternalArray(Handle<JSObject> target,
2608 const char* name,
2609 ElementsKind elements_kind) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002610 // --- I n t e r n a l A r r a y ---
2611 // An array constructor on the builtins object that works like
2612 // the public Array constructor, except that its prototype
2613 // doesn't inherit from Object.prototype.
2614 // To be used only for internal work by builtins. Instances
2615 // must not be leaked to user code.
2616 Handle<JSObject> prototype =
2617 factory()->NewJSObject(isolate()->object_function(), TENURED);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002618 Handle<JSFunction> array_function =
2619 InstallFunction(target, name, JS_ARRAY_TYPE, JSArray::kSize, prototype,
2620 Builtins::kInternalArrayCode);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002621
2622 InternalArrayConstructorStub internal_array_constructor_stub(isolate());
2623 Handle<Code> code = internal_array_constructor_stub.GetCode();
2624 array_function->shared()->set_construct_stub(*code);
2625 array_function->shared()->DontAdaptArguments();
2626
2627 Handle<Map> original_map(array_function->initial_map());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002628 Handle<Map> initial_map = Map::Copy(original_map, "InternalArray");
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002629 initial_map->set_elements_kind(elements_kind);
2630 JSFunction::SetInitialMap(array_function, initial_map, prototype);
2631
2632 // Make "length" magic on instances.
2633 Map::EnsureDescriptorSlack(initial_map, 1);
2634
2635 PropertyAttributes attribs = static_cast<PropertyAttributes>(
2636 DONT_ENUM | DONT_DELETE);
2637
2638 Handle<AccessorInfo> array_length =
2639 Accessors::ArrayLengthInfo(isolate(), attribs);
2640 { // Add length.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002641 AccessorConstantDescriptor d(Handle<Name>(Name::cast(array_length->name())),
2642 array_length, attribs);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002643 initial_map->AppendDescriptor(&d);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002644 }
2645
2646 return array_function;
2647}
2648
Ben Murdoch097c5b22016-05-18 11:27:45 +01002649bool Genesis::InstallNatives(GlobalContextType context_type) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002650 HandleScope scope(isolate());
Steve Blocka7e24c12009-10-30 11:49:00 +00002651
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002652 // Set up the utils object as shared container between native scripts.
2653 Handle<JSObject> utils = factory()->NewJSObject(isolate()->object_function());
2654 JSObject::NormalizeProperties(utils, CLEAR_INOBJECT_PROPERTIES, 16,
2655 "utils container for native scripts");
2656 native_context()->set_natives_utils_object(*utils);
Steve Blocka7e24c12009-10-30 11:49:00 +00002657
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002658 // Set up the extras utils object as a shared container between native
2659 // scripts and extras. (Extras consume things added there by native scripts.)
2660 Handle<JSObject> extras_utils =
2661 factory()->NewJSObject(isolate()->object_function());
2662 native_context()->set_extras_utils_object(*extras_utils);
Steve Blocka7e24c12009-10-30 11:49:00 +00002663
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002664 InstallInternalArray(extras_utils, "InternalPackedArray", FAST_ELEMENTS);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002665
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002666 int builtin_index = Natives::GetDebuggerCount();
2667 // Only run prologue.js and runtime.js at this point.
2668 DCHECK_EQ(builtin_index, Natives::GetIndex("prologue"));
2669 if (!Bootstrapper::CompileBuiltin(isolate(), builtin_index++)) return false;
2670 DCHECK_EQ(builtin_index, Natives::GetIndex("runtime"));
2671 if (!Bootstrapper::CompileBuiltin(isolate(), builtin_index++)) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00002672
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002673 // A thin context is ready at this point.
2674 if (context_type == THIN_CONTEXT) return true;
Steve Blocka7e24c12009-10-30 11:49:00 +00002675
Steve Block6ded16b2010-05-10 14:33:55 +01002676 {
2677 // Builtin function for OpaqueReference -- a JSValue-based object,
2678 // that keeps its field isolated from JavaScript code. It may store
2679 // objects, that JavaScript code may not access.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002680 Handle<JSFunction> opaque_reference_fun = factory()->NewFunction(
2681 factory()->empty_string(), isolate()->builtins()->Illegal(),
2682 isolate()->initial_object_prototype(), JS_VALUE_TYPE, JSValue::kSize);
Steve Block6ded16b2010-05-10 14:33:55 +01002683 Handle<JSObject> prototype =
Ben Murdoch257744e2011-11-30 15:57:28 +00002684 factory()->NewJSObject(isolate()->object_function(), TENURED);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002685 Accessors::FunctionSetPrototype(opaque_reference_fun, prototype).Assert();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002686 native_context()->set_opaque_reference_function(*opaque_reference_fun);
Steve Block6ded16b2010-05-10 14:33:55 +01002687 }
2688
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002689 // InternalArrays should not use Smi-Only array optimizations. There are too
2690 // many places in the C++ runtime code (e.g. RegEx) that assume that
2691 // elements in InternalArrays can be set to non-Smi values without going
2692 // through a common bottleneck that would make the SMI_ONLY -> FAST_ELEMENT
2693 // transition easy to trap. Moreover, they rarely are smi-only.
2694 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002695 HandleScope scope(isolate());
2696 Handle<JSObject> utils =
2697 Handle<JSObject>::cast(isolate()->natives_utils_object());
Ben Murdoche0cee9b2011-05-25 10:26:03 +01002698 Handle<JSFunction> array_function =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002699 InstallInternalArray(utils, "InternalArray", FAST_HOLEY_ELEMENTS);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002700 native_context()->set_internal_array_function(*array_function);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002701 InstallInternalArray(utils, "InternalPackedArray", FAST_ELEMENTS);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002702 }
2703
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002704 // Run the rest of the native scripts.
2705 while (builtin_index < Natives::GetBuiltinsCount()) {
2706 if (!Bootstrapper::CompileBuiltin(isolate(), builtin_index++)) return false;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002707 }
2708
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002709 if (!CallUtilsFunction(isolate(), "PostNatives")) return false;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002710
Ben Murdoch097c5b22016-05-18 11:27:45 +01002711 auto template_instantiations_cache =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002712 ObjectHashTable::New(isolate(), ApiNatives::kInitialFunctionCacheSize,
2713 USE_CUSTOM_MINIMUM_CAPACITY);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002714 native_context()->set_template_instantiations_cache(
2715 *template_instantiations_cache);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002716
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002717 // Store the map for the %ObjectPrototype% after the natives has been compiled
2718 // and the Object function has been set up.
2719 Handle<JSFunction> object_function(native_context()->object_function());
2720 DCHECK(JSObject::cast(object_function->initial_map()->prototype())
2721 ->HasFastProperties());
2722 native_context()->set_object_function_prototype_map(
2723 HeapObject::cast(object_function->initial_map()->prototype())->map());
Ben Murdoche0cee9b2011-05-25 10:26:03 +01002724
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002725 // Store the map for the %StringPrototype% after the natives has been compiled
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002726 // and the String function has been set up.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002727 Handle<JSFunction> string_function(native_context()->string_function());
2728 DCHECK(JSObject::cast(
Iain Merrick75681382010-08-19 15:07:18 +01002729 string_function->initial_map()->prototype())->HasFastProperties());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002730 native_context()->set_string_function_prototype_map(
Iain Merrick75681382010-08-19 15:07:18 +01002731 HeapObject::cast(string_function->initial_map()->prototype())->map());
2732
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002733 // Install Global.eval.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002734 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002735 Handle<JSFunction> eval = SimpleInstallFunction(
2736 handle(native_context()->global_object()), factory()->eval_string(),
2737 Builtins::kGlobalEval, 1, false);
2738 native_context()->set_global_eval_fun(*eval);
2739 }
Steve Blocka7e24c12009-10-30 11:49:00 +00002740
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002741 // Install Array.prototype.concat
2742 {
2743 Handle<JSFunction> array_constructor(native_context()->array_function());
2744 Handle<JSObject> proto(JSObject::cast(array_constructor->prototype()));
2745 Handle<JSFunction> concat =
2746 InstallFunction(proto, "concat", JS_OBJECT_TYPE, JSObject::kHeaderSize,
2747 MaybeHandle<JSObject>(), Builtins::kArrayConcat);
Steve Blocka7e24c12009-10-30 11:49:00 +00002748
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002749 // Make sure that Array.prototype.concat appears to be compiled.
Steve Blocka7e24c12009-10-30 11:49:00 +00002750 // The code will never be called, but inline caching for call will
2751 // only work if it appears to be compiled.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002752 concat->shared()->DontAdaptArguments();
2753 DCHECK(concat->is_compiled());
Steve Blocka7e24c12009-10-30 11:49:00 +00002754 // Set the lengths for the functions to satisfy ECMA-262.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002755 concat->shared()->set_length(1);
2756 }
2757
2758 // Install InternalArray.prototype.concat
2759 {
2760 Handle<JSFunction> array_constructor(
2761 native_context()->internal_array_function());
2762 Handle<JSObject> proto(JSObject::cast(array_constructor->prototype()));
2763 Handle<JSFunction> concat =
2764 InstallFunction(proto, "concat", JS_OBJECT_TYPE, JSObject::kHeaderSize,
2765 MaybeHandle<JSObject>(), Builtins::kArrayConcat);
2766
2767 // Make sure that InternalArray.prototype.concat appears to be compiled.
2768 // The code will never be called, but inline caching for call will
2769 // only work if it appears to be compiled.
2770 concat->shared()->DontAdaptArguments();
2771 DCHECK(concat->is_compiled());
2772 // Set the lengths for the functions to satisfy ECMA-262.
2773 concat->shared()->set_length(1);
2774 }
2775
2776 // Set up the Promise constructor.
2777 {
2778 Handle<String> key = factory()->Promise_string();
2779 Handle<JSFunction> function = Handle<JSFunction>::cast(
2780 Object::GetProperty(handle(native_context()->global_object()), key)
2781 .ToHandleChecked());
2782 JSFunction::EnsureHasInitialMap(function);
2783 function->initial_map()->set_instance_type(JS_PROMISE_TYPE);
2784 function->shared()->set_construct_stub(
2785 *isolate()->builtins()->JSBuiltinsConstructStub());
2786 InstallWithIntrinsicDefaultProto(isolate(), function,
2787 Context::PROMISE_FUNCTION_INDEX);
Steve Blocka7e24c12009-10-30 11:49:00 +00002788 }
2789
Ben Murdoch42effa52011-08-19 16:40:31 +01002790 InstallBuiltinFunctionIds();
2791
Ben Murdoch097c5b22016-05-18 11:27:45 +01002792 // Create a map for accessor property descriptors (a variant of JSObject
2793 // that predefines four properties get, set, configurable and enumerable).
2794 {
2795 // AccessorPropertyDescriptor initial map.
2796 Handle<Map> map =
2797 factory()->NewMap(JS_OBJECT_TYPE, JSAccessorPropertyDescriptor::kSize);
2798 // Create the descriptor array for the property descriptor object.
2799 Map::EnsureDescriptorSlack(map, 4);
2800
2801 { // get
2802 DataDescriptor d(factory()->get_string(),
2803 JSAccessorPropertyDescriptor::kGetIndex, NONE,
2804 Representation::Tagged());
2805 map->AppendDescriptor(&d);
2806 }
2807 { // set
2808 DataDescriptor d(factory()->set_string(),
2809 JSAccessorPropertyDescriptor::kSetIndex, NONE,
2810 Representation::Tagged());
2811 map->AppendDescriptor(&d);
2812 }
2813 { // enumerable
2814 DataDescriptor d(factory()->enumerable_string(),
2815 JSAccessorPropertyDescriptor::kEnumerableIndex, NONE,
2816 Representation::Tagged());
2817 map->AppendDescriptor(&d);
2818 }
2819 { // configurable
2820 DataDescriptor d(factory()->configurable_string(),
2821 JSAccessorPropertyDescriptor::kConfigurableIndex, NONE,
2822 Representation::Tagged());
2823 map->AppendDescriptor(&d);
2824 }
2825
2826 Map::SetPrototype(map, isolate()->initial_object_prototype());
2827 map->SetConstructor(native_context()->object_function());
2828 map->SetInObjectProperties(4);
2829 map->set_unused_property_fields(0);
2830
2831 native_context()->set_accessor_property_descriptor_map(*map);
2832 }
2833
2834 // Create a map for data property descriptors (a variant of JSObject
2835 // that predefines four properties value, writable, configurable and
2836 // enumerable).
2837 {
2838 // DataPropertyDescriptor initial map.
2839 Handle<Map> map =
2840 factory()->NewMap(JS_OBJECT_TYPE, JSDataPropertyDescriptor::kSize);
2841 // Create the descriptor array for the property descriptor object.
2842 Map::EnsureDescriptorSlack(map, 4);
2843
2844 { // value
2845 DataDescriptor d(factory()->value_string(),
2846 JSDataPropertyDescriptor::kValueIndex, NONE,
2847 Representation::Tagged());
2848 map->AppendDescriptor(&d);
2849 }
2850 { // writable
2851 DataDescriptor d(factory()->writable_string(),
2852 JSDataPropertyDescriptor::kWritableIndex, NONE,
2853 Representation::Tagged());
2854 map->AppendDescriptor(&d);
2855 }
2856 { // enumerable
2857 DataDescriptor d(factory()->enumerable_string(),
2858 JSDataPropertyDescriptor::kEnumerableIndex, NONE,
2859 Representation::Tagged());
2860 map->AppendDescriptor(&d);
2861 }
2862 { // configurable
2863 DataDescriptor d(factory()->configurable_string(),
2864 JSDataPropertyDescriptor::kConfigurableIndex, NONE,
2865 Representation::Tagged());
2866 map->AppendDescriptor(&d);
2867 }
2868
2869 Map::SetPrototype(map, isolate()->initial_object_prototype());
2870 map->SetConstructor(native_context()->object_function());
2871 map->SetInObjectProperties(4);
2872 map->set_unused_property_fields(0);
2873
2874 native_context()->set_data_property_descriptor_map(*map);
2875 }
2876
Steve Block6ded16b2010-05-10 14:33:55 +01002877 // Create a constructor for RegExp results (a variant of Array that
2878 // predefines the two properties index and match).
2879 {
2880 // RegExpResult initial map.
2881
2882 // Find global.Array.prototype to inherit from.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002883 Handle<JSFunction> array_constructor(native_context()->array_function());
Steve Block6ded16b2010-05-10 14:33:55 +01002884 Handle<JSObject> array_prototype(
2885 JSObject::cast(array_constructor->instance_prototype()));
2886
2887 // Add initial map.
2888 Handle<Map> initial_map =
Ben Murdoch257744e2011-11-30 15:57:28 +00002889 factory()->NewMap(JS_ARRAY_TYPE, JSRegExpResult::kSize);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002890 initial_map->SetConstructor(*array_constructor);
Steve Block6ded16b2010-05-10 14:33:55 +01002891
2892 // Set prototype on map.
2893 initial_map->set_non_instance_prototype(false);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002894 Map::SetPrototype(initial_map, array_prototype);
Steve Block6ded16b2010-05-10 14:33:55 +01002895
2896 // Update map with length accessor from Array and add "index" and "input".
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002897 Map::EnsureDescriptorSlack(initial_map, 3);
Ben Murdoch592a9fc2012-03-05 11:04:45 +00002898
Steve Block6ded16b2010-05-10 14:33:55 +01002899 {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002900 JSFunction* array_function = native_context()->array_function();
2901 Handle<DescriptorArray> array_descriptors(
2902 array_function->initial_map()->instance_descriptors());
2903 Handle<String> length = factory()->length_string();
2904 int old = array_descriptors->SearchWithCache(
Ben Murdoch097c5b22016-05-18 11:27:45 +01002905 isolate(), *length, array_function->initial_map());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002906 DCHECK(old != DescriptorArray::kNotFound);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002907 AccessorConstantDescriptor desc(
2908 length, handle(array_descriptors->GetValue(old), isolate()),
2909 array_descriptors->GetDetails(old).attributes());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002910 initial_map->AppendDescriptor(&desc);
2911 }
2912 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002913 DataDescriptor index_field(factory()->index_string(),
2914 JSRegExpResult::kIndexIndex, NONE,
2915 Representation::Tagged());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002916 initial_map->AppendDescriptor(&index_field);
Steve Block6ded16b2010-05-10 14:33:55 +01002917 }
2918
2919 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002920 DataDescriptor input_field(factory()->input_string(),
2921 JSRegExpResult::kInputIndex, NONE,
2922 Representation::Tagged());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002923 initial_map->AppendDescriptor(&input_field);
Steve Block6ded16b2010-05-10 14:33:55 +01002924 }
Steve Block6ded16b2010-05-10 14:33:55 +01002925
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002926 initial_map->SetInObjectProperties(2);
Steve Block6ded16b2010-05-10 14:33:55 +01002927 initial_map->set_unused_property_fields(0);
Steve Block6ded16b2010-05-10 14:33:55 +01002928
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002929 native_context()->set_regexp_result_map(*initial_map);
Steve Block6ded16b2010-05-10 14:33:55 +01002930 }
2931
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002932 // Add @@iterator method to the arguments object maps.
2933 {
2934 PropertyAttributes attribs = DONT_ENUM;
2935 Handle<AccessorInfo> arguments_iterator =
2936 Accessors::ArgumentsIteratorInfo(isolate(), attribs);
2937 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002938 AccessorConstantDescriptor d(factory()->iterator_symbol(),
2939 arguments_iterator, attribs);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002940 Handle<Map> map(native_context()->sloppy_arguments_map());
2941 Map::EnsureDescriptorSlack(map, 1);
2942 map->AppendDescriptor(&d);
2943 }
2944 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002945 AccessorConstantDescriptor d(factory()->iterator_symbol(),
2946 arguments_iterator, attribs);
2947 Handle<Map> map(native_context()->fast_aliased_arguments_map());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002948 Map::EnsureDescriptorSlack(map, 1);
2949 map->AppendDescriptor(&d);
2950 }
2951 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002952 AccessorConstantDescriptor d(factory()->iterator_symbol(),
2953 arguments_iterator, attribs);
2954 Handle<Map> map(native_context()->slow_aliased_arguments_map());
2955 Map::EnsureDescriptorSlack(map, 1);
2956 map->AppendDescriptor(&d);
2957 }
2958 {
2959 AccessorConstantDescriptor d(factory()->iterator_symbol(),
2960 arguments_iterator, attribs);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002961 Handle<Map> map(native_context()->strict_arguments_map());
2962 Map::EnsureDescriptorSlack(map, 1);
2963 map->AppendDescriptor(&d);
2964 }
2965 }
2966
Steve Blocka7e24c12009-10-30 11:49:00 +00002967 return true;
2968}
2969
2970
Ben Murdoch257744e2011-11-30 15:57:28 +00002971bool Genesis::InstallExperimentalNatives() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002972 static const char* harmony_proxies_natives[] = {"native proxy.js", nullptr};
2973 static const char* harmony_modules_natives[] = {nullptr};
2974 static const char* harmony_regexps_natives[] = {"native harmony-regexp.js",
2975 nullptr};
2976 static const char* harmony_tostring_natives[] = {nullptr};
Ben Murdoch097c5b22016-05-18 11:27:45 +01002977 static const char* harmony_iterator_close_natives[] = {nullptr};
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002978 static const char* harmony_sloppy_natives[] = {nullptr};
2979 static const char* harmony_sloppy_function_natives[] = {nullptr};
2980 static const char* harmony_sloppy_let_natives[] = {nullptr};
2981 static const char* harmony_species_natives[] = {"native harmony-species.js",
2982 nullptr};
Ben Murdoch097c5b22016-05-18 11:27:45 +01002983 static const char* harmony_tailcalls_natives[] = {nullptr};
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002984 static const char* harmony_unicode_regexps_natives[] = {
2985 "native harmony-unicode-regexps.js", nullptr};
2986 static const char* harmony_default_parameters_natives[] = {nullptr};
2987 static const char* harmony_reflect_natives[] = {"native harmony-reflect.js",
2988 nullptr};
2989 static const char* harmony_destructuring_bind_natives[] = {nullptr};
2990 static const char* harmony_destructuring_assignment_natives[] = {nullptr};
2991 static const char* harmony_object_observe_natives[] = {
2992 "native harmony-object-observe.js", nullptr};
2993 static const char* harmony_sharedarraybuffer_natives[] = {
2994 "native harmony-sharedarraybuffer.js", "native harmony-atomics.js", NULL};
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002995 static const char* harmony_simd_natives[] = {"native harmony-simd.js",
2996 nullptr};
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002997 static const char* harmony_do_expressions_natives[] = {nullptr};
2998 static const char* harmony_regexp_subclass_natives[] = {nullptr};
2999 static const char* harmony_regexp_lookbehind_natives[] = {nullptr};
Ben Murdoch097c5b22016-05-18 11:27:45 +01003000 static const char* harmony_instanceof_natives[] = {nullptr};
3001 static const char* harmony_regexp_property_natives[] = {nullptr};
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003002 static const char* harmony_function_name_natives[] = {nullptr};
Ben Murdoch097c5b22016-05-18 11:27:45 +01003003 static const char* harmony_function_sent_natives[] = {nullptr};
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003004 static const char* promise_extra_natives[] = {"native promise-extra.js",
3005 nullptr};
Ben Murdoch097c5b22016-05-18 11:27:45 +01003006 static const char* harmony_object_values_entries_natives[] = {nullptr};
3007 static const char* harmony_object_own_property_descriptors_natives[] = {
3008 nullptr};
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003009
Ben Murdoch257744e2011-11-30 15:57:28 +00003010 for (int i = ExperimentalNatives::GetDebuggerCount();
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003011 i < ExperimentalNatives::GetBuiltinsCount(); i++) {
3012#define INSTALL_EXPERIMENTAL_NATIVES(id, desc) \
3013 if (FLAG_##id) { \
3014 for (size_t j = 0; id##_natives[j] != NULL; j++) { \
3015 Vector<const char> script_name = ExperimentalNatives::GetScriptName(i); \
3016 if (strncmp(script_name.start(), id##_natives[j], \
3017 script_name.length()) == 0) { \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003018 if (!Bootstrapper::CompileExperimentalBuiltin(isolate(), i)) { \
3019 return false; \
3020 } \
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003021 } \
3022 } \
3023 }
3024 HARMONY_INPROGRESS(INSTALL_EXPERIMENTAL_NATIVES);
3025 HARMONY_STAGED(INSTALL_EXPERIMENTAL_NATIVES);
3026 HARMONY_SHIPPING(INSTALL_EXPERIMENTAL_NATIVES);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003027 INSTALL_EXPERIMENTAL_NATIVES(promise_extra, "");
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003028#undef INSTALL_EXPERIMENTAL_NATIVES
Ben Murdoch257744e2011-11-30 15:57:28 +00003029 }
3030
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003031 if (!CallUtilsFunction(isolate(), "PostExperimentals")) return false;
3032
3033 InstallExperimentalBuiltinFunctionIds();
Ben Murdoch257744e2011-11-30 15:57:28 +00003034 return true;
3035}
3036
3037
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003038bool Genesis::InstallExtraNatives() {
3039 HandleScope scope(isolate());
3040
3041 Handle<JSObject> extras_binding =
3042 factory()->NewJSObject(isolate()->object_function());
3043 native_context()->set_extras_binding_object(*extras_binding);
3044
3045 for (int i = ExtraNatives::GetDebuggerCount();
3046 i < ExtraNatives::GetBuiltinsCount(); i++) {
3047 if (!Bootstrapper::CompileExtraBuiltin(isolate(), i)) return false;
3048 }
3049
3050 return true;
3051}
3052
3053
3054bool Genesis::InstallExperimentalExtraNatives() {
3055 for (int i = ExperimentalExtraNatives::GetDebuggerCount();
3056 i < ExperimentalExtraNatives::GetBuiltinsCount(); i++) {
3057 if (!Bootstrapper::CompileExperimentalExtraBuiltin(isolate(), i))
3058 return false;
3059 }
3060
3061 return true;
3062}
3063
3064
3065bool Genesis::InstallDebuggerNatives() {
3066 for (int i = 0; i < Natives::GetDebuggerCount(); ++i) {
3067 if (!Bootstrapper::CompileBuiltin(isolate(), i)) return false;
3068 }
3069 return CallUtilsFunction(isolate(), "PostDebug");
3070}
3071
3072
Ben Murdochb0fe1622011-05-05 13:52:32 +01003073static void InstallBuiltinFunctionId(Handle<JSObject> holder,
3074 const char* function_name,
3075 BuiltinFunctionId id) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003076 Isolate* isolate = holder->GetIsolate();
3077 Handle<Object> function_object =
3078 Object::GetProperty(isolate, holder, function_name).ToHandleChecked();
3079 Handle<JSFunction> function = Handle<JSFunction>::cast(function_object);
Kristian Monsen25f61362010-05-21 11:50:48 +01003080 function->shared()->set_function_data(Smi::FromInt(id));
3081}
3082
3083
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003084#define INSTALL_BUILTIN_ID(holder_expr, fun_name, name) \
3085 { #holder_expr, #fun_name, k##name } \
3086 ,
3087
3088
Ben Murdochb0fe1622011-05-05 13:52:32 +01003089void Genesis::InstallBuiltinFunctionIds() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003090 HandleScope scope(isolate());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003091 struct BuiltinFunctionIds {
3092 const char* holder_expr;
3093 const char* fun_name;
3094 BuiltinFunctionId id;
3095 };
3096
3097 const BuiltinFunctionIds builtins[] = {
3098 FUNCTIONS_WITH_ID_LIST(INSTALL_BUILTIN_ID)};
3099
3100 for (const BuiltinFunctionIds& builtin : builtins) {
3101 Handle<JSObject> holder =
3102 ResolveBuiltinIdHolder(native_context(), builtin.holder_expr);
3103 InstallBuiltinFunctionId(holder, builtin.fun_name, builtin.id);
Kristian Monsen25f61362010-05-21 11:50:48 +01003104 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003105}
3106
3107
3108void Genesis::InstallExperimentalBuiltinFunctionIds() {
3109 if (FLAG_harmony_sharedarraybuffer) {
3110 struct BuiltinFunctionIds {
3111 const char* holder_expr;
3112 const char* fun_name;
3113 BuiltinFunctionId id;
3114 };
3115
3116 const BuiltinFunctionIds atomic_builtins[] = {
3117 ATOMIC_FUNCTIONS_WITH_ID_LIST(INSTALL_BUILTIN_ID)};
3118
3119 for (const BuiltinFunctionIds& builtin : atomic_builtins) {
3120 Handle<JSObject> holder =
3121 ResolveBuiltinIdHolder(native_context(), builtin.holder_expr);
3122 InstallBuiltinFunctionId(holder, builtin.fun_name, builtin.id);
3123 }
3124 }
3125}
3126
3127
Ben Murdochb0fe1622011-05-05 13:52:32 +01003128#undef INSTALL_BUILTIN_ID
Steve Block6ded16b2010-05-10 14:33:55 +01003129
3130
Kristian Monsen80d68ea2010-09-08 11:05:35 +01003131void Genesis::InitializeNormalizedMapCaches() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003132 Handle<NormalizedMapCache> cache = NormalizedMapCache::New(isolate());
3133 native_context()->set_normalized_map_cache(*cache);
Kristian Monsen80d68ea2010-09-08 11:05:35 +01003134}
3135
3136
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003137bool Bootstrapper::InstallExtensions(Handle<Context> native_context,
Andrei Popescu31002712010-02-23 13:46:05 +00003138 v8::ExtensionConfiguration* extensions) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003139 BootstrapperActive active(this);
3140 SaveContext saved_context(isolate_);
3141 isolate_->set_context(*native_context);
3142 return Genesis::InstallExtensions(native_context, extensions) &&
3143 Genesis::InstallSpecialObjects(native_context);
3144}
3145
3146
3147bool Genesis::InstallSpecialObjects(Handle<Context> native_context) {
3148 Isolate* isolate = native_context->GetIsolate();
3149 // Don't install extensions into the snapshot.
3150 if (isolate->serializer_enabled()) return true;
3151
3152 Factory* factory = isolate->factory();
3153 HandleScope scope(isolate);
3154 Handle<JSGlobalObject> global(JSGlobalObject::cast(
3155 native_context->global_object()));
3156
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003157 Handle<JSObject> Error = isolate->error_function();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003158 Handle<String> name =
3159 factory->InternalizeOneByteString(STATIC_CHAR_VECTOR("stackTraceLimit"));
3160 Handle<Smi> stack_trace_limit(Smi::FromInt(FLAG_stack_trace_limit), isolate);
3161 JSObject::AddProperty(Error, name, stack_trace_limit, NONE);
3162
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003163 // Expose the debug global object in global if a name for it is specified.
3164 if (FLAG_expose_debug_as != NULL && strlen(FLAG_expose_debug_as) != 0) {
3165 // If loading fails we just bail out without installing the
3166 // debugger but without tanking the whole context.
3167 Debug* debug = isolate->debug();
3168 if (!debug->Load()) return true;
3169 Handle<Context> debug_context = debug->debug_context();
3170 // Set the security token for the debugger context to the same as
3171 // the shell native context to allow calling between these (otherwise
3172 // exposing debug global object doesn't make much sense).
3173 debug_context->set_security_token(native_context->security_token());
3174 Handle<String> debug_string =
3175 factory->InternalizeUtf8String(FLAG_expose_debug_as);
3176 uint32_t index;
3177 if (debug_string->AsArrayIndex(&index)) return true;
3178 Handle<Object> global_proxy(debug_context->global_proxy(), isolate);
3179 JSObject::AddProperty(global, debug_string, global_proxy, DONT_ENUM);
3180 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003181
3182 if (FLAG_expose_wasm) {
3183 WasmJs::Install(isolate, global);
3184 }
3185
Andrei Popescu31002712010-02-23 13:46:05 +00003186 return true;
3187}
3188
3189
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003190static uint32_t Hash(RegisteredExtension* extension) {
3191 return v8::internal::ComputePointerHash(extension);
3192}
3193
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003194
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003195Genesis::ExtensionStates::ExtensionStates() : map_(HashMap::PointersMatch, 8) {}
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003196
3197Genesis::ExtensionTraversalState Genesis::ExtensionStates::get_state(
3198 RegisteredExtension* extension) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003199 i::HashMap::Entry* entry = map_.Lookup(extension, Hash(extension));
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003200 if (entry == NULL) {
3201 return UNVISITED;
3202 }
3203 return static_cast<ExtensionTraversalState>(
3204 reinterpret_cast<intptr_t>(entry->value));
3205}
3206
3207void Genesis::ExtensionStates::set_state(RegisteredExtension* extension,
3208 ExtensionTraversalState state) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003209 map_.LookupOrInsert(extension, Hash(extension))->value =
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003210 reinterpret_cast<void*>(static_cast<intptr_t>(state));
3211}
Steve Blocka7e24c12009-10-30 11:49:00 +00003212
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003213
3214bool Genesis::InstallExtensions(Handle<Context> native_context,
Andrei Popescu31002712010-02-23 13:46:05 +00003215 v8::ExtensionConfiguration* extensions) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003216 Isolate* isolate = native_context->GetIsolate();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003217 ExtensionStates extension_states; // All extensions have state UNVISITED.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003218 return InstallAutoExtensions(isolate, &extension_states) &&
3219 (!FLAG_expose_free_buffer ||
3220 InstallExtension(isolate, "v8/free-buffer", &extension_states)) &&
3221 (!FLAG_expose_gc ||
3222 InstallExtension(isolate, "v8/gc", &extension_states)) &&
3223 (!FLAG_expose_externalize_string ||
3224 InstallExtension(isolate, "v8/externalize", &extension_states)) &&
3225 (!FLAG_track_gc_object_stats ||
3226 InstallExtension(isolate, "v8/statistics", &extension_states)) &&
3227 (!FLAG_expose_trigger_failure ||
3228 InstallExtension(isolate, "v8/trigger-failure", &extension_states)) &&
3229 InstallRequestedExtensions(isolate, extensions, &extension_states);
3230}
Steve Blocka7e24c12009-10-30 11:49:00 +00003231
Steve Blocka7e24c12009-10-30 11:49:00 +00003232
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003233bool Genesis::InstallAutoExtensions(Isolate* isolate,
3234 ExtensionStates* extension_states) {
3235 for (v8::RegisteredExtension* it = v8::RegisteredExtension::first_extension();
3236 it != NULL;
3237 it = it->next()) {
3238 if (it->extension()->auto_enable() &&
3239 !InstallExtension(isolate, it, extension_states)) {
Steve Blocka7e24c12009-10-30 11:49:00 +00003240 return false;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003241 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003242 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003243 return true;
3244}
Steve Blocka7e24c12009-10-30 11:49:00 +00003245
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003246
3247bool Genesis::InstallRequestedExtensions(Isolate* isolate,
3248 v8::ExtensionConfiguration* extensions,
3249 ExtensionStates* extension_states) {
3250 for (const char** it = extensions->begin(); it != extensions->end(); ++it) {
3251 if (!InstallExtension(isolate, *it, extension_states)) return false;
3252 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003253 return true;
3254}
3255
3256
3257// Installs a named extension. This methods is unoptimized and does
3258// not scale well if we want to support a large number of extensions.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003259bool Genesis::InstallExtension(Isolate* isolate,
3260 const char* name,
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003261 ExtensionStates* extension_states) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003262 for (v8::RegisteredExtension* it = v8::RegisteredExtension::first_extension();
3263 it != NULL;
3264 it = it->next()) {
3265 if (strcmp(name, it->extension()->name()) == 0) {
3266 return InstallExtension(isolate, it, extension_states);
3267 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003268 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003269 return Utils::ApiCheck(false,
3270 "v8::Context::New()",
3271 "Cannot find required extension");
Steve Blocka7e24c12009-10-30 11:49:00 +00003272}
3273
3274
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003275bool Genesis::InstallExtension(Isolate* isolate,
3276 v8::RegisteredExtension* current,
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003277 ExtensionStates* extension_states) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003278 HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003279
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003280 if (extension_states->get_state(current) == INSTALLED) return true;
Steve Blocka7e24c12009-10-30 11:49:00 +00003281 // The current node has already been visited so there must be a
3282 // cycle in the dependency graph; fail.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003283 if (!Utils::ApiCheck(extension_states->get_state(current) != VISITED,
3284 "v8::Context::New()",
3285 "Circular extension dependency")) {
Steve Blocka7e24c12009-10-30 11:49:00 +00003286 return false;
3287 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003288 DCHECK(extension_states->get_state(current) == UNVISITED);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003289 extension_states->set_state(current, VISITED);
Steve Blocka7e24c12009-10-30 11:49:00 +00003290 v8::Extension* extension = current->extension();
3291 // Install the extension's dependencies
3292 for (int i = 0; i < extension->dependency_count(); i++) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003293 if (!InstallExtension(isolate,
3294 extension->dependencies()[i],
3295 extension_states)) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003296 return false;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003297 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003298 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003299 // We do not expect this to throw an exception. Change this if it does.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003300 bool result = CompileExtension(isolate, extension);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003301 DCHECK(isolate->has_pending_exception() != result);
Steve Blocka7e24c12009-10-30 11:49:00 +00003302 if (!result) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003303 // We print out the name of the extension that fail to install.
3304 // When an error is thrown during bootstrapping we automatically print
3305 // the line number at which this happened to the console in the isolate
3306 // error throwing functionality.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003307 base::OS::PrintError("Error installing extension '%s'.\n",
3308 current->extension()->name());
Steve Block44f0eee2011-05-26 01:26:41 +01003309 isolate->clear_pending_exception();
Steve Blocka7e24c12009-10-30 11:49:00 +00003310 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003311 extension_states->set_state(current, INSTALLED);
3312 isolate->NotifyExtensionInstalled();
Steve Blocka7e24c12009-10-30 11:49:00 +00003313 return result;
3314}
3315
3316
3317bool Genesis::ConfigureGlobalObjects(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003318 v8::Local<v8::ObjectTemplate> global_proxy_template) {
Steve Blocka7e24c12009-10-30 11:49:00 +00003319 Handle<JSObject> global_proxy(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003320 JSObject::cast(native_context()->global_proxy()));
3321 Handle<JSObject> global_object(
3322 JSObject::cast(native_context()->global_object()));
Steve Blocka7e24c12009-10-30 11:49:00 +00003323
3324 if (!global_proxy_template.IsEmpty()) {
3325 // Configure the global proxy object.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003326 Handle<ObjectTemplateInfo> global_proxy_data =
Steve Blocka7e24c12009-10-30 11:49:00 +00003327 v8::Utils::OpenHandle(*global_proxy_template);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003328 if (!ConfigureApiObject(global_proxy, global_proxy_data)) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00003329
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003330 // Configure the global object.
Steve Blocka7e24c12009-10-30 11:49:00 +00003331 Handle<FunctionTemplateInfo> proxy_constructor(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003332 FunctionTemplateInfo::cast(global_proxy_data->constructor()));
Steve Blocka7e24c12009-10-30 11:49:00 +00003333 if (!proxy_constructor->prototype_template()->IsUndefined()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003334 Handle<ObjectTemplateInfo> global_object_data(
Steve Blocka7e24c12009-10-30 11:49:00 +00003335 ObjectTemplateInfo::cast(proxy_constructor->prototype_template()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003336 if (!ConfigureApiObject(global_object, global_object_data)) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00003337 }
3338 }
3339
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003340 SetObjectPrototype(global_proxy, global_object);
3341
3342 native_context()->set_initial_array_prototype(
3343 JSArray::cast(native_context()->array_function()->prototype()));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003344 native_context()->set_array_buffer_map(
3345 native_context()->array_buffer_fun()->initial_map());
3346 native_context()->set_js_map_map(
3347 native_context()->js_map_fun()->initial_map());
3348 native_context()->set_js_set_map(
3349 native_context()->js_set_fun()->initial_map());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003350
Steve Blocka7e24c12009-10-30 11:49:00 +00003351 return true;
3352}
3353
3354
3355bool Genesis::ConfigureApiObject(Handle<JSObject> object,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003356 Handle<ObjectTemplateInfo> object_template) {
3357 DCHECK(!object_template.is_null());
3358 DCHECK(FunctionTemplateInfo::cast(object_template->constructor())
3359 ->IsTemplateFor(object->map()));;
Steve Blocka7e24c12009-10-30 11:49:00 +00003360
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003361 MaybeHandle<JSObject> maybe_obj =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003362 ApiNatives::InstantiateObject(object_template);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003363 Handle<JSObject> obj;
3364 if (!maybe_obj.ToHandle(&obj)) {
3365 DCHECK(isolate()->has_pending_exception());
Ben Murdoch257744e2011-11-30 15:57:28 +00003366 isolate()->clear_pending_exception();
Steve Blocka7e24c12009-10-30 11:49:00 +00003367 return false;
3368 }
3369 TransferObject(obj, object);
3370 return true;
3371}
3372
3373
3374void Genesis::TransferNamedProperties(Handle<JSObject> from,
3375 Handle<JSObject> to) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003376 // If JSObject::AddProperty asserts due to already existing property,
3377 // it is likely due to both global objects sharing property name(s).
3378 // Merging those two global objects is impossible.
3379 // The global template must not create properties that already exist
3380 // in the snapshotted global object.
Steve Blocka7e24c12009-10-30 11:49:00 +00003381 if (from->HasFastProperties()) {
3382 Handle<DescriptorArray> descs =
3383 Handle<DescriptorArray>(from->map()->instance_descriptors());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003384 for (int i = 0; i < from->map()->NumberOfOwnDescriptors(); i++) {
3385 PropertyDetails details = descs->GetDetails(i);
Steve Blocka7e24c12009-10-30 11:49:00 +00003386 switch (details.type()) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003387 case DATA: {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003388 HandleScope inner(isolate());
3389 Handle<Name> key = Handle<Name>(descs->GetKey(i));
3390 FieldIndex index = FieldIndex::ForDescriptor(from->map(), i);
3391 DCHECK(!descs->GetDetails(i).representation().IsDouble());
3392 Handle<Object> value = Handle<Object>(from->RawFastPropertyAt(index),
3393 isolate());
3394 JSObject::AddProperty(to, key, value, details.attributes());
Steve Blocka7e24c12009-10-30 11:49:00 +00003395 break;
3396 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003397 case DATA_CONSTANT: {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003398 HandleScope inner(isolate());
3399 Handle<Name> key = Handle<Name>(descs->GetKey(i));
3400 Handle<Object> constant(descs->GetConstant(i), isolate());
3401 JSObject::AddProperty(to, key, constant, details.attributes());
Steve Blocka7e24c12009-10-30 11:49:00 +00003402 break;
3403 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003404 case ACCESSOR:
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003405 UNREACHABLE();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003406 case ACCESSOR_CONSTANT: {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003407 Handle<Name> key(descs->GetKey(i));
3408 LookupIterator it(to, key, LookupIterator::OWN_SKIP_INTERCEPTOR);
3409 CHECK_NE(LookupIterator::ACCESS_CHECK, it.state());
Steve Blocka7e24c12009-10-30 11:49:00 +00003410 // If the property is already there we skip it
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003411 if (it.IsFound()) continue;
3412 HandleScope inner(isolate());
3413 DCHECK(!to->HasFastProperties());
Andrei Popescu31002712010-02-23 13:46:05 +00003414 // Add to dictionary.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003415 Handle<Object> callbacks(descs->GetCallbacksObject(i), isolate());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003416 PropertyDetails d(details.attributes(), ACCESSOR_CONSTANT, i + 1,
3417 PropertyCellType::kMutable);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003418 JSObject::SetNormalizedProperty(to, key, callbacks, d);
Steve Blocka7e24c12009-10-30 11:49:00 +00003419 break;
3420 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003421 }
3422 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003423 } else if (from->IsJSGlobalObject()) {
3424 Handle<GlobalDictionary> properties =
3425 Handle<GlobalDictionary>(from->global_dictionary());
3426 int capacity = properties->Capacity();
3427 for (int i = 0; i < capacity; i++) {
3428 Object* raw_key(properties->KeyAt(i));
3429 if (properties->IsKey(raw_key)) {
3430 DCHECK(raw_key->IsName());
3431 // If the property is already there we skip it.
3432 Handle<Name> key(Name::cast(raw_key));
3433 LookupIterator it(to, key, LookupIterator::OWN_SKIP_INTERCEPTOR);
3434 CHECK_NE(LookupIterator::ACCESS_CHECK, it.state());
3435 if (it.IsFound()) continue;
3436 // Set the property.
3437 DCHECK(properties->ValueAt(i)->IsPropertyCell());
3438 Handle<PropertyCell> cell(PropertyCell::cast(properties->ValueAt(i)));
3439 Handle<Object> value(cell->value(), isolate());
3440 if (value->IsTheHole()) continue;
3441 PropertyDetails details = cell->property_details();
3442 DCHECK_EQ(kData, details.kind());
3443 JSObject::AddProperty(to, key, value, details.attributes());
3444 }
3445 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003446 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003447 Handle<NameDictionary> properties =
3448 Handle<NameDictionary>(from->property_dictionary());
Steve Blocka7e24c12009-10-30 11:49:00 +00003449 int capacity = properties->Capacity();
3450 for (int i = 0; i < capacity; i++) {
3451 Object* raw_key(properties->KeyAt(i));
3452 if (properties->IsKey(raw_key)) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003453 DCHECK(raw_key->IsName());
Steve Blocka7e24c12009-10-30 11:49:00 +00003454 // If the property is already there we skip it.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003455 Handle<Name> key(Name::cast(raw_key));
3456 LookupIterator it(to, key, LookupIterator::OWN_SKIP_INTERCEPTOR);
3457 CHECK_NE(LookupIterator::ACCESS_CHECK, it.state());
3458 if (it.IsFound()) continue;
Steve Blocka7e24c12009-10-30 11:49:00 +00003459 // Set the property.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003460 Handle<Object> value = Handle<Object>(properties->ValueAt(i),
3461 isolate());
3462 DCHECK(!value->IsCell());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003463 DCHECK(!value->IsTheHole());
Steve Blocka7e24c12009-10-30 11:49:00 +00003464 PropertyDetails details = properties->DetailsAt(i);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003465 DCHECK_EQ(kData, details.kind());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003466 JSObject::AddProperty(to, key, value, details.attributes());
Steve Blocka7e24c12009-10-30 11:49:00 +00003467 }
3468 }
3469 }
3470}
3471
3472
3473void Genesis::TransferIndexedProperties(Handle<JSObject> from,
3474 Handle<JSObject> to) {
3475 // Cloning the elements array is sufficient.
3476 Handle<FixedArray> from_elements =
3477 Handle<FixedArray>(FixedArray::cast(from->elements()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003478 Handle<FixedArray> to_elements = factory()->CopyFixedArray(from_elements);
Steve Blocka7e24c12009-10-30 11:49:00 +00003479 to->set_elements(*to_elements);
3480}
3481
3482
3483void Genesis::TransferObject(Handle<JSObject> from, Handle<JSObject> to) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003484 HandleScope outer(isolate());
Steve Blocka7e24c12009-10-30 11:49:00 +00003485
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003486 DCHECK(!from->IsJSArray());
3487 DCHECK(!to->IsJSArray());
Steve Blocka7e24c12009-10-30 11:49:00 +00003488
3489 TransferNamedProperties(from, to);
3490 TransferIndexedProperties(from, to);
3491
3492 // Transfer the prototype (new map is needed).
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003493 Handle<Object> proto(from->map()->prototype(), isolate());
3494 SetObjectPrototype(to, proto);
Steve Blocka7e24c12009-10-30 11:49:00 +00003495}
3496
3497
3498void Genesis::MakeFunctionInstancePrototypeWritable() {
Steve Block44f0eee2011-05-26 01:26:41 +01003499 // The maps with writable prototype are created in CreateEmptyFunction
3500 // and CreateStrictModeFunctionMaps respectively. Initially the maps are
3501 // created with read-only prototype for JS builtins processing.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003502 DCHECK(!sloppy_function_map_writable_prototype_.is_null());
3503 DCHECK(!strict_function_map_writable_prototype_.is_null());
Steve Blocka7e24c12009-10-30 11:49:00 +00003504
Steve Block44f0eee2011-05-26 01:26:41 +01003505 // Replace function instance maps to make prototype writable.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003506 native_context()->set_sloppy_function_map(
3507 *sloppy_function_map_writable_prototype_);
3508 native_context()->set_strict_function_map(
3509 *strict_function_map_writable_prototype_);
Steve Blocka7e24c12009-10-30 11:49:00 +00003510}
3511
3512
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003513class NoTrackDoubleFieldsForSerializerScope {
3514 public:
3515 explicit NoTrackDoubleFieldsForSerializerScope(Isolate* isolate)
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003516 : flag_(FLAG_track_double_fields), enabled_(false) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003517 if (isolate->serializer_enabled()) {
3518 // Disable tracking double fields because heap numbers treated as
3519 // immutable by the serializer.
3520 FLAG_track_double_fields = false;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003521 enabled_ = true;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003522 }
3523 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003524
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003525 ~NoTrackDoubleFieldsForSerializerScope() {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003526 if (enabled_) {
3527 FLAG_track_double_fields = flag_;
3528 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003529 }
3530
3531 private:
3532 bool flag_;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003533 bool enabled_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003534};
3535
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003536Genesis::Genesis(Isolate* isolate,
3537 MaybeHandle<JSGlobalProxy> maybe_global_proxy,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003538 v8::Local<v8::ObjectTemplate> global_proxy_template,
3539 v8::ExtensionConfiguration* extensions,
Ben Murdoch097c5b22016-05-18 11:27:45 +01003540 GlobalContextType context_type)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003541 : isolate_(isolate), active_(isolate->bootstrapper()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003542 NoTrackDoubleFieldsForSerializerScope disable_scope(isolate);
3543 result_ = Handle<Context>::null();
Steve Blocka7e24c12009-10-30 11:49:00 +00003544 // Before creating the roots we must save the context and restore it
3545 // on all function exits.
Steve Block44f0eee2011-05-26 01:26:41 +01003546 SaveContext saved_context(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003547
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003548 // During genesis, the boilerplate for stack overflow won't work until the
3549 // environment has been at least partially initialized. Add a stack check
3550 // before entering JS code to catch overflow early.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003551 StackLimitCheck check(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003552 if (check.HasOverflowed()) {
3553 isolate->StackOverflow();
3554 return;
3555 }
3556
3557 // The deserializer needs to hook up references to the global proxy.
3558 // Create an uninitialized global proxy now if we don't have one
3559 // and initialize it later in CreateNewGlobals.
3560 Handle<JSGlobalProxy> global_proxy;
3561 if (!maybe_global_proxy.ToHandle(&global_proxy)) {
3562 global_proxy = isolate->factory()->NewUninitializedJSGlobalProxy();
3563 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003564
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003565 // We can only de-serialize a context if the isolate was initialized from
3566 // a snapshot. Otherwise we have to build the context from scratch.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003567 // Also create a context from scratch to expose natives, if required by flag.
3568 if (!isolate->initialized_from_snapshot() ||
3569 !Snapshot::NewContextFromSnapshot(isolate, global_proxy)
3570 .ToHandle(&native_context_)) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003571 native_context_ = Handle<Context>();
3572 }
3573
3574 if (!native_context().is_null()) {
3575 AddToWeakNativeContextList(*native_context());
3576 isolate->set_context(*native_context());
Steve Block44f0eee2011-05-26 01:26:41 +01003577 isolate->counters()->contexts_created_by_snapshot()->Increment();
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003578#if TRACE_MAPS
3579 if (FLAG_trace_maps) {
3580 Handle<JSFunction> object_fun = isolate->object_function();
3581 PrintF("[TraceMap: InitialMap map= %p SFI= %d_Object ]\n",
3582 reinterpret_cast<void*>(object_fun->initial_map()),
3583 object_fun->shared()->unique_id());
3584 Map::TraceAllTransitions(object_fun->initial_map());
3585 }
3586#endif
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003587 Handle<JSGlobalObject> global_object =
3588 CreateNewGlobals(global_proxy_template, global_proxy);
Andrei Popescu402d9372010-02-26 13:31:12 +00003589
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003590 HookUpGlobalProxy(global_object, global_proxy);
3591 HookUpGlobalObject(global_object);
Andrei Popescu402d9372010-02-26 13:31:12 +00003592
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003593 if (!ConfigureGlobalObjects(global_proxy_template)) return;
Andrei Popescu31002712010-02-23 13:46:05 +00003594 } else {
3595 // We get here if there was no context snapshot.
3596 CreateRoots();
Ben Murdoch257744e2011-11-30 15:57:28 +00003597 Handle<JSFunction> empty_function = CreateEmptyFunction(isolate);
Steve Block44f0eee2011-05-26 01:26:41 +01003598 CreateStrictModeFunctionMaps(empty_function);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003599 CreateStrongModeFunctionMaps(empty_function);
3600 CreateIteratorMaps();
3601 Handle<JSGlobalObject> global_object =
3602 CreateNewGlobals(global_proxy_template, global_proxy);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003603 HookUpGlobalProxy(global_object, global_proxy);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003604 InitializeGlobal(global_object, empty_function, context_type);
Kristian Monsen80d68ea2010-09-08 11:05:35 +01003605 InitializeNormalizedMapCaches();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003606
3607 if (!InstallNatives(context_type)) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00003608
Andrei Popescu31002712010-02-23 13:46:05 +00003609 MakeFunctionInstancePrototypeWritable();
Steve Blocka7e24c12009-10-30 11:49:00 +00003610
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003611 if (context_type != THIN_CONTEXT) {
3612 if (!InstallExtraNatives()) return;
3613 if (!ConfigureGlobalObjects(global_proxy_template)) return;
3614 }
Steve Block44f0eee2011-05-26 01:26:41 +01003615 isolate->counters()->contexts_created_from_scratch()->Increment();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003616 // Re-initialize the counter because it got incremented during snapshot
3617 // creation.
3618 isolate->native_context()->set_errors_thrown(Smi::FromInt(0));
Andrei Popescu31002712010-02-23 13:46:05 +00003619 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003620
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003621 // Install experimental natives. Do not include them into the
3622 // snapshot as we should be able to turn them off at runtime. Re-installing
3623 // them after they have already been deserialized would also fail.
3624 if (context_type == FULL_CONTEXT) {
3625 if (!isolate->serializer_enabled()) {
3626 InitializeExperimentalGlobal();
3627 if (!InstallExperimentalNatives()) return;
Ben Murdoch257744e2011-11-30 15:57:28 +00003628
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003629 if (FLAG_experimental_extras) {
3630 if (!InstallExperimentalExtraNatives()) return;
3631 }
3632 }
3633 // The serializer cannot serialize typed arrays. Reset those typed arrays
3634 // for each new context.
3635 } else if (context_type == DEBUG_CONTEXT) {
3636 DCHECK(!isolate->serializer_enabled());
3637 InitializeExperimentalGlobal();
3638 if (!InstallDebuggerNatives()) return;
3639 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003640
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003641 ConfigureUtilsObject(context_type);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003642
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003643 // Check that the script context table is empty except for the 'this' binding.
3644 // We do not need script contexts for native scripts.
3645 if (!FLAG_global_var_shortcuts) {
3646 DCHECK_EQ(1, native_context()->script_context_table()->used());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003647 }
3648
3649 result_ = native_context();
Steve Blocka7e24c12009-10-30 11:49:00 +00003650}
3651
3652
3653// Support for thread preemption.
3654
3655// Reserve space for statics needing saving and restoring.
3656int Bootstrapper::ArchiveSpacePerThread() {
Steve Block44f0eee2011-05-26 01:26:41 +01003657 return sizeof(NestingCounterType);
Steve Blocka7e24c12009-10-30 11:49:00 +00003658}
3659
3660
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003661// Archive statics that are thread-local.
Steve Blocka7e24c12009-10-30 11:49:00 +00003662char* Bootstrapper::ArchiveState(char* to) {
Steve Block44f0eee2011-05-26 01:26:41 +01003663 *reinterpret_cast<NestingCounterType*>(to) = nesting_;
3664 nesting_ = 0;
3665 return to + sizeof(NestingCounterType);
Steve Blocka7e24c12009-10-30 11:49:00 +00003666}
3667
3668
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003669// Restore statics that are thread-local.
Steve Blocka7e24c12009-10-30 11:49:00 +00003670char* Bootstrapper::RestoreState(char* from) {
Steve Block44f0eee2011-05-26 01:26:41 +01003671 nesting_ = *reinterpret_cast<NestingCounterType*>(from);
3672 return from + sizeof(NestingCounterType);
Steve Blocka7e24c12009-10-30 11:49:00 +00003673}
3674
3675
3676// Called when the top-level V8 mutex is destroyed.
3677void Bootstrapper::FreeThreadResources() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003678 DCHECK(!IsActive());
Steve Blocka7e24c12009-10-30 11:49:00 +00003679}
3680
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003681} // namespace internal
3682} // namespace v8