• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "src/bootstrapper.h"
6 
7 #include "src/accessors.h"
8 #include "src/api-natives.h"
9 #include "src/base/ieee754.h"
10 #include "src/code-stubs.h"
11 #include "src/compiler.h"
12 #include "src/debug/debug.h"
13 #include "src/extensions/externalize-string-extension.h"
14 #include "src/extensions/free-buffer-extension.h"
15 #include "src/extensions/gc-extension.h"
16 #include "src/extensions/ignition-statistics-extension.h"
17 #include "src/extensions/statistics-extension.h"
18 #include "src/extensions/trigger-failure-extension.h"
19 #include "src/ffi/ffi-compiler.h"
20 #include "src/heap/heap.h"
21 #include "src/isolate-inl.h"
22 #include "src/snapshot/natives.h"
23 #include "src/snapshot/snapshot.h"
24 #include "src/wasm/wasm-js.h"
25 
26 #if V8_I18N_SUPPORT
27 #include "src/i18n.h"
28 #endif  // V8_I18N_SUPPORT
29 
30 namespace v8 {
31 namespace internal {
32 
Bootstrapper(Isolate * isolate)33 Bootstrapper::Bootstrapper(Isolate* isolate)
34     : isolate_(isolate),
35       nesting_(0),
36       extensions_cache_(Script::TYPE_EXTENSION) {}
37 
38 template <class Source>
SourceLookup(int index)39 Handle<String> Bootstrapper::SourceLookup(int index) {
40   DCHECK(0 <= index && index < Source::GetBuiltinsCount());
41   Heap* heap = isolate_->heap();
42   if (Source::GetSourceCache(heap)->get(index)->IsUndefined(isolate_)) {
43     // We can use external strings for the natives.
44     Vector<const char> source = Source::GetScriptSource(index);
45     NativesExternalStringResource* resource =
46         new NativesExternalStringResource(source.start(), source.length());
47     Handle<ExternalOneByteString> source_code =
48         isolate_->factory()->NewNativeSourceString(resource);
49     // Mark this external string with a special map.
50     DCHECK(source_code->is_short());
51     Source::GetSourceCache(heap)->set(index, *source_code);
52   }
53   Handle<Object> cached_source(Source::GetSourceCache(heap)->get(index),
54                                isolate_);
55   return Handle<String>::cast(cached_source);
56 }
57 
58 
59 template Handle<String> Bootstrapper::SourceLookup<Natives>(int index);
60 template Handle<String> Bootstrapper::SourceLookup<ExperimentalNatives>(
61     int index);
62 template Handle<String> Bootstrapper::SourceLookup<ExperimentalExtraNatives>(
63     int index);
64 template Handle<String> Bootstrapper::SourceLookup<ExtraNatives>(int index);
65 
66 
Initialize(bool create_heap_objects)67 void Bootstrapper::Initialize(bool create_heap_objects) {
68   extensions_cache_.Initialize(isolate_, create_heap_objects);
69 }
70 
71 
GCFunctionName()72 static const char* GCFunctionName() {
73   bool flag_given = FLAG_expose_gc_as != NULL && strlen(FLAG_expose_gc_as) != 0;
74   return flag_given ? FLAG_expose_gc_as : "gc";
75 }
76 
77 
78 v8::Extension* Bootstrapper::free_buffer_extension_ = NULL;
79 v8::Extension* Bootstrapper::gc_extension_ = NULL;
80 v8::Extension* Bootstrapper::externalize_string_extension_ = NULL;
81 v8::Extension* Bootstrapper::statistics_extension_ = NULL;
82 v8::Extension* Bootstrapper::trigger_failure_extension_ = NULL;
83 v8::Extension* Bootstrapper::ignition_statistics_extension_ = NULL;
84 
InitializeOncePerProcess()85 void Bootstrapper::InitializeOncePerProcess() {
86   free_buffer_extension_ = new FreeBufferExtension;
87   v8::RegisterExtension(free_buffer_extension_);
88   gc_extension_ = new GCExtension(GCFunctionName());
89   v8::RegisterExtension(gc_extension_);
90   externalize_string_extension_ = new ExternalizeStringExtension;
91   v8::RegisterExtension(externalize_string_extension_);
92   statistics_extension_ = new StatisticsExtension;
93   v8::RegisterExtension(statistics_extension_);
94   trigger_failure_extension_ = new TriggerFailureExtension;
95   v8::RegisterExtension(trigger_failure_extension_);
96   ignition_statistics_extension_ = new IgnitionStatisticsExtension;
97   v8::RegisterExtension(ignition_statistics_extension_);
98 }
99 
100 
TearDownExtensions()101 void Bootstrapper::TearDownExtensions() {
102   delete free_buffer_extension_;
103   free_buffer_extension_ = NULL;
104   delete gc_extension_;
105   gc_extension_ = NULL;
106   delete externalize_string_extension_;
107   externalize_string_extension_ = NULL;
108   delete statistics_extension_;
109   statistics_extension_ = NULL;
110   delete trigger_failure_extension_;
111   trigger_failure_extension_ = NULL;
112   delete ignition_statistics_extension_;
113   ignition_statistics_extension_ = NULL;
114 }
115 
116 
DeleteNativeSources(Object * maybe_array)117 void DeleteNativeSources(Object* maybe_array) {
118   if (maybe_array->IsFixedArray()) {
119     FixedArray* array = FixedArray::cast(maybe_array);
120     Isolate* isolate = array->GetIsolate();
121     for (int i = 0; i < array->length(); i++) {
122       Object* natives_source = array->get(i);
123       if (!natives_source->IsUndefined(isolate)) {
124         const NativesExternalStringResource* resource =
125             reinterpret_cast<const NativesExternalStringResource*>(
126                 ExternalOneByteString::cast(natives_source)->resource());
127         delete resource;
128       }
129     }
130   }
131 }
132 
133 
TearDown()134 void Bootstrapper::TearDown() {
135   DeleteNativeSources(Natives::GetSourceCache(isolate_->heap()));
136   DeleteNativeSources(ExperimentalNatives::GetSourceCache(isolate_->heap()));
137   DeleteNativeSources(ExtraNatives::GetSourceCache(isolate_->heap()));
138   DeleteNativeSources(
139       ExperimentalExtraNatives::GetSourceCache(isolate_->heap()));
140 
141   extensions_cache_.Initialize(isolate_, false);  // Yes, symmetrical
142 }
143 
144 
145 class Genesis BASE_EMBEDDED {
146  public:
147   Genesis(Isolate* isolate, MaybeHandle<JSGlobalProxy> maybe_global_proxy,
148           v8::Local<v8::ObjectTemplate> global_proxy_template,
149           size_t context_snapshot_index,
150           v8::DeserializeInternalFieldsCallback internal_fields_deserializer,
151           GlobalContextType context_type);
152   Genesis(Isolate* isolate, MaybeHandle<JSGlobalProxy> maybe_global_proxy,
153           v8::Local<v8::ObjectTemplate> global_proxy_template);
~Genesis()154   ~Genesis() { }
155 
isolate() const156   Isolate* isolate() const { return isolate_; }
factory() const157   Factory* factory() const { return isolate_->factory(); }
heap() const158   Heap* heap() const { return isolate_->heap(); }
159 
result()160   Handle<Context> result() { return result_; }
161 
global_proxy()162   Handle<JSGlobalProxy> global_proxy() { return global_proxy_; }
163 
164  private:
native_context()165   Handle<Context> native_context() { return native_context_; }
166 
167   // Creates some basic objects. Used for creating a context from scratch.
168   void CreateRoots();
169   // Creates the empty function.  Used for creating a context from scratch.
170   Handle<JSFunction> CreateEmptyFunction(Isolate* isolate);
171   // Creates the ThrowTypeError function. ECMA 5th Ed. 13.2.3
172   Handle<JSFunction> GetRestrictedFunctionPropertiesThrower();
173   Handle<JSFunction> GetStrictArgumentsPoisonFunction();
174   Handle<JSFunction> GetThrowTypeErrorIntrinsic(Builtins::Name builtin_name);
175 
176   void CreateStrictModeFunctionMaps(Handle<JSFunction> empty);
177   void CreateIteratorMaps(Handle<JSFunction> empty);
178   void CreateAsyncIteratorMaps();
179   void CreateAsyncFunctionMaps(Handle<JSFunction> empty);
180   void CreateJSProxyMaps();
181 
182   // Make the "arguments" and "caller" properties throw a TypeError on access.
183   void AddRestrictedFunctionProperties(Handle<JSFunction> empty);
184 
185   // Creates the global objects using the global proxy and the template passed
186   // in through the API.  We call this regardless of whether we are building a
187   // context from scratch or using a deserialized one from the partial snapshot
188   // but in the latter case we don't use the objects it produces directly, as
189   // we have to use the deserialized ones that are linked together with the
190   // rest of the context snapshot. At the end we link the global proxy and the
191   // context to each other.
192   Handle<JSGlobalObject> CreateNewGlobals(
193       v8::Local<v8::ObjectTemplate> global_proxy_template,
194       Handle<JSGlobalProxy> global_proxy);
195   // Similarly, we want to use the global that has been created by the templates
196   // passed through the API.  The global from the snapshot is detached from the
197   // other objects in the snapshot.
198   void HookUpGlobalObject(Handle<JSGlobalObject> global_object);
199   // Hooks the given global proxy into the context in the case we do not
200   // replace the global object from the deserialized native context.
201   void HookUpGlobalProxy(Handle<JSGlobalProxy> global_proxy);
202   // The native context has a ScriptContextTable that store declarative bindings
203   // made in script scopes.  Add a "this" binding to that table pointing to the
204   // global proxy.
205   void InstallGlobalThisBinding();
206   // New context initialization.  Used for creating a context from scratch.
207   void InitializeGlobal(Handle<JSGlobalObject> global_object,
208                         Handle<JSFunction> empty_function,
209                         GlobalContextType context_type);
210   void InitializeExperimentalGlobal();
211   // Depending on the situation, expose and/or get rid of the utils object.
212   void ConfigureUtilsObject(GlobalContextType context_type);
213 
214 #define DECLARE_FEATURE_INITIALIZATION(id, descr) \
215   void InitializeGlobal_##id();
216 
217   HARMONY_INPROGRESS(DECLARE_FEATURE_INITIALIZATION)
218   HARMONY_STAGED(DECLARE_FEATURE_INITIALIZATION)
219   HARMONY_SHIPPING(DECLARE_FEATURE_INITIALIZATION)
220 #undef DECLARE_FEATURE_INITIALIZATION
221 
222   void InitializeGlobal_enable_fast_array_builtins();
223 
224   Handle<JSFunction> InstallArrayBuffer(Handle<JSObject> target,
225                                         const char* name, Builtins::Name call,
226                                         BuiltinFunctionId id);
227   Handle<JSFunction> InstallInternalArray(Handle<JSObject> target,
228                                           const char* name,
229                                           ElementsKind elements_kind);
230   bool InstallNatives(GlobalContextType context_type);
231 
232   void InstallTypedArray(const char* name, ElementsKind elements_kind,
233                          Handle<JSFunction>* fun);
234   bool InstallExperimentalNatives();
235   bool InstallExtraNatives();
236   bool InstallExperimentalExtraNatives();
237   bool InstallDebuggerNatives();
238   void InstallBuiltinFunctionIds();
239   void InstallExperimentalBuiltinFunctionIds();
240   void InitializeNormalizedMapCaches();
241 
242   enum ExtensionTraversalState {
243     UNVISITED, VISITED, INSTALLED
244   };
245 
246   class ExtensionStates {
247    public:
248     ExtensionStates();
249     ExtensionTraversalState get_state(RegisteredExtension* extension);
250     void set_state(RegisteredExtension* extension,
251                    ExtensionTraversalState state);
252    private:
253     base::HashMap map_;
254     DISALLOW_COPY_AND_ASSIGN(ExtensionStates);
255   };
256 
257   // Used both for deserialized and from-scratch contexts to add the extensions
258   // provided.
259   static bool InstallExtensions(Handle<Context> native_context,
260                                 v8::ExtensionConfiguration* extensions);
261   static bool InstallAutoExtensions(Isolate* isolate,
262                                     ExtensionStates* extension_states);
263   static bool InstallRequestedExtensions(Isolate* isolate,
264                                          v8::ExtensionConfiguration* extensions,
265                                          ExtensionStates* extension_states);
266   static bool InstallExtension(Isolate* isolate,
267                                const char* name,
268                                ExtensionStates* extension_states);
269   static bool InstallExtension(Isolate* isolate,
270                                v8::RegisteredExtension* current,
271                                ExtensionStates* extension_states);
272   static bool InstallSpecialObjects(Handle<Context> native_context);
273   bool ConfigureApiObject(Handle<JSObject> object,
274                           Handle<ObjectTemplateInfo> object_template);
275   bool ConfigureGlobalObjects(
276       v8::Local<v8::ObjectTemplate> global_proxy_template);
277 
278   // Migrates all properties from the 'from' object to the 'to'
279   // object and overrides the prototype in 'to' with the one from
280   // 'from'.
281   void TransferObject(Handle<JSObject> from, Handle<JSObject> to);
282   void TransferNamedProperties(Handle<JSObject> from, Handle<JSObject> to);
283   void TransferIndexedProperties(Handle<JSObject> from, Handle<JSObject> to);
284 
285   void MakeFunctionInstancePrototypeWritable();
286 
287   void SetStrictFunctionInstanceDescriptor(Handle<Map> map,
288                                            FunctionMode function_mode);
289 
290   static bool CallUtilsFunction(Isolate* isolate, const char* name);
291 
292   static bool CompileExtension(Isolate* isolate, v8::Extension* extension);
293 
294   Isolate* isolate_;
295   Handle<Context> result_;
296   Handle<Context> native_context_;
297   Handle<JSGlobalProxy> global_proxy_;
298 
299   // Function maps. Function maps are created initially with a read only
300   // prototype for the processing of JS builtins. Later the function maps are
301   // replaced in order to make prototype writable. These are the final, writable
302   // prototype, maps.
303   Handle<Map> sloppy_function_map_writable_prototype_;
304   Handle<Map> strict_function_map_writable_prototype_;
305   Handle<Map> class_function_map_;
306   Handle<JSFunction> strict_poison_function_;
307   Handle<JSFunction> restricted_function_properties_thrower_;
308 
309   BootstrapperActive active_;
310   friend class Bootstrapper;
311 };
312 
313 
Iterate(ObjectVisitor * v)314 void Bootstrapper::Iterate(ObjectVisitor* v) {
315   extensions_cache_.Iterate(v);
316   v->Synchronize(VisitorSynchronization::kExtensions);
317 }
318 
CreateEnvironment(MaybeHandle<JSGlobalProxy> maybe_global_proxy,v8::Local<v8::ObjectTemplate> global_proxy_template,v8::ExtensionConfiguration * extensions,size_t context_snapshot_index,v8::DeserializeInternalFieldsCallback internal_fields_deserializer,GlobalContextType context_type)319 Handle<Context> Bootstrapper::CreateEnvironment(
320     MaybeHandle<JSGlobalProxy> maybe_global_proxy,
321     v8::Local<v8::ObjectTemplate> global_proxy_template,
322     v8::ExtensionConfiguration* extensions, size_t context_snapshot_index,
323     v8::DeserializeInternalFieldsCallback internal_fields_deserializer,
324     GlobalContextType context_type) {
325   HandleScope scope(isolate_);
326   Genesis genesis(isolate_, maybe_global_proxy, global_proxy_template,
327                   context_snapshot_index, internal_fields_deserializer,
328                   context_type);
329   Handle<Context> env = genesis.result();
330   if (env.is_null() || !InstallExtensions(env, extensions)) {
331     return Handle<Context>();
332   }
333   return scope.CloseAndEscape(env);
334 }
335 
NewRemoteContext(MaybeHandle<JSGlobalProxy> maybe_global_proxy,v8::Local<v8::ObjectTemplate> global_proxy_template)336 Handle<JSGlobalProxy> Bootstrapper::NewRemoteContext(
337     MaybeHandle<JSGlobalProxy> maybe_global_proxy,
338     v8::Local<v8::ObjectTemplate> global_proxy_template) {
339   HandleScope scope(isolate_);
340   Genesis genesis(isolate_, maybe_global_proxy, global_proxy_template);
341   Handle<JSGlobalProxy> global_proxy = genesis.global_proxy();
342   if (global_proxy.is_null()) return Handle<JSGlobalProxy>();
343   return scope.CloseAndEscape(global_proxy);
344 }
345 
DetachGlobal(Handle<Context> env)346 void Bootstrapper::DetachGlobal(Handle<Context> env) {
347   Isolate* isolate = env->GetIsolate();
348   isolate->counters()->errors_thrown_per_context()->AddSample(
349       env->GetErrorsThrown());
350 
351   Heap* heap = isolate->heap();
352   Handle<JSGlobalProxy> global_proxy(JSGlobalProxy::cast(env->global_proxy()));
353   global_proxy->set_native_context(heap->null_value());
354   JSObject::ForceSetPrototype(global_proxy, isolate->factory()->null_value());
355   global_proxy->map()->SetConstructor(heap->null_value());
356   if (FLAG_track_detached_contexts) {
357     env->GetIsolate()->AddDetachedContext(env);
358   }
359 }
360 
361 namespace {
362 
InstallFunction(Handle<JSObject> target,Handle<Name> property_name,Handle<JSFunction> function,Handle<String> function_name,PropertyAttributes attributes=DONT_ENUM)363 void InstallFunction(Handle<JSObject> target, Handle<Name> property_name,
364                      Handle<JSFunction> function, Handle<String> function_name,
365                      PropertyAttributes attributes = DONT_ENUM) {
366   JSObject::AddProperty(target, property_name, function, attributes);
367   if (target->IsJSGlobalObject()) {
368     function->shared()->set_instance_class_name(*function_name);
369   }
370 }
371 
InstallFunction(Handle<JSObject> target,Handle<JSFunction> function,Handle<Name> name,PropertyAttributes attributes=DONT_ENUM)372 void InstallFunction(Handle<JSObject> target, Handle<JSFunction> function,
373                      Handle<Name> name,
374                      PropertyAttributes attributes = DONT_ENUM) {
375   Handle<String> name_string = Name::ToFunctionName(name).ToHandleChecked();
376   InstallFunction(target, name, function, name_string, attributes);
377 }
378 
CreateFunction(Isolate * isolate,Handle<String> name,InstanceType type,int instance_size,MaybeHandle<JSObject> maybe_prototype,Builtins::Name call,bool strict_function_map=false)379 Handle<JSFunction> CreateFunction(Isolate* isolate, Handle<String> name,
380                                   InstanceType type, int instance_size,
381                                   MaybeHandle<JSObject> maybe_prototype,
382                                   Builtins::Name call,
383                                   bool strict_function_map = false) {
384   Factory* factory = isolate->factory();
385   Handle<Code> call_code(isolate->builtins()->builtin(call));
386   Handle<JSObject> prototype;
387   Handle<JSFunction> result =
388       maybe_prototype.ToHandle(&prototype)
389           ? factory->NewFunction(name, call_code, prototype, type,
390                                  instance_size, strict_function_map)
391           : factory->NewFunctionWithoutPrototype(name, call_code,
392                                                  strict_function_map);
393   result->shared()->set_native(true);
394   return result;
395 }
396 
InstallFunction(Handle<JSObject> target,Handle<Name> name,InstanceType type,int instance_size,MaybeHandle<JSObject> maybe_prototype,Builtins::Name call,PropertyAttributes attributes,bool strict_function_map=false)397 Handle<JSFunction> InstallFunction(Handle<JSObject> target, Handle<Name> name,
398                                    InstanceType type, int instance_size,
399                                    MaybeHandle<JSObject> maybe_prototype,
400                                    Builtins::Name call,
401                                    PropertyAttributes attributes,
402                                    bool strict_function_map = false) {
403   Handle<String> name_string = Name::ToFunctionName(name).ToHandleChecked();
404   Handle<JSFunction> function =
405       CreateFunction(target->GetIsolate(), name_string, type, instance_size,
406                      maybe_prototype, call, strict_function_map);
407   InstallFunction(target, name, function, name_string, attributes);
408   return function;
409 }
410 
InstallFunction(Handle<JSObject> target,const char * name,InstanceType type,int instance_size,MaybeHandle<JSObject> maybe_prototype,Builtins::Name call,bool strict_function_map=false)411 Handle<JSFunction> InstallFunction(Handle<JSObject> target, const char* name,
412                                    InstanceType type, int instance_size,
413                                    MaybeHandle<JSObject> maybe_prototype,
414                                    Builtins::Name call,
415                                    bool strict_function_map = false) {
416   Factory* const factory = target->GetIsolate()->factory();
417   PropertyAttributes attributes = DONT_ENUM;
418   return InstallFunction(target, factory->InternalizeUtf8String(name), type,
419                          instance_size, maybe_prototype, call, attributes,
420                          strict_function_map);
421 }
422 
SimpleCreateFunction(Isolate * isolate,Handle<String> name,Builtins::Name call,int len,bool adapt)423 Handle<JSFunction> SimpleCreateFunction(Isolate* isolate, Handle<String> name,
424                                         Builtins::Name call, int len,
425                                         bool adapt) {
426   Handle<JSFunction> fun =
427       CreateFunction(isolate, name, JS_OBJECT_TYPE, JSObject::kHeaderSize,
428                      MaybeHandle<JSObject>(), call);
429   if (adapt) {
430     fun->shared()->set_internal_formal_parameter_count(len);
431   } else {
432     fun->shared()->DontAdaptArguments();
433   }
434   fun->shared()->set_length(len);
435   return fun;
436 }
437 
SimpleInstallFunction(Handle<JSObject> base,Handle<String> name,Builtins::Name call,int len,bool adapt,PropertyAttributes attrs=DONT_ENUM)438 Handle<JSFunction> SimpleInstallFunction(Handle<JSObject> base,
439                                          Handle<String> name,
440                                          Builtins::Name call, int len,
441                                          bool adapt,
442                                          PropertyAttributes attrs = DONT_ENUM) {
443   Handle<JSFunction> fun =
444       SimpleCreateFunction(base->GetIsolate(), name, call, len, adapt);
445   InstallFunction(base, fun, name, attrs);
446   return fun;
447 }
448 
SimpleInstallFunction(Handle<JSObject> base,const char * name,Builtins::Name call,int len,bool adapt,PropertyAttributes attrs=DONT_ENUM)449 Handle<JSFunction> SimpleInstallFunction(Handle<JSObject> base,
450                                          const char* name, Builtins::Name call,
451                                          int len, bool adapt,
452                                          PropertyAttributes attrs = DONT_ENUM) {
453   Factory* const factory = base->GetIsolate()->factory();
454   return SimpleInstallFunction(base, factory->InternalizeUtf8String(name), call,
455                                len, adapt, attrs);
456 }
457 
SimpleInstallFunction(Handle<JSObject> base,const char * name,Builtins::Name call,int len,bool adapt,BuiltinFunctionId id)458 Handle<JSFunction> SimpleInstallFunction(Handle<JSObject> base,
459                                          const char* name, Builtins::Name call,
460                                          int len, bool adapt,
461                                          BuiltinFunctionId id) {
462   Handle<JSFunction> fun = SimpleInstallFunction(base, name, call, len, adapt);
463   fun->shared()->set_builtin_function_id(id);
464   return fun;
465 }
466 
SimpleInstallGetterSetter(Handle<JSObject> base,Handle<String> name,Builtins::Name call_getter,Builtins::Name call_setter,PropertyAttributes attribs)467 void SimpleInstallGetterSetter(Handle<JSObject> base, Handle<String> name,
468                                Builtins::Name call_getter,
469                                Builtins::Name call_setter,
470                                PropertyAttributes attribs) {
471   Isolate* const isolate = base->GetIsolate();
472 
473   Handle<String> getter_name =
474       Name::ToFunctionName(name, isolate->factory()->get_string())
475           .ToHandleChecked();
476   Handle<JSFunction> getter =
477       SimpleCreateFunction(isolate, getter_name, call_getter, 0, true);
478 
479   Handle<String> setter_name =
480       Name::ToFunctionName(name, isolate->factory()->set_string())
481           .ToHandleChecked();
482   Handle<JSFunction> setter =
483       SimpleCreateFunction(isolate, setter_name, call_setter, 1, true);
484 
485   JSObject::DefineAccessor(base, name, getter, setter, attribs).Check();
486 }
487 
SimpleInstallGetter(Handle<JSObject> base,Handle<String> name,Handle<Name> property_name,Builtins::Name call,bool adapt)488 Handle<JSFunction> SimpleInstallGetter(Handle<JSObject> base,
489                                        Handle<String> name,
490                                        Handle<Name> property_name,
491                                        Builtins::Name call, bool adapt) {
492   Isolate* const isolate = base->GetIsolate();
493 
494   Handle<String> getter_name =
495       Name::ToFunctionName(name, isolate->factory()->get_string())
496           .ToHandleChecked();
497   Handle<JSFunction> getter =
498       SimpleCreateFunction(isolate, getter_name, call, 0, adapt);
499 
500   Handle<Object> setter = isolate->factory()->undefined_value();
501 
502   JSObject::DefineAccessor(base, property_name, getter, setter, DONT_ENUM)
503       .Check();
504 
505   return getter;
506 }
507 
SimpleInstallGetter(Handle<JSObject> base,Handle<String> name,Builtins::Name call,bool adapt)508 Handle<JSFunction> SimpleInstallGetter(Handle<JSObject> base,
509                                        Handle<String> name, Builtins::Name call,
510                                        bool adapt) {
511   return SimpleInstallGetter(base, name, name, call, adapt);
512 }
513 
SimpleInstallGetter(Handle<JSObject> base,Handle<String> name,Builtins::Name call,bool adapt,BuiltinFunctionId id)514 Handle<JSFunction> SimpleInstallGetter(Handle<JSObject> base,
515                                        Handle<String> name, Builtins::Name call,
516                                        bool adapt, BuiltinFunctionId id) {
517   Handle<JSFunction> fun = SimpleInstallGetter(base, name, call, adapt);
518   fun->shared()->set_builtin_function_id(id);
519   return fun;
520 }
521 
InstallConstant(Isolate * isolate,Handle<JSObject> holder,const char * name,Handle<Object> value)522 void InstallConstant(Isolate* isolate, Handle<JSObject> holder,
523                      const char* name, Handle<Object> value) {
524   JSObject::AddProperty(
525       holder, isolate->factory()->NewStringFromAsciiChecked(name), value,
526       static_cast<PropertyAttributes>(DONT_DELETE | DONT_ENUM | READ_ONLY));
527 }
528 
InstallSpeciesGetter(Handle<JSFunction> constructor)529 void InstallSpeciesGetter(Handle<JSFunction> constructor) {
530   Factory* factory = constructor->GetIsolate()->factory();
531   // TODO(adamk): We should be able to share a SharedFunctionInfo
532   // between all these JSFunctins.
533   SimpleInstallGetter(constructor, factory->symbol_species_string(),
534                       factory->species_symbol(), Builtins::kReturnReceiver,
535                       true);
536 }
537 
538 }  // namespace
539 
CreateEmptyFunction(Isolate * isolate)540 Handle<JSFunction> Genesis::CreateEmptyFunction(Isolate* isolate) {
541   // Allocate the map for function instances. Maps are allocated first and their
542   // prototypes patched later, once empty function is created.
543 
544   // Functions with this map will not have a 'prototype' property, and
545   // can not be used as constructors.
546   Handle<Map> function_without_prototype_map =
547       factory()->CreateSloppyFunctionMap(FUNCTION_WITHOUT_PROTOTYPE);
548   native_context()->set_sloppy_function_without_prototype_map(
549       *function_without_prototype_map);
550 
551   // Allocate the function map. This map is temporary, used only for processing
552   // of builtins.
553   // Later the map is replaced with writable prototype map, allocated below.
554   Handle<Map> function_map =
555       factory()->CreateSloppyFunctionMap(FUNCTION_WITH_READONLY_PROTOTYPE);
556   native_context()->set_sloppy_function_map(*function_map);
557   native_context()->set_sloppy_function_with_readonly_prototype_map(
558       *function_map);
559 
560   // The final map for functions. Writeable prototype.
561   // This map is installed in MakeFunctionInstancePrototypeWritable.
562   sloppy_function_map_writable_prototype_ =
563       factory()->CreateSloppyFunctionMap(FUNCTION_WITH_WRITEABLE_PROTOTYPE);
564   Factory* factory = isolate->factory();
565 
566   Handle<String> object_name = factory->Object_string();
567 
568   Handle<JSObject> object_function_prototype;
569 
570   {  // --- O b j e c t ---
571     Handle<JSFunction> object_fun = factory->NewFunction(object_name);
572     int unused = JSObject::kInitialGlobalObjectUnusedPropertiesCount;
573     int instance_size = JSObject::kHeaderSize + kPointerSize * unused;
574     Handle<Map> object_function_map =
575         factory->NewMap(JS_OBJECT_TYPE, instance_size);
576     object_function_map->SetInObjectProperties(unused);
577     JSFunction::SetInitialMap(object_fun, object_function_map,
578                               isolate->factory()->null_value());
579     object_function_map->set_unused_property_fields(unused);
580 
581     native_context()->set_object_function(*object_fun);
582 
583     // Allocate a new prototype for the object function.
584     object_function_prototype =
585         factory->NewJSObject(isolate->object_function(), TENURED);
586     Handle<Map> map = Map::Copy(handle(object_function_prototype->map()),
587                                 "EmptyObjectPrototype");
588     map->set_is_prototype_map(true);
589     // Ban re-setting Object.prototype.__proto__ to prevent Proxy security bug
590     map->set_immutable_proto(true);
591     object_function_prototype->set_map(*map);
592 
593     native_context()->set_initial_object_prototype(*object_function_prototype);
594     // For bootstrapping set the array prototype to be the same as the object
595     // prototype, otherwise the missing initial_array_prototype will cause
596     // assertions during startup.
597     native_context()->set_initial_array_prototype(*object_function_prototype);
598     Accessors::FunctionSetPrototype(object_fun, object_function_prototype)
599         .Assert();
600   }
601 
602   // Allocate the empty function as the prototype for function - ES6 19.2.3
603   Handle<Code> code(isolate->builtins()->EmptyFunction());
604   Handle<JSFunction> empty_function =
605       factory->NewFunctionWithoutPrototype(factory->empty_string(), code);
606 
607   // Allocate the function map first and then patch the prototype later
608   Handle<Map> empty_function_map =
609       factory->CreateSloppyFunctionMap(FUNCTION_WITHOUT_PROTOTYPE);
610   DCHECK(!empty_function_map->is_dictionary_map());
611   Map::SetPrototype(empty_function_map, object_function_prototype);
612   empty_function_map->set_is_prototype_map(true);
613 
614   empty_function->set_map(*empty_function_map);
615 
616   // --- E m p t y ---
617   Handle<String> source = factory->NewStringFromStaticChars("() {}");
618   Handle<Script> script = factory->NewScript(source);
619   script->set_type(Script::TYPE_NATIVE);
620   Handle<FixedArray> infos = factory->NewFixedArray(2);
621   script->set_shared_function_infos(*infos);
622   empty_function->shared()->set_start_position(0);
623   empty_function->shared()->set_end_position(source->length());
624   empty_function->shared()->set_function_literal_id(1);
625   empty_function->shared()->DontAdaptArguments();
626   SharedFunctionInfo::SetScript(handle(empty_function->shared()), script);
627 
628   // Set prototypes for the function maps.
629   Handle<Map> sloppy_function_map(native_context()->sloppy_function_map(),
630                                   isolate);
631   Handle<Map> sloppy_function_without_prototype_map(
632       native_context()->sloppy_function_without_prototype_map(), isolate);
633   Map::SetPrototype(sloppy_function_map, empty_function);
634   Map::SetPrototype(sloppy_function_without_prototype_map, empty_function);
635   Map::SetPrototype(sloppy_function_map_writable_prototype_, empty_function);
636 
637   return empty_function;
638 }
639 
640 
641 // Creates the %ThrowTypeError% function.
GetThrowTypeErrorIntrinsic(Builtins::Name builtin_name)642 Handle<JSFunction> Genesis::GetThrowTypeErrorIntrinsic(
643     Builtins::Name builtin_name) {
644   Handle<String> name =
645       factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("ThrowTypeError"));
646   Handle<Code> code(isolate()->builtins()->builtin(builtin_name));
647   Handle<JSFunction> function =
648       factory()->NewFunctionWithoutPrototype(name, code, true);
649   function->shared()->DontAdaptArguments();
650 
651   // %ThrowTypeError% must not have a name property.
652   if (JSReceiver::DeleteProperty(function, factory()->name_string())
653           .IsNothing()) {
654     DCHECK(false);
655   }
656 
657   // length needs to be non configurable.
658   Handle<Object> value(Smi::FromInt(function->shared()->length()), isolate());
659   JSObject::SetOwnPropertyIgnoreAttributes(
660       function, factory()->length_string(), value,
661       static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY))
662       .Assert();
663 
664   if (JSObject::PreventExtensions(function, Object::THROW_ON_ERROR)
665           .IsNothing()) {
666     DCHECK(false);
667   }
668 
669   return function;
670 }
671 
672 
673 // ECMAScript 5th Edition, 13.2.3
GetRestrictedFunctionPropertiesThrower()674 Handle<JSFunction> Genesis::GetRestrictedFunctionPropertiesThrower() {
675   if (restricted_function_properties_thrower_.is_null()) {
676     restricted_function_properties_thrower_ = GetThrowTypeErrorIntrinsic(
677         Builtins::kRestrictedFunctionPropertiesThrower);
678   }
679   return restricted_function_properties_thrower_;
680 }
681 
682 
GetStrictArgumentsPoisonFunction()683 Handle<JSFunction> Genesis::GetStrictArgumentsPoisonFunction() {
684   if (strict_poison_function_.is_null()) {
685     strict_poison_function_ = GetThrowTypeErrorIntrinsic(
686         Builtins::kRestrictedStrictArgumentsPropertiesThrower);
687   }
688   return strict_poison_function_;
689 }
690 
691 
CreateStrictModeFunctionMaps(Handle<JSFunction> empty)692 void Genesis::CreateStrictModeFunctionMaps(Handle<JSFunction> empty) {
693   // Allocate map for the prototype-less strict mode instances.
694   Handle<Map> strict_function_without_prototype_map =
695       factory()->CreateStrictFunctionMap(FUNCTION_WITHOUT_PROTOTYPE, empty);
696   native_context()->set_strict_function_without_prototype_map(
697       *strict_function_without_prototype_map);
698 
699   // Allocate map for the strict mode functions. This map is temporary, used
700   // only for processing of builtins.
701   // Later the map is replaced with writable prototype map, allocated below.
702   Handle<Map> strict_function_map = factory()->CreateStrictFunctionMap(
703       FUNCTION_WITH_READONLY_PROTOTYPE, empty);
704   native_context()->set_strict_function_map(*strict_function_map);
705 
706   // The final map for the strict mode functions. Writeable prototype.
707   // This map is installed in MakeFunctionInstancePrototypeWritable.
708   strict_function_map_writable_prototype_ = factory()->CreateStrictFunctionMap(
709       FUNCTION_WITH_WRITEABLE_PROTOTYPE, empty);
710 
711   // Allocate map for classes
712   class_function_map_ = factory()->CreateClassFunctionMap(empty);
713   native_context()->set_class_function_map(*class_function_map_);
714 
715   // Now that the strict mode function map is available, set up the
716   // restricted "arguments" and "caller" getters.
717   AddRestrictedFunctionProperties(empty);
718 }
719 
CreateIteratorMaps(Handle<JSFunction> empty)720 void Genesis::CreateIteratorMaps(Handle<JSFunction> empty) {
721   // Create iterator-related meta-objects.
722   Handle<JSObject> iterator_prototype =
723       factory()->NewJSObject(isolate()->object_function(), TENURED);
724 
725   Handle<JSFunction> iterator_prototype_iterator = SimpleCreateFunction(
726       isolate(), factory()->NewStringFromAsciiChecked("[Symbol.iterator]"),
727       Builtins::kReturnReceiver, 0, true);
728 
729   JSObject::AddProperty(iterator_prototype, factory()->iterator_symbol(),
730                         iterator_prototype_iterator, DONT_ENUM);
731   native_context()->set_initial_iterator_prototype(*iterator_prototype);
732 
733   Handle<JSObject> generator_object_prototype =
734       factory()->NewJSObject(isolate()->object_function(), TENURED);
735   native_context()->set_initial_generator_prototype(
736       *generator_object_prototype);
737   JSObject::ForceSetPrototype(generator_object_prototype, iterator_prototype);
738   Handle<JSObject> generator_function_prototype =
739       factory()->NewJSObject(isolate()->object_function(), TENURED);
740   JSObject::ForceSetPrototype(generator_function_prototype, empty);
741 
742   JSObject::AddProperty(
743       generator_function_prototype, factory()->to_string_tag_symbol(),
744       factory()->NewStringFromAsciiChecked("GeneratorFunction"),
745       static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
746   JSObject::AddProperty(generator_function_prototype,
747                         factory()->prototype_string(),
748                         generator_object_prototype,
749                         static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
750 
751   JSObject::AddProperty(generator_object_prototype,
752                         factory()->constructor_string(),
753                         generator_function_prototype,
754                         static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
755   JSObject::AddProperty(generator_object_prototype,
756                         factory()->to_string_tag_symbol(),
757                         factory()->NewStringFromAsciiChecked("Generator"),
758                         static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
759   SimpleInstallFunction(generator_object_prototype, "next",
760                         Builtins::kGeneratorPrototypeNext, 1, true);
761   SimpleInstallFunction(generator_object_prototype, "return",
762                         Builtins::kGeneratorPrototypeReturn, 1, true);
763   SimpleInstallFunction(generator_object_prototype, "throw",
764                         Builtins::kGeneratorPrototypeThrow, 1, true);
765 
766   // Internal version of generator_prototype_next, flagged as non-native such
767   // that it doesn't show up in Error traces.
768   Handle<JSFunction> generator_next_internal =
769       SimpleCreateFunction(isolate(), factory()->next_string(),
770                            Builtins::kGeneratorPrototypeNext, 1, true);
771   generator_next_internal->shared()->set_native(false);
772   native_context()->set_generator_next_internal(*generator_next_internal);
773 
774   // Create maps for generator functions and their prototypes.  Store those
775   // maps in the native context. The "prototype" property descriptor is
776   // writable, non-enumerable, and non-configurable (as per ES6 draft
777   // 04-14-15, section 25.2.4.3).
778   Handle<Map> strict_function_map(strict_function_map_writable_prototype_);
779   // Generator functions do not have "caller" or "arguments" accessors.
780   Handle<Map> generator_function_map =
781       Map::Copy(strict_function_map, "GeneratorFunction");
782   generator_function_map->set_is_constructor(false);
783   Map::SetPrototype(generator_function_map, generator_function_prototype);
784   native_context()->set_generator_function_map(*generator_function_map);
785 
786   Handle<JSFunction> object_function(native_context()->object_function());
787   Handle<Map> generator_object_prototype_map = Map::Create(isolate(), 0);
788   Map::SetPrototype(generator_object_prototype_map, generator_object_prototype);
789   native_context()->set_generator_object_prototype_map(
790       *generator_object_prototype_map);
791 }
792 
CreateAsyncIteratorMaps()793 void Genesis::CreateAsyncIteratorMaps() {
794   // %AsyncIteratorPrototype%
795   // proposal-async-iteration/#sec-asynciteratorprototype
796   Handle<JSObject> async_iterator_prototype =
797       factory()->NewJSObject(isolate()->object_function(), TENURED);
798 
799   Handle<JSFunction> async_iterator_prototype_iterator = SimpleCreateFunction(
800       isolate(), factory()->NewStringFromAsciiChecked("[Symbol.asyncIterator]"),
801       Builtins::kReturnReceiver, 0, true);
802 
803   JSObject::AddProperty(async_iterator_prototype,
804                         factory()->async_iterator_symbol(),
805                         async_iterator_prototype_iterator, DONT_ENUM);
806 
807   // %AsyncFromSyncIteratorPrototype%
808   // proposal-async-iteration/#sec-%asyncfromsynciteratorprototype%-object
809   Handle<JSObject> async_from_sync_iterator_prototype =
810       factory()->NewJSObject(isolate()->object_function(), TENURED);
811   SimpleInstallFunction(async_from_sync_iterator_prototype,
812                         factory()->next_string(),
813                         Builtins::kAsyncFromSyncIteratorPrototypeNext, 1, true);
814   SimpleInstallFunction(
815       async_from_sync_iterator_prototype, factory()->return_string(),
816       Builtins::kAsyncFromSyncIteratorPrototypeReturn, 1, true);
817   SimpleInstallFunction(
818       async_from_sync_iterator_prototype, factory()->throw_string(),
819       Builtins::kAsyncFromSyncIteratorPrototypeThrow, 1, true);
820 
821   JSObject::AddProperty(
822       async_from_sync_iterator_prototype, factory()->to_string_tag_symbol(),
823       factory()->NewStringFromAsciiChecked("Async-from-Sync Iterator"),
824       static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
825 
826   JSObject::ForceSetPrototype(async_from_sync_iterator_prototype,
827                               async_iterator_prototype);
828 
829   Handle<Map> async_from_sync_iterator_map = factory()->NewMap(
830       JS_ASYNC_FROM_SYNC_ITERATOR_TYPE, JSAsyncFromSyncIterator::kSize);
831   Map::SetPrototype(async_from_sync_iterator_map,
832                     async_from_sync_iterator_prototype);
833   native_context()->set_async_from_sync_iterator_map(
834       *async_from_sync_iterator_map);
835 }
836 
CreateAsyncFunctionMaps(Handle<JSFunction> empty)837 void Genesis::CreateAsyncFunctionMaps(Handle<JSFunction> empty) {
838   // %AsyncFunctionPrototype% intrinsic
839   Handle<JSObject> async_function_prototype =
840       factory()->NewJSObject(isolate()->object_function(), TENURED);
841   JSObject::ForceSetPrototype(async_function_prototype, empty);
842 
843   JSObject::AddProperty(async_function_prototype,
844                         factory()->to_string_tag_symbol(),
845                         factory()->NewStringFromAsciiChecked("AsyncFunction"),
846                         static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
847 
848   Handle<Map> strict_function_map(
849       native_context()->strict_function_without_prototype_map());
850   Handle<Map> async_function_map =
851       Map::Copy(strict_function_map, "AsyncFunction");
852   async_function_map->set_is_constructor(false);
853   Map::SetPrototype(async_function_map, async_function_prototype);
854   native_context()->set_async_function_map(*async_function_map);
855 }
856 
CreateJSProxyMaps()857 void Genesis::CreateJSProxyMaps() {
858   // Allocate the different maps for all Proxy types.
859   // Next to the default proxy, we need maps indicating callable and
860   // constructable proxies.
861   Handle<Map> proxy_function_map =
862       Map::Copy(isolate()->sloppy_function_without_prototype_map(), "Proxy");
863   proxy_function_map->set_is_constructor(true);
864   native_context()->set_proxy_function_map(*proxy_function_map);
865 
866   Handle<Map> proxy_map =
867       factory()->NewMap(JS_PROXY_TYPE, JSProxy::kSize, FAST_ELEMENTS);
868   proxy_map->set_dictionary_map(true);
869   native_context()->set_proxy_map(*proxy_map);
870 
871   Handle<Map> proxy_callable_map = Map::Copy(proxy_map, "callable Proxy");
872   proxy_callable_map->set_is_callable();
873   native_context()->set_proxy_callable_map(*proxy_callable_map);
874   proxy_callable_map->SetConstructor(native_context()->function_function());
875 
876   Handle<Map> proxy_constructor_map =
877       Map::Copy(proxy_callable_map, "constructor Proxy");
878   proxy_constructor_map->set_is_constructor(true);
879   native_context()->set_proxy_constructor_map(*proxy_constructor_map);
880 }
881 
ReplaceAccessors(Handle<Map> map,Handle<String> name,PropertyAttributes attributes,Handle<AccessorPair> accessor_pair)882 static void ReplaceAccessors(Handle<Map> map,
883                              Handle<String> name,
884                              PropertyAttributes attributes,
885                              Handle<AccessorPair> accessor_pair) {
886   DescriptorArray* descriptors = map->instance_descriptors();
887   int idx = descriptors->SearchWithCache(map->GetIsolate(), *name, *map);
888   Descriptor d = Descriptor::AccessorConstant(name, accessor_pair, attributes);
889   descriptors->Replace(idx, &d);
890 }
891 
AddRestrictedFunctionProperties(Handle<JSFunction> empty)892 void Genesis::AddRestrictedFunctionProperties(Handle<JSFunction> empty) {
893   PropertyAttributes rw_attribs = static_cast<PropertyAttributes>(DONT_ENUM);
894   Handle<JSFunction> thrower = GetRestrictedFunctionPropertiesThrower();
895   Handle<AccessorPair> accessors = factory()->NewAccessorPair();
896   accessors->set_getter(*thrower);
897   accessors->set_setter(*thrower);
898 
899   Handle<Map> map(empty->map());
900   ReplaceAccessors(map, factory()->arguments_string(), rw_attribs, accessors);
901   ReplaceAccessors(map, factory()->caller_string(), rw_attribs, accessors);
902 }
903 
904 
AddToWeakNativeContextList(Context * context)905 static void AddToWeakNativeContextList(Context* context) {
906   DCHECK(context->IsNativeContext());
907   Isolate* isolate = context->GetIsolate();
908   Heap* heap = isolate->heap();
909 #ifdef DEBUG
910   { // NOLINT
911     DCHECK(context->next_context_link()->IsUndefined(isolate));
912     // Check that context is not in the list yet.
913     for (Object* current = heap->native_contexts_list();
914          !current->IsUndefined(isolate);
915          current = Context::cast(current)->next_context_link()) {
916       DCHECK(current != context);
917     }
918   }
919 #endif
920   context->set(Context::NEXT_CONTEXT_LINK, heap->native_contexts_list(),
921                UPDATE_WEAK_WRITE_BARRIER);
922   heap->set_native_contexts_list(context);
923 }
924 
925 
CreateRoots()926 void Genesis::CreateRoots() {
927   // Allocate the native context FixedArray first and then patch the
928   // closure and extension object later (we need the empty function
929   // and the global object, but in order to create those, we need the
930   // native context).
931   native_context_ = factory()->NewNativeContext();
932   AddToWeakNativeContextList(*native_context());
933   isolate()->set_context(*native_context());
934 
935   // Allocate the message listeners object.
936   {
937     Handle<TemplateList> list = TemplateList::New(isolate(), 1);
938     native_context()->set_message_listeners(*list);
939   }
940 }
941 
942 
InstallGlobalThisBinding()943 void Genesis::InstallGlobalThisBinding() {
944   Handle<ScriptContextTable> script_contexts(
945       native_context()->script_context_table());
946   Handle<ScopeInfo> scope_info = ScopeInfo::CreateGlobalThisBinding(isolate());
947   Handle<JSFunction> closure(native_context()->closure());
948   Handle<Context> context = factory()->NewScriptContext(closure, scope_info);
949 
950   // Go ahead and hook it up while we're at it.
951   int slot = scope_info->ReceiverContextSlotIndex();
952   DCHECK_EQ(slot, Context::MIN_CONTEXT_SLOTS);
953   context->set(slot, native_context()->global_proxy());
954 
955   Handle<ScriptContextTable> new_script_contexts =
956       ScriptContextTable::Extend(script_contexts, context);
957   native_context()->set_script_context_table(*new_script_contexts);
958 }
959 
960 
CreateNewGlobals(v8::Local<v8::ObjectTemplate> global_proxy_template,Handle<JSGlobalProxy> global_proxy)961 Handle<JSGlobalObject> Genesis::CreateNewGlobals(
962     v8::Local<v8::ObjectTemplate> global_proxy_template,
963     Handle<JSGlobalProxy> global_proxy) {
964   // The argument global_proxy_template aka data is an ObjectTemplateInfo.
965   // It has a constructor pointer that points at global_constructor which is a
966   // FunctionTemplateInfo.
967   // The global_proxy_constructor is used to (re)initialize the
968   // global_proxy. The global_proxy_constructor also has a prototype_template
969   // pointer that points at js_global_object_template which is an
970   // ObjectTemplateInfo.
971   // That in turn has a constructor pointer that points at
972   // js_global_object_constructor which is a FunctionTemplateInfo.
973   // js_global_object_constructor is used to make js_global_object_function
974   // js_global_object_function is used to make the new global_object.
975   //
976   // --- G l o b a l ---
977   // Step 1: Create a fresh JSGlobalObject.
978   Handle<JSFunction> js_global_object_function;
979   Handle<ObjectTemplateInfo> js_global_object_template;
980   if (!global_proxy_template.IsEmpty()) {
981     // Get prototype template of the global_proxy_template.
982     Handle<ObjectTemplateInfo> data =
983         v8::Utils::OpenHandle(*global_proxy_template);
984     Handle<FunctionTemplateInfo> global_constructor =
985         Handle<FunctionTemplateInfo>(
986             FunctionTemplateInfo::cast(data->constructor()));
987     Handle<Object> proto_template(global_constructor->prototype_template(),
988                                   isolate());
989     if (!proto_template->IsUndefined(isolate())) {
990       js_global_object_template =
991           Handle<ObjectTemplateInfo>::cast(proto_template);
992     }
993   }
994 
995   if (js_global_object_template.is_null()) {
996     Handle<String> name = Handle<String>(heap()->empty_string());
997     Handle<Code> code = isolate()->builtins()->Illegal();
998     Handle<JSObject> prototype =
999         factory()->NewFunctionPrototype(isolate()->object_function());
1000     js_global_object_function = factory()->NewFunction(
1001         name, code, prototype, JS_GLOBAL_OBJECT_TYPE, JSGlobalObject::kSize);
1002 #ifdef DEBUG
1003     LookupIterator it(prototype, factory()->constructor_string(),
1004                       LookupIterator::OWN_SKIP_INTERCEPTOR);
1005     Handle<Object> value = Object::GetProperty(&it).ToHandleChecked();
1006     DCHECK(it.IsFound());
1007     DCHECK_EQ(*isolate()->object_function(), *value);
1008 #endif
1009   } else {
1010     Handle<FunctionTemplateInfo> js_global_object_constructor(
1011         FunctionTemplateInfo::cast(js_global_object_template->constructor()));
1012     js_global_object_function = ApiNatives::CreateApiFunction(
1013         isolate(), js_global_object_constructor, factory()->the_hole_value(),
1014         ApiNatives::GlobalObjectType);
1015   }
1016 
1017   js_global_object_function->initial_map()->set_is_prototype_map(true);
1018   js_global_object_function->initial_map()->set_dictionary_map(true);
1019   Handle<JSGlobalObject> global_object =
1020       factory()->NewJSGlobalObject(js_global_object_function);
1021 
1022   // Step 2: (re)initialize the global proxy object.
1023   Handle<JSFunction> global_proxy_function;
1024   if (global_proxy_template.IsEmpty()) {
1025     Handle<String> name = Handle<String>(heap()->empty_string());
1026     Handle<Code> code = isolate()->builtins()->Illegal();
1027     global_proxy_function =
1028         factory()->NewFunction(name, code, JS_GLOBAL_PROXY_TYPE,
1029                                JSGlobalProxy::SizeWithInternalFields(0));
1030   } else {
1031     Handle<ObjectTemplateInfo> data =
1032         v8::Utils::OpenHandle(*global_proxy_template);
1033     Handle<FunctionTemplateInfo> global_constructor(
1034             FunctionTemplateInfo::cast(data->constructor()));
1035     global_proxy_function = ApiNatives::CreateApiFunction(
1036         isolate(), global_constructor, factory()->the_hole_value(),
1037         ApiNatives::GlobalProxyType);
1038   }
1039   Handle<String> global_name = factory()->global_string();
1040   global_proxy_function->shared()->set_instance_class_name(*global_name);
1041   global_proxy_function->initial_map()->set_is_access_check_needed(true);
1042   global_proxy_function->initial_map()->set_has_hidden_prototype(true);
1043   native_context()->set_global_proxy_function(*global_proxy_function);
1044 
1045   // Set global_proxy.__proto__ to js_global after ConfigureGlobalObjects
1046   // Return the global proxy.
1047 
1048   factory()->ReinitializeJSGlobalProxy(global_proxy, global_proxy_function);
1049 
1050   // Set the native context for the global object.
1051   global_object->set_native_context(*native_context());
1052   global_object->set_global_proxy(*global_proxy);
1053   // Set the native context of the global proxy.
1054   global_proxy->set_native_context(*native_context());
1055   // Set the global proxy of the native context. If the native context has been
1056   // deserialized, the global proxy is already correctly set up by the
1057   // deserializer. Otherwise it's undefined.
1058   DCHECK(native_context()
1059              ->get(Context::GLOBAL_PROXY_INDEX)
1060              ->IsUndefined(isolate()) ||
1061          native_context()->global_proxy() == *global_proxy);
1062   native_context()->set_global_proxy(*global_proxy);
1063 
1064   return global_object;
1065 }
1066 
HookUpGlobalProxy(Handle<JSGlobalProxy> global_proxy)1067 void Genesis::HookUpGlobalProxy(Handle<JSGlobalProxy> global_proxy) {
1068   // Re-initialize the global proxy with the global proxy function from the
1069   // snapshot, and then set up the link to the native context.
1070   Handle<JSFunction> global_proxy_function(
1071       native_context()->global_proxy_function());
1072   factory()->ReinitializeJSGlobalProxy(global_proxy, global_proxy_function);
1073   Handle<JSObject> global_object(
1074       JSObject::cast(native_context()->global_object()));
1075   JSObject::ForceSetPrototype(global_proxy, global_object);
1076   global_proxy->set_native_context(*native_context());
1077   DCHECK(native_context()->global_proxy() == *global_proxy);
1078 }
1079 
HookUpGlobalObject(Handle<JSGlobalObject> global_object)1080 void Genesis::HookUpGlobalObject(Handle<JSGlobalObject> global_object) {
1081   Handle<JSGlobalObject> global_object_from_snapshot(
1082       JSGlobalObject::cast(native_context()->extension()));
1083   native_context()->set_extension(*global_object);
1084   native_context()->set_security_token(*global_object);
1085 
1086   TransferNamedProperties(global_object_from_snapshot, global_object);
1087   TransferIndexedProperties(global_object_from_snapshot, global_object);
1088 }
1089 
InstallWithIntrinsicDefaultProto(Isolate * isolate,Handle<JSFunction> function,int context_index)1090 static void InstallWithIntrinsicDefaultProto(Isolate* isolate,
1091                                              Handle<JSFunction> function,
1092                                              int context_index) {
1093   Handle<Smi> index(Smi::FromInt(context_index), isolate);
1094   JSObject::AddProperty(
1095       function, isolate->factory()->native_context_index_symbol(), index, NONE);
1096   isolate->native_context()->set(context_index, *function);
1097 }
1098 
InstallError(Isolate * isolate,Handle<JSObject> global,Handle<String> name,int context_index)1099 static void InstallError(Isolate* isolate, Handle<JSObject> global,
1100                          Handle<String> name, int context_index) {
1101   Factory* factory = isolate->factory();
1102 
1103   Handle<JSFunction> error_fun =
1104       InstallFunction(global, name, JS_ERROR_TYPE, JSObject::kHeaderSize,
1105                       isolate->initial_object_prototype(),
1106                       Builtins::kErrorConstructor, DONT_ENUM);
1107   error_fun->shared()->set_instance_class_name(*factory->Error_string());
1108   error_fun->shared()->DontAdaptArguments();
1109   error_fun->shared()->set_construct_stub(
1110       *isolate->builtins()->ErrorConstructor());
1111   error_fun->shared()->set_length(1);
1112 
1113   if (context_index == Context::ERROR_FUNCTION_INDEX) {
1114     SimpleInstallFunction(error_fun, "captureStackTrace",
1115                           Builtins::kErrorCaptureStackTrace, 2, false);
1116   }
1117 
1118   InstallWithIntrinsicDefaultProto(isolate, error_fun, context_index);
1119 
1120   {
1121     Handle<JSObject> prototype =
1122         factory->NewJSObject(isolate->object_function(), TENURED);
1123 
1124     JSObject::AddProperty(prototype, factory->name_string(), name, DONT_ENUM);
1125     JSObject::AddProperty(prototype, factory->message_string(),
1126                           factory->empty_string(), DONT_ENUM);
1127     JSObject::AddProperty(prototype, factory->constructor_string(), error_fun,
1128                           DONT_ENUM);
1129 
1130     if (context_index == Context::ERROR_FUNCTION_INDEX) {
1131       Handle<JSFunction> to_string_fun =
1132           SimpleInstallFunction(prototype, factory->toString_string(),
1133                                 Builtins::kErrorPrototypeToString, 0, true);
1134       isolate->native_context()->set_error_to_string(*to_string_fun);
1135     } else {
1136       DCHECK(isolate->native_context()->error_to_string()->IsJSFunction());
1137 
1138       InstallFunction(prototype, isolate->error_to_string(),
1139                       factory->toString_string(), DONT_ENUM);
1140 
1141       Handle<JSFunction> global_error = isolate->error_function();
1142       CHECK(JSReceiver::SetPrototype(error_fun, global_error, false,
1143                                      Object::THROW_ON_ERROR)
1144                 .FromMaybe(false));
1145       CHECK(JSReceiver::SetPrototype(prototype,
1146                                      handle(global_error->prototype(), isolate),
1147                                      false, Object::THROW_ON_ERROR)
1148                 .FromMaybe(false));
1149     }
1150 
1151     Accessors::FunctionSetPrototype(error_fun, prototype).Assert();
1152   }
1153 
1154   Handle<Map> initial_map(error_fun->initial_map());
1155   Map::EnsureDescriptorSlack(initial_map, 1);
1156 
1157   PropertyAttributes attribs = DONT_ENUM;
1158   Handle<AccessorInfo> error_stack =
1159       Accessors::ErrorStackInfo(isolate, attribs);
1160   {
1161     Descriptor d = Descriptor::AccessorConstant(
1162         Handle<Name>(Name::cast(error_stack->name())), error_stack, attribs);
1163     initial_map->AppendDescriptor(&d);
1164   }
1165 }
1166 
InstallMakeError(Isolate * isolate,Handle<Code> code,int context_index)1167 static void InstallMakeError(Isolate* isolate, Handle<Code> code,
1168                              int context_index) {
1169   Handle<JSFunction> function =
1170       isolate->factory()->NewFunction(isolate->factory()->empty_string(), code,
1171                                       JS_OBJECT_TYPE, JSObject::kHeaderSize);
1172   function->shared()->DontAdaptArguments();
1173   isolate->native_context()->set(context_index, *function);
1174 }
1175 
1176 // This is only called if we are not using snapshots.  The equivalent
1177 // work in the snapshot case is done in HookUpGlobalObject.
InitializeGlobal(Handle<JSGlobalObject> global_object,Handle<JSFunction> empty_function,GlobalContextType context_type)1178 void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
1179                                Handle<JSFunction> empty_function,
1180                                GlobalContextType context_type) {
1181   // --- N a t i v e   C o n t e x t ---
1182   // Use the empty function as closure (no scope info).
1183   native_context()->set_closure(*empty_function);
1184   native_context()->set_previous(NULL);
1185   // Set extension and global object.
1186   native_context()->set_extension(*global_object);
1187   // Security setup: Set the security token of the native context to the global
1188   // object. This makes the security check between two different contexts fail
1189   // by default even in case of global object reinitialization.
1190   native_context()->set_security_token(*global_object);
1191 
1192   Isolate* isolate = global_object->GetIsolate();
1193   Factory* factory = isolate->factory();
1194 
1195   native_context()->set_osr_code_table(*factory->empty_fixed_array());
1196 
1197   Handle<ScriptContextTable> script_context_table =
1198       factory->NewScriptContextTable();
1199   native_context()->set_script_context_table(*script_context_table);
1200   InstallGlobalThisBinding();
1201 
1202   {  // --- O b j e c t ---
1203     Handle<String> object_name = factory->Object_string();
1204     Handle<JSFunction> object_function = isolate->object_function();
1205     JSObject::AddProperty(global_object, object_name, object_function,
1206                           DONT_ENUM);
1207 
1208     SimpleInstallFunction(object_function, factory->assign_string(),
1209                           Builtins::kObjectAssign, 2, false);
1210     SimpleInstallFunction(object_function, "getOwnPropertyDescriptor",
1211                           Builtins::kObjectGetOwnPropertyDescriptor, 2, false);
1212     SimpleInstallFunction(object_function,
1213                           factory->getOwnPropertyDescriptors_string(),
1214                           Builtins::kObjectGetOwnPropertyDescriptors, 1, false);
1215     SimpleInstallFunction(object_function, "getOwnPropertyNames",
1216                           Builtins::kObjectGetOwnPropertyNames, 1, false);
1217     SimpleInstallFunction(object_function, "getOwnPropertySymbols",
1218                           Builtins::kObjectGetOwnPropertySymbols, 1, false);
1219     SimpleInstallFunction(object_function, "is",
1220                           Builtins::kObjectIs, 2, true);
1221     SimpleInstallFunction(object_function, "preventExtensions",
1222                           Builtins::kObjectPreventExtensions, 1, false);
1223     SimpleInstallFunction(object_function, "seal",
1224                           Builtins::kObjectSeal, 1, false);
1225 
1226     Handle<JSFunction> object_create =
1227         SimpleInstallFunction(object_function, factory->create_string(),
1228                               Builtins::kObjectCreate, 2, true);
1229     native_context()->set_object_create(*object_create);
1230 
1231     Handle<JSFunction> object_define_properties = SimpleInstallFunction(
1232         object_function, "defineProperties",
1233         Builtins::kObjectDefineProperties, 2, true);
1234     native_context()->set_object_define_properties(*object_define_properties);
1235 
1236     Handle<JSFunction> object_define_property = SimpleInstallFunction(
1237         object_function, factory->defineProperty_string(),
1238         Builtins::kObjectDefineProperty, 3, true);
1239     native_context()->set_object_define_property(*object_define_property);
1240 
1241     Handle<JSFunction> object_freeze = SimpleInstallFunction(
1242         object_function, "freeze", Builtins::kObjectFreeze, 1, false);
1243     native_context()->set_object_freeze(*object_freeze);
1244 
1245     Handle<JSFunction> object_get_prototype_of = SimpleInstallFunction(
1246         object_function, "getPrototypeOf", Builtins::kObjectGetPrototypeOf,
1247         1, false);
1248     native_context()->set_object_get_prototype_of(*object_get_prototype_of);
1249     SimpleInstallFunction(object_function, "setPrototypeOf",
1250                           Builtins::kObjectSetPrototypeOf, 2, false);
1251 
1252     Handle<JSFunction> object_is_extensible = SimpleInstallFunction(
1253         object_function, "isExtensible", Builtins::kObjectIsExtensible,
1254         1, false);
1255     native_context()->set_object_is_extensible(*object_is_extensible);
1256 
1257     Handle<JSFunction> object_is_frozen = SimpleInstallFunction(
1258         object_function, "isFrozen", Builtins::kObjectIsFrozen, 1, false);
1259     native_context()->set_object_is_frozen(*object_is_frozen);
1260 
1261     Handle<JSFunction> object_is_sealed = SimpleInstallFunction(
1262         object_function, "isSealed", Builtins::kObjectIsSealed, 1, false);
1263     native_context()->set_object_is_sealed(*object_is_sealed);
1264 
1265     Handle<JSFunction> object_keys = SimpleInstallFunction(
1266         object_function, "keys", Builtins::kObjectKeys, 1, false);
1267     native_context()->set_object_keys(*object_keys);
1268     SimpleInstallFunction(object_function, factory->entries_string(),
1269                           Builtins::kObjectEntries, 1, false);
1270     SimpleInstallFunction(object_function, factory->values_string(),
1271                           Builtins::kObjectValues, 1, false);
1272 
1273     SimpleInstallFunction(isolate->initial_object_prototype(),
1274                           "__defineGetter__", Builtins::kObjectDefineGetter, 2,
1275                           true);
1276     SimpleInstallFunction(isolate->initial_object_prototype(),
1277                           "__defineSetter__", Builtins::kObjectDefineSetter, 2,
1278                           true);
1279     SimpleInstallFunction(isolate->initial_object_prototype(), "hasOwnProperty",
1280                           Builtins::kObjectHasOwnProperty, 1, true);
1281     SimpleInstallFunction(isolate->initial_object_prototype(),
1282                           "__lookupGetter__", Builtins::kObjectLookupGetter, 1,
1283                           true);
1284     SimpleInstallFunction(isolate->initial_object_prototype(),
1285                           "__lookupSetter__", Builtins::kObjectLookupSetter, 1,
1286                           true);
1287     SimpleInstallFunction(
1288         isolate->initial_object_prototype(), "propertyIsEnumerable",
1289         Builtins::kObjectPrototypePropertyIsEnumerable, 1, false);
1290 
1291     SimpleInstallGetterSetter(isolate->initial_object_prototype(),
1292                               factory->proto_string(),
1293                               Builtins::kObjectPrototypeGetProto,
1294                               Builtins::kObjectPrototypeSetProto, DONT_ENUM);
1295   }
1296 
1297   Handle<JSObject> global(native_context()->global_object());
1298 
1299   {  // --- F u n c t i o n ---
1300     Handle<JSFunction> prototype = empty_function;
1301     Handle<JSFunction> function_fun =
1302         InstallFunction(global, "Function", JS_FUNCTION_TYPE, JSFunction::kSize,
1303                         prototype, Builtins::kFunctionConstructor);
1304     function_fun->set_prototype_or_initial_map(
1305         *sloppy_function_map_writable_prototype_);
1306     function_fun->shared()->DontAdaptArguments();
1307     function_fun->shared()->SetConstructStub(
1308         *isolate->builtins()->FunctionConstructor());
1309     function_fun->shared()->set_length(1);
1310     InstallWithIntrinsicDefaultProto(isolate, function_fun,
1311                                      Context::FUNCTION_FUNCTION_INDEX);
1312 
1313     // Setup the methods on the %FunctionPrototype%.
1314     SimpleInstallFunction(prototype, factory->apply_string(),
1315                           Builtins::kFunctionPrototypeApply, 2, false);
1316     SimpleInstallFunction(prototype, factory->bind_string(),
1317                           Builtins::kFastFunctionPrototypeBind, 1, false);
1318     SimpleInstallFunction(prototype, factory->call_string(),
1319                           Builtins::kFunctionPrototypeCall, 1, false);
1320     SimpleInstallFunction(prototype, factory->toString_string(),
1321                           Builtins::kFunctionPrototypeToString, 0, false);
1322 
1323     // Install the @@hasInstance function.
1324     Handle<JSFunction> has_instance = InstallFunction(
1325         prototype, factory->has_instance_symbol(), JS_OBJECT_TYPE,
1326         JSObject::kHeaderSize, MaybeHandle<JSObject>(),
1327         Builtins::kFunctionPrototypeHasInstance,
1328         static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY));
1329     has_instance->shared()->set_builtin_function_id(kFunctionHasInstance);
1330     native_context()->set_function_has_instance(*has_instance);
1331 
1332     // Set the expected parameters for @@hasInstance to 1; required by builtin.
1333     has_instance->shared()->set_internal_formal_parameter_count(1);
1334 
1335     // Set the length for the function to satisfy ECMA-262.
1336     has_instance->shared()->set_length(1);
1337 
1338     // Install the "constructor" property on the %FunctionPrototype%.
1339     JSObject::AddProperty(prototype, factory->constructor_string(),
1340                           function_fun, DONT_ENUM);
1341 
1342     sloppy_function_map_writable_prototype_->SetConstructor(*function_fun);
1343     strict_function_map_writable_prototype_->SetConstructor(*function_fun);
1344     class_function_map_->SetConstructor(*function_fun);
1345   }
1346 
1347   {
1348     // --- A s y n c F r o m S y n c I t e r a t o r
1349     Handle<Code> code = isolate->builtins()->AsyncIteratorValueUnwrap();
1350     Handle<SharedFunctionInfo> info =
1351         factory->NewSharedFunctionInfo(factory->empty_string(), code, false);
1352     info->set_internal_formal_parameter_count(1);
1353     info->set_length(1);
1354     native_context()->set_async_iterator_value_unwrap_shared_fun(*info);
1355   }
1356 
1357   {  // --- A r r a y ---
1358     Handle<JSFunction> array_function =
1359         InstallFunction(global, "Array", JS_ARRAY_TYPE, JSArray::kSize,
1360                         isolate->initial_object_prototype(),
1361                         Builtins::kArrayCode);
1362     array_function->shared()->DontAdaptArguments();
1363     array_function->shared()->set_builtin_function_id(kArrayCode);
1364 
1365     // This seems a bit hackish, but we need to make sure Array.length
1366     // is 1.
1367     array_function->shared()->set_length(1);
1368 
1369     Handle<Map> initial_map(array_function->initial_map());
1370 
1371     // This assert protects an optimization in
1372     // HGraphBuilder::JSArrayBuilder::EmitMapCode()
1373     DCHECK(initial_map->elements_kind() == GetInitialFastElementsKind());
1374     Map::EnsureDescriptorSlack(initial_map, 1);
1375 
1376     PropertyAttributes attribs = static_cast<PropertyAttributes>(
1377         DONT_ENUM | DONT_DELETE);
1378 
1379     Handle<AccessorInfo> array_length =
1380         Accessors::ArrayLengthInfo(isolate, attribs);
1381     {  // Add length.
1382       Descriptor d = Descriptor::AccessorConstant(
1383           Handle<Name>(Name::cast(array_length->name())), array_length,
1384           attribs);
1385       initial_map->AppendDescriptor(&d);
1386     }
1387 
1388     InstallWithIntrinsicDefaultProto(isolate, array_function,
1389                                      Context::ARRAY_FUNCTION_INDEX);
1390     InstallSpeciesGetter(array_function);
1391 
1392     // Cache the array maps, needed by ArrayConstructorStub
1393     CacheInitialJSArrayMaps(native_context(), initial_map);
1394     ArrayConstructorStub array_constructor_stub(isolate);
1395     Handle<Code> code = array_constructor_stub.GetCode();
1396     array_function->shared()->SetConstructStub(*code);
1397 
1398     Handle<JSFunction> is_arraylike = SimpleInstallFunction(
1399         array_function, isolate->factory()->InternalizeUtf8String("isArray"),
1400         Builtins::kArrayIsArray, 1, true);
1401     native_context()->set_is_arraylike(*is_arraylike);
1402   }
1403 
1404   {  // --- A r r a y I t e r a t o r ---
1405     Handle<JSObject> iterator_prototype(
1406         native_context()->initial_iterator_prototype());
1407 
1408     Handle<JSObject> array_iterator_prototype =
1409         factory->NewJSObject(isolate->object_function(), TENURED);
1410     JSObject::ForceSetPrototype(array_iterator_prototype, iterator_prototype);
1411 
1412     JSObject::AddProperty(
1413         array_iterator_prototype, factory->to_string_tag_symbol(),
1414         factory->ArrayIterator_string(),
1415         static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
1416 
1417     Handle<JSFunction> next = InstallFunction(
1418         array_iterator_prototype, "next", JS_OBJECT_TYPE, JSObject::kHeaderSize,
1419         MaybeHandle<JSObject>(), Builtins::kArrayIteratorPrototypeNext);
1420     next->shared()->set_builtin_function_id(kArrayIteratorNext);
1421 
1422     // Set the expected parameters for %ArrayIteratorPrototype%.next to 0 (not
1423     // including the receiver), as required by the builtin.
1424     next->shared()->set_internal_formal_parameter_count(0);
1425 
1426     // Set the length for the function to satisfy ECMA-262.
1427     next->shared()->set_length(0);
1428 
1429     Handle<JSFunction> array_iterator_function = CreateFunction(
1430         isolate, factory->ArrayIterator_string(),
1431         JS_FAST_ARRAY_VALUE_ITERATOR_TYPE, JSArrayIterator::kSize,
1432         array_iterator_prototype, Builtins::kIllegal);
1433     array_iterator_function->shared()->set_native(false);
1434     array_iterator_function->shared()->set_instance_class_name(
1435         isolate->heap()->ArrayIterator_string());
1436 
1437     native_context()->set_initial_array_iterator_prototype(
1438         *array_iterator_prototype);
1439     native_context()->set_initial_array_iterator_prototype_map(
1440         array_iterator_prototype->map());
1441 
1442     Handle<Map> initial_map(array_iterator_function->initial_map(), isolate);
1443 
1444 #define ARRAY_ITERATOR_LIST(V)                                              \
1445   V(TYPED_ARRAY, KEY, typed_array, key)                                     \
1446   V(FAST_ARRAY, KEY, fast_array, key)                                       \
1447   V(GENERIC_ARRAY, KEY, array, key)                                         \
1448   V(UINT8_ARRAY, KEY_VALUE, uint8_array, key_value)                         \
1449   V(INT8_ARRAY, KEY_VALUE, int8_array, key_value)                           \
1450   V(UINT16_ARRAY, KEY_VALUE, uint16_array, key_value)                       \
1451   V(INT16_ARRAY, KEY_VALUE, int16_array, key_value)                         \
1452   V(UINT32_ARRAY, KEY_VALUE, uint32_array, key_value)                       \
1453   V(INT32_ARRAY, KEY_VALUE, int32_array, key_value)                         \
1454   V(FLOAT32_ARRAY, KEY_VALUE, float32_array, key_value)                     \
1455   V(FLOAT64_ARRAY, KEY_VALUE, float64_array, key_value)                     \
1456   V(UINT8_CLAMPED_ARRAY, KEY_VALUE, uint8_clamped_array, key_value)         \
1457   V(FAST_SMI_ARRAY, KEY_VALUE, fast_smi_array, key_value)                   \
1458   V(FAST_HOLEY_SMI_ARRAY, KEY_VALUE, fast_holey_smi_array, key_value)       \
1459   V(FAST_ARRAY, KEY_VALUE, fast_array, key_value)                           \
1460   V(FAST_HOLEY_ARRAY, KEY_VALUE, fast_holey_array, key_value)               \
1461   V(FAST_DOUBLE_ARRAY, KEY_VALUE, fast_double_array, key_value)             \
1462   V(FAST_HOLEY_DOUBLE_ARRAY, KEY_VALUE, fast_holey_double_array, key_value) \
1463   V(GENERIC_ARRAY, KEY_VALUE, array, key_value)                             \
1464   V(UINT8_ARRAY, VALUE, uint8_array, value)                                 \
1465   V(INT8_ARRAY, VALUE, int8_array, value)                                   \
1466   V(UINT16_ARRAY, VALUE, uint16_array, value)                               \
1467   V(INT16_ARRAY, VALUE, int16_array, value)                                 \
1468   V(UINT32_ARRAY, VALUE, uint32_array, value)                               \
1469   V(INT32_ARRAY, VALUE, int32_array, value)                                 \
1470   V(FLOAT32_ARRAY, VALUE, float32_array, value)                             \
1471   V(FLOAT64_ARRAY, VALUE, float64_array, value)                             \
1472   V(UINT8_CLAMPED_ARRAY, VALUE, uint8_clamped_array, value)                 \
1473   V(FAST_SMI_ARRAY, VALUE, fast_smi_array, value)                           \
1474   V(FAST_HOLEY_SMI_ARRAY, VALUE, fast_holey_smi_array, value)               \
1475   V(FAST_ARRAY, VALUE, fast_array, value)                                   \
1476   V(FAST_HOLEY_ARRAY, VALUE, fast_holey_array, value)                       \
1477   V(FAST_DOUBLE_ARRAY, VALUE, fast_double_array, value)                     \
1478   V(FAST_HOLEY_DOUBLE_ARRAY, VALUE, fast_holey_double_array, value)         \
1479   V(GENERIC_ARRAY, VALUE, array, value)
1480 
1481 #define CREATE_ARRAY_ITERATOR_MAP(PREFIX, SUFFIX, prefix, suffix)           \
1482   do {                                                                      \
1483     const InstanceType type = JS_##PREFIX##_##SUFFIX##_ITERATOR_TYPE;       \
1484     Handle<Map> map =                                                       \
1485         Map::Copy(initial_map, "JS_" #PREFIX "_" #SUFFIX "_ITERATOR_TYPE"); \
1486     map->set_instance_type(type);                                           \
1487     native_context()->set_##prefix##_##suffix##_iterator_map(*map);         \
1488   } while (0);
1489 
1490     ARRAY_ITERATOR_LIST(CREATE_ARRAY_ITERATOR_MAP)
1491 
1492 #undef CREATE_ARRAY_ITERATOR_MAP
1493 #undef ARRAY_ITERATOR_LIST
1494   }
1495 
1496   {  // --- N u m b e r ---
1497     Handle<JSFunction> number_fun = InstallFunction(
1498         global, "Number", JS_VALUE_TYPE, JSValue::kSize,
1499         isolate->initial_object_prototype(), Builtins::kNumberConstructor);
1500     number_fun->shared()->DontAdaptArguments();
1501     number_fun->shared()->SetConstructStub(
1502         *isolate->builtins()->NumberConstructor_ConstructStub());
1503     number_fun->shared()->set_length(1);
1504     InstallWithIntrinsicDefaultProto(isolate, number_fun,
1505                                      Context::NUMBER_FUNCTION_INDEX);
1506 
1507     // Create the %NumberPrototype%
1508     Handle<JSValue> prototype =
1509         Handle<JSValue>::cast(factory->NewJSObject(number_fun, TENURED));
1510     prototype->set_value(Smi::kZero);
1511     Accessors::FunctionSetPrototype(number_fun, prototype).Assert();
1512 
1513     // Install the "constructor" property on the {prototype}.
1514     JSObject::AddProperty(prototype, factory->constructor_string(), number_fun,
1515                           DONT_ENUM);
1516 
1517     // Install the Number.prototype methods.
1518     SimpleInstallFunction(prototype, "toExponential",
1519                           Builtins::kNumberPrototypeToExponential, 1, false);
1520     SimpleInstallFunction(prototype, "toFixed",
1521                           Builtins::kNumberPrototypeToFixed, 1, false);
1522     SimpleInstallFunction(prototype, "toPrecision",
1523                           Builtins::kNumberPrototypeToPrecision, 1, false);
1524     SimpleInstallFunction(prototype, "toString",
1525                           Builtins::kNumberPrototypeToString, 1, false);
1526     SimpleInstallFunction(prototype, "valueOf",
1527                           Builtins::kNumberPrototypeValueOf, 0, true);
1528 
1529     // Install i18n fallback functions.
1530     SimpleInstallFunction(prototype, "toLocaleString",
1531                           Builtins::kNumberPrototypeToLocaleString, 0, false);
1532 
1533     // Install the Number functions.
1534     SimpleInstallFunction(number_fun, "isFinite", Builtins::kNumberIsFinite, 1,
1535                           true);
1536     SimpleInstallFunction(number_fun, "isInteger", Builtins::kNumberIsInteger,
1537                           1, true);
1538     SimpleInstallFunction(number_fun, "isNaN", Builtins::kNumberIsNaN, 1, true);
1539     SimpleInstallFunction(number_fun, "isSafeInteger",
1540                           Builtins::kNumberIsSafeInteger, 1, true);
1541 
1542     // Install Number.parseFloat and Global.parseFloat.
1543     Handle<JSFunction> parse_float_fun = SimpleInstallFunction(
1544         number_fun, "parseFloat", Builtins::kNumberParseFloat, 1, true);
1545     JSObject::AddProperty(global_object,
1546                           factory->NewStringFromAsciiChecked("parseFloat"),
1547                           parse_float_fun, DONT_ENUM);
1548 
1549     // Install Number.parseInt and Global.parseInt.
1550     Handle<JSFunction> parse_int_fun = SimpleInstallFunction(
1551         number_fun, "parseInt", Builtins::kNumberParseInt, 2, true);
1552     JSObject::AddProperty(global_object,
1553                           factory->NewStringFromAsciiChecked("parseInt"),
1554                           parse_int_fun, DONT_ENUM);
1555   }
1556 
1557   {  // --- B o o l e a n ---
1558     Handle<JSFunction> boolean_fun =
1559         InstallFunction(global, "Boolean", JS_VALUE_TYPE, JSValue::kSize,
1560                         isolate->initial_object_prototype(),
1561                         Builtins::kBooleanConstructor);
1562     boolean_fun->shared()->DontAdaptArguments();
1563     boolean_fun->shared()->SetConstructStub(
1564         *isolate->builtins()->BooleanConstructor_ConstructStub());
1565     boolean_fun->shared()->set_length(1);
1566     InstallWithIntrinsicDefaultProto(isolate, boolean_fun,
1567                                      Context::BOOLEAN_FUNCTION_INDEX);
1568 
1569     // Create the %BooleanPrototype%
1570     Handle<JSValue> prototype =
1571         Handle<JSValue>::cast(factory->NewJSObject(boolean_fun, TENURED));
1572     prototype->set_value(isolate->heap()->false_value());
1573     Accessors::FunctionSetPrototype(boolean_fun, prototype).Assert();
1574 
1575     // Install the "constructor" property on the {prototype}.
1576     JSObject::AddProperty(prototype, factory->constructor_string(), boolean_fun,
1577                           DONT_ENUM);
1578 
1579     // Install the Boolean.prototype methods.
1580     SimpleInstallFunction(prototype, "toString",
1581                           Builtins::kBooleanPrototypeToString, 0, true);
1582     SimpleInstallFunction(prototype, "valueOf",
1583                           Builtins::kBooleanPrototypeValueOf, 0, true);
1584   }
1585 
1586   {  // --- S t r i n g ---
1587     Handle<JSFunction> string_fun = InstallFunction(
1588         global, "String", JS_VALUE_TYPE, JSValue::kSize,
1589         isolate->initial_object_prototype(), Builtins::kStringConstructor);
1590     string_fun->shared()->SetConstructStub(
1591         *isolate->builtins()->StringConstructor_ConstructStub());
1592     string_fun->shared()->DontAdaptArguments();
1593     string_fun->shared()->set_length(1);
1594     InstallWithIntrinsicDefaultProto(isolate, string_fun,
1595                                      Context::STRING_FUNCTION_INDEX);
1596 
1597     Handle<Map> string_map =
1598         Handle<Map>(native_context()->string_function()->initial_map());
1599     string_map->set_elements_kind(FAST_STRING_WRAPPER_ELEMENTS);
1600     Map::EnsureDescriptorSlack(string_map, 1);
1601 
1602     PropertyAttributes attribs = static_cast<PropertyAttributes>(
1603         DONT_ENUM | DONT_DELETE | READ_ONLY);
1604     Handle<AccessorInfo> string_length(
1605         Accessors::StringLengthInfo(isolate, attribs));
1606 
1607     {  // Add length.
1608       Descriptor d = Descriptor::AccessorConstant(factory->length_string(),
1609                                                   string_length, attribs);
1610       string_map->AppendDescriptor(&d);
1611     }
1612 
1613     // Install the String.fromCharCode function.
1614     SimpleInstallFunction(string_fun, "fromCharCode",
1615                           Builtins::kStringFromCharCode, 1, false);
1616 
1617     // Install the String.fromCodePoint function.
1618     SimpleInstallFunction(string_fun, "fromCodePoint",
1619                           Builtins::kStringFromCodePoint, 1, false);
1620 
1621     // Create the %StringPrototype%
1622     Handle<JSValue> prototype =
1623         Handle<JSValue>::cast(factory->NewJSObject(string_fun, TENURED));
1624     prototype->set_value(isolate->heap()->empty_string());
1625     Accessors::FunctionSetPrototype(string_fun, prototype).Assert();
1626 
1627     // Install the "constructor" property on the {prototype}.
1628     JSObject::AddProperty(prototype, factory->constructor_string(), string_fun,
1629                           DONT_ENUM);
1630 
1631     // Install the String.prototype methods.
1632     SimpleInstallFunction(prototype, "charAt", Builtins::kStringPrototypeCharAt,
1633                           1, true);
1634     SimpleInstallFunction(prototype, "charCodeAt",
1635                           Builtins::kStringPrototypeCharCodeAt, 1, true);
1636     SimpleInstallFunction(prototype, "endsWith",
1637                           Builtins::kStringPrototypeEndsWith, 1, false);
1638     SimpleInstallFunction(prototype, "includes",
1639                           Builtins::kStringPrototypeIncludes, 1, false);
1640     SimpleInstallFunction(prototype, "indexOf",
1641                           Builtins::kStringPrototypeIndexOf, 1, false);
1642     SimpleInstallFunction(prototype, "lastIndexOf",
1643                           Builtins::kStringPrototypeLastIndexOf, 1, false);
1644     SimpleInstallFunction(prototype, "localeCompare",
1645                           Builtins::kStringPrototypeLocaleCompare, 1, true);
1646     SimpleInstallFunction(prototype, "normalize",
1647                           Builtins::kStringPrototypeNormalize, 0, false);
1648     SimpleInstallFunction(prototype, "replace",
1649                           Builtins::kStringPrototypeReplace, 2, true);
1650     SimpleInstallFunction(prototype, "split", Builtins::kStringPrototypeSplit,
1651                           2, true);
1652     SimpleInstallFunction(prototype, "substr", Builtins::kStringPrototypeSubstr,
1653                           2, true);
1654     SimpleInstallFunction(prototype, "substring",
1655                           Builtins::kStringPrototypeSubstring, 2, true);
1656     SimpleInstallFunction(prototype, "startsWith",
1657                           Builtins::kStringPrototypeStartsWith, 1, false);
1658     SimpleInstallFunction(prototype, "toString",
1659                           Builtins::kStringPrototypeToString, 0, true);
1660     SimpleInstallFunction(prototype, "trim", Builtins::kStringPrototypeTrim, 0,
1661                           false);
1662     SimpleInstallFunction(prototype, "trimLeft",
1663                           Builtins::kStringPrototypeTrimLeft, 0, false);
1664     SimpleInstallFunction(prototype, "trimRight",
1665                           Builtins::kStringPrototypeTrimRight, 0, false);
1666     SimpleInstallFunction(prototype, "toLocaleLowerCase",
1667                           Builtins::kStringPrototypeToLocaleLowerCase, 0,
1668                           false);
1669     SimpleInstallFunction(prototype, "toLocaleUpperCase",
1670                           Builtins::kStringPrototypeToLocaleUpperCase, 0,
1671                           false);
1672     SimpleInstallFunction(prototype, "toLowerCase",
1673                           Builtins::kStringPrototypeToLowerCase, 0, false);
1674     SimpleInstallFunction(prototype, "toUpperCase",
1675                           Builtins::kStringPrototypeToUpperCase, 0, false);
1676     SimpleInstallFunction(prototype, "valueOf",
1677                           Builtins::kStringPrototypeValueOf, 0, true);
1678 
1679     Handle<JSFunction> iterator = SimpleCreateFunction(
1680         isolate, factory->NewStringFromAsciiChecked("[Symbol.iterator]"),
1681         Builtins::kStringPrototypeIterator, 0, true);
1682     iterator->shared()->set_builtin_function_id(kStringIterator);
1683     JSObject::AddProperty(prototype, factory->iterator_symbol(), iterator,
1684                           static_cast<PropertyAttributes>(DONT_ENUM));
1685   }
1686 
1687   {  // --- S t r i n g I t e r a t o r ---
1688     Handle<JSObject> iterator_prototype(
1689         native_context()->initial_iterator_prototype());
1690 
1691     Handle<JSObject> string_iterator_prototype =
1692         factory->NewJSObject(isolate->object_function(), TENURED);
1693     JSObject::ForceSetPrototype(string_iterator_prototype, iterator_prototype);
1694 
1695     JSObject::AddProperty(
1696         string_iterator_prototype, factory->to_string_tag_symbol(),
1697         factory->NewStringFromAsciiChecked("String Iterator"),
1698         static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
1699 
1700     Handle<JSFunction> next =
1701         InstallFunction(string_iterator_prototype, "next", JS_OBJECT_TYPE,
1702                         JSObject::kHeaderSize, MaybeHandle<JSObject>(),
1703                         Builtins::kStringIteratorPrototypeNext);
1704     next->shared()->set_builtin_function_id(kStringIteratorNext);
1705 
1706     // Set the expected parameters for %StringIteratorPrototype%.next to 0 (not
1707     // including the receiver), as required by the builtin.
1708     next->shared()->set_internal_formal_parameter_count(0);
1709 
1710     // Set the length for the function to satisfy ECMA-262.
1711     next->shared()->set_length(0);
1712 
1713     Handle<JSFunction> string_iterator_function = CreateFunction(
1714         isolate, factory->NewStringFromAsciiChecked("StringIterator"),
1715         JS_STRING_ITERATOR_TYPE, JSStringIterator::kSize,
1716         string_iterator_prototype, Builtins::kIllegal);
1717     string_iterator_function->shared()->set_native(false);
1718     native_context()->set_string_iterator_map(
1719         string_iterator_function->initial_map());
1720   }
1721 
1722   {
1723     // --- S y m b o l ---
1724     Handle<JSObject> prototype =
1725         factory->NewJSObject(isolate->object_function(), TENURED);
1726     Handle<JSFunction> symbol_fun =
1727         InstallFunction(global, "Symbol", JS_VALUE_TYPE, JSValue::kSize,
1728                         prototype, Builtins::kSymbolConstructor);
1729     symbol_fun->shared()->SetConstructStub(
1730         *isolate->builtins()->SymbolConstructor_ConstructStub());
1731     symbol_fun->shared()->set_length(0);
1732     symbol_fun->shared()->DontAdaptArguments();
1733     native_context()->set_symbol_function(*symbol_fun);
1734 
1735     // Install the Symbol.for and Symbol.keyFor functions.
1736     SimpleInstallFunction(symbol_fun, "for", Builtins::kSymbolFor, 1, false);
1737     SimpleInstallFunction(symbol_fun, "keyFor", Builtins::kSymbolKeyFor, 1,
1738                           false);
1739 
1740     // Install well-known symbols.
1741     InstallConstant(isolate, symbol_fun, "hasInstance",
1742                     factory->has_instance_symbol());
1743     InstallConstant(isolate, symbol_fun, "isConcatSpreadable",
1744                     factory->is_concat_spreadable_symbol());
1745     InstallConstant(isolate, symbol_fun, "iterator",
1746                     factory->iterator_symbol());
1747     InstallConstant(isolate, symbol_fun, "match", factory->match_symbol());
1748     InstallConstant(isolate, symbol_fun, "replace", factory->replace_symbol());
1749     InstallConstant(isolate, symbol_fun, "search", factory->search_symbol());
1750     InstallConstant(isolate, symbol_fun, "species", factory->species_symbol());
1751     InstallConstant(isolate, symbol_fun, "split", factory->split_symbol());
1752     InstallConstant(isolate, symbol_fun, "toPrimitive",
1753                     factory->to_primitive_symbol());
1754     InstallConstant(isolate, symbol_fun, "toStringTag",
1755                     factory->to_string_tag_symbol());
1756     InstallConstant(isolate, symbol_fun, "unscopables",
1757                     factory->unscopables_symbol());
1758 
1759     // Install the @@toStringTag property on the {prototype}.
1760     JSObject::AddProperty(
1761         prototype, factory->to_string_tag_symbol(),
1762         factory->NewStringFromAsciiChecked("Symbol"),
1763         static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
1764 
1765     // Install the "constructor" property on the {prototype}.
1766     JSObject::AddProperty(prototype, factory->constructor_string(), symbol_fun,
1767                           DONT_ENUM);
1768 
1769     // Install the Symbol.prototype methods.
1770     SimpleInstallFunction(prototype, "toString",
1771                           Builtins::kSymbolPrototypeToString, 0, true);
1772     SimpleInstallFunction(prototype, "valueOf",
1773                           Builtins::kSymbolPrototypeValueOf, 0, true);
1774 
1775     // Install the @@toPrimitive function.
1776     Handle<JSFunction> to_primitive = InstallFunction(
1777         prototype, factory->to_primitive_symbol(), JS_OBJECT_TYPE,
1778         JSObject::kHeaderSize, MaybeHandle<JSObject>(),
1779         Builtins::kSymbolPrototypeToPrimitive,
1780         static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
1781 
1782     // Set the expected parameters for @@toPrimitive to 1; required by builtin.
1783     to_primitive->shared()->set_internal_formal_parameter_count(1);
1784 
1785     // Set the length for the function to satisfy ECMA-262.
1786     to_primitive->shared()->set_length(1);
1787   }
1788 
1789   {  // --- D a t e ---
1790     // Builtin functions for Date.prototype.
1791     Handle<JSObject> prototype =
1792         factory->NewJSObject(isolate->object_function(), TENURED);
1793     Handle<JSFunction> date_fun =
1794         InstallFunction(global, "Date", JS_DATE_TYPE, JSDate::kSize, prototype,
1795                         Builtins::kDateConstructor);
1796     InstallWithIntrinsicDefaultProto(isolate, date_fun,
1797                                      Context::DATE_FUNCTION_INDEX);
1798     date_fun->shared()->SetConstructStub(
1799         *isolate->builtins()->DateConstructor_ConstructStub());
1800     date_fun->shared()->set_length(7);
1801     date_fun->shared()->DontAdaptArguments();
1802 
1803     // Install the Date.now, Date.parse and Date.UTC functions.
1804     SimpleInstallFunction(date_fun, "now", Builtins::kDateNow, 0, false);
1805     SimpleInstallFunction(date_fun, "parse", Builtins::kDateParse, 1, false);
1806     SimpleInstallFunction(date_fun, "UTC", Builtins::kDateUTC, 7, false);
1807 
1808     // Install the "constructor" property on the {prototype}.
1809     JSObject::AddProperty(prototype, factory->constructor_string(), date_fun,
1810                           DONT_ENUM);
1811 
1812     // Install the Date.prototype methods.
1813     SimpleInstallFunction(prototype, "toString",
1814                           Builtins::kDatePrototypeToString, 0, false);
1815     SimpleInstallFunction(prototype, "toDateString",
1816                           Builtins::kDatePrototypeToDateString, 0, false);
1817     SimpleInstallFunction(prototype, "toTimeString",
1818                           Builtins::kDatePrototypeToTimeString, 0, false);
1819     SimpleInstallFunction(prototype, "toISOString",
1820                           Builtins::kDatePrototypeToISOString, 0, false);
1821     Handle<JSFunction> to_utc_string =
1822         SimpleInstallFunction(prototype, "toUTCString",
1823                               Builtins::kDatePrototypeToUTCString, 0, false);
1824     InstallFunction(prototype, to_utc_string,
1825                     factory->InternalizeUtf8String("toGMTString"), DONT_ENUM);
1826     SimpleInstallFunction(prototype, "getDate", Builtins::kDatePrototypeGetDate,
1827                           0, true);
1828     SimpleInstallFunction(prototype, "setDate", Builtins::kDatePrototypeSetDate,
1829                           1, false);
1830     SimpleInstallFunction(prototype, "getDay", Builtins::kDatePrototypeGetDay,
1831                           0, true);
1832     SimpleInstallFunction(prototype, "getFullYear",
1833                           Builtins::kDatePrototypeGetFullYear, 0, true);
1834     SimpleInstallFunction(prototype, "setFullYear",
1835                           Builtins::kDatePrototypeSetFullYear, 3, false);
1836     SimpleInstallFunction(prototype, "getHours",
1837                           Builtins::kDatePrototypeGetHours, 0, true);
1838     SimpleInstallFunction(prototype, "setHours",
1839                           Builtins::kDatePrototypeSetHours, 4, false);
1840     SimpleInstallFunction(prototype, "getMilliseconds",
1841                           Builtins::kDatePrototypeGetMilliseconds, 0, true);
1842     SimpleInstallFunction(prototype, "setMilliseconds",
1843                           Builtins::kDatePrototypeSetMilliseconds, 1, false);
1844     SimpleInstallFunction(prototype, "getMinutes",
1845                           Builtins::kDatePrototypeGetMinutes, 0, true);
1846     SimpleInstallFunction(prototype, "setMinutes",
1847                           Builtins::kDatePrototypeSetMinutes, 3, false);
1848     SimpleInstallFunction(prototype, "getMonth",
1849                           Builtins::kDatePrototypeGetMonth, 0, true);
1850     SimpleInstallFunction(prototype, "setMonth",
1851                           Builtins::kDatePrototypeSetMonth, 2, false);
1852     SimpleInstallFunction(prototype, "getSeconds",
1853                           Builtins::kDatePrototypeGetSeconds, 0, true);
1854     SimpleInstallFunction(prototype, "setSeconds",
1855                           Builtins::kDatePrototypeSetSeconds, 2, false);
1856     SimpleInstallFunction(prototype, "getTime", Builtins::kDatePrototypeGetTime,
1857                           0, true);
1858     SimpleInstallFunction(prototype, "setTime", Builtins::kDatePrototypeSetTime,
1859                           1, false);
1860     SimpleInstallFunction(prototype, "getTimezoneOffset",
1861                           Builtins::kDatePrototypeGetTimezoneOffset, 0, true);
1862     SimpleInstallFunction(prototype, "getUTCDate",
1863                           Builtins::kDatePrototypeGetUTCDate, 0, true);
1864     SimpleInstallFunction(prototype, "setUTCDate",
1865                           Builtins::kDatePrototypeSetUTCDate, 1, false);
1866     SimpleInstallFunction(prototype, "getUTCDay",
1867                           Builtins::kDatePrototypeGetUTCDay, 0, true);
1868     SimpleInstallFunction(prototype, "getUTCFullYear",
1869                           Builtins::kDatePrototypeGetUTCFullYear, 0, true);
1870     SimpleInstallFunction(prototype, "setUTCFullYear",
1871                           Builtins::kDatePrototypeSetUTCFullYear, 3, false);
1872     SimpleInstallFunction(prototype, "getUTCHours",
1873                           Builtins::kDatePrototypeGetUTCHours, 0, true);
1874     SimpleInstallFunction(prototype, "setUTCHours",
1875                           Builtins::kDatePrototypeSetUTCHours, 4, false);
1876     SimpleInstallFunction(prototype, "getUTCMilliseconds",
1877                           Builtins::kDatePrototypeGetUTCMilliseconds, 0, true);
1878     SimpleInstallFunction(prototype, "setUTCMilliseconds",
1879                           Builtins::kDatePrototypeSetUTCMilliseconds, 1, false);
1880     SimpleInstallFunction(prototype, "getUTCMinutes",
1881                           Builtins::kDatePrototypeGetUTCMinutes, 0, true);
1882     SimpleInstallFunction(prototype, "setUTCMinutes",
1883                           Builtins::kDatePrototypeSetUTCMinutes, 3, false);
1884     SimpleInstallFunction(prototype, "getUTCMonth",
1885                           Builtins::kDatePrototypeGetUTCMonth, 0, true);
1886     SimpleInstallFunction(prototype, "setUTCMonth",
1887                           Builtins::kDatePrototypeSetUTCMonth, 2, false);
1888     SimpleInstallFunction(prototype, "getUTCSeconds",
1889                           Builtins::kDatePrototypeGetUTCSeconds, 0, true);
1890     SimpleInstallFunction(prototype, "setUTCSeconds",
1891                           Builtins::kDatePrototypeSetUTCSeconds, 2, false);
1892     SimpleInstallFunction(prototype, "valueOf", Builtins::kDatePrototypeValueOf,
1893                           0, true);
1894     SimpleInstallFunction(prototype, "getYear", Builtins::kDatePrototypeGetYear,
1895                           0, true);
1896     SimpleInstallFunction(prototype, "setYear", Builtins::kDatePrototypeSetYear,
1897                           1, false);
1898     SimpleInstallFunction(prototype, "toJSON", Builtins::kDatePrototypeToJson,
1899                           1, false);
1900 
1901     // Install i18n fallback functions.
1902     SimpleInstallFunction(prototype, "toLocaleString",
1903                           Builtins::kDatePrototypeToString, 0, false);
1904     SimpleInstallFunction(prototype, "toLocaleDateString",
1905                           Builtins::kDatePrototypeToDateString, 0, false);
1906     SimpleInstallFunction(prototype, "toLocaleTimeString",
1907                           Builtins::kDatePrototypeToTimeString, 0, false);
1908 
1909     // Install the @@toPrimitive function.
1910     Handle<JSFunction> to_primitive = InstallFunction(
1911         prototype, factory->to_primitive_symbol(), JS_OBJECT_TYPE,
1912         JSObject::kHeaderSize, MaybeHandle<JSObject>(),
1913         Builtins::kDatePrototypeToPrimitive,
1914         static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
1915 
1916     // Set the expected parameters for @@toPrimitive to 1; required by builtin.
1917     to_primitive->shared()->set_internal_formal_parameter_count(1);
1918 
1919     // Set the length for the function to satisfy ECMA-262.
1920     to_primitive->shared()->set_length(1);
1921   }
1922 
1923   {
1924     Handle<Code> code = isolate->builtins()->PromiseGetCapabilitiesExecutor();
1925     Handle<SharedFunctionInfo> info =
1926         factory->NewSharedFunctionInfo(factory->empty_string(), code, true);
1927     info->SetConstructStub(*isolate->builtins()->JSBuiltinsConstructStub());
1928     info->set_instance_class_name(isolate->heap()->Object_string());
1929     info->set_internal_formal_parameter_count(2);
1930     info->set_length(2);
1931     native_context()->set_promise_get_capabilities_executor_shared_fun(*info);
1932 
1933     // %new_promise_capability(C, debugEvent)
1934     Handle<JSFunction> new_promise_capability =
1935         SimpleCreateFunction(isolate, factory->empty_string(),
1936                              Builtins::kNewPromiseCapability, 2, false);
1937     InstallWithIntrinsicDefaultProto(isolate, new_promise_capability,
1938                                      Context::NEW_PROMISE_CAPABILITY_INDEX);
1939   }
1940 
1941   {  // -- P r o m i s e
1942     // Set catch prediction
1943     Handle<Code> promise_code = isolate->builtins()->PromiseConstructor();
1944     promise_code->set_is_promise_rejection(true);
1945 
1946     Handle<JSObject> prototype =
1947         factory->NewJSObject(isolate->object_function(), TENURED);
1948     Handle<JSFunction> promise_fun =
1949         InstallFunction(global, "Promise", JS_PROMISE_TYPE, JSPromise::kSize,
1950                         prototype, Builtins::kPromiseConstructor);
1951     InstallWithIntrinsicDefaultProto(isolate, promise_fun,
1952                                      Context::PROMISE_FUNCTION_INDEX);
1953 
1954     Handle<SharedFunctionInfo> shared(promise_fun->shared(), isolate);
1955     shared->SetConstructStub(*isolate->builtins()->JSBuiltinsConstructStub());
1956     shared->set_instance_class_name(isolate->heap()->Object_string());
1957     shared->set_internal_formal_parameter_count(1);
1958     shared->set_length(1);
1959 
1960     // Install the "constructor" property on the {prototype}.
1961     JSObject::AddProperty(prototype, factory->constructor_string(), promise_fun,
1962                           DONT_ENUM);
1963 
1964     // Install the @@toStringTag property on the {prototype}.
1965     JSObject::AddProperty(
1966         prototype, factory->to_string_tag_symbol(), factory->Promise_string(),
1967         static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
1968 
1969     Handle<JSFunction> promise_then =
1970         SimpleInstallFunction(prototype, isolate->factory()->then_string(),
1971                               Builtins::kPromiseThen, 2, true);
1972     InstallWithIntrinsicDefaultProto(isolate, promise_then,
1973                                      Context::PROMISE_THEN_INDEX);
1974 
1975     Handle<JSFunction> promise_catch = SimpleInstallFunction(
1976         prototype, "catch", Builtins::kPromiseCatch, 1, true, DONT_ENUM);
1977     InstallWithIntrinsicDefaultProto(isolate, promise_catch,
1978                                      Context::PROMISE_CATCH_INDEX);
1979 
1980     InstallSpeciesGetter(promise_fun);
1981 
1982     SimpleInstallFunction(promise_fun, "resolve", Builtins::kPromiseResolve, 1,
1983                           true, DONT_ENUM);
1984 
1985     SimpleInstallFunction(promise_fun, "reject", Builtins::kPromiseReject, 1,
1986                           true, DONT_ENUM);
1987 
1988     Handle<Map> prototype_map(prototype->map());
1989     Map::SetShouldBeFastPrototypeMap(prototype_map, true, isolate);
1990 
1991     // Store the initial Promise.prototype map. This is used in fast-path
1992     // checks. Do not alter the prototype after this point.
1993     native_context()->set_promise_prototype_map(*prototype_map);
1994 
1995     {  // Internal: PromiseInternalConstructor
1996        // Also exposed as extrasUtils.createPromise.
1997       Handle<JSFunction> function =
1998           SimpleCreateFunction(isolate, factory->empty_string(),
1999                                Builtins::kPromiseInternalConstructor, 1, true);
2000       function->shared()->set_native(false);
2001       InstallWithIntrinsicDefaultProto(
2002           isolate, function, Context::PROMISE_INTERNAL_CONSTRUCTOR_INDEX);
2003     }
2004 
2005     {  // Internal: IsPromise
2006       Handle<JSFunction> function = SimpleCreateFunction(
2007           isolate, factory->empty_string(), Builtins::kIsPromise, 1, false);
2008       InstallWithIntrinsicDefaultProto(isolate, function,
2009                                        Context::IS_PROMISE_INDEX);
2010     }
2011 
2012     {  // Internal: ResolvePromise
2013        // Also exposed as extrasUtils.resolvePromise.
2014       Handle<JSFunction> function = SimpleCreateFunction(
2015           isolate, factory->empty_string(), Builtins::kResolvePromise, 2, true);
2016       function->shared()->set_native(false);
2017       InstallWithIntrinsicDefaultProto(isolate, function,
2018                                        Context::PROMISE_RESOLVE_INDEX);
2019     }
2020 
2021     {  // Internal: PromiseHandle
2022       Handle<JSFunction> function = SimpleCreateFunction(
2023           isolate, factory->empty_string(), Builtins::kPromiseHandle, 5, false);
2024       InstallWithIntrinsicDefaultProto(isolate, function,
2025                                        Context::PROMISE_HANDLE_INDEX);
2026       // Set up catch prediction
2027       Handle<Code> promise_handle = isolate->builtins()->PromiseHandle();
2028       promise_handle->set_is_promise_rejection(true);
2029     }
2030 
2031     {  // Internal: PromiseHandleReject
2032       Handle<JSFunction> function =
2033           SimpleCreateFunction(isolate, factory->empty_string(),
2034                                Builtins::kPromiseHandleReject, 3, false);
2035       InstallWithIntrinsicDefaultProto(isolate, function,
2036                                        Context::PROMISE_HANDLE_REJECT_INDEX);
2037       // Set up catch prediction
2038       Handle<Code> promise_handle = isolate->builtins()->PromiseHandleReject();
2039       promise_handle->set_is_exception_caught(true);
2040     }
2041 
2042     {  // Internal: InternalPromiseReject
2043       Handle<JSFunction> function =
2044           SimpleCreateFunction(isolate, factory->empty_string(),
2045                                Builtins::kInternalPromiseReject, 3, true);
2046       function->shared()->set_native(false);
2047       InstallWithIntrinsicDefaultProto(isolate, function,
2048                                        Context::PROMISE_INTERNAL_REJECT_INDEX);
2049     }
2050 
2051     {
2052       Handle<Code> code =
2053           handle(isolate->builtins()->builtin(Builtins::kPromiseResolveClosure),
2054                  isolate);
2055       Handle<SharedFunctionInfo> info =
2056           factory->NewSharedFunctionInfo(factory->empty_string(), code, false);
2057       info->set_internal_formal_parameter_count(1);
2058       info->set_length(1);
2059       native_context()->set_promise_resolve_shared_fun(*info);
2060 
2061       code =
2062           handle(isolate->builtins()->builtin(Builtins::kPromiseRejectClosure),
2063                  isolate);
2064       info =
2065           factory->NewSharedFunctionInfo(factory->empty_string(), code, false);
2066       info->set_internal_formal_parameter_count(1);
2067       info->set_length(1);
2068       native_context()->set_promise_reject_shared_fun(*info);
2069     }
2070   }
2071 
2072   {  // -- R e g E x p
2073     // Builtin functions for RegExp.prototype.
2074     Handle<JSObject> prototype =
2075         factory->NewJSObject(isolate->object_function(), TENURED);
2076     Handle<JSFunction> regexp_fun =
2077         InstallFunction(global, "RegExp", JS_REGEXP_TYPE, JSRegExp::kSize,
2078                         prototype, Builtins::kRegExpConstructor);
2079     InstallWithIntrinsicDefaultProto(isolate, regexp_fun,
2080                                      Context::REGEXP_FUNCTION_INDEX);
2081 
2082     Handle<SharedFunctionInfo> shared(regexp_fun->shared(), isolate);
2083     shared->SetConstructStub(*isolate->builtins()->JSBuiltinsConstructStub());
2084     shared->set_instance_class_name(isolate->heap()->RegExp_string());
2085     shared->set_internal_formal_parameter_count(2);
2086     shared->set_length(2);
2087 
2088     {
2089       // RegExp.prototype setup.
2090 
2091       // Install the "constructor" property on the {prototype}.
2092       JSObject::AddProperty(prototype, factory->constructor_string(),
2093                             regexp_fun, DONT_ENUM);
2094 
2095       {
2096         Handle<JSFunction> fun = SimpleInstallFunction(
2097             prototype, factory->exec_string(), Builtins::kRegExpPrototypeExec,
2098             1, true, DONT_ENUM);
2099         native_context()->set_regexp_exec_function(*fun);
2100       }
2101 
2102       SimpleInstallGetter(prototype, factory->flags_string(),
2103                           Builtins::kRegExpPrototypeFlagsGetter, true);
2104       SimpleInstallGetter(prototype, factory->global_string(),
2105                           Builtins::kRegExpPrototypeGlobalGetter, true);
2106       SimpleInstallGetter(prototype, factory->ignoreCase_string(),
2107                           Builtins::kRegExpPrototypeIgnoreCaseGetter, true);
2108       SimpleInstallGetter(prototype, factory->multiline_string(),
2109                           Builtins::kRegExpPrototypeMultilineGetter, true);
2110       SimpleInstallGetter(prototype, factory->source_string(),
2111                           Builtins::kRegExpPrototypeSourceGetter, true);
2112       SimpleInstallGetter(prototype, factory->sticky_string(),
2113                           Builtins::kRegExpPrototypeStickyGetter, true);
2114       SimpleInstallGetter(prototype, factory->unicode_string(),
2115                           Builtins::kRegExpPrototypeUnicodeGetter, true);
2116 
2117       SimpleInstallFunction(prototype, "compile",
2118                             Builtins::kRegExpPrototypeCompile, 2, true,
2119                             DONT_ENUM);
2120       SimpleInstallFunction(prototype, factory->toString_string(),
2121                             Builtins::kRegExpPrototypeToString, 0, false,
2122                             DONT_ENUM);
2123       SimpleInstallFunction(prototype, "test", Builtins::kRegExpPrototypeTest,
2124                             1, true, DONT_ENUM);
2125 
2126       {
2127         Handle<JSFunction> fun = SimpleCreateFunction(
2128             isolate, factory->InternalizeUtf8String("[Symbol.match]"),
2129             Builtins::kRegExpPrototypeMatch, 1, true);
2130         InstallFunction(prototype, fun, factory->match_symbol(), DONT_ENUM);
2131       }
2132 
2133       {
2134         Handle<JSFunction> fun = SimpleCreateFunction(
2135             isolate, factory->InternalizeUtf8String("[Symbol.replace]"),
2136             Builtins::kRegExpPrototypeReplace, 2, true);
2137         InstallFunction(prototype, fun, factory->replace_symbol(), DONT_ENUM);
2138       }
2139 
2140       {
2141         Handle<JSFunction> fun = SimpleCreateFunction(
2142             isolate, factory->InternalizeUtf8String("[Symbol.search]"),
2143             Builtins::kRegExpPrototypeSearch, 1, true);
2144         InstallFunction(prototype, fun, factory->search_symbol(), DONT_ENUM);
2145       }
2146 
2147       {
2148         Handle<JSFunction> fun = SimpleCreateFunction(
2149             isolate, factory->InternalizeUtf8String("[Symbol.split]"),
2150             Builtins::kRegExpPrototypeSplit, 2, true);
2151         InstallFunction(prototype, fun, factory->split_symbol(), DONT_ENUM);
2152       }
2153 
2154       Handle<Map> prototype_map(prototype->map());
2155       Map::SetShouldBeFastPrototypeMap(prototype_map, true, isolate);
2156 
2157       // Store the initial RegExp.prototype map. This is used in fast-path
2158       // checks. Do not alter the prototype after this point.
2159       native_context()->set_regexp_prototype_map(*prototype_map);
2160     }
2161 
2162     {
2163       // RegExp getters and setters.
2164 
2165       InstallSpeciesGetter(regexp_fun);
2166 
2167       // Static properties set by a successful match.
2168 
2169       const PropertyAttributes no_enum = DONT_ENUM;
2170       SimpleInstallGetterSetter(regexp_fun, factory->input_string(),
2171                                 Builtins::kRegExpInputGetter,
2172                                 Builtins::kRegExpInputSetter, no_enum);
2173       SimpleInstallGetterSetter(
2174           regexp_fun, factory->InternalizeUtf8String("$_"),
2175           Builtins::kRegExpInputGetter, Builtins::kRegExpInputSetter, no_enum);
2176 
2177       SimpleInstallGetterSetter(
2178           regexp_fun, factory->InternalizeUtf8String("lastMatch"),
2179           Builtins::kRegExpLastMatchGetter, Builtins::kEmptyFunction, no_enum);
2180       SimpleInstallGetterSetter(
2181           regexp_fun, factory->InternalizeUtf8String("$&"),
2182           Builtins::kRegExpLastMatchGetter, Builtins::kEmptyFunction, no_enum);
2183 
2184       SimpleInstallGetterSetter(
2185           regexp_fun, factory->InternalizeUtf8String("lastParen"),
2186           Builtins::kRegExpLastParenGetter, Builtins::kEmptyFunction, no_enum);
2187       SimpleInstallGetterSetter(
2188           regexp_fun, factory->InternalizeUtf8String("$+"),
2189           Builtins::kRegExpLastParenGetter, Builtins::kEmptyFunction, no_enum);
2190 
2191       SimpleInstallGetterSetter(regexp_fun,
2192                                 factory->InternalizeUtf8String("leftContext"),
2193                                 Builtins::kRegExpLeftContextGetter,
2194                                 Builtins::kEmptyFunction, no_enum);
2195       SimpleInstallGetterSetter(regexp_fun,
2196                                 factory->InternalizeUtf8String("$`"),
2197                                 Builtins::kRegExpLeftContextGetter,
2198                                 Builtins::kEmptyFunction, no_enum);
2199 
2200       SimpleInstallGetterSetter(regexp_fun,
2201                                 factory->InternalizeUtf8String("rightContext"),
2202                                 Builtins::kRegExpRightContextGetter,
2203                                 Builtins::kEmptyFunction, no_enum);
2204       SimpleInstallGetterSetter(regexp_fun,
2205                                 factory->InternalizeUtf8String("$'"),
2206                                 Builtins::kRegExpRightContextGetter,
2207                                 Builtins::kEmptyFunction, no_enum);
2208 
2209 #define INSTALL_CAPTURE_GETTER(i)                         \
2210   SimpleInstallGetterSetter(                              \
2211       regexp_fun, factory->InternalizeUtf8String("$" #i), \
2212       Builtins::kRegExpCapture##i##Getter, Builtins::kEmptyFunction, no_enum)
2213       INSTALL_CAPTURE_GETTER(1);
2214       INSTALL_CAPTURE_GETTER(2);
2215       INSTALL_CAPTURE_GETTER(3);
2216       INSTALL_CAPTURE_GETTER(4);
2217       INSTALL_CAPTURE_GETTER(5);
2218       INSTALL_CAPTURE_GETTER(6);
2219       INSTALL_CAPTURE_GETTER(7);
2220       INSTALL_CAPTURE_GETTER(8);
2221       INSTALL_CAPTURE_GETTER(9);
2222 #undef INSTALL_CAPTURE_GETTER
2223     }
2224 
2225     DCHECK(regexp_fun->has_initial_map());
2226     Handle<Map> initial_map(regexp_fun->initial_map());
2227 
2228     DCHECK_EQ(0, initial_map->GetInObjectProperties());
2229 
2230     Map::EnsureDescriptorSlack(initial_map, 1);
2231 
2232     // ECMA-262, section 15.10.7.5.
2233     PropertyAttributes writable =
2234         static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE);
2235     Descriptor d = Descriptor::DataField(factory->lastIndex_string(),
2236                                          JSRegExp::kLastIndexFieldIndex,
2237                                          writable, Representation::Tagged());
2238     initial_map->AppendDescriptor(&d);
2239 
2240     static const int num_fields = JSRegExp::kInObjectFieldCount;
2241     initial_map->SetInObjectProperties(num_fields);
2242     initial_map->set_unused_property_fields(0);
2243     initial_map->set_instance_size(initial_map->instance_size() +
2244                                    num_fields * kPointerSize);
2245 
2246     {  // Internal: RegExpInternalMatch
2247       Handle<JSFunction> function =
2248           factory->NewFunction(isolate->factory()->empty_string(),
2249                                isolate->builtins()->RegExpInternalMatch(),
2250                                JS_OBJECT_TYPE, JSObject::kHeaderSize);
2251       function->shared()->set_internal_formal_parameter_count(2);
2252       function->shared()->set_length(2);
2253       function->shared()->set_native(true);
2254       native_context()->set(Context::REGEXP_INTERNAL_MATCH, *function);
2255     }
2256 
2257     // Create the last match info. One for external use, and one for internal
2258     // use when we don't want to modify the externally visible match info.
2259     Handle<RegExpMatchInfo> last_match_info = factory->NewRegExpMatchInfo();
2260     native_context()->set_regexp_last_match_info(*last_match_info);
2261     Handle<RegExpMatchInfo> internal_match_info = factory->NewRegExpMatchInfo();
2262     native_context()->set_regexp_internal_match_info(*internal_match_info);
2263   }
2264 
2265   {  // -- E r r o r
2266     InstallError(isolate, global, factory->Error_string(),
2267                  Context::ERROR_FUNCTION_INDEX);
2268     InstallMakeError(isolate, isolate->builtins()->MakeError(),
2269                      Context::MAKE_ERROR_INDEX);
2270   }
2271 
2272   {  // -- E v a l E r r o r
2273     InstallError(isolate, global, factory->EvalError_string(),
2274                  Context::EVAL_ERROR_FUNCTION_INDEX);
2275   }
2276 
2277   {  // -- R a n g e E r r o r
2278     InstallError(isolate, global, factory->RangeError_string(),
2279                  Context::RANGE_ERROR_FUNCTION_INDEX);
2280     InstallMakeError(isolate, isolate->builtins()->MakeRangeError(),
2281                      Context::MAKE_RANGE_ERROR_INDEX);
2282   }
2283 
2284   {  // -- R e f e r e n c e E r r o r
2285     InstallError(isolate, global, factory->ReferenceError_string(),
2286                  Context::REFERENCE_ERROR_FUNCTION_INDEX);
2287   }
2288 
2289   {  // -- S y n t a x E r r o r
2290     InstallError(isolate, global, factory->SyntaxError_string(),
2291                  Context::SYNTAX_ERROR_FUNCTION_INDEX);
2292     InstallMakeError(isolate, isolate->builtins()->MakeSyntaxError(),
2293                      Context::MAKE_SYNTAX_ERROR_INDEX);
2294   }
2295 
2296   {  // -- T y p e E r r o r
2297     InstallError(isolate, global, factory->TypeError_string(),
2298                  Context::TYPE_ERROR_FUNCTION_INDEX);
2299     InstallMakeError(isolate, isolate->builtins()->MakeTypeError(),
2300                      Context::MAKE_TYPE_ERROR_INDEX);
2301   }
2302 
2303   {  // -- U R I E r r o r
2304     InstallError(isolate, global, factory->URIError_string(),
2305                  Context::URI_ERROR_FUNCTION_INDEX);
2306     InstallMakeError(isolate, isolate->builtins()->MakeURIError(),
2307                      Context::MAKE_URI_ERROR_INDEX);
2308   }
2309 
2310   {  // -- C o m p i l e E r r o r
2311     Handle<JSObject> dummy = factory->NewJSObject(isolate->object_function());
2312     InstallError(isolate, dummy, factory->CompileError_string(),
2313                  Context::WASM_COMPILE_ERROR_FUNCTION_INDEX);
2314 
2315     // -- L i n k E r r o r
2316     InstallError(isolate, dummy, factory->LinkError_string(),
2317                  Context::WASM_LINK_ERROR_FUNCTION_INDEX);
2318 
2319     // -- R u n t i m e E r r o r
2320     InstallError(isolate, dummy, factory->RuntimeError_string(),
2321                  Context::WASM_RUNTIME_ERROR_FUNCTION_INDEX);
2322   }
2323 
2324   // Initialize the embedder data slot.
2325   Handle<FixedArray> embedder_data = factory->NewFixedArray(3);
2326   native_context()->set_embedder_data(*embedder_data);
2327 
2328   {  // -- J S O N
2329     Handle<String> name = factory->InternalizeUtf8String("JSON");
2330     Handle<JSFunction> cons = factory->NewFunction(name);
2331     JSFunction::SetInstancePrototype(cons,
2332         Handle<Object>(native_context()->initial_object_prototype(), isolate));
2333     Handle<JSObject> json_object = factory->NewJSObject(cons, TENURED);
2334     DCHECK(json_object->IsJSObject());
2335     JSObject::AddProperty(global, name, json_object, DONT_ENUM);
2336     SimpleInstallFunction(json_object, "parse", Builtins::kJsonParse, 2, false);
2337     SimpleInstallFunction(json_object, "stringify", Builtins::kJsonStringify, 3,
2338                           true);
2339     JSObject::AddProperty(
2340         json_object, factory->to_string_tag_symbol(),
2341         factory->NewStringFromAsciiChecked("JSON"),
2342         static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
2343   }
2344 
2345   {  // -- M a t h
2346     Handle<String> name = factory->InternalizeUtf8String("Math");
2347     Handle<JSFunction> cons = factory->NewFunction(name);
2348     JSFunction::SetInstancePrototype(
2349         cons,
2350         Handle<Object>(native_context()->initial_object_prototype(), isolate));
2351     Handle<JSObject> math = factory->NewJSObject(cons, TENURED);
2352     DCHECK(math->IsJSObject());
2353     JSObject::AddProperty(global, name, math, DONT_ENUM);
2354     SimpleInstallFunction(math, "abs", Builtins::kMathAbs, 1, true);
2355     SimpleInstallFunction(math, "acos", Builtins::kMathAcos, 1, true);
2356     SimpleInstallFunction(math, "acosh", Builtins::kMathAcosh, 1, true);
2357     SimpleInstallFunction(math, "asin", Builtins::kMathAsin, 1, true);
2358     SimpleInstallFunction(math, "asinh", Builtins::kMathAsinh, 1, true);
2359     SimpleInstallFunction(math, "atan", Builtins::kMathAtan, 1, true);
2360     SimpleInstallFunction(math, "atanh", Builtins::kMathAtanh, 1, true);
2361     SimpleInstallFunction(math, "atan2", Builtins::kMathAtan2, 2, true);
2362     SimpleInstallFunction(math, "ceil", Builtins::kMathCeil, 1, true);
2363     SimpleInstallFunction(math, "cbrt", Builtins::kMathCbrt, 1, true);
2364     SimpleInstallFunction(math, "expm1", Builtins::kMathExpm1, 1, true);
2365     SimpleInstallFunction(math, "clz32", Builtins::kMathClz32, 1, true);
2366     SimpleInstallFunction(math, "cos", Builtins::kMathCos, 1, true);
2367     SimpleInstallFunction(math, "cosh", Builtins::kMathCosh, 1, true);
2368     SimpleInstallFunction(math, "exp", Builtins::kMathExp, 1, true);
2369     Handle<JSFunction> math_floor =
2370         SimpleInstallFunction(math, "floor", Builtins::kMathFloor, 1, true);
2371     native_context()->set_math_floor(*math_floor);
2372     SimpleInstallFunction(math, "fround", Builtins::kMathFround, 1, true);
2373     SimpleInstallFunction(math, "hypot", Builtins::kMathHypot, 2, false);
2374     SimpleInstallFunction(math, "imul", Builtins::kMathImul, 2, true);
2375     SimpleInstallFunction(math, "log", Builtins::kMathLog, 1, true);
2376     SimpleInstallFunction(math, "log1p", Builtins::kMathLog1p, 1, true);
2377     SimpleInstallFunction(math, "log2", Builtins::kMathLog2, 1, true);
2378     SimpleInstallFunction(math, "log10", Builtins::kMathLog10, 1, true);
2379     SimpleInstallFunction(math, "max", Builtins::kMathMax, 2, false);
2380     SimpleInstallFunction(math, "min", Builtins::kMathMin, 2, false);
2381     Handle<JSFunction> math_pow =
2382         SimpleInstallFunction(math, "pow", Builtins::kMathPow, 2, true);
2383     native_context()->set_math_pow(*math_pow);
2384     SimpleInstallFunction(math, "random", Builtins::kMathRandom, 0, true);
2385     SimpleInstallFunction(math, "round", Builtins::kMathRound, 1, true);
2386     SimpleInstallFunction(math, "sign", Builtins::kMathSign, 1, true);
2387     SimpleInstallFunction(math, "sin", Builtins::kMathSin, 1, true);
2388     SimpleInstallFunction(math, "sinh", Builtins::kMathSinh, 1, true);
2389     SimpleInstallFunction(math, "sqrt", Builtins::kMathSqrt, 1, true);
2390     SimpleInstallFunction(math, "tan", Builtins::kMathTan, 1, true);
2391     SimpleInstallFunction(math, "tanh", Builtins::kMathTanh, 1, true);
2392     SimpleInstallFunction(math, "trunc", Builtins::kMathTrunc, 1, true);
2393 
2394     // Install math constants.
2395     double const kE = base::ieee754::exp(1.0);
2396     double const kPI = 3.1415926535897932;
2397     InstallConstant(isolate, math, "E", factory->NewNumber(kE));
2398     InstallConstant(isolate, math, "LN10",
2399                     factory->NewNumber(base::ieee754::log(10.0)));
2400     InstallConstant(isolate, math, "LN2",
2401                     factory->NewNumber(base::ieee754::log(2.0)));
2402     InstallConstant(isolate, math, "LOG10E",
2403                     factory->NewNumber(base::ieee754::log10(kE)));
2404     InstallConstant(isolate, math, "LOG2E",
2405                     factory->NewNumber(base::ieee754::log2(kE)));
2406     InstallConstant(isolate, math, "PI", factory->NewNumber(kPI));
2407     InstallConstant(isolate, math, "SQRT1_2",
2408                     factory->NewNumber(std::sqrt(0.5)));
2409     InstallConstant(isolate, math, "SQRT2", factory->NewNumber(std::sqrt(2.0)));
2410     JSObject::AddProperty(
2411         math, factory->to_string_tag_symbol(),
2412         factory->NewStringFromAsciiChecked("Math"),
2413         static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
2414   }
2415 
2416 #ifdef V8_I18N_SUPPORT
2417   {  // -- I n t l
2418     Handle<String> name = factory->InternalizeUtf8String("Intl");
2419     Handle<JSFunction> cons = factory->NewFunction(name);
2420     JSFunction::SetInstancePrototype(
2421         cons,
2422         Handle<Object>(native_context()->initial_object_prototype(), isolate));
2423     Handle<JSObject> intl = factory->NewJSObject(cons, TENURED);
2424     DCHECK(intl->IsJSObject());
2425     JSObject::AddProperty(global, name, intl, DONT_ENUM);
2426 
2427     Handle<JSObject> date_time_format_prototype =
2428         factory->NewJSObject(isolate->object_function(), TENURED);
2429     // Install the @@toStringTag property on the {prototype}.
2430     JSObject::AddProperty(
2431         date_time_format_prototype, factory->to_string_tag_symbol(),
2432         factory->Object_string(),
2433         static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
2434     Handle<JSFunction> date_time_format_constructor = InstallFunction(
2435         intl, "DateTimeFormat", JS_OBJECT_TYPE, DateFormat::kSize,
2436         date_time_format_prototype, Builtins::kIllegal);
2437     JSObject::AddProperty(date_time_format_prototype,
2438                           factory->constructor_string(),
2439                           date_time_format_constructor, DONT_ENUM);
2440     InstallWithIntrinsicDefaultProto(
2441         isolate, date_time_format_constructor,
2442         Context::INTL_DATE_TIME_FORMAT_FUNCTION_INDEX);
2443 
2444     Handle<JSObject> number_format_prototype =
2445         factory->NewJSObject(isolate->object_function(), TENURED);
2446     // Install the @@toStringTag property on the {prototype}.
2447     JSObject::AddProperty(
2448         number_format_prototype, factory->to_string_tag_symbol(),
2449         factory->Object_string(),
2450         static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
2451     Handle<JSFunction> number_format_constructor = InstallFunction(
2452         intl, "NumberFormat", JS_OBJECT_TYPE, NumberFormat::kSize,
2453         number_format_prototype, Builtins::kIllegal);
2454     JSObject::AddProperty(number_format_prototype,
2455                           factory->constructor_string(),
2456                           number_format_constructor, DONT_ENUM);
2457     InstallWithIntrinsicDefaultProto(
2458         isolate, number_format_constructor,
2459         Context::INTL_NUMBER_FORMAT_FUNCTION_INDEX);
2460 
2461     Handle<JSObject> collator_prototype =
2462         factory->NewJSObject(isolate->object_function(), TENURED);
2463     // Install the @@toStringTag property on the {prototype}.
2464     JSObject::AddProperty(
2465         collator_prototype, factory->to_string_tag_symbol(),
2466         factory->Object_string(),
2467         static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
2468     Handle<JSFunction> collator_constructor =
2469         InstallFunction(intl, "Collator", JS_OBJECT_TYPE, Collator::kSize,
2470                         collator_prototype, Builtins::kIllegal);
2471     JSObject::AddProperty(collator_prototype, factory->constructor_string(),
2472                           collator_constructor, DONT_ENUM);
2473     InstallWithIntrinsicDefaultProto(isolate, collator_constructor,
2474                                      Context::INTL_COLLATOR_FUNCTION_INDEX);
2475 
2476     Handle<JSObject> v8_break_iterator_prototype =
2477         factory->NewJSObject(isolate->object_function(), TENURED);
2478     // Install the @@toStringTag property on the {prototype}.
2479     JSObject::AddProperty(
2480         v8_break_iterator_prototype, factory->to_string_tag_symbol(),
2481         factory->Object_string(),
2482         static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
2483     Handle<JSFunction> v8_break_iterator_constructor = InstallFunction(
2484         intl, "v8BreakIterator", JS_OBJECT_TYPE, V8BreakIterator::kSize,
2485         v8_break_iterator_prototype, Builtins::kIllegal);
2486     JSObject::AddProperty(v8_break_iterator_prototype,
2487                           factory->constructor_string(),
2488                           v8_break_iterator_constructor, DONT_ENUM);
2489     InstallWithIntrinsicDefaultProto(
2490         isolate, v8_break_iterator_constructor,
2491         Context::INTL_V8_BREAK_ITERATOR_FUNCTION_INDEX);
2492   }
2493 #endif  // V8_I18N_SUPPORT
2494 
2495   {  // -- A r r a y B u f f e r
2496     Handle<JSFunction> array_buffer_fun = InstallArrayBuffer(
2497         global, "ArrayBuffer", Builtins::kArrayBufferPrototypeGetByteLength,
2498         BuiltinFunctionId::kArrayBufferByteLength);
2499     InstallWithIntrinsicDefaultProto(isolate, array_buffer_fun,
2500                                      Context::ARRAY_BUFFER_FUN_INDEX);
2501     InstallSpeciesGetter(array_buffer_fun);
2502   }
2503 
2504   {  // -- T y p e d A r r a y
2505     Handle<JSObject> prototype =
2506         factory->NewJSObject(isolate->object_function(), TENURED);
2507     native_context()->set_typed_array_prototype(*prototype);
2508 
2509     Handle<JSFunction> typed_array_fun =
2510         CreateFunction(isolate, factory->InternalizeUtf8String("TypedArray"),
2511                        JS_TYPED_ARRAY_TYPE, JSTypedArray::kSize, prototype,
2512                        Builtins::kIllegal);
2513     typed_array_fun->shared()->set_native(false);
2514     InstallSpeciesGetter(typed_array_fun);
2515 
2516     // Install the "constructor" property on the {prototype}.
2517     JSObject::AddProperty(prototype, factory->constructor_string(),
2518                           typed_array_fun, DONT_ENUM);
2519     native_context()->set_typed_array_function(*typed_array_fun);
2520 
2521     // Install the "buffer", "byteOffset", "byteLength" and "length"
2522     // getters on the {prototype}.
2523     SimpleInstallGetter(prototype, factory->buffer_string(),
2524                         Builtins::kTypedArrayPrototypeBuffer, false);
2525     SimpleInstallGetter(prototype, factory->byte_length_string(),
2526                         Builtins::kTypedArrayPrototypeByteLength, true,
2527                         kTypedArrayByteLength);
2528     SimpleInstallGetter(prototype, factory->byte_offset_string(),
2529                         Builtins::kTypedArrayPrototypeByteOffset, true,
2530                         kTypedArrayByteOffset);
2531     SimpleInstallGetter(prototype, factory->length_string(),
2532                         Builtins::kTypedArrayPrototypeLength, true,
2533                         kTypedArrayLength);
2534 
2535     // Install "keys", "values" and "entries" methods on the {prototype}.
2536     Handle<JSFunction> entries =
2537         SimpleInstallFunction(prototype, factory->entries_string(),
2538                               Builtins::kTypedArrayPrototypeEntries, 0, true);
2539     entries->shared()->set_builtin_function_id(kTypedArrayEntries);
2540 
2541     Handle<JSFunction> keys =
2542         SimpleInstallFunction(prototype, factory->keys_string(),
2543                               Builtins::kTypedArrayPrototypeKeys, 0, true);
2544     keys->shared()->set_builtin_function_id(kTypedArrayKeys);
2545 
2546     Handle<JSFunction> values =
2547         SimpleInstallFunction(prototype, factory->values_string(),
2548                               Builtins::kTypedArrayPrototypeValues, 0, true);
2549     values->shared()->set_builtin_function_id(kTypedArrayValues);
2550     JSObject::AddProperty(prototype, factory->iterator_symbol(), values,
2551                           DONT_ENUM);
2552 
2553     // TODO(caitp): alphasort accessors/methods
2554     SimpleInstallFunction(prototype, "copyWithin",
2555                           Builtins::kTypedArrayPrototypeCopyWithin, 2, false);
2556   }
2557 
2558   {  // -- T y p e d A r r a y s
2559 #define INSTALL_TYPED_ARRAY(Type, type, TYPE, ctype, size)             \
2560   {                                                                    \
2561     Handle<JSFunction> fun;                                            \
2562     InstallTypedArray(#Type "Array", TYPE##_ELEMENTS, &fun);           \
2563     InstallWithIntrinsicDefaultProto(isolate, fun,                     \
2564                                      Context::TYPE##_ARRAY_FUN_INDEX); \
2565   }
2566     TYPED_ARRAYS(INSTALL_TYPED_ARRAY)
2567 #undef INSTALL_TYPED_ARRAY
2568   }
2569 
2570   {  // -- D a t a V i e w
2571     Handle<JSObject> prototype =
2572         factory->NewJSObject(isolate->object_function(), TENURED);
2573     Handle<JSFunction> data_view_fun =
2574         InstallFunction(global, "DataView", JS_DATA_VIEW_TYPE,
2575                         JSDataView::kSizeWithInternalFields, prototype,
2576                         Builtins::kDataViewConstructor);
2577     InstallWithIntrinsicDefaultProto(isolate, data_view_fun,
2578                                      Context::DATA_VIEW_FUN_INDEX);
2579     data_view_fun->shared()->SetConstructStub(
2580         *isolate->builtins()->DataViewConstructor_ConstructStub());
2581     data_view_fun->shared()->set_length(3);
2582     data_view_fun->shared()->DontAdaptArguments();
2583 
2584     // Install the @@toStringTag property on the {prototype}.
2585     JSObject::AddProperty(
2586         prototype, factory->to_string_tag_symbol(),
2587         factory->NewStringFromAsciiChecked("DataView"),
2588         static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
2589 
2590     // Install the "constructor" property on the {prototype}.
2591     JSObject::AddProperty(prototype, factory->constructor_string(),
2592                           data_view_fun, DONT_ENUM);
2593 
2594     // Install the "buffer", "byteOffset" and "byteLength" getters
2595     // on the {prototype}.
2596     SimpleInstallGetter(prototype, factory->buffer_string(),
2597                         Builtins::kDataViewPrototypeGetBuffer, false,
2598                         kDataViewBuffer);
2599     SimpleInstallGetter(prototype, factory->byte_length_string(),
2600                         Builtins::kDataViewPrototypeGetByteLength, false,
2601                         kDataViewByteLength);
2602     SimpleInstallGetter(prototype, factory->byte_offset_string(),
2603                         Builtins::kDataViewPrototypeGetByteOffset, false,
2604                         kDataViewByteOffset);
2605 
2606     SimpleInstallFunction(prototype, "getInt8",
2607                           Builtins::kDataViewPrototypeGetInt8, 1, false);
2608     SimpleInstallFunction(prototype, "setInt8",
2609                           Builtins::kDataViewPrototypeSetInt8, 2, false);
2610     SimpleInstallFunction(prototype, "getUint8",
2611                           Builtins::kDataViewPrototypeGetUint8, 1, false);
2612     SimpleInstallFunction(prototype, "setUint8",
2613                           Builtins::kDataViewPrototypeSetUint8, 2, false);
2614     SimpleInstallFunction(prototype, "getInt16",
2615                           Builtins::kDataViewPrototypeGetInt16, 1, false);
2616     SimpleInstallFunction(prototype, "setInt16",
2617                           Builtins::kDataViewPrototypeSetInt16, 2, false);
2618     SimpleInstallFunction(prototype, "getUint16",
2619                           Builtins::kDataViewPrototypeGetUint16, 1, false);
2620     SimpleInstallFunction(prototype, "setUint16",
2621                           Builtins::kDataViewPrototypeSetUint16, 2, false);
2622     SimpleInstallFunction(prototype, "getInt32",
2623                           Builtins::kDataViewPrototypeGetInt32, 1, false);
2624     SimpleInstallFunction(prototype, "setInt32",
2625                           Builtins::kDataViewPrototypeSetInt32, 2, false);
2626     SimpleInstallFunction(prototype, "getUint32",
2627                           Builtins::kDataViewPrototypeGetUint32, 1, false);
2628     SimpleInstallFunction(prototype, "setUint32",
2629                           Builtins::kDataViewPrototypeSetUint32, 2, false);
2630     SimpleInstallFunction(prototype, "getFloat32",
2631                           Builtins::kDataViewPrototypeGetFloat32, 1, false);
2632     SimpleInstallFunction(prototype, "setFloat32",
2633                           Builtins::kDataViewPrototypeSetFloat32, 2, false);
2634     SimpleInstallFunction(prototype, "getFloat64",
2635                           Builtins::kDataViewPrototypeGetFloat64, 1, false);
2636     SimpleInstallFunction(prototype, "setFloat64",
2637                           Builtins::kDataViewPrototypeSetFloat64, 2, false);
2638   }
2639 
2640   {  // -- M a p
2641     Handle<JSFunction> js_map_fun = InstallFunction(
2642         global, "Map", JS_MAP_TYPE, JSMap::kSize,
2643         isolate->initial_object_prototype(), Builtins::kIllegal);
2644     InstallWithIntrinsicDefaultProto(isolate, js_map_fun,
2645                                      Context::JS_MAP_FUN_INDEX);
2646     InstallSpeciesGetter(js_map_fun);
2647   }
2648 
2649   {  // -- S e t
2650     Handle<JSFunction> js_set_fun = InstallFunction(
2651         global, "Set", JS_SET_TYPE, JSSet::kSize,
2652         isolate->initial_object_prototype(), Builtins::kIllegal);
2653     InstallWithIntrinsicDefaultProto(isolate, js_set_fun,
2654                                      Context::JS_SET_FUN_INDEX);
2655     InstallSpeciesGetter(js_set_fun);
2656   }
2657 
2658   {  // -- J S M o d u l e N a m e s p a c e
2659     Handle<Map> map =
2660         factory->NewMap(JS_MODULE_NAMESPACE_TYPE, JSModuleNamespace::kSize);
2661     Map::SetPrototype(map, isolate->factory()->null_value());
2662     Map::EnsureDescriptorSlack(map, 1);
2663     native_context()->set_js_module_namespace_map(*map);
2664 
2665     {  // Install @@toStringTag.
2666       PropertyAttributes attribs =
2667           static_cast<PropertyAttributes>(DONT_DELETE | DONT_ENUM | READ_ONLY);
2668       Descriptor d =
2669           Descriptor::DataField(factory->to_string_tag_symbol(),
2670                                 JSModuleNamespace::kToStringTagFieldIndex,
2671                                 attribs, Representation::Tagged());
2672       map->AppendDescriptor(&d);
2673     }
2674 
2675     map->SetInObjectProperties(JSModuleNamespace::kInObjectFieldCount);
2676   }
2677 
2678   {  // -- I t e r a t o r R e s u l t
2679     Handle<Map> map =
2680         factory->NewMap(JS_OBJECT_TYPE, JSIteratorResult::kSize);
2681     Map::SetPrototype(map, isolate->initial_object_prototype());
2682     Map::EnsureDescriptorSlack(map, 2);
2683 
2684     {  // value
2685       Descriptor d = Descriptor::DataField(factory->value_string(),
2686                                            JSIteratorResult::kValueIndex, NONE,
2687                                            Representation::Tagged());
2688       map->AppendDescriptor(&d);
2689     }
2690 
2691     {  // done
2692       Descriptor d = Descriptor::DataField(factory->done_string(),
2693                                            JSIteratorResult::kDoneIndex, NONE,
2694                                            Representation::Tagged());
2695       map->AppendDescriptor(&d);
2696     }
2697 
2698     map->SetConstructor(native_context()->object_function());
2699     map->SetInObjectProperties(2);
2700     native_context()->set_iterator_result_map(*map);
2701   }
2702 
2703   {  // -- W e a k M a p
2704     Handle<JSFunction> js_weak_map_fun = InstallFunction(
2705         global, "WeakMap", JS_WEAK_MAP_TYPE, JSWeakMap::kSize,
2706         isolate->initial_object_prototype(), Builtins::kIllegal);
2707     InstallWithIntrinsicDefaultProto(isolate, js_weak_map_fun,
2708                                      Context::JS_WEAK_MAP_FUN_INDEX);
2709   }
2710 
2711   {  // -- W e a k S e t
2712     Handle<JSFunction> js_weak_set_fun = InstallFunction(
2713         global, "WeakSet", JS_WEAK_SET_TYPE, JSWeakSet::kSize,
2714         isolate->initial_object_prototype(), Builtins::kIllegal);
2715     InstallWithIntrinsicDefaultProto(isolate, js_weak_set_fun,
2716                                      Context::JS_WEAK_SET_FUN_INDEX);
2717   }
2718 
2719   {  // -- P r o x y
2720     CreateJSProxyMaps();
2721 
2722     Handle<String> name = factory->Proxy_string();
2723     Handle<Code> code(isolate->builtins()->ProxyConstructor());
2724 
2725     Handle<JSFunction> proxy_function =
2726         factory->NewFunction(isolate->proxy_function_map(),
2727                              factory->Proxy_string(), MaybeHandle<Code>(code));
2728 
2729     JSFunction::SetInitialMap(
2730         proxy_function, Handle<Map>(native_context()->proxy_map(), isolate),
2731         factory->null_value());
2732 
2733     proxy_function->shared()->SetConstructStub(
2734         *isolate->builtins()->ProxyConstructor_ConstructStub());
2735     proxy_function->shared()->set_internal_formal_parameter_count(2);
2736     proxy_function->shared()->set_length(2);
2737 
2738     native_context()->set_proxy_function(*proxy_function);
2739     InstallFunction(global, name, proxy_function, factory->Object_string());
2740   }
2741 
2742   {  // -- R e f l e c t
2743     Handle<String> reflect_string = factory->InternalizeUtf8String("Reflect");
2744     Handle<JSObject> reflect =
2745         factory->NewJSObject(isolate->object_function(), TENURED);
2746     JSObject::AddProperty(global, reflect_string, reflect, DONT_ENUM);
2747 
2748     Handle<JSFunction> define_property =
2749         SimpleInstallFunction(reflect, factory->defineProperty_string(),
2750                               Builtins::kReflectDefineProperty, 3, true);
2751     native_context()->set_reflect_define_property(*define_property);
2752 
2753     Handle<JSFunction> delete_property =
2754         SimpleInstallFunction(reflect, factory->deleteProperty_string(),
2755                               Builtins::kReflectDeleteProperty, 2, true);
2756     native_context()->set_reflect_delete_property(*delete_property);
2757 
2758     Handle<JSFunction> apply = SimpleInstallFunction(
2759         reflect, factory->apply_string(), Builtins::kReflectApply, 3, false);
2760     native_context()->set_reflect_apply(*apply);
2761 
2762     Handle<JSFunction> construct =
2763         SimpleInstallFunction(reflect, factory->construct_string(),
2764                               Builtins::kReflectConstruct, 2, false);
2765     native_context()->set_reflect_construct(*construct);
2766 
2767     SimpleInstallFunction(reflect, factory->get_string(), Builtins::kReflectGet,
2768                           2, false);
2769     SimpleInstallFunction(reflect, factory->getOwnPropertyDescriptor_string(),
2770                           Builtins::kReflectGetOwnPropertyDescriptor, 2, true);
2771     SimpleInstallFunction(reflect, factory->getPrototypeOf_string(),
2772                           Builtins::kReflectGetPrototypeOf, 1, true);
2773     SimpleInstallFunction(reflect, factory->has_string(), Builtins::kReflectHas,
2774                           2, true);
2775     SimpleInstallFunction(reflect, factory->isExtensible_string(),
2776                           Builtins::kReflectIsExtensible, 1, true);
2777     SimpleInstallFunction(reflect, factory->ownKeys_string(),
2778                           Builtins::kReflectOwnKeys, 1, true);
2779     SimpleInstallFunction(reflect, factory->preventExtensions_string(),
2780                           Builtins::kReflectPreventExtensions, 1, true);
2781     SimpleInstallFunction(reflect, factory->set_string(), Builtins::kReflectSet,
2782                           3, false);
2783     SimpleInstallFunction(reflect, factory->setPrototypeOf_string(),
2784                           Builtins::kReflectSetPrototypeOf, 2, true);
2785   }
2786 
2787   {  // --- B o u n d F u n c t i o n
2788     Handle<Map> map =
2789         factory->NewMap(JS_BOUND_FUNCTION_TYPE, JSBoundFunction::kSize);
2790     map->set_is_callable();
2791     Map::SetPrototype(map, empty_function);
2792 
2793     PropertyAttributes roc_attribs =
2794         static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY);
2795     Map::EnsureDescriptorSlack(map, 2);
2796 
2797     Handle<AccessorInfo> bound_length =
2798         Accessors::BoundFunctionLengthInfo(isolate, roc_attribs);
2799     {  // length
2800       Descriptor d = Descriptor::AccessorConstant(factory->length_string(),
2801                                                   bound_length, roc_attribs);
2802       map->AppendDescriptor(&d);
2803     }
2804     Handle<AccessorInfo> bound_name =
2805         Accessors::BoundFunctionNameInfo(isolate, roc_attribs);
2806     {  // name
2807       Descriptor d = Descriptor::AccessorConstant(factory->name_string(),
2808                                                   bound_name, roc_attribs);
2809       map->AppendDescriptor(&d);
2810     }
2811     map->SetInObjectProperties(0);
2812     native_context()->set_bound_function_without_constructor_map(*map);
2813 
2814     map = Map::Copy(map, "IsConstructor");
2815     map->set_is_constructor(true);
2816     native_context()->set_bound_function_with_constructor_map(*map);
2817   }
2818 
2819   {  // --- sloppy arguments map
2820     // Make sure we can recognize argument objects at runtime.
2821     // This is done by introducing an anonymous function with
2822     // class_name equals 'Arguments'.
2823     Handle<String> arguments_string = factory->Arguments_string();
2824     Handle<Code> code = isolate->builtins()->Illegal();
2825     Handle<JSFunction> function = factory->NewFunctionWithoutPrototype(
2826         arguments_string, code);
2827     function->shared()->set_instance_class_name(*arguments_string);
2828 
2829     Handle<Map> map = factory->NewMap(
2830         JS_ARGUMENTS_TYPE, JSSloppyArgumentsObject::kSize, FAST_ELEMENTS);
2831     // Create the descriptor array for the arguments object.
2832     Map::EnsureDescriptorSlack(map, 2);
2833 
2834     {  // length
2835       Descriptor d = Descriptor::DataField(
2836           factory->length_string(), JSSloppyArgumentsObject::kLengthIndex,
2837           DONT_ENUM, Representation::Tagged());
2838       map->AppendDescriptor(&d);
2839     }
2840     {  // callee
2841       Descriptor d = Descriptor::DataField(
2842           factory->callee_string(), JSSloppyArgumentsObject::kCalleeIndex,
2843           DONT_ENUM, Representation::Tagged());
2844       map->AppendDescriptor(&d);
2845     }
2846     // @@iterator method is added later.
2847 
2848     map->SetInObjectProperties(2);
2849     native_context()->set_sloppy_arguments_map(*map);
2850 
2851     DCHECK(!function->has_initial_map());
2852     JSFunction::SetInitialMap(function, map,
2853                               isolate->initial_object_prototype());
2854 
2855     DCHECK(!map->is_dictionary_map());
2856     DCHECK(IsFastObjectElementsKind(map->elements_kind()));
2857   }
2858 
2859   {  // --- fast and slow aliased arguments map
2860     Handle<Map> map = isolate->sloppy_arguments_map();
2861     map = Map::Copy(map, "FastAliasedArguments");
2862     map->set_elements_kind(FAST_SLOPPY_ARGUMENTS_ELEMENTS);
2863     DCHECK_EQ(2, map->GetInObjectProperties());
2864     native_context()->set_fast_aliased_arguments_map(*map);
2865 
2866     map = Map::Copy(map, "SlowAliasedArguments");
2867     map->set_elements_kind(SLOW_SLOPPY_ARGUMENTS_ELEMENTS);
2868     DCHECK_EQ(2, map->GetInObjectProperties());
2869     native_context()->set_slow_aliased_arguments_map(*map);
2870   }
2871 
2872   {  // --- strict mode arguments map
2873     const PropertyAttributes attributes =
2874       static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
2875 
2876     // Create the ThrowTypeError function.
2877     Handle<AccessorPair> callee = factory->NewAccessorPair();
2878 
2879     Handle<JSFunction> poison = GetStrictArgumentsPoisonFunction();
2880 
2881     // Install the ThrowTypeError function.
2882     callee->set_getter(*poison);
2883     callee->set_setter(*poison);
2884 
2885     // Create the map. Allocate one in-object field for length.
2886     Handle<Map> map = factory->NewMap(
2887         JS_ARGUMENTS_TYPE, JSStrictArgumentsObject::kSize, FAST_ELEMENTS);
2888     // Create the descriptor array for the arguments object.
2889     Map::EnsureDescriptorSlack(map, 2);
2890 
2891     {  // length
2892       Descriptor d = Descriptor::DataField(
2893           factory->length_string(), JSStrictArgumentsObject::kLengthIndex,
2894           DONT_ENUM, Representation::Tagged());
2895       map->AppendDescriptor(&d);
2896     }
2897     {  // callee
2898       Descriptor d = Descriptor::AccessorConstant(factory->callee_string(),
2899                                                   callee, attributes);
2900       map->AppendDescriptor(&d);
2901     }
2902     // @@iterator method is added later.
2903 
2904     DCHECK_EQ(native_context()->object_function()->prototype(),
2905               *isolate->initial_object_prototype());
2906     Map::SetPrototype(map, isolate->initial_object_prototype());
2907     map->SetInObjectProperties(1);
2908 
2909     // Copy constructor from the sloppy arguments boilerplate.
2910     map->SetConstructor(
2911         native_context()->sloppy_arguments_map()->GetConstructor());
2912 
2913     native_context()->set_strict_arguments_map(*map);
2914 
2915     DCHECK(!map->is_dictionary_map());
2916     DCHECK(IsFastObjectElementsKind(map->elements_kind()));
2917   }
2918 
2919   {  // --- context extension
2920     // Create a function for the context extension objects.
2921     Handle<Code> code = isolate->builtins()->Illegal();
2922     Handle<JSFunction> context_extension_fun = factory->NewFunction(
2923         factory->empty_string(), code, JS_CONTEXT_EXTENSION_OBJECT_TYPE,
2924         JSObject::kHeaderSize);
2925 
2926     Handle<String> name = factory->InternalizeOneByteString(
2927         STATIC_CHAR_VECTOR("context_extension"));
2928     context_extension_fun->shared()->set_instance_class_name(*name);
2929     native_context()->set_context_extension_function(*context_extension_fun);
2930   }
2931 
2932 
2933   {
2934     // Set up the call-as-function delegate.
2935     Handle<Code> code = isolate->builtins()->HandleApiCallAsFunction();
2936     Handle<JSFunction> delegate = factory->NewFunction(
2937         factory->empty_string(), code, JS_OBJECT_TYPE, JSObject::kHeaderSize);
2938     native_context()->set_call_as_function_delegate(*delegate);
2939     delegate->shared()->DontAdaptArguments();
2940   }
2941 
2942   {
2943     // Set up the call-as-constructor delegate.
2944     Handle<Code> code = isolate->builtins()->HandleApiCallAsConstructor();
2945     Handle<JSFunction> delegate = factory->NewFunction(
2946         factory->empty_string(), code, JS_OBJECT_TYPE, JSObject::kHeaderSize);
2947     native_context()->set_call_as_constructor_delegate(*delegate);
2948     delegate->shared()->DontAdaptArguments();
2949   }
2950 }  // NOLINT(readability/fn_size)
2951 
InstallTypedArray(const char * name,ElementsKind elements_kind,Handle<JSFunction> * fun)2952 void Genesis::InstallTypedArray(const char* name, ElementsKind elements_kind,
2953                                 Handle<JSFunction>* fun) {
2954   Handle<JSObject> global = Handle<JSObject>(native_context()->global_object());
2955 
2956   Handle<JSObject> typed_array_prototype =
2957       Handle<JSObject>(isolate()->typed_array_prototype());
2958   Handle<JSFunction> typed_array_function =
2959       Handle<JSFunction>(isolate()->typed_array_function());
2960 
2961   Handle<JSObject> prototype =
2962       factory()->NewJSObject(isolate()->object_function(), TENURED);
2963   Handle<JSFunction> result = InstallFunction(
2964       global, name, JS_TYPED_ARRAY_TYPE, JSTypedArray::kSizeWithInternalFields,
2965       prototype, Builtins::kIllegal);
2966   result->initial_map()->set_elements_kind(elements_kind);
2967 
2968   CHECK(JSObject::SetPrototype(result, typed_array_function, false,
2969                                Object::DONT_THROW)
2970             .FromJust());
2971 
2972   CHECK(JSObject::SetPrototype(prototype, typed_array_prototype, false,
2973                                Object::DONT_THROW)
2974             .FromJust());
2975   *fun = result;
2976 }
2977 
2978 
InitializeExperimentalGlobal()2979 void Genesis::InitializeExperimentalGlobal() {
2980 #define FEATURE_INITIALIZE_GLOBAL(id, descr) InitializeGlobal_##id();
2981 
2982   HARMONY_INPROGRESS(FEATURE_INITIALIZE_GLOBAL)
2983   HARMONY_STAGED(FEATURE_INITIALIZE_GLOBAL)
2984   HARMONY_SHIPPING(FEATURE_INITIALIZE_GLOBAL)
2985 #undef FEATURE_INITIALIZE_GLOBAL
2986 
2987   InitializeGlobal_enable_fast_array_builtins();
2988 }
2989 
2990 
CompileBuiltin(Isolate * isolate,int index)2991 bool Bootstrapper::CompileBuiltin(Isolate* isolate, int index) {
2992   Vector<const char> name = Natives::GetScriptName(index);
2993   Handle<String> source_code =
2994       isolate->bootstrapper()->SourceLookup<Natives>(index);
2995 
2996   // We pass in extras_utils so that builtin code can set it up for later use
2997   // by actual extras code, compiled with CompileExtraBuiltin.
2998   Handle<Object> global = isolate->global_object();
2999   Handle<Object> utils = isolate->natives_utils_object();
3000   Handle<Object> extras_utils = isolate->extras_utils_object();
3001   Handle<Object> args[] = {global, utils, extras_utils};
3002 
3003   return Bootstrapper::CompileNative(isolate, name, source_code,
3004                                      arraysize(args), args, NATIVES_CODE);
3005 }
3006 
3007 
CompileExperimentalBuiltin(Isolate * isolate,int index)3008 bool Bootstrapper::CompileExperimentalBuiltin(Isolate* isolate, int index) {
3009   HandleScope scope(isolate);
3010   Vector<const char> name = ExperimentalNatives::GetScriptName(index);
3011   Handle<String> source_code =
3012       isolate->bootstrapper()->SourceLookup<ExperimentalNatives>(index);
3013   Handle<Object> global = isolate->global_object();
3014   Handle<Object> utils = isolate->natives_utils_object();
3015   Handle<Object> args[] = {global, utils};
3016   return Bootstrapper::CompileNative(isolate, name, source_code,
3017                                      arraysize(args), args, NATIVES_CODE);
3018 }
3019 
3020 
CompileExtraBuiltin(Isolate * isolate,int index)3021 bool Bootstrapper::CompileExtraBuiltin(Isolate* isolate, int index) {
3022   HandleScope scope(isolate);
3023   Vector<const char> name = ExtraNatives::GetScriptName(index);
3024   Handle<String> source_code =
3025       isolate->bootstrapper()->SourceLookup<ExtraNatives>(index);
3026   Handle<Object> global = isolate->global_object();
3027   Handle<Object> binding = isolate->extras_binding_object();
3028   Handle<Object> extras_utils = isolate->extras_utils_object();
3029   Handle<Object> args[] = {global, binding, extras_utils};
3030   return Bootstrapper::CompileNative(isolate, name, source_code,
3031                                      arraysize(args), args, EXTENSION_CODE);
3032 }
3033 
3034 
CompileExperimentalExtraBuiltin(Isolate * isolate,int index)3035 bool Bootstrapper::CompileExperimentalExtraBuiltin(Isolate* isolate,
3036                                                    int index) {
3037   HandleScope scope(isolate);
3038   Vector<const char> name = ExperimentalExtraNatives::GetScriptName(index);
3039   Handle<String> source_code =
3040       isolate->bootstrapper()->SourceLookup<ExperimentalExtraNatives>(index);
3041   Handle<Object> global = isolate->global_object();
3042   Handle<Object> binding = isolate->extras_binding_object();
3043   Handle<Object> extras_utils = isolate->extras_utils_object();
3044   Handle<Object> args[] = {global, binding, extras_utils};
3045   return Bootstrapper::CompileNative(isolate, name, source_code,
3046                                      arraysize(args), args, EXTENSION_CODE);
3047 }
3048 
CompileNative(Isolate * isolate,Vector<const char> name,Handle<String> source,int argc,Handle<Object> argv[],NativesFlag natives_flag)3049 bool Bootstrapper::CompileNative(Isolate* isolate, Vector<const char> name,
3050                                  Handle<String> source, int argc,
3051                                  Handle<Object> argv[],
3052                                  NativesFlag natives_flag) {
3053   SuppressDebug compiling_natives(isolate->debug());
3054   // During genesis, the boilerplate for stack overflow won't work until the
3055   // environment has been at least partially initialized. Add a stack check
3056   // before entering JS code to catch overflow early.
3057   StackLimitCheck check(isolate);
3058   if (check.JsHasOverflowed(4 * KB)) {
3059     isolate->StackOverflow();
3060     return false;
3061   }
3062 
3063   Handle<Context> context(isolate->context());
3064 
3065   Handle<String> script_name =
3066       isolate->factory()->NewStringFromUtf8(name).ToHandleChecked();
3067   Handle<SharedFunctionInfo> function_info =
3068       Compiler::GetSharedFunctionInfoForScript(
3069           source, script_name, 0, 0, ScriptOriginOptions(), Handle<Object>(),
3070           context, NULL, NULL, ScriptCompiler::kNoCompileOptions, natives_flag);
3071   if (function_info.is_null()) return false;
3072 
3073   DCHECK(context->IsNativeContext());
3074 
3075   Handle<JSFunction> fun =
3076       isolate->factory()->NewFunctionFromSharedFunctionInfo(function_info,
3077                                                             context);
3078   Handle<Object> receiver = isolate->factory()->undefined_value();
3079 
3080   // For non-extension scripts, run script to get the function wrapper.
3081   Handle<Object> wrapper;
3082   if (!Execution::TryCall(isolate, fun, receiver, 0, nullptr,
3083                           Execution::MessageHandling::kKeepPending, nullptr)
3084            .ToHandle(&wrapper)) {
3085     return false;
3086   }
3087   // Then run the function wrapper.
3088   return !Execution::TryCall(isolate, Handle<JSFunction>::cast(wrapper),
3089                              receiver, argc, argv,
3090                              Execution::MessageHandling::kKeepPending, nullptr)
3091               .is_null();
3092 }
3093 
3094 
CallUtilsFunction(Isolate * isolate,const char * name)3095 bool Genesis::CallUtilsFunction(Isolate* isolate, const char* name) {
3096   Handle<JSObject> utils =
3097       Handle<JSObject>::cast(isolate->natives_utils_object());
3098   Handle<String> name_string =
3099       isolate->factory()->NewStringFromAsciiChecked(name);
3100   Handle<Object> fun = JSObject::GetDataProperty(utils, name_string);
3101   Handle<Object> receiver = isolate->factory()->undefined_value();
3102   Handle<Object> args[] = {utils};
3103   return !Execution::TryCall(isolate, fun, receiver, 1, args,
3104                              Execution::MessageHandling::kKeepPending, nullptr)
3105               .is_null();
3106 }
3107 
3108 
CompileExtension(Isolate * isolate,v8::Extension * extension)3109 bool Genesis::CompileExtension(Isolate* isolate, v8::Extension* extension) {
3110   Factory* factory = isolate->factory();
3111   HandleScope scope(isolate);
3112   Handle<SharedFunctionInfo> function_info;
3113 
3114   Handle<String> source =
3115       isolate->factory()
3116           ->NewExternalStringFromOneByte(extension->source())
3117           .ToHandleChecked();
3118   DCHECK(source->IsOneByteRepresentation());
3119 
3120   // If we can't find the function in the cache, we compile a new
3121   // function and insert it into the cache.
3122   Vector<const char> name = CStrVector(extension->name());
3123   SourceCodeCache* cache = isolate->bootstrapper()->extensions_cache();
3124   Handle<Context> context(isolate->context());
3125   DCHECK(context->IsNativeContext());
3126 
3127   if (!cache->Lookup(name, &function_info)) {
3128     Handle<String> script_name =
3129         factory->NewStringFromUtf8(name).ToHandleChecked();
3130     function_info = Compiler::GetSharedFunctionInfoForScript(
3131         source, script_name, 0, 0, ScriptOriginOptions(), Handle<Object>(),
3132         context, extension, NULL, ScriptCompiler::kNoCompileOptions,
3133         EXTENSION_CODE);
3134     if (function_info.is_null()) return false;
3135     cache->Add(name, function_info);
3136   }
3137 
3138   // Set up the function context. Conceptually, we should clone the
3139   // function before overwriting the context but since we're in a
3140   // single-threaded environment it is not strictly necessary.
3141   Handle<JSFunction> fun =
3142       factory->NewFunctionFromSharedFunctionInfo(function_info, context);
3143 
3144   // Call function using either the runtime object or the global
3145   // object as the receiver. Provide no parameters.
3146   Handle<Object> receiver = isolate->global_object();
3147   return !Execution::TryCall(isolate, fun, receiver, 0, nullptr,
3148                              Execution::MessageHandling::kKeepPending, nullptr)
3149               .is_null();
3150 }
3151 
3152 
ResolveBuiltinIdHolder(Handle<Context> native_context,const char * holder_expr)3153 static Handle<JSObject> ResolveBuiltinIdHolder(Handle<Context> native_context,
3154                                                const char* holder_expr) {
3155   Isolate* isolate = native_context->GetIsolate();
3156   Factory* factory = isolate->factory();
3157   Handle<JSGlobalObject> global(native_context->global_object());
3158   const char* period_pos = strchr(holder_expr, '.');
3159   if (period_pos == NULL) {
3160     return Handle<JSObject>::cast(
3161         Object::GetPropertyOrElement(
3162             global, factory->InternalizeUtf8String(holder_expr))
3163             .ToHandleChecked());
3164   }
3165   const char* inner = period_pos + 1;
3166   DCHECK(!strchr(inner, '.'));
3167   Vector<const char> property(holder_expr,
3168                               static_cast<int>(period_pos - holder_expr));
3169   Handle<String> property_string = factory->InternalizeUtf8String(property);
3170   DCHECK(!property_string.is_null());
3171   Handle<JSObject> object = Handle<JSObject>::cast(
3172       JSReceiver::GetProperty(global, property_string).ToHandleChecked());
3173   if (strcmp("prototype", inner) == 0) {
3174     Handle<JSFunction> function = Handle<JSFunction>::cast(object);
3175     return Handle<JSObject>(JSObject::cast(function->prototype()));
3176   }
3177   Handle<String> inner_string = factory->InternalizeUtf8String(inner);
3178   DCHECK(!inner_string.is_null());
3179   Handle<Object> value =
3180       JSReceiver::GetProperty(object, inner_string).ToHandleChecked();
3181   return Handle<JSObject>::cast(value);
3182 }
3183 
ConfigureUtilsObject(GlobalContextType context_type)3184 void Genesis::ConfigureUtilsObject(GlobalContextType context_type) {
3185   switch (context_type) {
3186     // We still need the utils object to find debug functions.
3187     case DEBUG_CONTEXT:
3188       return;
3189     // Expose the natives in global if a valid name for it is specified.
3190     case FULL_CONTEXT: {
3191       // We still need the utils object after deserialization.
3192       if (isolate()->serializer_enabled()) return;
3193       if (FLAG_expose_natives_as == NULL) break;
3194       if (strlen(FLAG_expose_natives_as) == 0) break;
3195       HandleScope scope(isolate());
3196       Handle<String> natives_key =
3197           factory()->InternalizeUtf8String(FLAG_expose_natives_as);
3198       uint32_t dummy_index;
3199       if (natives_key->AsArrayIndex(&dummy_index)) break;
3200       Handle<Object> utils = isolate()->natives_utils_object();
3201       Handle<JSObject> global = isolate()->global_object();
3202       JSObject::AddProperty(global, natives_key, utils, DONT_ENUM);
3203       break;
3204     }
3205   }
3206 
3207   // The utils object can be removed for cases that reach this point.
3208   native_context()->set_natives_utils_object(heap()->undefined_value());
3209   native_context()->set_extras_utils_object(heap()->undefined_value());
3210   native_context()->set_exports_container(heap()->undefined_value());
3211 }
3212 
3213 
ExportFromRuntime(Isolate * isolate,Handle<JSObject> container)3214 void Bootstrapper::ExportFromRuntime(Isolate* isolate,
3215                                      Handle<JSObject> container) {
3216   Factory* factory = isolate->factory();
3217   HandleScope scope(isolate);
3218   Handle<Context> native_context = isolate->native_context();
3219 #define EXPORT_PRIVATE_SYMBOL(NAME)                                       \
3220   Handle<String> NAME##_name = factory->NewStringFromAsciiChecked(#NAME); \
3221   JSObject::AddProperty(container, NAME##_name, factory->NAME(), NONE);
3222   PRIVATE_SYMBOL_LIST(EXPORT_PRIVATE_SYMBOL)
3223 #undef EXPORT_PRIVATE_SYMBOL
3224 
3225 #define EXPORT_PUBLIC_SYMBOL(NAME, DESCRIPTION)                           \
3226   Handle<String> NAME##_name = factory->NewStringFromAsciiChecked(#NAME); \
3227   JSObject::AddProperty(container, NAME##_name, factory->NAME(), NONE);
3228   PUBLIC_SYMBOL_LIST(EXPORT_PUBLIC_SYMBOL)
3229   WELL_KNOWN_SYMBOL_LIST(EXPORT_PUBLIC_SYMBOL)
3230 #undef EXPORT_PUBLIC_SYMBOL
3231 
3232   {
3233     Handle<JSFunction> to_string = InstallFunction(
3234         container, "object_to_string", JS_OBJECT_TYPE, JSObject::kHeaderSize,
3235         MaybeHandle<JSObject>(), Builtins::kObjectProtoToString);
3236     to_string->shared()->set_internal_formal_parameter_count(0);
3237     to_string->shared()->set_length(0);
3238     native_context->set_object_to_string(*to_string);
3239   }
3240 
3241   Handle<JSObject> iterator_prototype(
3242       native_context->initial_iterator_prototype());
3243 
3244   JSObject::AddProperty(container,
3245                         factory->InternalizeUtf8String("IteratorPrototype"),
3246                         iterator_prototype, NONE);
3247 
3248   {
3249     PrototypeIterator iter(native_context->generator_function_map());
3250     Handle<JSObject> generator_function_prototype(iter.GetCurrent<JSObject>());
3251 
3252     JSObject::AddProperty(
3253         container, factory->InternalizeUtf8String("GeneratorFunctionPrototype"),
3254         generator_function_prototype, NONE);
3255 
3256     static const bool kUseStrictFunctionMap = true;
3257     Handle<JSFunction> generator_function_function = InstallFunction(
3258         container, "GeneratorFunction", JS_FUNCTION_TYPE, JSFunction::kSize,
3259         generator_function_prototype, Builtins::kGeneratorFunctionConstructor,
3260         kUseStrictFunctionMap);
3261     generator_function_function->set_prototype_or_initial_map(
3262         native_context->generator_function_map());
3263     generator_function_function->shared()->DontAdaptArguments();
3264     generator_function_function->shared()->SetConstructStub(
3265         *isolate->builtins()->GeneratorFunctionConstructor());
3266     generator_function_function->shared()->set_length(1);
3267     InstallWithIntrinsicDefaultProto(
3268         isolate, generator_function_function,
3269         Context::GENERATOR_FUNCTION_FUNCTION_INDEX);
3270 
3271     JSObject::ForceSetPrototype(generator_function_function,
3272                                 isolate->function_function());
3273     JSObject::AddProperty(
3274         generator_function_prototype, factory->constructor_string(),
3275         generator_function_function,
3276         static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
3277 
3278     native_context->generator_function_map()->SetConstructor(
3279         *generator_function_function);
3280   }
3281 
3282   {  // -- S e t I t e r a t o r
3283     Handle<JSObject> set_iterator_prototype =
3284         isolate->factory()->NewJSObject(isolate->object_function(), TENURED);
3285     JSObject::ForceSetPrototype(set_iterator_prototype, iterator_prototype);
3286     Handle<JSFunction> set_iterator_function = InstallFunction(
3287         container, "SetIterator", JS_SET_ITERATOR_TYPE, JSSetIterator::kSize,
3288         set_iterator_prototype, Builtins::kIllegal);
3289     native_context->set_set_iterator_map(set_iterator_function->initial_map());
3290   }
3291 
3292   {  // -- M a p I t e r a t o r
3293     Handle<JSObject> map_iterator_prototype =
3294         isolate->factory()->NewJSObject(isolate->object_function(), TENURED);
3295     JSObject::ForceSetPrototype(map_iterator_prototype, iterator_prototype);
3296     Handle<JSFunction> map_iterator_function = InstallFunction(
3297         container, "MapIterator", JS_MAP_ITERATOR_TYPE, JSMapIterator::kSize,
3298         map_iterator_prototype, Builtins::kIllegal);
3299     native_context->set_map_iterator_map(map_iterator_function->initial_map());
3300   }
3301 
3302   {  // -- S c r i p t
3303     // Builtin functions for Script.
3304     Handle<JSFunction> script_fun = InstallFunction(
3305         container, "Script", JS_VALUE_TYPE, JSValue::kSize,
3306         isolate->initial_object_prototype(), Builtins::kUnsupportedThrower);
3307     Handle<JSObject> prototype =
3308         factory->NewJSObject(isolate->object_function(), TENURED);
3309     Accessors::FunctionSetPrototype(script_fun, prototype).Assert();
3310     native_context->set_script_function(*script_fun);
3311 
3312     Handle<Map> script_map = Handle<Map>(script_fun->initial_map());
3313     Map::EnsureDescriptorSlack(script_map, 15);
3314 
3315     PropertyAttributes attribs =
3316         static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
3317 
3318     Handle<AccessorInfo> script_column =
3319         Accessors::ScriptColumnOffsetInfo(isolate, attribs);
3320     {
3321       Descriptor d = Descriptor::AccessorConstant(
3322           Handle<Name>(Name::cast(script_column->name())), script_column,
3323           attribs);
3324       script_map->AppendDescriptor(&d);
3325     }
3326 
3327     Handle<AccessorInfo> script_id = Accessors::ScriptIdInfo(isolate, attribs);
3328     {
3329       Descriptor d = Descriptor::AccessorConstant(
3330           Handle<Name>(Name::cast(script_id->name())), script_id, attribs);
3331       script_map->AppendDescriptor(&d);
3332     }
3333 
3334 
3335     Handle<AccessorInfo> script_name =
3336         Accessors::ScriptNameInfo(isolate, attribs);
3337     {
3338       Descriptor d = Descriptor::AccessorConstant(
3339           Handle<Name>(Name::cast(script_name->name())), script_name, attribs);
3340       script_map->AppendDescriptor(&d);
3341     }
3342 
3343     Handle<AccessorInfo> script_line =
3344         Accessors::ScriptLineOffsetInfo(isolate, attribs);
3345     {
3346       Descriptor d = Descriptor::AccessorConstant(
3347           Handle<Name>(Name::cast(script_line->name())), script_line, attribs);
3348       script_map->AppendDescriptor(&d);
3349     }
3350 
3351     Handle<AccessorInfo> script_source =
3352         Accessors::ScriptSourceInfo(isolate, attribs);
3353     {
3354       Descriptor d = Descriptor::AccessorConstant(
3355           Handle<Name>(Name::cast(script_source->name())), script_source,
3356           attribs);
3357       script_map->AppendDescriptor(&d);
3358     }
3359 
3360     Handle<AccessorInfo> script_type =
3361         Accessors::ScriptTypeInfo(isolate, attribs);
3362     {
3363       Descriptor d = Descriptor::AccessorConstant(
3364           Handle<Name>(Name::cast(script_type->name())), script_type, attribs);
3365       script_map->AppendDescriptor(&d);
3366     }
3367 
3368     Handle<AccessorInfo> script_compilation_type =
3369         Accessors::ScriptCompilationTypeInfo(isolate, attribs);
3370     {
3371       Descriptor d = Descriptor::AccessorConstant(
3372           Handle<Name>(Name::cast(script_compilation_type->name())),
3373           script_compilation_type, attribs);
3374       script_map->AppendDescriptor(&d);
3375     }
3376 
3377     Handle<AccessorInfo> script_context_data =
3378         Accessors::ScriptContextDataInfo(isolate, attribs);
3379     {
3380       Descriptor d = Descriptor::AccessorConstant(
3381           Handle<Name>(Name::cast(script_context_data->name())),
3382           script_context_data, attribs);
3383       script_map->AppendDescriptor(&d);
3384     }
3385 
3386     Handle<AccessorInfo> script_eval_from_script =
3387         Accessors::ScriptEvalFromScriptInfo(isolate, attribs);
3388     {
3389       Descriptor d = Descriptor::AccessorConstant(
3390           Handle<Name>(Name::cast(script_eval_from_script->name())),
3391           script_eval_from_script, attribs);
3392       script_map->AppendDescriptor(&d);
3393     }
3394 
3395     Handle<AccessorInfo> script_eval_from_script_position =
3396         Accessors::ScriptEvalFromScriptPositionInfo(isolate, attribs);
3397     {
3398       Descriptor d = Descriptor::AccessorConstant(
3399           Handle<Name>(Name::cast(script_eval_from_script_position->name())),
3400           script_eval_from_script_position, attribs);
3401       script_map->AppendDescriptor(&d);
3402     }
3403 
3404     Handle<AccessorInfo> script_eval_from_function_name =
3405         Accessors::ScriptEvalFromFunctionNameInfo(isolate, attribs);
3406     {
3407       Descriptor d = Descriptor::AccessorConstant(
3408           Handle<Name>(Name::cast(script_eval_from_function_name->name())),
3409           script_eval_from_function_name, attribs);
3410       script_map->AppendDescriptor(&d);
3411     }
3412 
3413     Handle<AccessorInfo> script_source_url =
3414         Accessors::ScriptSourceUrlInfo(isolate, attribs);
3415     {
3416       Descriptor d = Descriptor::AccessorConstant(
3417           Handle<Name>(Name::cast(script_source_url->name())),
3418           script_source_url, attribs);
3419       script_map->AppendDescriptor(&d);
3420     }
3421 
3422     Handle<AccessorInfo> script_source_mapping_url =
3423         Accessors::ScriptSourceMappingUrlInfo(isolate, attribs);
3424     {
3425       Descriptor d = Descriptor::AccessorConstant(
3426           Handle<Name>(Name::cast(script_source_mapping_url->name())),
3427           script_source_mapping_url, attribs);
3428       script_map->AppendDescriptor(&d);
3429     }
3430   }
3431 
3432   {  // -- A s y n c F u n c t i o n
3433     // Builtin functions for AsyncFunction.
3434     PrototypeIterator iter(native_context->async_function_map());
3435     Handle<JSObject> async_function_prototype(iter.GetCurrent<JSObject>());
3436 
3437     static const bool kUseStrictFunctionMap = true;
3438     Handle<JSFunction> async_function_constructor = InstallFunction(
3439         container, "AsyncFunction", JS_FUNCTION_TYPE, JSFunction::kSize,
3440         async_function_prototype, Builtins::kAsyncFunctionConstructor,
3441         kUseStrictFunctionMap);
3442     async_function_constructor->shared()->DontAdaptArguments();
3443     async_function_constructor->shared()->SetConstructStub(
3444         *isolate->builtins()->AsyncFunctionConstructor());
3445     async_function_constructor->shared()->set_length(1);
3446     InstallWithIntrinsicDefaultProto(isolate, async_function_constructor,
3447                                      Context::ASYNC_FUNCTION_FUNCTION_INDEX);
3448     JSObject::ForceSetPrototype(async_function_constructor,
3449                                 isolate->function_function());
3450 
3451     JSObject::AddProperty(
3452         async_function_prototype, factory->constructor_string(),
3453         async_function_constructor,
3454         static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
3455 
3456     JSFunction::SetPrototype(async_function_constructor,
3457                              async_function_prototype);
3458 
3459     {
3460       Handle<JSFunction> function =
3461           SimpleCreateFunction(isolate, factory->empty_string(),
3462                                Builtins::kAsyncFunctionAwaitCaught, 3, false);
3463       InstallWithIntrinsicDefaultProto(
3464           isolate, function, Context::ASYNC_FUNCTION_AWAIT_CAUGHT_INDEX);
3465     }
3466 
3467     {
3468       Handle<JSFunction> function =
3469           SimpleCreateFunction(isolate, factory->empty_string(),
3470                                Builtins::kAsyncFunctionAwaitUncaught, 3, false);
3471       InstallWithIntrinsicDefaultProto(
3472           isolate, function, Context::ASYNC_FUNCTION_AWAIT_UNCAUGHT_INDEX);
3473     }
3474 
3475     {
3476       Handle<Code> code =
3477           isolate->builtins()->AsyncFunctionAwaitRejectClosure();
3478       Handle<SharedFunctionInfo> info =
3479           factory->NewSharedFunctionInfo(factory->empty_string(), code, false);
3480       info->set_internal_formal_parameter_count(1);
3481       info->set_length(1);
3482       native_context->set_async_function_await_reject_shared_fun(*info);
3483     }
3484 
3485     {
3486       Handle<Code> code =
3487           isolate->builtins()->AsyncFunctionAwaitResolveClosure();
3488       Handle<SharedFunctionInfo> info =
3489           factory->NewSharedFunctionInfo(factory->empty_string(), code, false);
3490       info->set_internal_formal_parameter_count(1);
3491       info->set_length(1);
3492       native_context->set_async_function_await_resolve_shared_fun(*info);
3493     }
3494 
3495     {
3496       Handle<JSFunction> function =
3497           SimpleCreateFunction(isolate, factory->empty_string(),
3498                                Builtins::kAsyncFunctionPromiseCreate, 0, false);
3499       InstallWithIntrinsicDefaultProto(
3500           isolate, function, Context::ASYNC_FUNCTION_PROMISE_CREATE_INDEX);
3501     }
3502 
3503     {
3504       Handle<JSFunction> function = SimpleCreateFunction(
3505           isolate, factory->empty_string(),
3506           Builtins::kAsyncFunctionPromiseRelease, 1, false);
3507       InstallWithIntrinsicDefaultProto(
3508           isolate, function, Context::ASYNC_FUNCTION_PROMISE_RELEASE_INDEX);
3509     }
3510   }
3511 
3512   {  // -- C a l l S i t e
3513     // Builtin functions for CallSite.
3514 
3515     // CallSites are a special case; the constructor is for our private use
3516     // only, therefore we set it up as a builtin that throws. Internally, we use
3517     // CallSiteUtils::Construct to create CallSite objects.
3518 
3519     Handle<JSFunction> callsite_fun = InstallFunction(
3520         container, "CallSite", JS_OBJECT_TYPE, JSObject::kHeaderSize,
3521         isolate->initial_object_prototype(), Builtins::kUnsupportedThrower);
3522     callsite_fun->shared()->DontAdaptArguments();
3523     isolate->native_context()->set_callsite_function(*callsite_fun);
3524 
3525     {
3526       Handle<JSObject> proto =
3527           factory->NewJSObject(isolate->object_function(), TENURED);
3528       JSObject::AddProperty(proto, factory->constructor_string(), callsite_fun,
3529                             DONT_ENUM);
3530 
3531       struct FunctionInfo {
3532         const char* name;
3533         Builtins::Name id;
3534       };
3535 
3536       FunctionInfo infos[] = {
3537           {"getColumnNumber", Builtins::kCallSitePrototypeGetColumnNumber},
3538           {"getEvalOrigin", Builtins::kCallSitePrototypeGetEvalOrigin},
3539           {"getFileName", Builtins::kCallSitePrototypeGetFileName},
3540           {"getFunction", Builtins::kCallSitePrototypeGetFunction},
3541           {"getFunctionName", Builtins::kCallSitePrototypeGetFunctionName},
3542           {"getLineNumber", Builtins::kCallSitePrototypeGetLineNumber},
3543           {"getMethodName", Builtins::kCallSitePrototypeGetMethodName},
3544           {"getPosition", Builtins::kCallSitePrototypeGetPosition},
3545           {"getScriptNameOrSourceURL",
3546            Builtins::kCallSitePrototypeGetScriptNameOrSourceURL},
3547           {"getThis", Builtins::kCallSitePrototypeGetThis},
3548           {"getTypeName", Builtins::kCallSitePrototypeGetTypeName},
3549           {"isConstructor", Builtins::kCallSitePrototypeIsConstructor},
3550           {"isEval", Builtins::kCallSitePrototypeIsEval},
3551           {"isNative", Builtins::kCallSitePrototypeIsNative},
3552           {"isToplevel", Builtins::kCallSitePrototypeIsToplevel},
3553           {"toString", Builtins::kCallSitePrototypeToString}};
3554 
3555       PropertyAttributes attrs =
3556           static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
3557 
3558       Handle<JSFunction> fun;
3559       for (const FunctionInfo& info : infos) {
3560         SimpleInstallFunction(proto, info.name, info.id, 0, true, attrs);
3561       }
3562 
3563       Accessors::FunctionSetPrototype(callsite_fun, proto).Assert();
3564     }
3565   }
3566   isolate->native_context()->set_exports_container(*container);
3567 }
3568 
3569 
3570 #define EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(id) \
3571   void Genesis::InitializeGlobal_##id() {}
3572 
3573 EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_do_expressions)
EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_regexp_lookbehind)3574 EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_regexp_lookbehind)
3575 EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_regexp_named_captures)
3576 EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_regexp_property)
3577 EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_function_sent)
3578 EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_tailcalls)
3579 EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_restrictive_generators)
3580 EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_trailing_commas)
3581 EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_function_tostring)
3582 EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_class_fields)
3583 EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_object_rest_spread)
3584 EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_dynamic_import)
3585 EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_template_escapes)
3586 
3587 void InstallPublicSymbol(Factory* factory, Handle<Context> native_context,
3588                          const char* name, Handle<Symbol> value) {
3589   Handle<JSGlobalObject> global(
3590       JSGlobalObject::cast(native_context->global_object()));
3591   Handle<String> symbol_string = factory->InternalizeUtf8String("Symbol");
3592   Handle<JSObject> symbol = Handle<JSObject>::cast(
3593       JSObject::GetProperty(global, symbol_string).ToHandleChecked());
3594   Handle<String> name_string = factory->InternalizeUtf8String(name);
3595   PropertyAttributes attributes =
3596       static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
3597   JSObject::AddProperty(symbol, name_string, value, attributes);
3598 }
3599 
InitializeGlobal_enable_fast_array_builtins()3600 void Genesis::InitializeGlobal_enable_fast_array_builtins() {
3601   if (!FLAG_enable_fast_array_builtins) return;
3602 
3603   Handle<JSGlobalObject> global(native_context()->global_object());
3604   Isolate* isolate = global->GetIsolate();
3605   Factory* factory = isolate->factory();
3606 
3607   LookupIterator it1(global, factory->NewStringFromAsciiChecked("Array"),
3608                      LookupIterator::OWN_SKIP_INTERCEPTOR);
3609   Handle<Object> array_object = Object::GetProperty(&it1).ToHandleChecked();
3610   LookupIterator it2(array_object,
3611                      factory->NewStringFromAsciiChecked("prototype"),
3612                      LookupIterator::OWN_SKIP_INTERCEPTOR);
3613   Handle<Object> array_prototype = Object::GetProperty(&it2).ToHandleChecked();
3614   LookupIterator it3(array_prototype,
3615                      factory->NewStringFromAsciiChecked("forEach"),
3616                      LookupIterator::OWN_SKIP_INTERCEPTOR);
3617   Handle<Object> for_each_function =
3618       Object::GetProperty(&it3).ToHandleChecked();
3619   Handle<JSFunction>::cast(for_each_function)
3620       ->set_code(isolate->builtins()->builtin(Builtins::kArrayForEach));
3621   Handle<JSFunction>::cast(for_each_function)
3622       ->shared()
3623       ->set_code(isolate->builtins()->builtin(Builtins::kArrayForEach));
3624 }
3625 
InitializeGlobal_harmony_sharedarraybuffer()3626 void Genesis::InitializeGlobal_harmony_sharedarraybuffer() {
3627   if (!FLAG_harmony_sharedarraybuffer) return;
3628 
3629   Handle<JSGlobalObject> global(native_context()->global_object());
3630   Isolate* isolate = global->GetIsolate();
3631   Factory* factory = isolate->factory();
3632 
3633   Handle<JSFunction> shared_array_buffer_fun =
3634       InstallArrayBuffer(global, "SharedArrayBuffer",
3635                          Builtins::kSharedArrayBufferPrototypeGetByteLength,
3636                          BuiltinFunctionId::kSharedArrayBufferByteLength);
3637   native_context()->set_shared_array_buffer_fun(*shared_array_buffer_fun);
3638 
3639   Handle<String> name = factory->InternalizeUtf8String("Atomics");
3640   Handle<JSFunction> cons = factory->NewFunction(name);
3641   JSFunction::SetInstancePrototype(
3642       cons,
3643       Handle<Object>(native_context()->initial_object_prototype(), isolate));
3644   Handle<JSObject> atomics_object = factory->NewJSObject(cons, TENURED);
3645   DCHECK(atomics_object->IsJSObject());
3646   JSObject::AddProperty(global, name, atomics_object, DONT_ENUM);
3647 
3648   SimpleInstallFunction(atomics_object, factory->InternalizeUtf8String("load"),
3649                         Builtins::kAtomicsLoad, 2, true);
3650   SimpleInstallFunction(atomics_object, factory->InternalizeUtf8String("store"),
3651                         Builtins::kAtomicsStore, 3, true);
3652 }
3653 
InitializeGlobal_harmony_array_prototype_values()3654 void Genesis::InitializeGlobal_harmony_array_prototype_values() {
3655   if (!FLAG_harmony_array_prototype_values) return;
3656   Handle<JSFunction> array_constructor(native_context()->array_function());
3657   Handle<JSObject> array_prototype(
3658       JSObject::cast(array_constructor->instance_prototype()));
3659   Handle<Object> values_iterator =
3660       JSObject::GetProperty(array_prototype, factory()->iterator_symbol())
3661           .ToHandleChecked();
3662   DCHECK(values_iterator->IsJSFunction());
3663   JSObject::AddProperty(array_prototype, factory()->values_string(),
3664                         values_iterator, DONT_ENUM);
3665 
3666   Handle<Object> unscopables =
3667       JSObject::GetProperty(array_prototype, factory()->unscopables_symbol())
3668           .ToHandleChecked();
3669   DCHECK(unscopables->IsJSObject());
3670   JSObject::AddProperty(Handle<JSObject>::cast(unscopables),
3671                         factory()->values_string(), factory()->true_value(),
3672                         NONE);
3673 }
3674 
InitializeGlobal_harmony_async_iteration()3675 void Genesis::InitializeGlobal_harmony_async_iteration() {
3676   if (!FLAG_harmony_async_iteration) return;
3677   Handle<JSFunction> symbol_fun(native_context()->symbol_function());
3678   InstallConstant(isolate(), symbol_fun, "asyncIterator",
3679                   factory()->async_iterator_symbol());
3680 }
3681 
InitializeGlobal_harmony_promise_finally()3682 void Genesis::InitializeGlobal_harmony_promise_finally() {
3683   if (!FLAG_harmony_promise_finally) return;
3684 
3685   Handle<JSFunction> constructor(native_context()->promise_function());
3686   Handle<JSObject> prototype(JSObject::cast(constructor->instance_prototype()));
3687   SimpleInstallFunction(prototype, "finally", Builtins::kPromiseFinally, 1,
3688                         true, DONT_ENUM);
3689 
3690   // The promise prototype map has changed because we added a property
3691   // to prototype, so we update the saved map.
3692   Handle<Map> prototype_map(prototype->map());
3693   Map::SetShouldBeFastPrototypeMap(prototype_map, true, isolate());
3694   native_context()->set_promise_prototype_map(*prototype_map);
3695 
3696   {
3697     Handle<Code> code =
3698         handle(isolate()->builtins()->builtin(Builtins::kPromiseThenFinally),
3699                isolate());
3700     Handle<SharedFunctionInfo> info = factory()->NewSharedFunctionInfo(
3701         factory()->empty_string(), code, false);
3702     info->set_internal_formal_parameter_count(1);
3703     info->set_length(1);
3704     info->set_native(true);
3705     native_context()->set_promise_then_finally_shared_fun(*info);
3706   }
3707 
3708   {
3709     Handle<Code> code =
3710         handle(isolate()->builtins()->builtin(Builtins::kPromiseCatchFinally),
3711                isolate());
3712     Handle<SharedFunctionInfo> info = factory()->NewSharedFunctionInfo(
3713         factory()->empty_string(), code, false);
3714     info->set_internal_formal_parameter_count(1);
3715     info->set_length(1);
3716     info->set_native(true);
3717     native_context()->set_promise_catch_finally_shared_fun(*info);
3718   }
3719 
3720   {
3721     Handle<Code> code = handle(
3722         isolate()->builtins()->builtin(Builtins::kPromiseValueThunkFinally),
3723         isolate());
3724     Handle<SharedFunctionInfo> info = factory()->NewSharedFunctionInfo(
3725         factory()->empty_string(), code, false);
3726     info->set_internal_formal_parameter_count(0);
3727     info->set_length(0);
3728     native_context()->set_promise_value_thunk_finally_shared_fun(*info);
3729   }
3730 
3731   {
3732     Handle<Code> code =
3733         handle(isolate()->builtins()->builtin(Builtins::kPromiseThrowerFinally),
3734                isolate());
3735     Handle<SharedFunctionInfo> info = factory()->NewSharedFunctionInfo(
3736         factory()->empty_string(), code, false);
3737     info->set_internal_formal_parameter_count(0);
3738     info->set_length(0);
3739     native_context()->set_promise_thrower_finally_shared_fun(*info);
3740   }
3741 }
3742 
3743 #ifdef V8_I18N_SUPPORT
InitializeGlobal_datetime_format_to_parts()3744 void Genesis::InitializeGlobal_datetime_format_to_parts() {
3745   if (!FLAG_datetime_format_to_parts) return;
3746   Handle<JSReceiver> exports_container(
3747       JSReceiver::cast(native_context()->exports_container()));
3748   Handle<JSObject> date_time_format_prototype(JSObject::cast(
3749       native_context()->intl_date_time_format_function()->prototype()));
3750   Handle<JSFunction> format_date_to_parts = Handle<JSFunction>::cast(
3751       JSReceiver::GetProperty(
3752           exports_container,
3753           factory()->InternalizeUtf8String("FormatDateToParts"))
3754           .ToHandleChecked());
3755   InstallFunction(date_time_format_prototype, format_date_to_parts,
3756                   factory()->InternalizeUtf8String("formatToParts"));
3757 }
3758 
3759 namespace {
3760 
SetFunction(Handle<JSObject> target,Handle<JSFunction> function,Handle<Name> name,PropertyAttributes attributes=DONT_ENUM)3761 void SetFunction(Handle<JSObject> target, Handle<JSFunction> function,
3762                  Handle<Name> name, PropertyAttributes attributes = DONT_ENUM) {
3763   JSObject::SetOwnPropertyIgnoreAttributes(target, name, function, attributes)
3764       .ToHandleChecked();
3765 }
3766 
3767 }  // namespace
3768 
InitializeGlobal_icu_case_mapping()3769 void Genesis::InitializeGlobal_icu_case_mapping() {
3770   if (!FLAG_icu_case_mapping) return;
3771 
3772   Handle<JSReceiver> exports_container(
3773       JSReceiver::cast(native_context()->exports_container()));
3774 
3775   Handle<JSObject> string_prototype(
3776       JSObject::cast(native_context()->string_function()->prototype()));
3777 
3778   Handle<JSFunction> to_lower_case = Handle<JSFunction>::cast(
3779       JSReceiver::GetProperty(
3780           exports_container,
3781           factory()->InternalizeUtf8String("ToLowerCaseI18N"))
3782           .ToHandleChecked());
3783   SetFunction(string_prototype, to_lower_case,
3784               factory()->InternalizeUtf8String("toLowerCase"));
3785 
3786   Handle<JSFunction> to_upper_case = Handle<JSFunction>::cast(
3787       JSReceiver::GetProperty(
3788           exports_container,
3789           factory()->InternalizeUtf8String("ToUpperCaseI18N"))
3790           .ToHandleChecked());
3791   SetFunction(string_prototype, to_upper_case,
3792               factory()->InternalizeUtf8String("toUpperCase"));
3793 
3794   Handle<JSFunction> to_locale_lower_case = Handle<JSFunction>::cast(
3795       JSReceiver::GetProperty(
3796           exports_container,
3797           factory()->InternalizeUtf8String("ToLocaleLowerCaseI18N"))
3798           .ToHandleChecked());
3799   SetFunction(string_prototype, to_locale_lower_case,
3800               factory()->InternalizeUtf8String("toLocaleLowerCase"));
3801 
3802   Handle<JSFunction> to_locale_upper_case = Handle<JSFunction>::cast(
3803       JSReceiver::GetProperty(
3804           exports_container,
3805           factory()->InternalizeUtf8String("ToLocaleUpperCaseI18N"))
3806           .ToHandleChecked());
3807   SetFunction(string_prototype, to_locale_upper_case,
3808               factory()->InternalizeUtf8String("toLocaleUpperCase"));
3809 }
3810 #endif
3811 
InstallArrayBuffer(Handle<JSObject> target,const char * name,Builtins::Name call,BuiltinFunctionId id)3812 Handle<JSFunction> Genesis::InstallArrayBuffer(Handle<JSObject> target,
3813                                                const char* name,
3814                                                Builtins::Name call,
3815                                                BuiltinFunctionId id) {
3816   // Create the %ArrayBufferPrototype%
3817   // Setup the {prototype} with the given {name} for @@toStringTag.
3818   Handle<JSObject> prototype =
3819       factory()->NewJSObject(isolate()->object_function(), TENURED);
3820   JSObject::AddProperty(prototype, factory()->to_string_tag_symbol(),
3821                         factory()->NewStringFromAsciiChecked(name),
3822                         static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
3823 
3824   // Allocate the constructor with the given {prototype}.
3825   Handle<JSFunction> array_buffer_fun =
3826       InstallFunction(target, name, JS_ARRAY_BUFFER_TYPE,
3827                       JSArrayBuffer::kSizeWithInternalFields, prototype,
3828                       Builtins::kArrayBufferConstructor);
3829   array_buffer_fun->shared()->SetConstructStub(
3830       *isolate()->builtins()->ArrayBufferConstructor_ConstructStub());
3831   array_buffer_fun->shared()->DontAdaptArguments();
3832   array_buffer_fun->shared()->set_length(1);
3833 
3834   // Install the "constructor" property on the {prototype}.
3835   JSObject::AddProperty(prototype, factory()->constructor_string(),
3836                         array_buffer_fun, DONT_ENUM);
3837 
3838   SimpleInstallFunction(array_buffer_fun, factory()->isView_string(),
3839                         Builtins::kArrayBufferIsView, 1, true);
3840 
3841   // Install the "byteLength" getter on the {prototype}.
3842   SimpleInstallGetter(prototype, factory()->byte_length_string(), call, false,
3843                       id);
3844 
3845   return array_buffer_fun;
3846 }
3847 
3848 
InstallInternalArray(Handle<JSObject> target,const char * name,ElementsKind elements_kind)3849 Handle<JSFunction> Genesis::InstallInternalArray(Handle<JSObject> target,
3850                                                  const char* name,
3851                                                  ElementsKind elements_kind) {
3852   // --- I n t e r n a l   A r r a y ---
3853   // An array constructor on the builtins object that works like
3854   // the public Array constructor, except that its prototype
3855   // doesn't inherit from Object.prototype.
3856   // To be used only for internal work by builtins. Instances
3857   // must not be leaked to user code.
3858   Handle<JSObject> prototype =
3859       factory()->NewJSObject(isolate()->object_function(), TENURED);
3860   Handle<JSFunction> array_function =
3861       InstallFunction(target, name, JS_ARRAY_TYPE, JSArray::kSize, prototype,
3862                       Builtins::kInternalArrayCode);
3863 
3864   InternalArrayConstructorStub internal_array_constructor_stub(isolate());
3865   Handle<Code> code = internal_array_constructor_stub.GetCode();
3866   array_function->shared()->SetConstructStub(*code);
3867   array_function->shared()->DontAdaptArguments();
3868 
3869   Handle<Map> original_map(array_function->initial_map());
3870   Handle<Map> initial_map = Map::Copy(original_map, "InternalArray");
3871   initial_map->set_elements_kind(elements_kind);
3872   JSFunction::SetInitialMap(array_function, initial_map, prototype);
3873 
3874   // Make "length" magic on instances.
3875   Map::EnsureDescriptorSlack(initial_map, 1);
3876 
3877   PropertyAttributes attribs = static_cast<PropertyAttributes>(
3878       DONT_ENUM | DONT_DELETE);
3879 
3880   Handle<AccessorInfo> array_length =
3881       Accessors::ArrayLengthInfo(isolate(), attribs);
3882   {  // Add length.
3883     Descriptor d = Descriptor::AccessorConstant(
3884         Handle<Name>(Name::cast(array_length->name())), array_length, attribs);
3885     initial_map->AppendDescriptor(&d);
3886   }
3887 
3888   return array_function;
3889 }
3890 
InstallNatives(GlobalContextType context_type)3891 bool Genesis::InstallNatives(GlobalContextType context_type) {
3892   HandleScope scope(isolate());
3893 
3894   // Set up the utils object as shared container between native scripts.
3895   Handle<JSObject> utils = factory()->NewJSObject(isolate()->object_function());
3896   JSObject::NormalizeProperties(utils, CLEAR_INOBJECT_PROPERTIES, 16,
3897                                 "utils container for native scripts");
3898   native_context()->set_natives_utils_object(*utils);
3899 
3900   // Set up the extras utils object as a shared container between native
3901   // scripts and extras. (Extras consume things added there by native scripts.)
3902   Handle<JSObject> extras_utils =
3903       factory()->NewJSObject(isolate()->object_function());
3904   native_context()->set_extras_utils_object(*extras_utils);
3905 
3906   InstallInternalArray(extras_utils, "InternalPackedArray", FAST_ELEMENTS);
3907 
3908   InstallFunction(extras_utils, isolate()->promise_internal_constructor(),
3909                   factory()->NewStringFromAsciiChecked("createPromise"));
3910   InstallFunction(extras_utils, isolate()->promise_resolve(),
3911                   factory()->NewStringFromAsciiChecked("resolvePromise"));
3912 
3913   int builtin_index = Natives::GetDebuggerCount();
3914   // Only run prologue.js and runtime.js at this point.
3915   DCHECK_EQ(builtin_index, Natives::GetIndex("prologue"));
3916   if (!Bootstrapper::CompileBuiltin(isolate(), builtin_index++)) return false;
3917   DCHECK_EQ(builtin_index, Natives::GetIndex("runtime"));
3918   if (!Bootstrapper::CompileBuiltin(isolate(), builtin_index++)) return false;
3919 
3920   {
3921     // Builtin function for OpaqueReference -- a JSValue-based object,
3922     // that keeps its field isolated from JavaScript code. It may store
3923     // objects, that JavaScript code may not access.
3924     Handle<JSFunction> opaque_reference_fun = factory()->NewFunction(
3925         factory()->empty_string(), isolate()->builtins()->Illegal(),
3926         isolate()->initial_object_prototype(), JS_VALUE_TYPE, JSValue::kSize);
3927     Handle<JSObject> prototype =
3928         factory()->NewJSObject(isolate()->object_function(), TENURED);
3929     Accessors::FunctionSetPrototype(opaque_reference_fun, prototype).Assert();
3930     native_context()->set_opaque_reference_function(*opaque_reference_fun);
3931   }
3932 
3933   // InternalArrays should not use Smi-Only array optimizations. There are too
3934   // many places in the C++ runtime code (e.g. RegEx) that assume that
3935   // elements in InternalArrays can be set to non-Smi values without going
3936   // through a common bottleneck that would make the SMI_ONLY -> FAST_ELEMENT
3937   // transition easy to trap. Moreover, they rarely are smi-only.
3938   {
3939     HandleScope scope(isolate());
3940     Handle<JSObject> utils =
3941         Handle<JSObject>::cast(isolate()->natives_utils_object());
3942     Handle<JSFunction> array_function =
3943         InstallInternalArray(utils, "InternalArray", FAST_HOLEY_ELEMENTS);
3944     native_context()->set_internal_array_function(*array_function);
3945     InstallInternalArray(utils, "InternalPackedArray", FAST_ELEMENTS);
3946   }
3947 
3948   // Run the rest of the native scripts.
3949   while (builtin_index < Natives::GetBuiltinsCount()) {
3950     if (!Bootstrapper::CompileBuiltin(isolate(), builtin_index++)) return false;
3951   }
3952 
3953   if (!CallUtilsFunction(isolate(), "PostNatives")) return false;
3954   auto fast_template_instantiations_cache = isolate()->factory()->NewFixedArray(
3955       TemplateInfo::kFastTemplateInstantiationsCacheSize);
3956   native_context()->set_fast_template_instantiations_cache(
3957       *fast_template_instantiations_cache);
3958 
3959   auto slow_template_instantiations_cache = UnseededNumberDictionary::New(
3960       isolate(), ApiNatives::kInitialFunctionCacheSize);
3961   native_context()->set_slow_template_instantiations_cache(
3962       *slow_template_instantiations_cache);
3963 
3964   // Store the map for the %ObjectPrototype% after the natives has been compiled
3965   // and the Object function has been set up.
3966   Handle<JSFunction> object_function(native_context()->object_function());
3967   DCHECK(JSObject::cast(object_function->initial_map()->prototype())
3968              ->HasFastProperties());
3969   native_context()->set_object_function_prototype_map(
3970       HeapObject::cast(object_function->initial_map()->prototype())->map());
3971 
3972   // Set up the map for Object.create(null) instances.
3973   Handle<Map> slow_object_with_null_prototype_map =
3974       Map::CopyInitialMap(handle(object_function->initial_map(), isolate()));
3975   slow_object_with_null_prototype_map->set_dictionary_map(true);
3976   Map::SetPrototype(slow_object_with_null_prototype_map,
3977                     isolate()->factory()->null_value());
3978   native_context()->set_slow_object_with_null_prototype_map(
3979       *slow_object_with_null_prototype_map);
3980 
3981   // Store the map for the %StringPrototype% after the natives has been compiled
3982   // and the String function has been set up.
3983   Handle<JSFunction> string_function(native_context()->string_function());
3984   JSObject* string_function_prototype =
3985       JSObject::cast(string_function->initial_map()->prototype());
3986   DCHECK(string_function_prototype->HasFastProperties());
3987   native_context()->set_string_function_prototype_map(
3988       string_function_prototype->map());
3989 
3990   Handle<JSGlobalObject> global_object =
3991       handle(native_context()->global_object());
3992 
3993   // Install Global.decodeURI.
3994   SimpleInstallFunction(global_object, "decodeURI", Builtins::kGlobalDecodeURI,
3995                         1, false, kGlobalDecodeURI);
3996 
3997   // Install Global.decodeURIComponent.
3998   SimpleInstallFunction(global_object, "decodeURIComponent",
3999                         Builtins::kGlobalDecodeURIComponent, 1, false,
4000                         kGlobalDecodeURIComponent);
4001 
4002   // Install Global.encodeURI.
4003   SimpleInstallFunction(global_object, "encodeURI", Builtins::kGlobalEncodeURI,
4004                         1, false, kGlobalEncodeURI);
4005 
4006   // Install Global.encodeURIComponent.
4007   SimpleInstallFunction(global_object, "encodeURIComponent",
4008                         Builtins::kGlobalEncodeURIComponent, 1, false,
4009                         kGlobalEncodeURIComponent);
4010 
4011   // Install Global.escape.
4012   SimpleInstallFunction(global_object, "escape", Builtins::kGlobalEscape, 1,
4013                         false, kGlobalEscape);
4014 
4015   // Install Global.unescape.
4016   SimpleInstallFunction(global_object, "unescape", Builtins::kGlobalUnescape, 1,
4017                         false, kGlobalUnescape);
4018 
4019   // Install Global.eval.
4020   {
4021     Handle<JSFunction> eval =
4022         SimpleInstallFunction(global_object, factory()->eval_string(),
4023                               Builtins::kGlobalEval, 1, false);
4024     native_context()->set_global_eval_fun(*eval);
4025   }
4026 
4027   // Install Global.isFinite
4028   SimpleInstallFunction(global_object, "isFinite", Builtins::kGlobalIsFinite, 1,
4029                         true, kGlobalIsFinite);
4030 
4031   // Install Global.isNaN
4032   SimpleInstallFunction(global_object, "isNaN", Builtins::kGlobalIsNaN, 1, true,
4033                         kGlobalIsNaN);
4034 
4035   // Install Array.prototype.concat
4036   {
4037     Handle<JSFunction> array_constructor(native_context()->array_function());
4038     Handle<JSObject> proto(JSObject::cast(array_constructor->prototype()));
4039     Handle<JSFunction> concat =
4040         InstallFunction(proto, "concat", JS_OBJECT_TYPE, JSObject::kHeaderSize,
4041                         MaybeHandle<JSObject>(), Builtins::kArrayConcat);
4042 
4043     // Make sure that Array.prototype.concat appears to be compiled.
4044     // The code will never be called, but inline caching for call will
4045     // only work if it appears to be compiled.
4046     concat->shared()->DontAdaptArguments();
4047     DCHECK(concat->is_compiled());
4048     // Set the lengths for the functions to satisfy ECMA-262.
4049     concat->shared()->set_length(1);
4050   }
4051 
4052   // Install InternalArray.prototype.concat
4053   {
4054     Handle<JSFunction> array_constructor(
4055         native_context()->internal_array_function());
4056     Handle<JSObject> proto(JSObject::cast(array_constructor->prototype()));
4057     Handle<JSFunction> concat =
4058         InstallFunction(proto, "concat", JS_OBJECT_TYPE, JSObject::kHeaderSize,
4059                         MaybeHandle<JSObject>(), Builtins::kArrayConcat);
4060 
4061     // Make sure that InternalArray.prototype.concat appears to be compiled.
4062     // The code will never be called, but inline caching for call will
4063     // only work if it appears to be compiled.
4064     concat->shared()->DontAdaptArguments();
4065     DCHECK(concat->is_compiled());
4066     // Set the lengths for the functions to satisfy ECMA-262.
4067     concat->shared()->set_length(1);
4068   }
4069 
4070   InstallBuiltinFunctionIds();
4071 
4072   // Create a map for accessor property descriptors (a variant of JSObject
4073   // that predefines four properties get, set, configurable and enumerable).
4074   {
4075     // AccessorPropertyDescriptor initial map.
4076     Handle<Map> map =
4077         factory()->NewMap(JS_OBJECT_TYPE, JSAccessorPropertyDescriptor::kSize);
4078     // Create the descriptor array for the property descriptor object.
4079     Map::EnsureDescriptorSlack(map, 4);
4080 
4081     {  // get
4082       Descriptor d = Descriptor::DataField(
4083           factory()->get_string(), JSAccessorPropertyDescriptor::kGetIndex,
4084           NONE, Representation::Tagged());
4085       map->AppendDescriptor(&d);
4086     }
4087     {  // set
4088       Descriptor d = Descriptor::DataField(
4089           factory()->set_string(), JSAccessorPropertyDescriptor::kSetIndex,
4090           NONE, Representation::Tagged());
4091       map->AppendDescriptor(&d);
4092     }
4093     {  // enumerable
4094       Descriptor d =
4095           Descriptor::DataField(factory()->enumerable_string(),
4096                                 JSAccessorPropertyDescriptor::kEnumerableIndex,
4097                                 NONE, Representation::Tagged());
4098       map->AppendDescriptor(&d);
4099     }
4100     {  // configurable
4101       Descriptor d = Descriptor::DataField(
4102           factory()->configurable_string(),
4103           JSAccessorPropertyDescriptor::kConfigurableIndex, NONE,
4104           Representation::Tagged());
4105       map->AppendDescriptor(&d);
4106     }
4107 
4108     Map::SetPrototype(map, isolate()->initial_object_prototype());
4109     map->SetConstructor(native_context()->object_function());
4110     map->SetInObjectProperties(4);
4111     map->set_unused_property_fields(0);
4112 
4113     native_context()->set_accessor_property_descriptor_map(*map);
4114   }
4115 
4116   // Create a map for data property descriptors (a variant of JSObject
4117   // that predefines four properties value, writable, configurable and
4118   // enumerable).
4119   {
4120     // DataPropertyDescriptor initial map.
4121     Handle<Map> map =
4122         factory()->NewMap(JS_OBJECT_TYPE, JSDataPropertyDescriptor::kSize);
4123     // Create the descriptor array for the property descriptor object.
4124     Map::EnsureDescriptorSlack(map, 4);
4125 
4126     {  // value
4127       Descriptor d = Descriptor::DataField(
4128           factory()->value_string(), JSDataPropertyDescriptor::kValueIndex,
4129           NONE, Representation::Tagged());
4130       map->AppendDescriptor(&d);
4131     }
4132     {  // writable
4133       Descriptor d =
4134           Descriptor::DataField(factory()->writable_string(),
4135                                 JSDataPropertyDescriptor::kWritableIndex, NONE,
4136                                 Representation::Tagged());
4137       map->AppendDescriptor(&d);
4138     }
4139     {  // enumerable
4140       Descriptor d =
4141           Descriptor::DataField(factory()->enumerable_string(),
4142                                 JSDataPropertyDescriptor::kEnumerableIndex,
4143                                 NONE, Representation::Tagged());
4144       map->AppendDescriptor(&d);
4145     }
4146     {  // configurable
4147       Descriptor d =
4148           Descriptor::DataField(factory()->configurable_string(),
4149                                 JSDataPropertyDescriptor::kConfigurableIndex,
4150                                 NONE, Representation::Tagged());
4151       map->AppendDescriptor(&d);
4152     }
4153 
4154     Map::SetPrototype(map, isolate()->initial_object_prototype());
4155     map->SetConstructor(native_context()->object_function());
4156     map->SetInObjectProperties(4);
4157     map->set_unused_property_fields(0);
4158 
4159     native_context()->set_data_property_descriptor_map(*map);
4160   }
4161 
4162   // Create a constructor for RegExp results (a variant of Array that
4163   // predefines the two properties index and match).
4164   {
4165     // RegExpResult initial map.
4166 
4167     // Find global.Array.prototype to inherit from.
4168     Handle<JSFunction> array_constructor(native_context()->array_function());
4169     Handle<JSObject> array_prototype(
4170         JSObject::cast(array_constructor->instance_prototype()));
4171 
4172     // Add initial map.
4173     Handle<Map> initial_map =
4174         factory()->NewMap(JS_ARRAY_TYPE, JSRegExpResult::kSize);
4175     initial_map->SetConstructor(*array_constructor);
4176 
4177     // Set prototype on map.
4178     initial_map->set_non_instance_prototype(false);
4179     Map::SetPrototype(initial_map, array_prototype);
4180 
4181     // Update map with length accessor from Array and add "index" and "input".
4182     Map::EnsureDescriptorSlack(initial_map, 3);
4183 
4184     {
4185       JSFunction* array_function = native_context()->array_function();
4186       Handle<DescriptorArray> array_descriptors(
4187           array_function->initial_map()->instance_descriptors());
4188       Handle<String> length = factory()->length_string();
4189       int old = array_descriptors->SearchWithCache(
4190           isolate(), *length, array_function->initial_map());
4191       DCHECK(old != DescriptorArray::kNotFound);
4192       Descriptor d = Descriptor::AccessorConstant(
4193           length, handle(array_descriptors->GetValue(old), isolate()),
4194           array_descriptors->GetDetails(old).attributes());
4195       initial_map->AppendDescriptor(&d);
4196     }
4197     {
4198       Descriptor d = Descriptor::DataField(factory()->index_string(),
4199                                            JSRegExpResult::kIndexIndex, NONE,
4200                                            Representation::Tagged());
4201       initial_map->AppendDescriptor(&d);
4202     }
4203 
4204     {
4205       Descriptor d = Descriptor::DataField(factory()->input_string(),
4206                                            JSRegExpResult::kInputIndex, NONE,
4207                                            Representation::Tagged());
4208       initial_map->AppendDescriptor(&d);
4209     }
4210 
4211     initial_map->SetInObjectProperties(2);
4212     initial_map->set_unused_property_fields(0);
4213 
4214     native_context()->set_regexp_result_map(*initial_map);
4215   }
4216 
4217   // Add @@iterator method to the arguments object maps.
4218   {
4219     PropertyAttributes attribs = DONT_ENUM;
4220     Handle<AccessorInfo> arguments_iterator =
4221         Accessors::ArgumentsIteratorInfo(isolate(), attribs);
4222     {
4223       Descriptor d = Descriptor::AccessorConstant(factory()->iterator_symbol(),
4224                                                   arguments_iterator, attribs);
4225       Handle<Map> map(native_context()->sloppy_arguments_map());
4226       Map::EnsureDescriptorSlack(map, 1);
4227       map->AppendDescriptor(&d);
4228     }
4229     {
4230       Descriptor d = Descriptor::AccessorConstant(factory()->iterator_symbol(),
4231                                                   arguments_iterator, attribs);
4232       Handle<Map> map(native_context()->fast_aliased_arguments_map());
4233       Map::EnsureDescriptorSlack(map, 1);
4234       map->AppendDescriptor(&d);
4235     }
4236     {
4237       Descriptor d = Descriptor::AccessorConstant(factory()->iterator_symbol(),
4238                                                   arguments_iterator, attribs);
4239       Handle<Map> map(native_context()->slow_aliased_arguments_map());
4240       Map::EnsureDescriptorSlack(map, 1);
4241       map->AppendDescriptor(&d);
4242     }
4243     {
4244       Descriptor d = Descriptor::AccessorConstant(factory()->iterator_symbol(),
4245                                                   arguments_iterator, attribs);
4246       Handle<Map> map(native_context()->strict_arguments_map());
4247       Map::EnsureDescriptorSlack(map, 1);
4248       map->AppendDescriptor(&d);
4249     }
4250   }
4251 
4252   return true;
4253 }
4254 
4255 
InstallExperimentalNatives()4256 bool Genesis::InstallExperimentalNatives() {
4257   static const char* harmony_tailcalls_natives[] = {nullptr};
4258   static const char* harmony_sharedarraybuffer_natives[] = {
4259       "native harmony-atomics.js", NULL};
4260   static const char* harmony_do_expressions_natives[] = {nullptr};
4261   static const char* harmony_regexp_lookbehind_natives[] = {nullptr};
4262   static const char* harmony_regexp_named_captures_natives[] = {nullptr};
4263   static const char* harmony_regexp_property_natives[] = {nullptr};
4264   static const char* harmony_function_sent_natives[] = {nullptr};
4265   static const char* harmony_array_prototype_values_natives[] = {nullptr};
4266 #ifdef V8_I18N_SUPPORT
4267   static const char* icu_case_mapping_natives[] = {nullptr};
4268   static const char* datetime_format_to_parts_natives[] = {nullptr};
4269 #endif
4270   static const char* harmony_restrictive_generators_natives[] = {nullptr};
4271   static const char* harmony_trailing_commas_natives[] = {nullptr};
4272   static const char* harmony_function_tostring_natives[] = {nullptr};
4273   static const char* harmony_class_fields_natives[] = {nullptr};
4274   static const char* harmony_object_rest_spread_natives[] = {nullptr};
4275   static const char* harmony_async_iteration_natives[] = {nullptr};
4276   static const char* harmony_dynamic_import_natives[] = {nullptr};
4277   static const char* harmony_promise_finally_natives[] = {nullptr};
4278   static const char* harmony_template_escapes_natives[] = {nullptr};
4279 
4280   for (int i = ExperimentalNatives::GetDebuggerCount();
4281        i < ExperimentalNatives::GetBuiltinsCount(); i++) {
4282 #define INSTALL_EXPERIMENTAL_NATIVES(id, desc)                                \
4283   if (FLAG_##id) {                                                            \
4284     for (size_t j = 0; id##_natives[j] != NULL; j++) {                        \
4285       Vector<const char> script_name = ExperimentalNatives::GetScriptName(i); \
4286       if (strncmp(script_name.start(), id##_natives[j],                       \
4287                   script_name.length()) == 0) {                               \
4288         if (!Bootstrapper::CompileExperimentalBuiltin(isolate(), i)) {        \
4289           return false;                                                       \
4290         }                                                                     \
4291       }                                                                       \
4292     }                                                                         \
4293   }
4294     HARMONY_INPROGRESS(INSTALL_EXPERIMENTAL_NATIVES);
4295     HARMONY_STAGED(INSTALL_EXPERIMENTAL_NATIVES);
4296     HARMONY_SHIPPING(INSTALL_EXPERIMENTAL_NATIVES);
4297 #undef INSTALL_EXPERIMENTAL_NATIVES
4298   }
4299 
4300   if (!CallUtilsFunction(isolate(), "PostExperimentals")) return false;
4301 
4302   InstallExperimentalBuiltinFunctionIds();
4303   return true;
4304 }
4305 
4306 
InstallExtraNatives()4307 bool Genesis::InstallExtraNatives() {
4308   HandleScope scope(isolate());
4309 
4310   Handle<JSObject> extras_binding =
4311       factory()->NewJSObject(isolate()->object_function());
4312   native_context()->set_extras_binding_object(*extras_binding);
4313 
4314   for (int i = ExtraNatives::GetDebuggerCount();
4315        i < ExtraNatives::GetBuiltinsCount(); i++) {
4316     if (!Bootstrapper::CompileExtraBuiltin(isolate(), i)) return false;
4317   }
4318 
4319   return true;
4320 }
4321 
4322 
InstallExperimentalExtraNatives()4323 bool Genesis::InstallExperimentalExtraNatives() {
4324   for (int i = ExperimentalExtraNatives::GetDebuggerCount();
4325        i < ExperimentalExtraNatives::GetBuiltinsCount(); i++) {
4326     if (!Bootstrapper::CompileExperimentalExtraBuiltin(isolate(), i))
4327       return false;
4328   }
4329 
4330   return true;
4331 }
4332 
4333 
InstallDebuggerNatives()4334 bool Genesis::InstallDebuggerNatives() {
4335   for (int i = 0; i < Natives::GetDebuggerCount(); ++i) {
4336     if (!Bootstrapper::CompileBuiltin(isolate(), i)) return false;
4337   }
4338   return CallUtilsFunction(isolate(), "PostDebug");
4339 }
4340 
4341 
InstallBuiltinFunctionId(Handle<JSObject> holder,const char * function_name,BuiltinFunctionId id)4342 static void InstallBuiltinFunctionId(Handle<JSObject> holder,
4343                                      const char* function_name,
4344                                      BuiltinFunctionId id) {
4345   Isolate* isolate = holder->GetIsolate();
4346   Handle<Object> function_object =
4347       JSReceiver::GetProperty(isolate, holder, function_name).ToHandleChecked();
4348   Handle<JSFunction> function = Handle<JSFunction>::cast(function_object);
4349   function->shared()->set_builtin_function_id(id);
4350 }
4351 
4352 
4353 #define INSTALL_BUILTIN_ID(holder_expr, fun_name, name) \
4354   { #holder_expr, #fun_name, k##name }                  \
4355   ,
4356 
4357 
InstallBuiltinFunctionIds()4358 void Genesis::InstallBuiltinFunctionIds() {
4359   HandleScope scope(isolate());
4360   struct BuiltinFunctionIds {
4361     const char* holder_expr;
4362     const char* fun_name;
4363     BuiltinFunctionId id;
4364   };
4365 
4366   const BuiltinFunctionIds builtins[] = {
4367       FUNCTIONS_WITH_ID_LIST(INSTALL_BUILTIN_ID)};
4368 
4369   for (const BuiltinFunctionIds& builtin : builtins) {
4370     Handle<JSObject> holder =
4371         ResolveBuiltinIdHolder(native_context(), builtin.holder_expr);
4372     InstallBuiltinFunctionId(holder, builtin.fun_name, builtin.id);
4373   }
4374 }
4375 
4376 
InstallExperimentalBuiltinFunctionIds()4377 void Genesis::InstallExperimentalBuiltinFunctionIds() {
4378   if (FLAG_harmony_sharedarraybuffer) {
4379     struct BuiltinFunctionIds {
4380       const char* holder_expr;
4381       const char* fun_name;
4382       BuiltinFunctionId id;
4383     };
4384 
4385     const BuiltinFunctionIds atomic_builtins[] = {
4386         ATOMIC_FUNCTIONS_WITH_ID_LIST(INSTALL_BUILTIN_ID)};
4387 
4388     for (const BuiltinFunctionIds& builtin : atomic_builtins) {
4389       Handle<JSObject> holder =
4390           ResolveBuiltinIdHolder(native_context(), builtin.holder_expr);
4391       InstallBuiltinFunctionId(holder, builtin.fun_name, builtin.id);
4392     }
4393   }
4394 }
4395 
4396 #undef INSTALL_BUILTIN_ID
4397 
4398 
InitializeNormalizedMapCaches()4399 void Genesis::InitializeNormalizedMapCaches() {
4400   Handle<NormalizedMapCache> cache = NormalizedMapCache::New(isolate());
4401   native_context()->set_normalized_map_cache(*cache);
4402 }
4403 
4404 
InstallExtensions(Handle<Context> native_context,v8::ExtensionConfiguration * extensions)4405 bool Bootstrapper::InstallExtensions(Handle<Context> native_context,
4406                                      v8::ExtensionConfiguration* extensions) {
4407   BootstrapperActive active(this);
4408   SaveContext saved_context(isolate_);
4409   isolate_->set_context(*native_context);
4410   return Genesis::InstallExtensions(native_context, extensions) &&
4411       Genesis::InstallSpecialObjects(native_context);
4412 }
4413 
4414 
InstallSpecialObjects(Handle<Context> native_context)4415 bool Genesis::InstallSpecialObjects(Handle<Context> native_context) {
4416   Isolate* isolate = native_context->GetIsolate();
4417   // Don't install extensions into the snapshot.
4418   if (isolate->serializer_enabled()) return true;
4419 
4420   Factory* factory = isolate->factory();
4421   HandleScope scope(isolate);
4422 
4423   Handle<JSObject> Error = isolate->error_function();
4424   Handle<String> name =
4425       factory->InternalizeOneByteString(STATIC_CHAR_VECTOR("stackTraceLimit"));
4426   Handle<Smi> stack_trace_limit(Smi::FromInt(FLAG_stack_trace_limit), isolate);
4427   JSObject::AddProperty(Error, name, stack_trace_limit, NONE);
4428 
4429   if (FLAG_expose_wasm || FLAG_validate_asm) {
4430     WasmJs::Install(isolate);
4431   }
4432 
4433   InstallFFIMap(isolate);
4434 
4435   return true;
4436 }
4437 
4438 
Hash(RegisteredExtension * extension)4439 static uint32_t Hash(RegisteredExtension* extension) {
4440   return v8::internal::ComputePointerHash(extension);
4441 }
4442 
ExtensionStates()4443 Genesis::ExtensionStates::ExtensionStates() : map_(8) {}
4444 
get_state(RegisteredExtension * extension)4445 Genesis::ExtensionTraversalState Genesis::ExtensionStates::get_state(
4446     RegisteredExtension* extension) {
4447   base::HashMap::Entry* entry = map_.Lookup(extension, Hash(extension));
4448   if (entry == NULL) {
4449     return UNVISITED;
4450   }
4451   return static_cast<ExtensionTraversalState>(
4452       reinterpret_cast<intptr_t>(entry->value));
4453 }
4454 
set_state(RegisteredExtension * extension,ExtensionTraversalState state)4455 void Genesis::ExtensionStates::set_state(RegisteredExtension* extension,
4456                                          ExtensionTraversalState state) {
4457   map_.LookupOrInsert(extension, Hash(extension))->value =
4458       reinterpret_cast<void*>(static_cast<intptr_t>(state));
4459 }
4460 
4461 
InstallExtensions(Handle<Context> native_context,v8::ExtensionConfiguration * extensions)4462 bool Genesis::InstallExtensions(Handle<Context> native_context,
4463                                 v8::ExtensionConfiguration* extensions) {
4464   Isolate* isolate = native_context->GetIsolate();
4465   ExtensionStates extension_states;  // All extensions have state UNVISITED.
4466   return InstallAutoExtensions(isolate, &extension_states) &&
4467          (!FLAG_expose_free_buffer ||
4468           InstallExtension(isolate, "v8/free-buffer", &extension_states)) &&
4469          (!FLAG_expose_gc ||
4470           InstallExtension(isolate, "v8/gc", &extension_states)) &&
4471          (!FLAG_expose_externalize_string ||
4472           InstallExtension(isolate, "v8/externalize", &extension_states)) &&
4473          (!FLAG_gc_stats ||
4474           InstallExtension(isolate, "v8/statistics", &extension_states)) &&
4475          (!FLAG_expose_trigger_failure ||
4476           InstallExtension(isolate, "v8/trigger-failure", &extension_states)) &&
4477          (!FLAG_trace_ignition_dispatches ||
4478           InstallExtension(isolate, "v8/ignition-statistics",
4479                            &extension_states)) &&
4480          InstallRequestedExtensions(isolate, extensions, &extension_states);
4481 }
4482 
4483 
InstallAutoExtensions(Isolate * isolate,ExtensionStates * extension_states)4484 bool Genesis::InstallAutoExtensions(Isolate* isolate,
4485                                     ExtensionStates* extension_states) {
4486   for (v8::RegisteredExtension* it = v8::RegisteredExtension::first_extension();
4487        it != NULL;
4488        it = it->next()) {
4489     if (it->extension()->auto_enable() &&
4490         !InstallExtension(isolate, it, extension_states)) {
4491       return false;
4492     }
4493   }
4494   return true;
4495 }
4496 
4497 
InstallRequestedExtensions(Isolate * isolate,v8::ExtensionConfiguration * extensions,ExtensionStates * extension_states)4498 bool Genesis::InstallRequestedExtensions(Isolate* isolate,
4499                                          v8::ExtensionConfiguration* extensions,
4500                                          ExtensionStates* extension_states) {
4501   for (const char** it = extensions->begin(); it != extensions->end(); ++it) {
4502     if (!InstallExtension(isolate, *it, extension_states)) return false;
4503   }
4504   return true;
4505 }
4506 
4507 
4508 // Installs a named extension.  This methods is unoptimized and does
4509 // not scale well if we want to support a large number of extensions.
InstallExtension(Isolate * isolate,const char * name,ExtensionStates * extension_states)4510 bool Genesis::InstallExtension(Isolate* isolate,
4511                                const char* name,
4512                                ExtensionStates* extension_states) {
4513   for (v8::RegisteredExtension* it = v8::RegisteredExtension::first_extension();
4514        it != NULL;
4515        it = it->next()) {
4516     if (strcmp(name, it->extension()->name()) == 0) {
4517       return InstallExtension(isolate, it, extension_states);
4518     }
4519   }
4520   return Utils::ApiCheck(false,
4521                          "v8::Context::New()",
4522                          "Cannot find required extension");
4523 }
4524 
4525 
InstallExtension(Isolate * isolate,v8::RegisteredExtension * current,ExtensionStates * extension_states)4526 bool Genesis::InstallExtension(Isolate* isolate,
4527                                v8::RegisteredExtension* current,
4528                                ExtensionStates* extension_states) {
4529   HandleScope scope(isolate);
4530 
4531   if (extension_states->get_state(current) == INSTALLED) return true;
4532   // The current node has already been visited so there must be a
4533   // cycle in the dependency graph; fail.
4534   if (!Utils::ApiCheck(extension_states->get_state(current) != VISITED,
4535                        "v8::Context::New()",
4536                        "Circular extension dependency")) {
4537     return false;
4538   }
4539   DCHECK(extension_states->get_state(current) == UNVISITED);
4540   extension_states->set_state(current, VISITED);
4541   v8::Extension* extension = current->extension();
4542   // Install the extension's dependencies
4543   for (int i = 0; i < extension->dependency_count(); i++) {
4544     if (!InstallExtension(isolate,
4545                           extension->dependencies()[i],
4546                           extension_states)) {
4547       return false;
4548     }
4549   }
4550   // We do not expect this to throw an exception. Change this if it does.
4551   bool result = CompileExtension(isolate, extension);
4552   DCHECK(isolate->has_pending_exception() != result);
4553   if (!result) {
4554     // We print out the name of the extension that fail to install.
4555     // When an error is thrown during bootstrapping we automatically print
4556     // the line number at which this happened to the console in the isolate
4557     // error throwing functionality.
4558     base::OS::PrintError("Error installing extension '%s'.\n",
4559                          current->extension()->name());
4560     isolate->clear_pending_exception();
4561   }
4562   extension_states->set_state(current, INSTALLED);
4563   return result;
4564 }
4565 
4566 
ConfigureGlobalObjects(v8::Local<v8::ObjectTemplate> global_proxy_template)4567 bool Genesis::ConfigureGlobalObjects(
4568     v8::Local<v8::ObjectTemplate> global_proxy_template) {
4569   Handle<JSObject> global_proxy(
4570       JSObject::cast(native_context()->global_proxy()));
4571   Handle<JSObject> global_object(
4572       JSObject::cast(native_context()->global_object()));
4573 
4574   if (!global_proxy_template.IsEmpty()) {
4575     // Configure the global proxy object.
4576     Handle<ObjectTemplateInfo> global_proxy_data =
4577         v8::Utils::OpenHandle(*global_proxy_template);
4578     if (!ConfigureApiObject(global_proxy, global_proxy_data)) return false;
4579 
4580     // Configure the global object.
4581     Handle<FunctionTemplateInfo> proxy_constructor(
4582         FunctionTemplateInfo::cast(global_proxy_data->constructor()));
4583     if (!proxy_constructor->prototype_template()->IsUndefined(isolate())) {
4584       Handle<ObjectTemplateInfo> global_object_data(
4585           ObjectTemplateInfo::cast(proxy_constructor->prototype_template()));
4586       if (!ConfigureApiObject(global_object, global_object_data)) return false;
4587     }
4588   }
4589 
4590   JSObject::ForceSetPrototype(global_proxy, global_object);
4591 
4592   native_context()->set_initial_array_prototype(
4593       JSArray::cast(native_context()->array_function()->prototype()));
4594   native_context()->set_array_buffer_map(
4595       native_context()->array_buffer_fun()->initial_map());
4596   native_context()->set_js_map_map(
4597       native_context()->js_map_fun()->initial_map());
4598   native_context()->set_js_set_map(
4599       native_context()->js_set_fun()->initial_map());
4600 
4601   return true;
4602 }
4603 
4604 
ConfigureApiObject(Handle<JSObject> object,Handle<ObjectTemplateInfo> object_template)4605 bool Genesis::ConfigureApiObject(Handle<JSObject> object,
4606                                  Handle<ObjectTemplateInfo> object_template) {
4607   DCHECK(!object_template.is_null());
4608   DCHECK(FunctionTemplateInfo::cast(object_template->constructor())
4609              ->IsTemplateFor(object->map()));;
4610 
4611   MaybeHandle<JSObject> maybe_obj =
4612       ApiNatives::InstantiateObject(object_template);
4613   Handle<JSObject> obj;
4614   if (!maybe_obj.ToHandle(&obj)) {
4615     DCHECK(isolate()->has_pending_exception());
4616     isolate()->clear_pending_exception();
4617     return false;
4618   }
4619   TransferObject(obj, object);
4620   return true;
4621 }
4622 
4623 
TransferNamedProperties(Handle<JSObject> from,Handle<JSObject> to)4624 void Genesis::TransferNamedProperties(Handle<JSObject> from,
4625                                       Handle<JSObject> to) {
4626   // If JSObject::AddProperty asserts due to already existing property,
4627   // it is likely due to both global objects sharing property name(s).
4628   // Merging those two global objects is impossible.
4629   // The global template must not create properties that already exist
4630   // in the snapshotted global object.
4631   if (from->HasFastProperties()) {
4632     Handle<DescriptorArray> descs =
4633         Handle<DescriptorArray>(from->map()->instance_descriptors());
4634     for (int i = 0; i < from->map()->NumberOfOwnDescriptors(); i++) {
4635       PropertyDetails details = descs->GetDetails(i);
4636       if (details.location() == kField) {
4637         if (details.kind() == kData) {
4638           HandleScope inner(isolate());
4639           Handle<Name> key = Handle<Name>(descs->GetKey(i));
4640           FieldIndex index = FieldIndex::ForDescriptor(from->map(), i);
4641           DCHECK(!descs->GetDetails(i).representation().IsDouble());
4642           Handle<Object> value(from->RawFastPropertyAt(index), isolate());
4643           JSObject::AddProperty(to, key, value, details.attributes());
4644         } else {
4645           DCHECK_EQ(kAccessor, details.kind());
4646           UNREACHABLE();
4647         }
4648 
4649       } else {
4650         DCHECK_EQ(kDescriptor, details.location());
4651         if (details.kind() == kData) {
4652           DCHECK(!FLAG_track_constant_fields);
4653           HandleScope inner(isolate());
4654           Handle<Name> key = Handle<Name>(descs->GetKey(i));
4655           Handle<Object> value(descs->GetValue(i), isolate());
4656           JSObject::AddProperty(to, key, value, details.attributes());
4657 
4658         } else {
4659           DCHECK_EQ(kAccessor, details.kind());
4660           Handle<Name> key(descs->GetKey(i));
4661           LookupIterator it(to, key, LookupIterator::OWN_SKIP_INTERCEPTOR);
4662           CHECK_NE(LookupIterator::ACCESS_CHECK, it.state());
4663           // If the property is already there we skip it
4664           if (it.IsFound()) continue;
4665           HandleScope inner(isolate());
4666           DCHECK(!to->HasFastProperties());
4667           // Add to dictionary.
4668           Handle<Object> value(descs->GetValue(i), isolate());
4669           PropertyDetails d(kAccessor, details.attributes(), i + 1,
4670                             PropertyCellType::kMutable);
4671           JSObject::SetNormalizedProperty(to, key, value, d);
4672         }
4673       }
4674     }
4675   } else if (from->IsJSGlobalObject()) {
4676     // Copy all keys and values in enumeration order.
4677     Handle<GlobalDictionary> properties =
4678         Handle<GlobalDictionary>(from->global_dictionary());
4679     Handle<FixedArray> key_indices =
4680         GlobalDictionary::IterationIndices(properties);
4681     for (int i = 0; i < key_indices->length(); i++) {
4682       int key_index = Smi::cast(key_indices->get(i))->value();
4683       Object* raw_key = properties->KeyAt(key_index);
4684       DCHECK(properties->IsKey(isolate(), raw_key));
4685       DCHECK(raw_key->IsName());
4686       // If the property is already there we skip it.
4687       Handle<Name> key(Name::cast(raw_key), isolate());
4688       LookupIterator it(to, key, LookupIterator::OWN_SKIP_INTERCEPTOR);
4689       CHECK_NE(LookupIterator::ACCESS_CHECK, it.state());
4690       if (it.IsFound()) continue;
4691       // Set the property.
4692       DCHECK(properties->ValueAt(key_index)->IsPropertyCell());
4693       Handle<PropertyCell> cell(
4694           PropertyCell::cast(properties->ValueAt(key_index)), isolate());
4695       Handle<Object> value(cell->value(), isolate());
4696       if (value->IsTheHole(isolate())) continue;
4697       PropertyDetails details = cell->property_details();
4698       if (details.kind() != kData) continue;
4699       JSObject::AddProperty(to, key, value, details.attributes());
4700     }
4701   } else {
4702     // Copy all keys and values in enumeration order.
4703     Handle<NameDictionary> properties =
4704         Handle<NameDictionary>(from->property_dictionary());
4705     Handle<FixedArray> key_indices =
4706         NameDictionary::IterationIndices(properties);
4707     for (int i = 0; i < key_indices->length(); i++) {
4708       int key_index = Smi::cast(key_indices->get(i))->value();
4709       Object* raw_key = properties->KeyAt(key_index);
4710       DCHECK(properties->IsKey(isolate(), raw_key));
4711       DCHECK(raw_key->IsName());
4712       // If the property is already there we skip it.
4713       Handle<Name> key(Name::cast(raw_key), isolate());
4714       LookupIterator it(to, key, LookupIterator::OWN_SKIP_INTERCEPTOR);
4715       CHECK_NE(LookupIterator::ACCESS_CHECK, it.state());
4716       if (it.IsFound()) continue;
4717       // Set the property.
4718       Handle<Object> value =
4719           Handle<Object>(properties->ValueAt(key_index), isolate());
4720       DCHECK(!value->IsCell());
4721       DCHECK(!value->IsTheHole(isolate()));
4722       PropertyDetails details = properties->DetailsAt(key_index);
4723       DCHECK_EQ(kData, details.kind());
4724       JSObject::AddProperty(to, key, value, details.attributes());
4725     }
4726   }
4727 }
4728 
4729 
TransferIndexedProperties(Handle<JSObject> from,Handle<JSObject> to)4730 void Genesis::TransferIndexedProperties(Handle<JSObject> from,
4731                                         Handle<JSObject> to) {
4732   // Cloning the elements array is sufficient.
4733   Handle<FixedArray> from_elements =
4734       Handle<FixedArray>(FixedArray::cast(from->elements()));
4735   Handle<FixedArray> to_elements = factory()->CopyFixedArray(from_elements);
4736   to->set_elements(*to_elements);
4737 }
4738 
4739 
TransferObject(Handle<JSObject> from,Handle<JSObject> to)4740 void Genesis::TransferObject(Handle<JSObject> from, Handle<JSObject> to) {
4741   HandleScope outer(isolate());
4742 
4743   DCHECK(!from->IsJSArray());
4744   DCHECK(!to->IsJSArray());
4745 
4746   TransferNamedProperties(from, to);
4747   TransferIndexedProperties(from, to);
4748 
4749   // Transfer the prototype (new map is needed).
4750   Handle<Object> proto(from->map()->prototype(), isolate());
4751   JSObject::ForceSetPrototype(to, proto);
4752 }
4753 
4754 
MakeFunctionInstancePrototypeWritable()4755 void Genesis::MakeFunctionInstancePrototypeWritable() {
4756   // The maps with writable prototype are created in CreateEmptyFunction
4757   // and CreateStrictModeFunctionMaps respectively. Initially the maps are
4758   // created with read-only prototype for JS builtins processing.
4759   DCHECK(!sloppy_function_map_writable_prototype_.is_null());
4760   DCHECK(!strict_function_map_writable_prototype_.is_null());
4761 
4762   // Replace function instance maps to make prototype writable.
4763   native_context()->set_sloppy_function_map(
4764       *sloppy_function_map_writable_prototype_);
4765   native_context()->set_strict_function_map(
4766       *strict_function_map_writable_prototype_);
4767 }
4768 
4769 
4770 class NoTrackDoubleFieldsForSerializerScope {
4771  public:
NoTrackDoubleFieldsForSerializerScope(Isolate * isolate)4772   explicit NoTrackDoubleFieldsForSerializerScope(Isolate* isolate)
4773       : flag_(FLAG_track_double_fields), enabled_(false) {
4774     if (isolate->serializer_enabled()) {
4775       // Disable tracking double fields because heap numbers treated as
4776       // immutable by the serializer.
4777       FLAG_track_double_fields = false;
4778       enabled_ = true;
4779     }
4780   }
4781 
~NoTrackDoubleFieldsForSerializerScope()4782   ~NoTrackDoubleFieldsForSerializerScope() {
4783     if (enabled_) {
4784       FLAG_track_double_fields = flag_;
4785     }
4786   }
4787 
4788  private:
4789   bool flag_;
4790   bool enabled_;
4791 };
4792 
Genesis(Isolate * isolate,MaybeHandle<JSGlobalProxy> maybe_global_proxy,v8::Local<v8::ObjectTemplate> global_proxy_template,size_t context_snapshot_index,v8::DeserializeInternalFieldsCallback internal_fields_deserializer,GlobalContextType context_type)4793 Genesis::Genesis(
4794     Isolate* isolate, MaybeHandle<JSGlobalProxy> maybe_global_proxy,
4795     v8::Local<v8::ObjectTemplate> global_proxy_template,
4796     size_t context_snapshot_index,
4797     v8::DeserializeInternalFieldsCallback internal_fields_deserializer,
4798     GlobalContextType context_type)
4799     : isolate_(isolate), active_(isolate->bootstrapper()) {
4800   NoTrackDoubleFieldsForSerializerScope disable_scope(isolate);
4801   result_ = Handle<Context>::null();
4802   global_proxy_ = Handle<JSGlobalProxy>::null();
4803 
4804   // Before creating the roots we must save the context and restore it
4805   // on all function exits.
4806   SaveContext saved_context(isolate);
4807 
4808   // During genesis, the boilerplate for stack overflow won't work until the
4809   // environment has been at least partially initialized. Add a stack check
4810   // before entering JS code to catch overflow early.
4811   StackLimitCheck check(isolate);
4812   if (check.HasOverflowed()) {
4813     isolate->StackOverflow();
4814     return;
4815   }
4816 
4817   // The deserializer needs to hook up references to the global proxy.
4818   // Create an uninitialized global proxy now if we don't have one
4819   // and initialize it later in CreateNewGlobals.
4820   Handle<JSGlobalProxy> global_proxy;
4821   if (!maybe_global_proxy.ToHandle(&global_proxy)) {
4822     int instance_size = 0;
4823     if (context_snapshot_index > 0) {
4824       // The global proxy function to reinitialize this global proxy is in the
4825       // context that is yet to be deserialized. We need to prepare a global
4826       // proxy of the correct size.
4827       Object* size = isolate->heap()->serialized_global_proxy_sizes()->get(
4828           static_cast<int>(context_snapshot_index) - 1);
4829       instance_size = Smi::cast(size)->value();
4830     } else {
4831       instance_size = JSGlobalProxy::SizeWithInternalFields(
4832           global_proxy_template.IsEmpty()
4833               ? 0
4834               : global_proxy_template->InternalFieldCount());
4835     }
4836     global_proxy =
4837         isolate->factory()->NewUninitializedJSGlobalProxy(instance_size);
4838   }
4839 
4840   // We can only de-serialize a context if the isolate was initialized from
4841   // a snapshot. Otherwise we have to build the context from scratch.
4842   // Also create a context from scratch to expose natives, if required by flag.
4843   if (!isolate->initialized_from_snapshot() ||
4844       !Snapshot::NewContextFromSnapshot(isolate, global_proxy,
4845                                         context_snapshot_index,
4846                                         internal_fields_deserializer)
4847            .ToHandle(&native_context_)) {
4848     native_context_ = Handle<Context>();
4849   }
4850 
4851   if (!native_context().is_null()) {
4852     AddToWeakNativeContextList(*native_context());
4853     isolate->set_context(*native_context());
4854     isolate->counters()->contexts_created_by_snapshot()->Increment();
4855 #if TRACE_MAPS
4856     if (FLAG_trace_maps) {
4857       Handle<JSFunction> object_fun = isolate->object_function();
4858       PrintF("[TraceMap: InitialMap map= %p SFI= %d_Object ]\n",
4859              reinterpret_cast<void*>(object_fun->initial_map()),
4860              object_fun->shared()->unique_id());
4861       Map::TraceAllTransitions(object_fun->initial_map());
4862     }
4863 #endif
4864 
4865     if (context_snapshot_index == 0) {
4866       Handle<JSGlobalObject> global_object =
4867           CreateNewGlobals(global_proxy_template, global_proxy);
4868       HookUpGlobalObject(global_object);
4869 
4870       if (!ConfigureGlobalObjects(global_proxy_template)) return;
4871     } else {
4872       // The global proxy needs to be integrated into the native context.
4873       HookUpGlobalProxy(global_proxy);
4874     }
4875     DCHECK(!global_proxy->IsDetachedFrom(native_context()->global_object()));
4876   } else {
4877     DCHECK_EQ(0u, context_snapshot_index);
4878     // We get here if there was no context snapshot.
4879     CreateRoots();
4880     Handle<JSFunction> empty_function = CreateEmptyFunction(isolate);
4881     CreateStrictModeFunctionMaps(empty_function);
4882     CreateIteratorMaps(empty_function);
4883     CreateAsyncIteratorMaps();
4884     CreateAsyncFunctionMaps(empty_function);
4885     Handle<JSGlobalObject> global_object =
4886         CreateNewGlobals(global_proxy_template, global_proxy);
4887     InitializeGlobal(global_object, empty_function, context_type);
4888     InitializeNormalizedMapCaches();
4889 
4890     if (!InstallNatives(context_type)) return;
4891 
4892     MakeFunctionInstancePrototypeWritable();
4893 
4894     if (!InstallExtraNatives()) return;
4895     if (!ConfigureGlobalObjects(global_proxy_template)) return;
4896 
4897     isolate->counters()->contexts_created_from_scratch()->Increment();
4898   }
4899 
4900   // Install experimental natives. Do not include them into the
4901   // snapshot as we should be able to turn them off at runtime. Re-installing
4902   // them after they have already been deserialized would also fail.
4903   if (context_type == FULL_CONTEXT) {
4904     if (!isolate->serializer_enabled()) {
4905       InitializeExperimentalGlobal();
4906       if (!InstallExperimentalNatives()) return;
4907 
4908       if (FLAG_experimental_extras) {
4909         if (!InstallExperimentalExtraNatives()) return;
4910       }
4911 
4912       // Store String.prototype's map again in case it has been changed by
4913       // experimental natives.
4914       Handle<JSFunction> string_function(native_context()->string_function());
4915       JSObject* string_function_prototype =
4916           JSObject::cast(string_function->initial_map()->prototype());
4917       DCHECK(string_function_prototype->HasFastProperties());
4918       native_context()->set_string_function_prototype_map(
4919           string_function_prototype->map());
4920     }
4921     // The serializer cannot serialize typed arrays. Reset those typed arrays
4922     // for each new context.
4923   } else if (context_type == DEBUG_CONTEXT) {
4924     DCHECK(!isolate->serializer_enabled());
4925     InitializeExperimentalGlobal();
4926     if (!InstallDebuggerNatives()) return;
4927   }
4928 
4929   ConfigureUtilsObject(context_type);
4930 
4931   // Check that the script context table is empty except for the 'this' binding.
4932   // We do not need script contexts for native scripts.
4933   DCHECK_EQ(1, native_context()->script_context_table()->used());
4934 
4935   native_context()->ResetErrorsThrown();
4936   result_ = native_context();
4937 }
4938 
Genesis(Isolate * isolate,MaybeHandle<JSGlobalProxy> maybe_global_proxy,v8::Local<v8::ObjectTemplate> global_proxy_template)4939 Genesis::Genesis(Isolate* isolate,
4940                  MaybeHandle<JSGlobalProxy> maybe_global_proxy,
4941                  v8::Local<v8::ObjectTemplate> global_proxy_template)
4942     : isolate_(isolate), active_(isolate->bootstrapper()) {
4943   NoTrackDoubleFieldsForSerializerScope disable_scope(isolate);
4944   result_ = Handle<Context>::null();
4945   global_proxy_ = Handle<JSGlobalProxy>::null();
4946 
4947   // Before creating the roots we must save the context and restore it
4948   // on all function exits.
4949   SaveContext saved_context(isolate);
4950 
4951   // During genesis, the boilerplate for stack overflow won't work until the
4952   // environment has been at least partially initialized. Add a stack check
4953   // before entering JS code to catch overflow early.
4954   StackLimitCheck check(isolate);
4955   if (check.HasOverflowed()) {
4956     isolate->StackOverflow();
4957     return;
4958   }
4959 
4960   const int proxy_size = JSGlobalProxy::SizeWithInternalFields(
4961       global_proxy_template->InternalFieldCount());
4962 
4963   Handle<JSGlobalProxy> global_proxy;
4964   if (!maybe_global_proxy.ToHandle(&global_proxy)) {
4965     global_proxy = factory()->NewUninitializedJSGlobalProxy(proxy_size);
4966   }
4967 
4968   // Create a remote object as the global object.
4969   Handle<ObjectTemplateInfo> global_proxy_data =
4970       Utils::OpenHandle(*global_proxy_template);
4971   Handle<FunctionTemplateInfo> global_constructor(
4972       FunctionTemplateInfo::cast(global_proxy_data->constructor()));
4973 
4974   Handle<ObjectTemplateInfo> global_object_template(
4975       ObjectTemplateInfo::cast(global_constructor->prototype_template()));
4976   Handle<JSObject> global_object =
4977       ApiNatives::InstantiateRemoteObject(
4978           global_object_template).ToHandleChecked();
4979 
4980   // (Re)initialize the global proxy object.
4981   Handle<SharedFunctionInfo> shared =
4982       FunctionTemplateInfo::GetOrCreateSharedFunctionInfo(isolate,
4983                                                           global_constructor);
4984   Handle<Map> initial_map =
4985       factory()->CreateSloppyFunctionMap(FUNCTION_WITH_WRITEABLE_PROTOTYPE);
4986   Handle<JSFunction> global_proxy_function =
4987       isolate->factory()->NewFunctionFromSharedFunctionInfo(
4988           initial_map, shared, factory()->undefined_value());
4989   DCHECK_EQ(global_proxy_data->internal_field_count(),
4990             global_proxy_template->InternalFieldCount());
4991   Handle<Map> global_proxy_map = isolate->factory()->NewMap(
4992       JS_GLOBAL_PROXY_TYPE, proxy_size, FAST_HOLEY_SMI_ELEMENTS);
4993   JSFunction::SetInitialMap(global_proxy_function, global_proxy_map,
4994                             factory()->null_value());
4995   global_proxy_map->set_is_access_check_needed(true);
4996   global_proxy_map->set_has_hidden_prototype(true);
4997 
4998   Handle<String> global_name = factory()->global_string();
4999   global_proxy_function->shared()->set_instance_class_name(*global_name);
5000   factory()->ReinitializeJSGlobalProxy(global_proxy, global_proxy_function);
5001 
5002   // A remote global proxy has no native context.
5003   global_proxy->set_native_context(heap()->null_value());
5004 
5005   // Configure the hidden prototype chain of the global proxy.
5006   JSObject::ForceSetPrototype(global_proxy, global_object);
5007   // TODO(dcheng): This is a hack. Why does this need to be manually called
5008   // here? Line 4812 should have taken care of it?
5009   global_proxy->map()->set_has_hidden_prototype(true);
5010 
5011   global_proxy_ = global_proxy;
5012 }
5013 
5014 // Support for thread preemption.
5015 
5016 // Reserve space for statics needing saving and restoring.
ArchiveSpacePerThread()5017 int Bootstrapper::ArchiveSpacePerThread() {
5018   return sizeof(NestingCounterType);
5019 }
5020 
5021 
5022 // Archive statics that are thread-local.
ArchiveState(char * to)5023 char* Bootstrapper::ArchiveState(char* to) {
5024   *reinterpret_cast<NestingCounterType*>(to) = nesting_;
5025   nesting_ = 0;
5026   return to + sizeof(NestingCounterType);
5027 }
5028 
5029 
5030 // Restore statics that are thread-local.
RestoreState(char * from)5031 char* Bootstrapper::RestoreState(char* from) {
5032   nesting_ = *reinterpret_cast<NestingCounterType*>(from);
5033   return from + sizeof(NestingCounterType);
5034 }
5035 
5036 
5037 // Called when the top-level V8 mutex is destroyed.
FreeThreadResources()5038 void Bootstrapper::FreeThreadResources() {
5039   DCHECK(!IsActive());
5040 }
5041 
5042 }  // namespace internal
5043 }  // namespace v8
5044