• 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/extensions/externalize-string-extension.h"
12 #include "src/extensions/free-buffer-extension.h"
13 #include "src/extensions/gc-extension.h"
14 #include "src/extensions/ignition-statistics-extension.h"
15 #include "src/extensions/statistics-extension.h"
16 #include "src/extensions/trigger-failure-extension.h"
17 #include "src/heap/heap.h"
18 #include "src/isolate-inl.h"
19 #include "src/snapshot/natives.h"
20 #include "src/snapshot/snapshot.h"
21 #include "src/wasm/wasm-js.h"
22 
23 namespace v8 {
24 namespace internal {
25 
Bootstrapper(Isolate * isolate)26 Bootstrapper::Bootstrapper(Isolate* isolate)
27     : isolate_(isolate),
28       nesting_(0),
29       extensions_cache_(Script::TYPE_EXTENSION) {}
30 
31 template <class Source>
SourceLookup(int index)32 Handle<String> Bootstrapper::SourceLookup(int index) {
33   DCHECK(0 <= index && index < Source::GetBuiltinsCount());
34   Heap* heap = isolate_->heap();
35   if (Source::GetSourceCache(heap)->get(index)->IsUndefined(isolate_)) {
36     // We can use external strings for the natives.
37     Vector<const char> source = Source::GetScriptSource(index);
38     NativesExternalStringResource* resource =
39         new NativesExternalStringResource(source.start(), source.length());
40     Handle<ExternalOneByteString> source_code =
41         isolate_->factory()->NewNativeSourceString(resource);
42     // Mark this external string with a special map.
43     DCHECK(source_code->is_short());
44     Source::GetSourceCache(heap)->set(index, *source_code);
45   }
46   Handle<Object> cached_source(Source::GetSourceCache(heap)->get(index),
47                                isolate_);
48   return Handle<String>::cast(cached_source);
49 }
50 
51 
52 template Handle<String> Bootstrapper::SourceLookup<Natives>(int index);
53 template Handle<String> Bootstrapper::SourceLookup<ExperimentalNatives>(
54     int index);
55 template Handle<String> Bootstrapper::SourceLookup<ExperimentalExtraNatives>(
56     int index);
57 template Handle<String> Bootstrapper::SourceLookup<ExtraNatives>(int index);
58 
59 
Initialize(bool create_heap_objects)60 void Bootstrapper::Initialize(bool create_heap_objects) {
61   extensions_cache_.Initialize(isolate_, create_heap_objects);
62 }
63 
64 
GCFunctionName()65 static const char* GCFunctionName() {
66   bool flag_given = FLAG_expose_gc_as != NULL && strlen(FLAG_expose_gc_as) != 0;
67   return flag_given ? FLAG_expose_gc_as : "gc";
68 }
69 
70 
71 v8::Extension* Bootstrapper::free_buffer_extension_ = NULL;
72 v8::Extension* Bootstrapper::gc_extension_ = NULL;
73 v8::Extension* Bootstrapper::externalize_string_extension_ = NULL;
74 v8::Extension* Bootstrapper::statistics_extension_ = NULL;
75 v8::Extension* Bootstrapper::trigger_failure_extension_ = NULL;
76 v8::Extension* Bootstrapper::ignition_statistics_extension_ = NULL;
77 
InitializeOncePerProcess()78 void Bootstrapper::InitializeOncePerProcess() {
79   free_buffer_extension_ = new FreeBufferExtension;
80   v8::RegisterExtension(free_buffer_extension_);
81   gc_extension_ = new GCExtension(GCFunctionName());
82   v8::RegisterExtension(gc_extension_);
83   externalize_string_extension_ = new ExternalizeStringExtension;
84   v8::RegisterExtension(externalize_string_extension_);
85   statistics_extension_ = new StatisticsExtension;
86   v8::RegisterExtension(statistics_extension_);
87   trigger_failure_extension_ = new TriggerFailureExtension;
88   v8::RegisterExtension(trigger_failure_extension_);
89   ignition_statistics_extension_ = new IgnitionStatisticsExtension;
90   v8::RegisterExtension(ignition_statistics_extension_);
91 }
92 
93 
TearDownExtensions()94 void Bootstrapper::TearDownExtensions() {
95   delete free_buffer_extension_;
96   free_buffer_extension_ = NULL;
97   delete gc_extension_;
98   gc_extension_ = NULL;
99   delete externalize_string_extension_;
100   externalize_string_extension_ = NULL;
101   delete statistics_extension_;
102   statistics_extension_ = NULL;
103   delete trigger_failure_extension_;
104   trigger_failure_extension_ = NULL;
105   delete ignition_statistics_extension_;
106   ignition_statistics_extension_ = NULL;
107 }
108 
109 
DeleteNativeSources(Object * maybe_array)110 void DeleteNativeSources(Object* maybe_array) {
111   if (maybe_array->IsFixedArray()) {
112     FixedArray* array = FixedArray::cast(maybe_array);
113     Isolate* isolate = array->GetIsolate();
114     for (int i = 0; i < array->length(); i++) {
115       Object* natives_source = array->get(i);
116       if (!natives_source->IsUndefined(isolate)) {
117         const NativesExternalStringResource* resource =
118             reinterpret_cast<const NativesExternalStringResource*>(
119                 ExternalOneByteString::cast(natives_source)->resource());
120         delete resource;
121       }
122     }
123   }
124 }
125 
126 
TearDown()127 void Bootstrapper::TearDown() {
128   DeleteNativeSources(Natives::GetSourceCache(isolate_->heap()));
129   DeleteNativeSources(ExperimentalNatives::GetSourceCache(isolate_->heap()));
130   DeleteNativeSources(ExtraNatives::GetSourceCache(isolate_->heap()));
131   DeleteNativeSources(
132       ExperimentalExtraNatives::GetSourceCache(isolate_->heap()));
133 
134   extensions_cache_.Initialize(isolate_, false);  // Yes, symmetrical
135 }
136 
137 
138 class Genesis BASE_EMBEDDED {
139  public:
140   Genesis(Isolate* isolate, MaybeHandle<JSGlobalProxy> maybe_global_proxy,
141           v8::Local<v8::ObjectTemplate> global_proxy_template,
142           v8::ExtensionConfiguration* extensions, size_t context_snapshot_index,
143           GlobalContextType context_type);
~Genesis()144   ~Genesis() { }
145 
isolate() const146   Isolate* isolate() const { return isolate_; }
factory() const147   Factory* factory() const { return isolate_->factory(); }
heap() const148   Heap* heap() const { return isolate_->heap(); }
149 
result()150   Handle<Context> result() { return result_; }
151 
152  private:
native_context()153   Handle<Context> native_context() { return native_context_; }
154 
155   // Creates some basic objects. Used for creating a context from scratch.
156   void CreateRoots();
157   // Creates the empty function.  Used for creating a context from scratch.
158   Handle<JSFunction> CreateEmptyFunction(Isolate* isolate);
159   // Creates the ThrowTypeError function. ECMA 5th Ed. 13.2.3
160   Handle<JSFunction> GetRestrictedFunctionPropertiesThrower();
161   Handle<JSFunction> GetStrictArgumentsPoisonFunction();
162   Handle<JSFunction> GetThrowTypeErrorIntrinsic(Builtins::Name builtin_name);
163 
164   void CreateStrictModeFunctionMaps(Handle<JSFunction> empty);
165   void CreateIteratorMaps(Handle<JSFunction> empty);
166   void CreateAsyncFunctionMaps(Handle<JSFunction> empty);
167   void CreateJSProxyMaps();
168 
169   // Make the "arguments" and "caller" properties throw a TypeError on access.
170   void AddRestrictedFunctionProperties(Handle<JSFunction> empty);
171 
172   // Creates the global objects using the global proxy and the template passed
173   // in through the API.  We call this regardless of whether we are building a
174   // context from scratch or using a deserialized one from the partial snapshot
175   // but in the latter case we don't use the objects it produces directly, as
176   // we have to used the deserialized ones that are linked together with the
177   // rest of the context snapshot.
178   Handle<JSGlobalObject> CreateNewGlobals(
179       v8::Local<v8::ObjectTemplate> global_proxy_template,
180       Handle<JSGlobalProxy> global_proxy);
181   // Hooks the given global proxy into the context.  If the context was created
182   // by deserialization then this will unhook the global proxy that was
183   // deserialized, leaving the GC to pick it up.
184   void HookUpGlobalProxy(Handle<JSGlobalObject> global_object,
185                          Handle<JSGlobalProxy> global_proxy);
186   // Similarly, we want to use the global that has been created by the templates
187   // passed through the API.  The global from the snapshot is detached from the
188   // other objects in the snapshot.
189   void HookUpGlobalObject(Handle<JSGlobalObject> global_object);
190   // The native context has a ScriptContextTable that store declarative bindings
191   // made in script scopes.  Add a "this" binding to that table pointing to the
192   // global proxy.
193   void InstallGlobalThisBinding();
194   // New context initialization.  Used for creating a context from scratch.
195   void InitializeGlobal(Handle<JSGlobalObject> global_object,
196                         Handle<JSFunction> empty_function,
197                         GlobalContextType context_type);
198   void InitializeExperimentalGlobal();
199   // Depending on the situation, expose and/or get rid of the utils object.
200   void ConfigureUtilsObject(GlobalContextType context_type);
201 
202 #define DECLARE_FEATURE_INITIALIZATION(id, descr) \
203   void InitializeGlobal_##id();
204 
205   HARMONY_INPROGRESS(DECLARE_FEATURE_INITIALIZATION)
206   HARMONY_STAGED(DECLARE_FEATURE_INITIALIZATION)
207   HARMONY_SHIPPING(DECLARE_FEATURE_INITIALIZATION)
208   DECLARE_FEATURE_INITIALIZATION(promise_extra, "")
209   DECLARE_FEATURE_INITIALIZATION(intl_extra, "")
210 #undef DECLARE_FEATURE_INITIALIZATION
211 
212   Handle<JSFunction> InstallArrayBuffer(Handle<JSObject> target,
213                                         const char* name);
214   Handle<JSFunction> InstallInternalArray(Handle<JSObject> target,
215                                           const char* name,
216                                           ElementsKind elements_kind);
217   bool InstallNatives(GlobalContextType context_type);
218 
219   void InstallTypedArray(const char* name, ElementsKind elements_kind,
220                          Handle<JSFunction>* fun);
221   bool InstallExperimentalNatives();
222   bool InstallExtraNatives();
223   bool InstallExperimentalExtraNatives();
224   bool InstallDebuggerNatives();
225   void InstallBuiltinFunctionIds();
226   void InstallExperimentalBuiltinFunctionIds();
227   void InitializeNormalizedMapCaches();
228 
229   enum ExtensionTraversalState {
230     UNVISITED, VISITED, INSTALLED
231   };
232 
233   class ExtensionStates {
234    public:
235     ExtensionStates();
236     ExtensionTraversalState get_state(RegisteredExtension* extension);
237     void set_state(RegisteredExtension* extension,
238                    ExtensionTraversalState state);
239    private:
240     base::HashMap map_;
241     DISALLOW_COPY_AND_ASSIGN(ExtensionStates);
242   };
243 
244   // Used both for deserialized and from-scratch contexts to add the extensions
245   // provided.
246   static bool InstallExtensions(Handle<Context> native_context,
247                                 v8::ExtensionConfiguration* extensions);
248   static bool InstallAutoExtensions(Isolate* isolate,
249                                     ExtensionStates* extension_states);
250   static bool InstallRequestedExtensions(Isolate* isolate,
251                                          v8::ExtensionConfiguration* extensions,
252                                          ExtensionStates* extension_states);
253   static bool InstallExtension(Isolate* isolate,
254                                const char* name,
255                                ExtensionStates* extension_states);
256   static bool InstallExtension(Isolate* isolate,
257                                v8::RegisteredExtension* current,
258                                ExtensionStates* extension_states);
259   static bool InstallSpecialObjects(Handle<Context> native_context);
260   bool ConfigureApiObject(Handle<JSObject> object,
261                           Handle<ObjectTemplateInfo> object_template);
262   bool ConfigureGlobalObjects(
263       v8::Local<v8::ObjectTemplate> global_proxy_template);
264 
265   // Migrates all properties from the 'from' object to the 'to'
266   // object and overrides the prototype in 'to' with the one from
267   // 'from'.
268   void TransferObject(Handle<JSObject> from, Handle<JSObject> to);
269   void TransferNamedProperties(Handle<JSObject> from, Handle<JSObject> to);
270   void TransferIndexedProperties(Handle<JSObject> from, Handle<JSObject> to);
271 
272   enum FunctionMode {
273     // With prototype.
274     FUNCTION_WITH_WRITEABLE_PROTOTYPE,
275     FUNCTION_WITH_READONLY_PROTOTYPE,
276     // Without prototype.
277     FUNCTION_WITHOUT_PROTOTYPE
278   };
279 
IsFunctionModeWithPrototype(FunctionMode function_mode)280   static bool IsFunctionModeWithPrototype(FunctionMode function_mode) {
281     return (function_mode == FUNCTION_WITH_WRITEABLE_PROTOTYPE ||
282             function_mode == FUNCTION_WITH_READONLY_PROTOTYPE);
283   }
284 
285   Handle<Map> CreateSloppyFunctionMap(FunctionMode function_mode);
286 
287   void SetFunctionInstanceDescriptor(Handle<Map> map,
288                                      FunctionMode function_mode);
289   void MakeFunctionInstancePrototypeWritable();
290 
291   Handle<Map> CreateStrictFunctionMap(FunctionMode function_mode,
292                                       Handle<JSFunction> empty_function);
293 
294 
295   void SetStrictFunctionInstanceDescriptor(Handle<Map> map,
296                                            FunctionMode function_mode);
297 
298   static bool CallUtilsFunction(Isolate* isolate, const char* name);
299 
300   static bool CompileExtension(Isolate* isolate, v8::Extension* extension);
301 
302   Isolate* isolate_;
303   Handle<Context> result_;
304   Handle<Context> native_context_;
305 
306   // Function maps. Function maps are created initially with a read only
307   // prototype for the processing of JS builtins. Later the function maps are
308   // replaced in order to make prototype writable. These are the final, writable
309   // prototype, maps.
310   Handle<Map> sloppy_function_map_writable_prototype_;
311   Handle<Map> strict_function_map_writable_prototype_;
312   Handle<JSFunction> strict_poison_function_;
313   Handle<JSFunction> restricted_function_properties_thrower_;
314 
315   BootstrapperActive active_;
316   friend class Bootstrapper;
317 };
318 
319 
Iterate(ObjectVisitor * v)320 void Bootstrapper::Iterate(ObjectVisitor* v) {
321   extensions_cache_.Iterate(v);
322   v->Synchronize(VisitorSynchronization::kExtensions);
323 }
324 
CreateEnvironment(MaybeHandle<JSGlobalProxy> maybe_global_proxy,v8::Local<v8::ObjectTemplate> global_proxy_template,v8::ExtensionConfiguration * extensions,size_t context_snapshot_index,GlobalContextType context_type)325 Handle<Context> Bootstrapper::CreateEnvironment(
326     MaybeHandle<JSGlobalProxy> maybe_global_proxy,
327     v8::Local<v8::ObjectTemplate> global_proxy_template,
328     v8::ExtensionConfiguration* extensions, size_t context_snapshot_index,
329     GlobalContextType context_type) {
330   HandleScope scope(isolate_);
331   Genesis genesis(isolate_, maybe_global_proxy, global_proxy_template,
332                   extensions, context_snapshot_index, context_type);
333   Handle<Context> env = genesis.result();
334   if (env.is_null() || !InstallExtensions(env, extensions)) {
335     return Handle<Context>();
336   }
337   return scope.CloseAndEscape(env);
338 }
339 
340 
SetObjectPrototype(Handle<JSObject> object,Handle<Object> proto)341 static void SetObjectPrototype(Handle<JSObject> object, Handle<Object> proto) {
342   // object.__proto__ = proto;
343   Handle<Map> old_map = Handle<Map>(object->map());
344   Handle<Map> new_map = Map::Copy(old_map, "SetObjectPrototype");
345   Map::SetPrototype(new_map, proto, FAST_PROTOTYPE);
346   JSObject::MigrateToMap(object, new_map);
347 }
348 
349 
DetachGlobal(Handle<Context> env)350 void Bootstrapper::DetachGlobal(Handle<Context> env) {
351   env->GetIsolate()->counters()->errors_thrown_per_context()->AddSample(
352     env->GetErrorsThrown());
353 
354   Factory* factory = env->GetIsolate()->factory();
355   Handle<JSGlobalProxy> global_proxy(JSGlobalProxy::cast(env->global_proxy()));
356   global_proxy->set_native_context(*factory->null_value());
357   SetObjectPrototype(global_proxy, factory->null_value());
358   global_proxy->map()->SetConstructor(*factory->null_value());
359   if (FLAG_track_detached_contexts) {
360     env->GetIsolate()->AddDetachedContext(env);
361   }
362 }
363 
364 namespace {
365 
InstallFunction(Handle<JSObject> target,Handle<Name> property_name,Handle<JSFunction> function,Handle<String> function_name,PropertyAttributes attributes=DONT_ENUM)366 void InstallFunction(Handle<JSObject> target, Handle<Name> property_name,
367                      Handle<JSFunction> function, Handle<String> function_name,
368                      PropertyAttributes attributes = DONT_ENUM) {
369   JSObject::AddProperty(target, property_name, function, attributes);
370   if (target->IsJSGlobalObject()) {
371     function->shared()->set_instance_class_name(*function_name);
372   }
373   function->shared()->set_native(true);
374 }
375 
InstallFunction(Handle<JSObject> target,Handle<JSFunction> function,Handle<Name> name,PropertyAttributes attributes=DONT_ENUM)376 void InstallFunction(Handle<JSObject> target, Handle<JSFunction> function,
377                      Handle<Name> name,
378                      PropertyAttributes attributes = DONT_ENUM) {
379   Handle<String> name_string = Name::ToFunctionName(name).ToHandleChecked();
380   InstallFunction(target, name, function, name_string, attributes);
381 }
382 
InstallGetter(Handle<JSObject> target,Handle<Name> property_name,Handle<JSFunction> getter,PropertyAttributes attributes=DONT_ENUM)383 Handle<JSFunction> InstallGetter(Handle<JSObject> target,
384                                  Handle<Name> property_name,
385                                  Handle<JSFunction> getter,
386                                  PropertyAttributes attributes = DONT_ENUM) {
387   Handle<Object> setter = target->GetIsolate()->factory()->undefined_value();
388   JSObject::DefineAccessor(target, property_name, getter, setter, attributes)
389       .Check();
390   return getter;
391 }
392 
CreateFunction(Isolate * isolate,Handle<String> name,InstanceType type,int instance_size,MaybeHandle<JSObject> maybe_prototype,Builtins::Name call,bool strict_function_map=false)393 Handle<JSFunction> CreateFunction(Isolate* isolate, Handle<String> name,
394                                   InstanceType type, int instance_size,
395                                   MaybeHandle<JSObject> maybe_prototype,
396                                   Builtins::Name call,
397                                   bool strict_function_map = false) {
398   Factory* factory = isolate->factory();
399   Handle<Code> call_code(isolate->builtins()->builtin(call));
400   Handle<JSObject> prototype;
401   return maybe_prototype.ToHandle(&prototype)
402              ? factory->NewFunction(name, call_code, prototype, type,
403                                     instance_size, strict_function_map)
404              : factory->NewFunctionWithoutPrototype(name, call_code,
405                                                     strict_function_map);
406 }
407 
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)408 Handle<JSFunction> InstallFunction(Handle<JSObject> target, Handle<Name> name,
409                                    InstanceType type, int instance_size,
410                                    MaybeHandle<JSObject> maybe_prototype,
411                                    Builtins::Name call,
412                                    PropertyAttributes attributes,
413                                    bool strict_function_map = false) {
414   Handle<String> name_string = Name::ToFunctionName(name).ToHandleChecked();
415   Handle<JSFunction> function =
416       CreateFunction(target->GetIsolate(), name_string, type, instance_size,
417                      maybe_prototype, call, strict_function_map);
418   InstallFunction(target, name, function, name_string, attributes);
419   return function;
420 }
421 
InstallFunction(Handle<JSObject> target,const char * name,InstanceType type,int instance_size,MaybeHandle<JSObject> maybe_prototype,Builtins::Name call,bool strict_function_map=false)422 Handle<JSFunction> InstallFunction(Handle<JSObject> target, const char* name,
423                                    InstanceType type, int instance_size,
424                                    MaybeHandle<JSObject> maybe_prototype,
425                                    Builtins::Name call,
426                                    bool strict_function_map = false) {
427   Factory* const factory = target->GetIsolate()->factory();
428   PropertyAttributes attributes = DONT_ENUM;
429   return InstallFunction(target, factory->InternalizeUtf8String(name), type,
430                          instance_size, maybe_prototype, call, attributes,
431                          strict_function_map);
432 }
433 
SimpleCreateFunction(Isolate * isolate,Handle<String> name,Builtins::Name call,int len,bool adapt)434 Handle<JSFunction> SimpleCreateFunction(Isolate* isolate, Handle<String> name,
435                                         Builtins::Name call, int len,
436                                         bool adapt) {
437   Handle<JSFunction> fun =
438       CreateFunction(isolate, name, JS_OBJECT_TYPE, JSObject::kHeaderSize,
439                      MaybeHandle<JSObject>(), call);
440   if (adapt) {
441     fun->shared()->set_internal_formal_parameter_count(len);
442   } else {
443     fun->shared()->DontAdaptArguments();
444   }
445   fun->shared()->set_length(len);
446   return fun;
447 }
448 
SimpleInstallFunction(Handle<JSObject> base,Handle<String> name,Builtins::Name call,int len,bool adapt)449 Handle<JSFunction> SimpleInstallFunction(Handle<JSObject> base,
450                                          Handle<String> name,
451                                          Builtins::Name call, int len,
452                                          bool adapt) {
453   Handle<JSFunction> fun =
454       SimpleCreateFunction(base->GetIsolate(), name, call, len, adapt);
455   InstallFunction(base, fun, name, DONT_ENUM);
456   return fun;
457 }
458 
SimpleInstallFunction(Handle<JSObject> base,const char * name,Builtins::Name call,int len,bool adapt)459 Handle<JSFunction> SimpleInstallFunction(Handle<JSObject> base,
460                                          const char* name, Builtins::Name call,
461                                          int len, bool adapt) {
462   Factory* const factory = base->GetIsolate()->factory();
463   return SimpleInstallFunction(base, factory->InternalizeUtf8String(name), call,
464                                len, adapt);
465 }
466 
SimpleInstallGetter(Handle<JSObject> base,Handle<String> name,Builtins::Name call,bool adapt)467 Handle<JSFunction> SimpleInstallGetter(Handle<JSObject> base,
468                                        Handle<String> name, Builtins::Name call,
469                                        bool adapt) {
470   Isolate* const isolate = base->GetIsolate();
471   Handle<String> fun_name =
472       Name::ToFunctionName(name, isolate->factory()->get_string())
473           .ToHandleChecked();
474   Handle<JSFunction> fun =
475       SimpleCreateFunction(isolate, fun_name, call, 0, adapt);
476   InstallGetter(base, name, fun);
477   return fun;
478 }
479 
SimpleInstallGetter(Handle<JSObject> base,Handle<String> name,Builtins::Name call,bool adapt,BuiltinFunctionId id)480 Handle<JSFunction> SimpleInstallGetter(Handle<JSObject> base,
481                                        Handle<String> name, Builtins::Name call,
482                                        bool adapt, BuiltinFunctionId id) {
483   Handle<JSFunction> fun = SimpleInstallGetter(base, name, call, adapt);
484   fun->shared()->set_builtin_function_id(id);
485   return fun;
486 }
487 
488 }  // namespace
489 
SetFunctionInstanceDescriptor(Handle<Map> map,FunctionMode function_mode)490 void Genesis::SetFunctionInstanceDescriptor(Handle<Map> map,
491                                             FunctionMode function_mode) {
492   int size = IsFunctionModeWithPrototype(function_mode) ? 5 : 4;
493   Map::EnsureDescriptorSlack(map, size);
494 
495   PropertyAttributes ro_attribs =
496       static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
497   PropertyAttributes roc_attribs =
498       static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY);
499 
500   STATIC_ASSERT(JSFunction::kLengthDescriptorIndex == 0);
501   Handle<AccessorInfo> length =
502       Accessors::FunctionLengthInfo(isolate(), roc_attribs);
503   {  // Add length.
504     AccessorConstantDescriptor d(Handle<Name>(Name::cast(length->name())),
505                                  length, roc_attribs);
506     map->AppendDescriptor(&d);
507   }
508 
509   STATIC_ASSERT(JSFunction::kNameDescriptorIndex == 1);
510   Handle<AccessorInfo> name =
511       Accessors::FunctionNameInfo(isolate(), ro_attribs);
512   {  // Add name.
513     AccessorConstantDescriptor d(Handle<Name>(Name::cast(name->name())), name,
514                                  roc_attribs);
515     map->AppendDescriptor(&d);
516   }
517   Handle<AccessorInfo> args =
518       Accessors::FunctionArgumentsInfo(isolate(), ro_attribs);
519   {  // Add arguments.
520     AccessorConstantDescriptor d(Handle<Name>(Name::cast(args->name())), args,
521                                  ro_attribs);
522     map->AppendDescriptor(&d);
523   }
524   Handle<AccessorInfo> caller =
525       Accessors::FunctionCallerInfo(isolate(), ro_attribs);
526   {  // Add caller.
527     AccessorConstantDescriptor d(Handle<Name>(Name::cast(caller->name())),
528                                  caller, ro_attribs);
529     map->AppendDescriptor(&d);
530   }
531   if (IsFunctionModeWithPrototype(function_mode)) {
532     if (function_mode == FUNCTION_WITH_WRITEABLE_PROTOTYPE) {
533       ro_attribs = static_cast<PropertyAttributes>(ro_attribs & ~READ_ONLY);
534     }
535     Handle<AccessorInfo> prototype =
536         Accessors::FunctionPrototypeInfo(isolate(), ro_attribs);
537     AccessorConstantDescriptor d(Handle<Name>(Name::cast(prototype->name())),
538                                  prototype, ro_attribs);
539     map->AppendDescriptor(&d);
540   }
541 }
542 
543 
CreateSloppyFunctionMap(FunctionMode function_mode)544 Handle<Map> Genesis::CreateSloppyFunctionMap(FunctionMode function_mode) {
545   Handle<Map> map = factory()->NewMap(JS_FUNCTION_TYPE, JSFunction::kSize);
546   SetFunctionInstanceDescriptor(map, function_mode);
547   map->set_is_constructor(IsFunctionModeWithPrototype(function_mode));
548   map->set_is_callable();
549   return map;
550 }
551 
552 
CreateEmptyFunction(Isolate * isolate)553 Handle<JSFunction> Genesis::CreateEmptyFunction(Isolate* isolate) {
554   // Allocate the map for function instances. Maps are allocated first and their
555   // prototypes patched later, once empty function is created.
556 
557   // Functions with this map will not have a 'prototype' property, and
558   // can not be used as constructors.
559   Handle<Map> function_without_prototype_map =
560       CreateSloppyFunctionMap(FUNCTION_WITHOUT_PROTOTYPE);
561   native_context()->set_sloppy_function_without_prototype_map(
562       *function_without_prototype_map);
563 
564   // Allocate the function map. This map is temporary, used only for processing
565   // of builtins.
566   // Later the map is replaced with writable prototype map, allocated below.
567   Handle<Map> function_map =
568       CreateSloppyFunctionMap(FUNCTION_WITH_READONLY_PROTOTYPE);
569   native_context()->set_sloppy_function_map(*function_map);
570   native_context()->set_sloppy_function_with_readonly_prototype_map(
571       *function_map);
572 
573   // The final map for functions. Writeable prototype.
574   // This map is installed in MakeFunctionInstancePrototypeWritable.
575   sloppy_function_map_writable_prototype_ =
576       CreateSloppyFunctionMap(FUNCTION_WITH_WRITEABLE_PROTOTYPE);
577   Factory* factory = isolate->factory();
578 
579   Handle<String> object_name = factory->Object_string();
580 
581   Handle<JSObject> object_function_prototype;
582 
583   {  // --- O b j e c t ---
584     Handle<JSFunction> object_fun = factory->NewFunction(object_name);
585     int unused = JSObject::kInitialGlobalObjectUnusedPropertiesCount;
586     int instance_size = JSObject::kHeaderSize + kPointerSize * unused;
587     Handle<Map> object_function_map =
588         factory->NewMap(JS_OBJECT_TYPE, instance_size);
589     object_function_map->SetInObjectProperties(unused);
590     JSFunction::SetInitialMap(object_fun, object_function_map,
591                               isolate->factory()->null_value());
592     object_function_map->set_unused_property_fields(unused);
593 
594     native_context()->set_object_function(*object_fun);
595 
596     // Allocate a new prototype for the object function.
597     object_function_prototype =
598         factory->NewJSObject(isolate->object_function(), TENURED);
599     Handle<Map> map = Map::Copy(handle(object_function_prototype->map()),
600                                 "EmptyObjectPrototype");
601     map->set_is_prototype_map(true);
602     object_function_prototype->set_map(*map);
603 
604     native_context()->set_initial_object_prototype(*object_function_prototype);
605     // For bootstrapping set the array prototype to be the same as the object
606     // prototype, otherwise the missing initial_array_prototype will cause
607     // assertions during startup.
608     native_context()->set_initial_array_prototype(*object_function_prototype);
609     Accessors::FunctionSetPrototype(object_fun, object_function_prototype)
610         .Assert();
611   }
612 
613   // Allocate the empty function as the prototype for function - ES6 19.2.3
614   Handle<Code> code(isolate->builtins()->EmptyFunction());
615   Handle<JSFunction> empty_function =
616       factory->NewFunctionWithoutPrototype(factory->empty_string(), code);
617 
618   // Allocate the function map first and then patch the prototype later
619   Handle<Map> empty_function_map =
620       CreateSloppyFunctionMap(FUNCTION_WITHOUT_PROTOTYPE);
621   DCHECK(!empty_function_map->is_dictionary_map());
622   Map::SetPrototype(empty_function_map, object_function_prototype);
623   empty_function_map->set_is_prototype_map(true);
624 
625   empty_function->set_map(*empty_function_map);
626 
627   // --- E m p t y ---
628   Handle<String> source = factory->NewStringFromStaticChars("() {}");
629   Handle<Script> script = factory->NewScript(source);
630   script->set_type(Script::TYPE_NATIVE);
631   empty_function->shared()->set_start_position(0);
632   empty_function->shared()->set_end_position(source->length());
633   empty_function->shared()->DontAdaptArguments();
634   SharedFunctionInfo::SetScript(handle(empty_function->shared()), script);
635 
636   // Set prototypes for the function maps.
637   Handle<Map> sloppy_function_map(native_context()->sloppy_function_map(),
638                                   isolate);
639   Handle<Map> sloppy_function_without_prototype_map(
640       native_context()->sloppy_function_without_prototype_map(), isolate);
641   Map::SetPrototype(sloppy_function_map, empty_function);
642   Map::SetPrototype(sloppy_function_without_prototype_map, empty_function);
643   Map::SetPrototype(sloppy_function_map_writable_prototype_, empty_function);
644 
645   return empty_function;
646 }
647 
648 
SetStrictFunctionInstanceDescriptor(Handle<Map> map,FunctionMode function_mode)649 void Genesis::SetStrictFunctionInstanceDescriptor(Handle<Map> map,
650                                                   FunctionMode function_mode) {
651   int size = IsFunctionModeWithPrototype(function_mode) ? 3 : 2;
652   Map::EnsureDescriptorSlack(map, size);
653 
654   PropertyAttributes rw_attribs =
655       static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE);
656   PropertyAttributes ro_attribs =
657       static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
658   PropertyAttributes roc_attribs =
659       static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY);
660 
661   DCHECK(function_mode == FUNCTION_WITH_WRITEABLE_PROTOTYPE ||
662          function_mode == FUNCTION_WITH_READONLY_PROTOTYPE ||
663          function_mode == FUNCTION_WITHOUT_PROTOTYPE);
664   STATIC_ASSERT(JSFunction::kLengthDescriptorIndex == 0);
665   {  // Add length.
666     Handle<AccessorInfo> length =
667         Accessors::FunctionLengthInfo(isolate(), roc_attribs);
668     AccessorConstantDescriptor d(handle(Name::cast(length->name())), length,
669                                  roc_attribs);
670     map->AppendDescriptor(&d);
671   }
672 
673   STATIC_ASSERT(JSFunction::kNameDescriptorIndex == 1);
674   {  // Add name.
675     Handle<AccessorInfo> name =
676         Accessors::FunctionNameInfo(isolate(), roc_attribs);
677     AccessorConstantDescriptor d(handle(Name::cast(name->name())), name,
678                                  roc_attribs);
679     map->AppendDescriptor(&d);
680   }
681   if (IsFunctionModeWithPrototype(function_mode)) {
682     // Add prototype.
683     PropertyAttributes attribs =
684         function_mode == FUNCTION_WITH_WRITEABLE_PROTOTYPE ? rw_attribs
685                                                            : ro_attribs;
686     Handle<AccessorInfo> prototype =
687         Accessors::FunctionPrototypeInfo(isolate(), attribs);
688     AccessorConstantDescriptor d(Handle<Name>(Name::cast(prototype->name())),
689                                  prototype, attribs);
690     map->AppendDescriptor(&d);
691   }
692 }
693 
694 
695 // Creates the %ThrowTypeError% function.
GetThrowTypeErrorIntrinsic(Builtins::Name builtin_name)696 Handle<JSFunction> Genesis::GetThrowTypeErrorIntrinsic(
697     Builtins::Name builtin_name) {
698   Handle<String> name =
699       factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("ThrowTypeError"));
700   Handle<Code> code(isolate()->builtins()->builtin(builtin_name));
701   Handle<JSFunction> function =
702       factory()->NewFunctionWithoutPrototype(name, code, true);
703   function->shared()->DontAdaptArguments();
704 
705   // %ThrowTypeError% must not have a name property.
706   if (JSReceiver::DeleteProperty(function, factory()->name_string())
707           .IsNothing()) {
708     DCHECK(false);
709   }
710 
711   // length needs to be non configurable.
712   Handle<Object> value(Smi::FromInt(function->shared()->length()), isolate());
713   JSObject::SetOwnPropertyIgnoreAttributes(
714       function, factory()->length_string(), value,
715       static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY))
716       .Assert();
717 
718   if (JSObject::PreventExtensions(function, Object::THROW_ON_ERROR)
719           .IsNothing()) {
720     DCHECK(false);
721   }
722 
723   return function;
724 }
725 
726 
727 // ECMAScript 5th Edition, 13.2.3
GetRestrictedFunctionPropertiesThrower()728 Handle<JSFunction> Genesis::GetRestrictedFunctionPropertiesThrower() {
729   if (restricted_function_properties_thrower_.is_null()) {
730     restricted_function_properties_thrower_ = GetThrowTypeErrorIntrinsic(
731         Builtins::kRestrictedFunctionPropertiesThrower);
732   }
733   return restricted_function_properties_thrower_;
734 }
735 
736 
GetStrictArgumentsPoisonFunction()737 Handle<JSFunction> Genesis::GetStrictArgumentsPoisonFunction() {
738   if (strict_poison_function_.is_null()) {
739     strict_poison_function_ = GetThrowTypeErrorIntrinsic(
740         Builtins::kRestrictedStrictArgumentsPropertiesThrower);
741   }
742   return strict_poison_function_;
743 }
744 
745 
CreateStrictFunctionMap(FunctionMode function_mode,Handle<JSFunction> empty_function)746 Handle<Map> Genesis::CreateStrictFunctionMap(
747     FunctionMode function_mode, Handle<JSFunction> empty_function) {
748   Handle<Map> map = factory()->NewMap(JS_FUNCTION_TYPE, JSFunction::kSize);
749   SetStrictFunctionInstanceDescriptor(map, function_mode);
750   map->set_is_constructor(IsFunctionModeWithPrototype(function_mode));
751   map->set_is_callable();
752   Map::SetPrototype(map, empty_function);
753   return map;
754 }
755 
756 
CreateStrictModeFunctionMaps(Handle<JSFunction> empty)757 void Genesis::CreateStrictModeFunctionMaps(Handle<JSFunction> empty) {
758   // Allocate map for the prototype-less strict mode instances.
759   Handle<Map> strict_function_without_prototype_map =
760       CreateStrictFunctionMap(FUNCTION_WITHOUT_PROTOTYPE, empty);
761   native_context()->set_strict_function_without_prototype_map(
762       *strict_function_without_prototype_map);
763 
764   // Allocate map for the strict mode functions. This map is temporary, used
765   // only for processing of builtins.
766   // Later the map is replaced with writable prototype map, allocated below.
767   Handle<Map> strict_function_map =
768       CreateStrictFunctionMap(FUNCTION_WITH_READONLY_PROTOTYPE, empty);
769   native_context()->set_strict_function_map(*strict_function_map);
770 
771   // The final map for the strict mode functions. Writeable prototype.
772   // This map is installed in MakeFunctionInstancePrototypeWritable.
773   strict_function_map_writable_prototype_ =
774       CreateStrictFunctionMap(FUNCTION_WITH_WRITEABLE_PROTOTYPE, empty);
775 
776   // Now that the strict mode function map is available, set up the
777   // restricted "arguments" and "caller" getters.
778   AddRestrictedFunctionProperties(empty);
779 }
780 
CreateIteratorMaps(Handle<JSFunction> empty)781 void Genesis::CreateIteratorMaps(Handle<JSFunction> empty) {
782   // Create iterator-related meta-objects.
783   Handle<JSObject> iterator_prototype =
784       factory()->NewJSObject(isolate()->object_function(), TENURED);
785   Handle<JSObject> generator_object_prototype =
786       factory()->NewJSObject(isolate()->object_function(), TENURED);
787   native_context()->set_initial_generator_prototype(
788       *generator_object_prototype);
789   SetObjectPrototype(generator_object_prototype, iterator_prototype);
790   Handle<JSObject> generator_function_prototype =
791       factory()->NewJSObject(isolate()->object_function(), TENURED);
792   SetObjectPrototype(generator_function_prototype, empty);
793 
794   JSObject::AddProperty(
795       generator_function_prototype, factory()->to_string_tag_symbol(),
796       factory()->NewStringFromAsciiChecked("GeneratorFunction"),
797       static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
798   JSObject::AddProperty(generator_function_prototype,
799                         factory()->prototype_string(),
800                         generator_object_prototype,
801                         static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
802 
803   JSObject::AddProperty(generator_object_prototype,
804                         factory()->constructor_string(),
805                         generator_function_prototype,
806                         static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
807   JSObject::AddProperty(generator_object_prototype,
808                         factory()->to_string_tag_symbol(),
809                         factory()->NewStringFromAsciiChecked("Generator"),
810                         static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
811   SimpleInstallFunction(generator_object_prototype, "next",
812                         Builtins::kGeneratorPrototypeNext, 1, true);
813   SimpleInstallFunction(generator_object_prototype, "return",
814                         Builtins::kGeneratorPrototypeReturn, 1, true);
815   SimpleInstallFunction(generator_object_prototype, "throw",
816                         Builtins::kGeneratorPrototypeThrow, 1, true);
817 
818   // Create maps for generator functions and their prototypes.  Store those
819   // maps in the native context. The "prototype" property descriptor is
820   // writable, non-enumerable, and non-configurable (as per ES6 draft
821   // 04-14-15, section 25.2.4.3).
822   Handle<Map> strict_function_map(strict_function_map_writable_prototype_);
823   // Generator functions do not have "caller" or "arguments" accessors.
824   Handle<Map> sloppy_generator_function_map =
825       Map::Copy(strict_function_map, "SloppyGeneratorFunction");
826   sloppy_generator_function_map->set_is_constructor(false);
827   Map::SetPrototype(sloppy_generator_function_map,
828                     generator_function_prototype);
829   native_context()->set_sloppy_generator_function_map(
830       *sloppy_generator_function_map);
831 
832   Handle<Map> strict_generator_function_map =
833       Map::Copy(strict_function_map, "StrictGeneratorFunction");
834   strict_generator_function_map->set_is_constructor(false);
835   Map::SetPrototype(strict_generator_function_map,
836                     generator_function_prototype);
837   native_context()->set_strict_generator_function_map(
838       *strict_generator_function_map);
839 
840   Handle<JSFunction> object_function(native_context()->object_function());
841   Handle<Map> generator_object_prototype_map = Map::Create(isolate(), 0);
842   Map::SetPrototype(generator_object_prototype_map, generator_object_prototype);
843   native_context()->set_generator_object_prototype_map(
844       *generator_object_prototype_map);
845 }
846 
CreateAsyncFunctionMaps(Handle<JSFunction> empty)847 void Genesis::CreateAsyncFunctionMaps(Handle<JSFunction> empty) {
848   // %AsyncFunctionPrototype% intrinsic
849   Handle<JSObject> async_function_prototype =
850       factory()->NewJSObject(isolate()->object_function(), TENURED);
851   SetObjectPrototype(async_function_prototype, empty);
852 
853   JSObject::AddProperty(async_function_prototype,
854                         factory()->to_string_tag_symbol(),
855                         factory()->NewStringFromAsciiChecked("AsyncFunction"),
856                         static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
857 
858   Handle<Map> strict_function_map(
859       native_context()->strict_function_without_prototype_map());
860   Handle<Map> sloppy_async_function_map =
861       Map::Copy(strict_function_map, "SloppyAsyncFunction");
862   sloppy_async_function_map->set_is_constructor(false);
863   Map::SetPrototype(sloppy_async_function_map, async_function_prototype);
864   native_context()->set_sloppy_async_function_map(*sloppy_async_function_map);
865 
866   Handle<Map> strict_async_function_map =
867       Map::Copy(strict_function_map, "StrictAsyncFunction");
868   strict_async_function_map->set_is_constructor(false);
869   Map::SetPrototype(strict_async_function_map, async_function_prototype);
870   native_context()->set_strict_async_function_map(*strict_async_function_map);
871 }
872 
CreateJSProxyMaps()873 void Genesis::CreateJSProxyMaps() {
874   // Allocate the different maps for all Proxy types.
875   // Next to the default proxy, we need maps indicating callable and
876   // constructable proxies.
877   Handle<Map> proxy_function_map =
878       Map::Copy(isolate()->sloppy_function_without_prototype_map(), "Proxy");
879   proxy_function_map->set_is_constructor(true);
880   native_context()->set_proxy_function_map(*proxy_function_map);
881 
882   Handle<Map> proxy_map =
883       factory()->NewMap(JS_PROXY_TYPE, JSProxy::kSize, FAST_ELEMENTS);
884   proxy_map->set_dictionary_map(true);
885   native_context()->set_proxy_map(*proxy_map);
886 
887   Handle<Map> proxy_callable_map = Map::Copy(proxy_map, "callable Proxy");
888   proxy_callable_map->set_is_callable();
889   native_context()->set_proxy_callable_map(*proxy_callable_map);
890   proxy_callable_map->SetConstructor(native_context()->function_function());
891 
892   Handle<Map> proxy_constructor_map =
893       Map::Copy(proxy_callable_map, "constructor Proxy");
894   proxy_constructor_map->set_is_constructor(true);
895   native_context()->set_proxy_constructor_map(*proxy_constructor_map);
896 }
897 
ReplaceAccessors(Handle<Map> map,Handle<String> name,PropertyAttributes attributes,Handle<AccessorPair> accessor_pair)898 static void ReplaceAccessors(Handle<Map> map,
899                              Handle<String> name,
900                              PropertyAttributes attributes,
901                              Handle<AccessorPair> accessor_pair) {
902   DescriptorArray* descriptors = map->instance_descriptors();
903   int idx = descriptors->SearchWithCache(map->GetIsolate(), *name, *map);
904   AccessorConstantDescriptor descriptor(name, accessor_pair, attributes);
905   descriptors->Replace(idx, &descriptor);
906 }
907 
AddRestrictedFunctionProperties(Handle<JSFunction> empty)908 void Genesis::AddRestrictedFunctionProperties(Handle<JSFunction> empty) {
909   PropertyAttributes rw_attribs = static_cast<PropertyAttributes>(DONT_ENUM);
910   Handle<JSFunction> thrower = GetRestrictedFunctionPropertiesThrower();
911   Handle<AccessorPair> accessors = factory()->NewAccessorPair();
912   accessors->set_getter(*thrower);
913   accessors->set_setter(*thrower);
914 
915   Handle<Map> map(empty->map());
916   ReplaceAccessors(map, factory()->arguments_string(), rw_attribs, accessors);
917   ReplaceAccessors(map, factory()->caller_string(), rw_attribs, accessors);
918 }
919 
920 
AddToWeakNativeContextList(Context * context)921 static void AddToWeakNativeContextList(Context* context) {
922   DCHECK(context->IsNativeContext());
923   Isolate* isolate = context->GetIsolate();
924   Heap* heap = isolate->heap();
925 #ifdef DEBUG
926   { // NOLINT
927     DCHECK(context->next_context_link()->IsUndefined(isolate));
928     // Check that context is not in the list yet.
929     for (Object* current = heap->native_contexts_list();
930          !current->IsUndefined(isolate);
931          current = Context::cast(current)->next_context_link()) {
932       DCHECK(current != context);
933     }
934   }
935 #endif
936   context->set(Context::NEXT_CONTEXT_LINK, heap->native_contexts_list(),
937                UPDATE_WEAK_WRITE_BARRIER);
938   heap->set_native_contexts_list(context);
939 }
940 
941 
CreateRoots()942 void Genesis::CreateRoots() {
943   // Allocate the native context FixedArray first and then patch the
944   // closure and extension object later (we need the empty function
945   // and the global object, but in order to create those, we need the
946   // native context).
947   native_context_ = factory()->NewNativeContext();
948   AddToWeakNativeContextList(*native_context());
949   isolate()->set_context(*native_context());
950 
951   // Allocate the message listeners object.
952   {
953     v8::NeanderArray listeners(isolate());
954     native_context()->set_message_listeners(*listeners.value());
955   }
956 }
957 
958 
InstallGlobalThisBinding()959 void Genesis::InstallGlobalThisBinding() {
960   Handle<ScriptContextTable> script_contexts(
961       native_context()->script_context_table());
962   Handle<ScopeInfo> scope_info = ScopeInfo::CreateGlobalThisBinding(isolate());
963   Handle<JSFunction> closure(native_context()->closure());
964   Handle<Context> context = factory()->NewScriptContext(closure, scope_info);
965 
966   // Go ahead and hook it up while we're at it.
967   int slot = scope_info->ReceiverContextSlotIndex();
968   DCHECK_EQ(slot, Context::MIN_CONTEXT_SLOTS);
969   context->set(slot, native_context()->global_proxy());
970 
971   Handle<ScriptContextTable> new_script_contexts =
972       ScriptContextTable::Extend(script_contexts, context);
973   native_context()->set_script_context_table(*new_script_contexts);
974 }
975 
976 
CreateNewGlobals(v8::Local<v8::ObjectTemplate> global_proxy_template,Handle<JSGlobalProxy> global_proxy)977 Handle<JSGlobalObject> Genesis::CreateNewGlobals(
978     v8::Local<v8::ObjectTemplate> global_proxy_template,
979     Handle<JSGlobalProxy> global_proxy) {
980   // The argument global_proxy_template aka data is an ObjectTemplateInfo.
981   // It has a constructor pointer that points at global_constructor which is a
982   // FunctionTemplateInfo.
983   // The global_proxy_constructor is used to (re)initialize the
984   // global_proxy. The global_proxy_constructor also has a prototype_template
985   // pointer that points at js_global_object_template which is an
986   // ObjectTemplateInfo.
987   // That in turn has a constructor pointer that points at
988   // js_global_object_constructor which is a FunctionTemplateInfo.
989   // js_global_object_constructor is used to make js_global_object_function
990   // js_global_object_function is used to make the new global_object.
991   //
992   // --- G l o b a l ---
993   // Step 1: Create a fresh JSGlobalObject.
994   Handle<JSFunction> js_global_object_function;
995   Handle<ObjectTemplateInfo> js_global_object_template;
996   if (!global_proxy_template.IsEmpty()) {
997     // Get prototype template of the global_proxy_template.
998     Handle<ObjectTemplateInfo> data =
999         v8::Utils::OpenHandle(*global_proxy_template);
1000     Handle<FunctionTemplateInfo> global_constructor =
1001         Handle<FunctionTemplateInfo>(
1002             FunctionTemplateInfo::cast(data->constructor()));
1003     Handle<Object> proto_template(global_constructor->prototype_template(),
1004                                   isolate());
1005     if (!proto_template->IsUndefined(isolate())) {
1006       js_global_object_template =
1007           Handle<ObjectTemplateInfo>::cast(proto_template);
1008     }
1009   }
1010 
1011   if (js_global_object_template.is_null()) {
1012     Handle<String> name = Handle<String>(heap()->empty_string());
1013     Handle<Code> code = isolate()->builtins()->Illegal();
1014     Handle<JSObject> prototype =
1015         factory()->NewFunctionPrototype(isolate()->object_function());
1016     js_global_object_function = factory()->NewFunction(
1017         name, code, prototype, JS_GLOBAL_OBJECT_TYPE, JSGlobalObject::kSize);
1018 #ifdef DEBUG
1019     LookupIterator it(prototype, factory()->constructor_string(),
1020                       LookupIterator::OWN_SKIP_INTERCEPTOR);
1021     Handle<Object> value = Object::GetProperty(&it).ToHandleChecked();
1022     DCHECK(it.IsFound());
1023     DCHECK_EQ(*isolate()->object_function(), *value);
1024 #endif
1025   } else {
1026     Handle<FunctionTemplateInfo> js_global_object_constructor(
1027         FunctionTemplateInfo::cast(js_global_object_template->constructor()));
1028     js_global_object_function = ApiNatives::CreateApiFunction(
1029         isolate(), js_global_object_constructor, factory()->the_hole_value(),
1030         ApiNatives::GlobalObjectType);
1031   }
1032 
1033   js_global_object_function->initial_map()->set_is_prototype_map(true);
1034   js_global_object_function->initial_map()->set_dictionary_map(true);
1035   Handle<JSGlobalObject> global_object =
1036       factory()->NewJSGlobalObject(js_global_object_function);
1037 
1038   // Step 2: (re)initialize the global proxy object.
1039   Handle<JSFunction> global_proxy_function;
1040   if (global_proxy_template.IsEmpty()) {
1041     Handle<String> name = Handle<String>(heap()->empty_string());
1042     Handle<Code> code = isolate()->builtins()->Illegal();
1043     global_proxy_function = factory()->NewFunction(
1044         name, code, JS_GLOBAL_PROXY_TYPE, JSGlobalProxy::kSize);
1045   } else {
1046     Handle<ObjectTemplateInfo> data =
1047         v8::Utils::OpenHandle(*global_proxy_template);
1048     Handle<FunctionTemplateInfo> global_constructor(
1049             FunctionTemplateInfo::cast(data->constructor()));
1050     global_proxy_function = ApiNatives::CreateApiFunction(
1051         isolate(), global_constructor, factory()->the_hole_value(),
1052         ApiNatives::GlobalProxyType);
1053   }
1054   Handle<String> global_name = factory()->global_string();
1055   global_proxy_function->shared()->set_instance_class_name(*global_name);
1056   global_proxy_function->initial_map()->set_is_access_check_needed(true);
1057   global_proxy_function->initial_map()->set_has_hidden_prototype(true);
1058 
1059   // Set global_proxy.__proto__ to js_global after ConfigureGlobalObjects
1060   // Return the global proxy.
1061 
1062   factory()->ReinitializeJSGlobalProxy(global_proxy, global_proxy_function);
1063   return global_object;
1064 }
1065 
1066 
HookUpGlobalProxy(Handle<JSGlobalObject> global_object,Handle<JSGlobalProxy> global_proxy)1067 void Genesis::HookUpGlobalProxy(Handle<JSGlobalObject> global_object,
1068                                 Handle<JSGlobalProxy> global_proxy) {
1069   // Set the native context for the global object.
1070   global_object->set_native_context(*native_context());
1071   global_object->set_global_proxy(*global_proxy);
1072   global_proxy->set_native_context(*native_context());
1073   // If we deserialized the context, the global proxy is already
1074   // correctly set up. Otherwise it's undefined.
1075   DCHECK(native_context()
1076              ->get(Context::GLOBAL_PROXY_INDEX)
1077              ->IsUndefined(isolate()) ||
1078          native_context()->global_proxy() == *global_proxy);
1079   native_context()->set_global_proxy(*global_proxy);
1080 }
1081 
1082 
HookUpGlobalObject(Handle<JSGlobalObject> global_object)1083 void Genesis::HookUpGlobalObject(Handle<JSGlobalObject> global_object) {
1084   Handle<JSGlobalObject> global_object_from_snapshot(
1085       JSGlobalObject::cast(native_context()->extension()));
1086   native_context()->set_extension(*global_object);
1087   native_context()->set_security_token(*global_object);
1088 
1089   TransferNamedProperties(global_object_from_snapshot, global_object);
1090   TransferIndexedProperties(global_object_from_snapshot, global_object);
1091 }
1092 
InstallWithIntrinsicDefaultProto(Isolate * isolate,Handle<JSFunction> function,int context_index)1093 static void InstallWithIntrinsicDefaultProto(Isolate* isolate,
1094                                              Handle<JSFunction> function,
1095                                              int context_index) {
1096   Handle<Smi> index(Smi::FromInt(context_index), isolate);
1097   JSObject::AddProperty(
1098       function, isolate->factory()->native_context_index_symbol(), index, NONE);
1099   isolate->native_context()->set(context_index, *function);
1100 }
1101 
1102 
1103 // This is only called if we are not using snapshots.  The equivalent
1104 // work in the snapshot case is done in HookUpGlobalObject.
InitializeGlobal(Handle<JSGlobalObject> global_object,Handle<JSFunction> empty_function,GlobalContextType context_type)1105 void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
1106                                Handle<JSFunction> empty_function,
1107                                GlobalContextType context_type) {
1108   // --- N a t i v e   C o n t e x t ---
1109   // Use the empty function as closure (no scope info).
1110   native_context()->set_closure(*empty_function);
1111   native_context()->set_previous(NULL);
1112   // Set extension and global object.
1113   native_context()->set_extension(*global_object);
1114   // Security setup: Set the security token of the native context to the global
1115   // object. This makes the security check between two different contexts fail
1116   // by default even in case of global object reinitialization.
1117   native_context()->set_security_token(*global_object);
1118 
1119   Isolate* isolate = global_object->GetIsolate();
1120   Factory* factory = isolate->factory();
1121 
1122   Handle<ScriptContextTable> script_context_table =
1123       factory->NewScriptContextTable();
1124   native_context()->set_script_context_table(*script_context_table);
1125   InstallGlobalThisBinding();
1126 
1127   {  // --- O b j e c t ---
1128     Handle<String> object_name = factory->Object_string();
1129     Handle<JSFunction> object_function = isolate->object_function();
1130     JSObject::AddProperty(global_object, object_name, object_function,
1131                           DONT_ENUM);
1132 
1133     SimpleInstallFunction(object_function, factory->assign_string(),
1134                           Builtins::kObjectAssign, 2, false);
1135     SimpleInstallFunction(object_function, factory->create_string(),
1136                           Builtins::kObjectCreate, 2, false);
1137     SimpleInstallFunction(object_function, "getOwnPropertyDescriptor",
1138                           Builtins::kObjectGetOwnPropertyDescriptor, 2, false);
1139     SimpleInstallFunction(object_function, "getOwnPropertyNames",
1140                           Builtins::kObjectGetOwnPropertyNames, 1, false);
1141     SimpleInstallFunction(object_function, "getOwnPropertySymbols",
1142                           Builtins::kObjectGetOwnPropertySymbols, 1, false);
1143     SimpleInstallFunction(object_function, "is",
1144                           Builtins::kObjectIs, 2, true);
1145     SimpleInstallFunction(object_function, "preventExtensions",
1146                           Builtins::kObjectPreventExtensions, 1, false);
1147     SimpleInstallFunction(object_function, "seal",
1148                           Builtins::kObjectSeal, 1, false);
1149 
1150     Handle<JSFunction> object_define_properties = SimpleInstallFunction(
1151         object_function, "defineProperties",
1152         Builtins::kObjectDefineProperties, 2, true);
1153     native_context()->set_object_define_properties(*object_define_properties);
1154 
1155     Handle<JSFunction> object_define_property = SimpleInstallFunction(
1156         object_function, factory->defineProperty_string(),
1157         Builtins::kObjectDefineProperty, 3, true);
1158     native_context()->set_object_define_property(*object_define_property);
1159 
1160     Handle<JSFunction> object_freeze = SimpleInstallFunction(
1161         object_function, "freeze", Builtins::kObjectFreeze, 1, false);
1162     native_context()->set_object_freeze(*object_freeze);
1163 
1164     Handle<JSFunction> object_get_prototype_of = SimpleInstallFunction(
1165         object_function, "getPrototypeOf", Builtins::kObjectGetPrototypeOf,
1166         1, false);
1167     native_context()->set_object_get_prototype_of(*object_get_prototype_of);
1168 
1169     Handle<JSFunction> object_is_extensible = SimpleInstallFunction(
1170         object_function, "isExtensible", Builtins::kObjectIsExtensible,
1171         1, false);
1172     native_context()->set_object_is_extensible(*object_is_extensible);
1173 
1174     Handle<JSFunction> object_is_frozen = SimpleInstallFunction(
1175         object_function, "isFrozen", Builtins::kObjectIsFrozen, 1, false);
1176     native_context()->set_object_is_frozen(*object_is_frozen);
1177 
1178     Handle<JSFunction> object_is_sealed = SimpleInstallFunction(
1179         object_function, "isSealed", Builtins::kObjectIsSealed, 1, false);
1180     native_context()->set_object_is_sealed(*object_is_sealed);
1181 
1182     Handle<JSFunction> object_keys = SimpleInstallFunction(
1183         object_function, "keys", Builtins::kObjectKeys, 1, false);
1184     native_context()->set_object_keys(*object_keys);
1185 
1186     SimpleInstallFunction(isolate->initial_object_prototype(),
1187                           "__defineGetter__", Builtins::kObjectDefineGetter, 2,
1188                           true);
1189     SimpleInstallFunction(isolate->initial_object_prototype(),
1190                           "__defineSetter__", Builtins::kObjectDefineSetter, 2,
1191                           true);
1192     SimpleInstallFunction(isolate->initial_object_prototype(), "hasOwnProperty",
1193                           Builtins::kObjectHasOwnProperty, 1, true);
1194     SimpleInstallFunction(isolate->initial_object_prototype(),
1195                           "__lookupGetter__", Builtins::kObjectLookupGetter, 1,
1196                           true);
1197     SimpleInstallFunction(isolate->initial_object_prototype(),
1198                           "__lookupSetter__", Builtins::kObjectLookupSetter, 1,
1199                           true);
1200   }
1201 
1202   Handle<JSObject> global(native_context()->global_object());
1203 
1204   {  // --- F u n c t i o n ---
1205     Handle<JSFunction> prototype = empty_function;
1206     Handle<JSFunction> function_fun =
1207         InstallFunction(global, "Function", JS_FUNCTION_TYPE, JSFunction::kSize,
1208                         prototype, Builtins::kFunctionConstructor);
1209     function_fun->set_prototype_or_initial_map(
1210         *sloppy_function_map_writable_prototype_);
1211     function_fun->shared()->DontAdaptArguments();
1212     function_fun->shared()->set_construct_stub(
1213         *isolate->builtins()->FunctionConstructor());
1214     function_fun->shared()->set_length(1);
1215     InstallWithIntrinsicDefaultProto(isolate, function_fun,
1216                                      Context::FUNCTION_FUNCTION_INDEX);
1217 
1218     // Setup the methods on the %FunctionPrototype%.
1219     SimpleInstallFunction(prototype, factory->apply_string(),
1220                           Builtins::kFunctionPrototypeApply, 2, false);
1221 
1222     FastFunctionBindStub bind_stub(isolate);
1223     Handle<JSFunction> bind_function = factory->NewFunctionWithoutPrototype(
1224         factory->bind_string(), bind_stub.GetCode(), false);
1225     bind_function->shared()->DontAdaptArguments();
1226     bind_function->shared()->set_length(1);
1227     InstallFunction(prototype, bind_function, factory->bind_string(),
1228                     DONT_ENUM);
1229 
1230     SimpleInstallFunction(prototype, factory->call_string(),
1231                           Builtins::kFunctionPrototypeCall, 1, false);
1232     SimpleInstallFunction(prototype, factory->toString_string(),
1233                           Builtins::kFunctionPrototypeToString, 0, false);
1234 
1235     // Install the @@hasInstance function.
1236     Handle<JSFunction> has_instance = InstallFunction(
1237         prototype, factory->has_instance_symbol(), JS_OBJECT_TYPE,
1238         JSObject::kHeaderSize, MaybeHandle<JSObject>(),
1239         Builtins::kFunctionPrototypeHasInstance,
1240         static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY));
1241 
1242     // Set the expected parameters for @@hasInstance to 1; required by builtin.
1243     has_instance->shared()->set_internal_formal_parameter_count(1);
1244 
1245     // Set the length for the function to satisfy ECMA-262.
1246     has_instance->shared()->set_length(1);
1247 
1248     // Install the "constructor" property on the %FunctionPrototype%.
1249     JSObject::AddProperty(prototype, factory->constructor_string(),
1250                           function_fun, DONT_ENUM);
1251 
1252     sloppy_function_map_writable_prototype_->SetConstructor(*function_fun);
1253     strict_function_map_writable_prototype_->SetConstructor(*function_fun);
1254   }
1255 
1256   {  // --- A r r a y ---
1257     Handle<JSFunction> array_function =
1258         InstallFunction(global, "Array", JS_ARRAY_TYPE, JSArray::kSize,
1259                         isolate->initial_object_prototype(),
1260                         Builtins::kArrayCode);
1261     array_function->shared()->DontAdaptArguments();
1262     array_function->shared()->set_builtin_function_id(kArrayCode);
1263 
1264     // This seems a bit hackish, but we need to make sure Array.length
1265     // is 1.
1266     array_function->shared()->set_length(1);
1267 
1268     Handle<Map> initial_map(array_function->initial_map());
1269 
1270     // This assert protects an optimization in
1271     // HGraphBuilder::JSArrayBuilder::EmitMapCode()
1272     DCHECK(initial_map->elements_kind() == GetInitialFastElementsKind());
1273     Map::EnsureDescriptorSlack(initial_map, 1);
1274 
1275     PropertyAttributes attribs = static_cast<PropertyAttributes>(
1276         DONT_ENUM | DONT_DELETE);
1277 
1278     Handle<AccessorInfo> array_length =
1279         Accessors::ArrayLengthInfo(isolate, attribs);
1280     {  // Add length.
1281       AccessorConstantDescriptor d(
1282           Handle<Name>(Name::cast(array_length->name())), array_length,
1283           attribs);
1284       initial_map->AppendDescriptor(&d);
1285     }
1286 
1287     InstallWithIntrinsicDefaultProto(isolate, array_function,
1288                                      Context::ARRAY_FUNCTION_INDEX);
1289 
1290     // Cache the array maps, needed by ArrayConstructorStub
1291     CacheInitialJSArrayMaps(native_context(), initial_map);
1292     ArrayConstructorStub array_constructor_stub(isolate);
1293     Handle<Code> code = array_constructor_stub.GetCode();
1294     array_function->shared()->set_construct_stub(*code);
1295 
1296     Handle<JSFunction> is_arraylike = SimpleInstallFunction(
1297         array_function, isolate->factory()->InternalizeUtf8String("isArray"),
1298         Builtins::kArrayIsArray, 1, true);
1299     native_context()->set_is_arraylike(*is_arraylike);
1300   }
1301 
1302   {  // --- N u m b e r ---
1303     Handle<JSFunction> number_fun = InstallFunction(
1304         global, "Number", JS_VALUE_TYPE, JSValue::kSize,
1305         isolate->initial_object_prototype(), Builtins::kNumberConstructor);
1306     number_fun->shared()->DontAdaptArguments();
1307     number_fun->shared()->set_construct_stub(
1308         *isolate->builtins()->NumberConstructor_ConstructStub());
1309     number_fun->shared()->set_length(1);
1310     InstallWithIntrinsicDefaultProto(isolate, number_fun,
1311                                      Context::NUMBER_FUNCTION_INDEX);
1312   }
1313 
1314   {  // --- B o o l e a n ---
1315     Handle<JSFunction> boolean_fun =
1316         InstallFunction(global, "Boolean", JS_VALUE_TYPE, JSValue::kSize,
1317                         isolate->initial_object_prototype(),
1318                         Builtins::kBooleanConstructor);
1319     boolean_fun->shared()->DontAdaptArguments();
1320     boolean_fun->shared()->set_construct_stub(
1321         *isolate->builtins()->BooleanConstructor_ConstructStub());
1322     boolean_fun->shared()->set_length(1);
1323     InstallWithIntrinsicDefaultProto(isolate, boolean_fun,
1324                                      Context::BOOLEAN_FUNCTION_INDEX);
1325 
1326     // Create the %BooleanPrototype%
1327     Handle<JSValue> prototype =
1328         Handle<JSValue>::cast(factory->NewJSObject(boolean_fun, TENURED));
1329     prototype->set_value(isolate->heap()->false_value());
1330     Accessors::FunctionSetPrototype(boolean_fun, prototype).Assert();
1331 
1332     // Install the "constructor" property on the {prototype}.
1333     JSObject::AddProperty(prototype, factory->constructor_string(), boolean_fun,
1334                           DONT_ENUM);
1335 
1336     // Install the Boolean.prototype methods.
1337     SimpleInstallFunction(prototype, "toString",
1338                           Builtins::kBooleanPrototypeToString, 0, false);
1339     SimpleInstallFunction(prototype, "valueOf",
1340                           Builtins::kBooleanPrototypeValueOf, 0, false);
1341   }
1342 
1343   {  // --- S t r i n g ---
1344     Handle<JSFunction> string_fun = InstallFunction(
1345         global, "String", JS_VALUE_TYPE, JSValue::kSize,
1346         isolate->initial_object_prototype(), Builtins::kStringConstructor);
1347     string_fun->shared()->set_construct_stub(
1348         *isolate->builtins()->StringConstructor_ConstructStub());
1349     string_fun->shared()->DontAdaptArguments();
1350     string_fun->shared()->set_length(1);
1351     InstallWithIntrinsicDefaultProto(isolate, string_fun,
1352                                      Context::STRING_FUNCTION_INDEX);
1353 
1354     Handle<Map> string_map =
1355         Handle<Map>(native_context()->string_function()->initial_map());
1356     string_map->set_elements_kind(FAST_STRING_WRAPPER_ELEMENTS);
1357     Map::EnsureDescriptorSlack(string_map, 1);
1358 
1359     PropertyAttributes attribs = static_cast<PropertyAttributes>(
1360         DONT_ENUM | DONT_DELETE | READ_ONLY);
1361     Handle<AccessorInfo> string_length(
1362         Accessors::StringLengthInfo(isolate, attribs));
1363 
1364     {  // Add length.
1365       AccessorConstantDescriptor d(factory->length_string(), string_length,
1366                                    attribs);
1367       string_map->AppendDescriptor(&d);
1368     }
1369 
1370     // Install the String.fromCharCode function.
1371     SimpleInstallFunction(string_fun, "fromCharCode",
1372                           Builtins::kStringFromCharCode, 1, true);
1373 
1374     // Install the String.fromCodePoint function.
1375     SimpleInstallFunction(string_fun, "fromCodePoint",
1376                           Builtins::kStringFromCodePoint, 1, false);
1377 
1378     // Create the %StringPrototype%
1379     Handle<JSValue> prototype =
1380         Handle<JSValue>::cast(factory->NewJSObject(string_fun, TENURED));
1381     prototype->set_value(isolate->heap()->empty_string());
1382     Accessors::FunctionSetPrototype(string_fun, prototype).Assert();
1383 
1384     // Install the "constructor" property on the {prototype}.
1385     JSObject::AddProperty(prototype, factory->constructor_string(), string_fun,
1386                           DONT_ENUM);
1387 
1388     // Install the String.prototype methods.
1389     SimpleInstallFunction(prototype, "charAt", Builtins::kStringPrototypeCharAt,
1390                           1, true);
1391     SimpleInstallFunction(prototype, "charCodeAt",
1392                           Builtins::kStringPrototypeCharCodeAt, 1, true);
1393     SimpleInstallFunction(prototype, "trim", Builtins::kStringPrototypeTrim, 0,
1394                           false);
1395     SimpleInstallFunction(prototype, "trimLeft",
1396                           Builtins::kStringPrototypeTrimLeft, 0, false);
1397     SimpleInstallFunction(prototype, "trimRight",
1398                           Builtins::kStringPrototypeTrimRight, 0, false);
1399   }
1400 
1401   {
1402     // --- S y m b o l ---
1403     Handle<JSObject> prototype =
1404         factory->NewJSObject(isolate->object_function(), TENURED);
1405     Handle<JSFunction> symbol_fun =
1406         InstallFunction(global, "Symbol", JS_VALUE_TYPE, JSValue::kSize,
1407                         prototype, Builtins::kSymbolConstructor);
1408     symbol_fun->shared()->set_construct_stub(
1409         *isolate->builtins()->SymbolConstructor_ConstructStub());
1410     symbol_fun->shared()->set_length(0);
1411     symbol_fun->shared()->DontAdaptArguments();
1412     native_context()->set_symbol_function(*symbol_fun);
1413 
1414     // Install the "constructor" property on the {prototype}.
1415     JSObject::AddProperty(prototype, factory->constructor_string(), symbol_fun,
1416                           DONT_ENUM);
1417   }
1418 
1419   {  // --- D a t e ---
1420     // Builtin functions for Date.prototype.
1421     Handle<JSObject> prototype =
1422         factory->NewJSObject(isolate->object_function(), TENURED);
1423     Handle<JSFunction> date_fun =
1424         InstallFunction(global, "Date", JS_DATE_TYPE, JSDate::kSize, prototype,
1425                         Builtins::kDateConstructor);
1426     InstallWithIntrinsicDefaultProto(isolate, date_fun,
1427                                      Context::DATE_FUNCTION_INDEX);
1428     date_fun->shared()->set_construct_stub(
1429         *isolate->builtins()->DateConstructor_ConstructStub());
1430     date_fun->shared()->set_length(7);
1431     date_fun->shared()->DontAdaptArguments();
1432 
1433     // Install the Date.now, Date.parse and Date.UTC functions.
1434     SimpleInstallFunction(date_fun, "now", Builtins::kDateNow, 0, false);
1435     SimpleInstallFunction(date_fun, "parse", Builtins::kDateParse, 1, false);
1436     SimpleInstallFunction(date_fun, "UTC", Builtins::kDateUTC, 7, false);
1437 
1438     // Install the "constructor" property on the {prototype}.
1439     JSObject::AddProperty(prototype, factory->constructor_string(), date_fun,
1440                           DONT_ENUM);
1441 
1442     // Install the Date.prototype methods.
1443     SimpleInstallFunction(prototype, "toString",
1444                           Builtins::kDatePrototypeToString, 0, false);
1445     SimpleInstallFunction(prototype, "toDateString",
1446                           Builtins::kDatePrototypeToDateString, 0, false);
1447     SimpleInstallFunction(prototype, "toTimeString",
1448                           Builtins::kDatePrototypeToTimeString, 0, false);
1449     SimpleInstallFunction(prototype, "toISOString",
1450                           Builtins::kDatePrototypeToISOString, 0, false);
1451     Handle<JSFunction> to_utc_string =
1452         SimpleInstallFunction(prototype, "toUTCString",
1453                               Builtins::kDatePrototypeToUTCString, 0, false);
1454     InstallFunction(prototype, to_utc_string,
1455                     factory->InternalizeUtf8String("toGMTString"), DONT_ENUM);
1456     SimpleInstallFunction(prototype, "getDate", Builtins::kDatePrototypeGetDate,
1457                           0, true);
1458     SimpleInstallFunction(prototype, "setDate", Builtins::kDatePrototypeSetDate,
1459                           1, false);
1460     SimpleInstallFunction(prototype, "getDay", Builtins::kDatePrototypeGetDay,
1461                           0, true);
1462     SimpleInstallFunction(prototype, "getFullYear",
1463                           Builtins::kDatePrototypeGetFullYear, 0, true);
1464     SimpleInstallFunction(prototype, "setFullYear",
1465                           Builtins::kDatePrototypeSetFullYear, 3, false);
1466     SimpleInstallFunction(prototype, "getHours",
1467                           Builtins::kDatePrototypeGetHours, 0, true);
1468     SimpleInstallFunction(prototype, "setHours",
1469                           Builtins::kDatePrototypeSetHours, 4, false);
1470     SimpleInstallFunction(prototype, "getMilliseconds",
1471                           Builtins::kDatePrototypeGetMilliseconds, 0, true);
1472     SimpleInstallFunction(prototype, "setMilliseconds",
1473                           Builtins::kDatePrototypeSetMilliseconds, 1, false);
1474     SimpleInstallFunction(prototype, "getMinutes",
1475                           Builtins::kDatePrototypeGetMinutes, 0, true);
1476     SimpleInstallFunction(prototype, "setMinutes",
1477                           Builtins::kDatePrototypeSetMinutes, 3, false);
1478     SimpleInstallFunction(prototype, "getMonth",
1479                           Builtins::kDatePrototypeGetMonth, 0, true);
1480     SimpleInstallFunction(prototype, "setMonth",
1481                           Builtins::kDatePrototypeSetMonth, 2, false);
1482     SimpleInstallFunction(prototype, "getSeconds",
1483                           Builtins::kDatePrototypeGetSeconds, 0, true);
1484     SimpleInstallFunction(prototype, "setSeconds",
1485                           Builtins::kDatePrototypeSetSeconds, 2, false);
1486     SimpleInstallFunction(prototype, "getTime", Builtins::kDatePrototypeGetTime,
1487                           0, true);
1488     SimpleInstallFunction(prototype, "setTime", Builtins::kDatePrototypeSetTime,
1489                           1, false);
1490     SimpleInstallFunction(prototype, "getTimezoneOffset",
1491                           Builtins::kDatePrototypeGetTimezoneOffset, 0, true);
1492     SimpleInstallFunction(prototype, "getUTCDate",
1493                           Builtins::kDatePrototypeGetUTCDate, 0, true);
1494     SimpleInstallFunction(prototype, "setUTCDate",
1495                           Builtins::kDatePrototypeSetUTCDate, 1, false);
1496     SimpleInstallFunction(prototype, "getUTCDay",
1497                           Builtins::kDatePrototypeGetUTCDay, 0, true);
1498     SimpleInstallFunction(prototype, "getUTCFullYear",
1499                           Builtins::kDatePrototypeGetUTCFullYear, 0, true);
1500     SimpleInstallFunction(prototype, "setUTCFullYear",
1501                           Builtins::kDatePrototypeSetUTCFullYear, 3, false);
1502     SimpleInstallFunction(prototype, "getUTCHours",
1503                           Builtins::kDatePrototypeGetUTCHours, 0, true);
1504     SimpleInstallFunction(prototype, "setUTCHours",
1505                           Builtins::kDatePrototypeSetUTCHours, 4, false);
1506     SimpleInstallFunction(prototype, "getUTCMilliseconds",
1507                           Builtins::kDatePrototypeGetUTCMilliseconds, 0, true);
1508     SimpleInstallFunction(prototype, "setUTCMilliseconds",
1509                           Builtins::kDatePrototypeSetUTCMilliseconds, 1, false);
1510     SimpleInstallFunction(prototype, "getUTCMinutes",
1511                           Builtins::kDatePrototypeGetUTCMinutes, 0, true);
1512     SimpleInstallFunction(prototype, "setUTCMinutes",
1513                           Builtins::kDatePrototypeSetUTCMinutes, 3, false);
1514     SimpleInstallFunction(prototype, "getUTCMonth",
1515                           Builtins::kDatePrototypeGetUTCMonth, 0, true);
1516     SimpleInstallFunction(prototype, "setUTCMonth",
1517                           Builtins::kDatePrototypeSetUTCMonth, 2, false);
1518     SimpleInstallFunction(prototype, "getUTCSeconds",
1519                           Builtins::kDatePrototypeGetUTCSeconds, 0, true);
1520     SimpleInstallFunction(prototype, "setUTCSeconds",
1521                           Builtins::kDatePrototypeSetUTCSeconds, 2, false);
1522     SimpleInstallFunction(prototype, "valueOf", Builtins::kDatePrototypeValueOf,
1523                           0, false);
1524     SimpleInstallFunction(prototype, "getYear", Builtins::kDatePrototypeGetYear,
1525                           0, true);
1526     SimpleInstallFunction(prototype, "setYear", Builtins::kDatePrototypeSetYear,
1527                           1, false);
1528     SimpleInstallFunction(prototype, "toJSON", Builtins::kDatePrototypeToJson,
1529                           1, false);
1530 
1531     // Install i18n fallback functions.
1532     SimpleInstallFunction(prototype, "toLocaleString",
1533                           Builtins::kDatePrototypeToString, 0, false);
1534     SimpleInstallFunction(prototype, "toLocaleDateString",
1535                           Builtins::kDatePrototypeToDateString, 0, false);
1536     SimpleInstallFunction(prototype, "toLocaleTimeString",
1537                           Builtins::kDatePrototypeToTimeString, 0, false);
1538 
1539     // Install the @@toPrimitive function.
1540     Handle<JSFunction> to_primitive = InstallFunction(
1541         prototype, factory->to_primitive_symbol(), JS_OBJECT_TYPE,
1542         JSObject::kHeaderSize, MaybeHandle<JSObject>(),
1543         Builtins::kDatePrototypeToPrimitive,
1544         static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
1545 
1546     // Set the expected parameters for @@toPrimitive to 1; required by builtin.
1547     to_primitive->shared()->set_internal_formal_parameter_count(1);
1548 
1549     // Set the length for the function to satisfy ECMA-262.
1550     to_primitive->shared()->set_length(1);
1551   }
1552 
1553   {  // -- R e g E x p
1554     // Builtin functions for RegExp.prototype.
1555     Handle<JSFunction> regexp_fun =
1556         InstallFunction(global, "RegExp", JS_REGEXP_TYPE, JSRegExp::kSize,
1557                         isolate->initial_object_prototype(),
1558                         Builtins::kIllegal);
1559     InstallWithIntrinsicDefaultProto(isolate, regexp_fun,
1560                                      Context::REGEXP_FUNCTION_INDEX);
1561     regexp_fun->shared()->set_construct_stub(
1562         *isolate->builtins()->JSBuiltinsConstructStub());
1563 
1564     DCHECK(regexp_fun->has_initial_map());
1565     Handle<Map> initial_map(regexp_fun->initial_map());
1566 
1567     DCHECK_EQ(0, initial_map->GetInObjectProperties());
1568 
1569     Map::EnsureDescriptorSlack(initial_map, 1);
1570 
1571     // ECMA-262, section 15.10.7.5.
1572     PropertyAttributes writable =
1573         static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE);
1574     DataDescriptor field(factory->last_index_string(),
1575                          JSRegExp::kLastIndexFieldIndex, writable,
1576                          Representation::Tagged());
1577     initial_map->AppendDescriptor(&field);
1578 
1579     static const int num_fields = JSRegExp::kInObjectFieldCount;
1580     initial_map->SetInObjectProperties(num_fields);
1581     initial_map->set_unused_property_fields(0);
1582     initial_map->set_instance_size(initial_map->instance_size() +
1583                                    num_fields * kPointerSize);
1584   }
1585 
1586   {  // -- E r r o r
1587     Handle<JSFunction> error_fun = InstallFunction(
1588         global, "Error", JS_ERROR_TYPE, JSObject::kHeaderSize,
1589         isolate->initial_object_prototype(), Builtins::kIllegal);
1590     InstallWithIntrinsicDefaultProto(isolate, error_fun,
1591                                      Context::ERROR_FUNCTION_INDEX);
1592   }
1593 
1594   {  // -- E v a l E r r o r
1595     Handle<JSFunction> eval_error_fun = InstallFunction(
1596         global, "EvalError", JS_ERROR_TYPE, JSObject::kHeaderSize,
1597         isolate->initial_object_prototype(), Builtins::kIllegal);
1598     InstallWithIntrinsicDefaultProto(isolate, eval_error_fun,
1599                                      Context::EVAL_ERROR_FUNCTION_INDEX);
1600   }
1601 
1602   {  // -- R a n g e E r r o r
1603     Handle<JSFunction> range_error_fun = InstallFunction(
1604         global, "RangeError", JS_ERROR_TYPE, JSObject::kHeaderSize,
1605         isolate->initial_object_prototype(), Builtins::kIllegal);
1606     InstallWithIntrinsicDefaultProto(isolate, range_error_fun,
1607                                      Context::RANGE_ERROR_FUNCTION_INDEX);
1608   }
1609 
1610   {  // -- R e f e r e n c e E r r o r
1611     Handle<JSFunction> reference_error_fun = InstallFunction(
1612         global, "ReferenceError", JS_ERROR_TYPE, JSObject::kHeaderSize,
1613         isolate->initial_object_prototype(), Builtins::kIllegal);
1614     InstallWithIntrinsicDefaultProto(isolate, reference_error_fun,
1615                                      Context::REFERENCE_ERROR_FUNCTION_INDEX);
1616   }
1617 
1618   {  // -- S y n t a x E r r o r
1619     Handle<JSFunction> syntax_error_fun = InstallFunction(
1620         global, "SyntaxError", JS_ERROR_TYPE, JSObject::kHeaderSize,
1621         isolate->initial_object_prototype(), Builtins::kIllegal);
1622     InstallWithIntrinsicDefaultProto(isolate, syntax_error_fun,
1623                                      Context::SYNTAX_ERROR_FUNCTION_INDEX);
1624   }
1625 
1626   {  // -- T y p e E r r o r
1627     Handle<JSFunction> type_error_fun = InstallFunction(
1628         global, "TypeError", JS_ERROR_TYPE, JSObject::kHeaderSize,
1629         isolate->initial_object_prototype(), Builtins::kIllegal);
1630     InstallWithIntrinsicDefaultProto(isolate, type_error_fun,
1631                                      Context::TYPE_ERROR_FUNCTION_INDEX);
1632   }
1633 
1634   {  // -- U R I E r r o r
1635     Handle<JSFunction> uri_error_fun = InstallFunction(
1636         global, "URIError", JS_ERROR_TYPE, JSObject::kHeaderSize,
1637         isolate->initial_object_prototype(), Builtins::kIllegal);
1638     InstallWithIntrinsicDefaultProto(isolate, uri_error_fun,
1639                                      Context::URI_ERROR_FUNCTION_INDEX);
1640   }
1641 
1642   // Initialize the embedder data slot.
1643   Handle<FixedArray> embedder_data = factory->NewFixedArray(3);
1644   native_context()->set_embedder_data(*embedder_data);
1645 
1646   {  // -- J S O N
1647     Handle<String> name = factory->InternalizeUtf8String("JSON");
1648     Handle<JSFunction> cons = factory->NewFunction(name);
1649     JSFunction::SetInstancePrototype(cons,
1650         Handle<Object>(native_context()->initial_object_prototype(), isolate));
1651     Handle<JSObject> json_object = factory->NewJSObject(cons, TENURED);
1652     DCHECK(json_object->IsJSObject());
1653     JSObject::AddProperty(global, name, json_object, DONT_ENUM);
1654     SimpleInstallFunction(json_object, "parse", Builtins::kJsonParse, 2, false);
1655     SimpleInstallFunction(json_object, "stringify", Builtins::kJsonStringify, 3,
1656                           true);
1657     JSObject::AddProperty(
1658         json_object, factory->to_string_tag_symbol(),
1659         factory->NewStringFromAsciiChecked("JSON"),
1660         static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
1661   }
1662 
1663   {  // -- M a t h
1664     Handle<String> name = factory->InternalizeUtf8String("Math");
1665     Handle<JSFunction> cons = factory->NewFunction(name);
1666     JSFunction::SetInstancePrototype(
1667         cons,
1668         Handle<Object>(native_context()->initial_object_prototype(), isolate));
1669     Handle<JSObject> math = factory->NewJSObject(cons, TENURED);
1670     DCHECK(math->IsJSObject());
1671     JSObject::AddProperty(global, name, math, DONT_ENUM);
1672     SimpleInstallFunction(math, "acos", Builtins::kMathAcos, 1, true);
1673     SimpleInstallFunction(math, "asin", Builtins::kMathAsin, 1, true);
1674     SimpleInstallFunction(math, "atan", Builtins::kMathAtan, 1, true);
1675     SimpleInstallFunction(math, "atan2", Builtins::kMathAtan2, 2, true);
1676     SimpleInstallFunction(math, "atanh", Builtins::kMathAtanh, 1, true);
1677     SimpleInstallFunction(math, "ceil", Builtins::kMathCeil, 1, true);
1678     SimpleInstallFunction(math, "cbrt", Builtins::kMathCbrt, 1, true);
1679     SimpleInstallFunction(math, "expm1", Builtins::kMathExpm1, 1, true);
1680     SimpleInstallFunction(math, "clz32", Builtins::kMathClz32, 1, true);
1681     SimpleInstallFunction(math, "cos", Builtins::kMathCos, 1, true);
1682     Handle<JSFunction> math_exp =
1683         SimpleInstallFunction(math, "exp", Builtins::kMathExp, 1, true);
1684     native_context()->set_math_exp(*math_exp);
1685     Handle<JSFunction> math_floor =
1686         SimpleInstallFunction(math, "floor", Builtins::kMathFloor, 1, true);
1687     native_context()->set_math_floor(*math_floor);
1688     SimpleInstallFunction(math, "fround", Builtins::kMathFround, 1, true);
1689     SimpleInstallFunction(math, "imul", Builtins::kMathImul, 2, true);
1690     Handle<JSFunction> math_log =
1691         SimpleInstallFunction(math, "log", Builtins::kMathLog, 1, true);
1692     native_context()->set_math_log(*math_log);
1693     SimpleInstallFunction(math, "log1p", Builtins::kMathLog1p, 1, true);
1694     SimpleInstallFunction(math, "log2", Builtins::kMathLog2, 1, true);
1695     SimpleInstallFunction(math, "log10", Builtins::kMathLog10, 1, true);
1696     SimpleInstallFunction(math, "max", Builtins::kMathMax, 2, false);
1697     SimpleInstallFunction(math, "min", Builtins::kMathMin, 2, false);
1698     SimpleInstallFunction(math, "round", Builtins::kMathRound, 1, true);
1699     SimpleInstallFunction(math, "sin", Builtins::kMathSin, 1, true);
1700     Handle<JSFunction> math_sqrt =
1701         SimpleInstallFunction(math, "sqrt", Builtins::kMathSqrt, 1, true);
1702     native_context()->set_math_sqrt(*math_sqrt);
1703     SimpleInstallFunction(math, "tan", Builtins::kMathTan, 1, true);
1704     SimpleInstallFunction(math, "trunc", Builtins::kMathTrunc, 1, true);
1705 
1706     // Install math constants.
1707     double const kE = base::ieee754::exp(1.0);
1708     JSObject::AddProperty(
1709         math, factory->NewStringFromAsciiChecked("E"), factory->NewNumber(kE),
1710         static_cast<PropertyAttributes>(DONT_DELETE | DONT_ENUM | READ_ONLY));
1711     JSObject::AddProperty(
1712         math, factory->NewStringFromAsciiChecked("LN10"),
1713         factory->NewNumber(base::ieee754::log(10.0)),
1714         static_cast<PropertyAttributes>(DONT_DELETE | DONT_ENUM | READ_ONLY));
1715     JSObject::AddProperty(
1716         math, factory->NewStringFromAsciiChecked("LN2"),
1717         factory->NewNumber(base::ieee754::log(2.0)),
1718         static_cast<PropertyAttributes>(DONT_DELETE | DONT_ENUM | READ_ONLY));
1719     JSObject::AddProperty(
1720         math, factory->NewStringFromAsciiChecked("LOG10E"),
1721         factory->NewNumber(base::ieee754::log10(kE)),
1722         static_cast<PropertyAttributes>(DONT_DELETE | DONT_ENUM | READ_ONLY));
1723     JSObject::AddProperty(
1724         math, factory->NewStringFromAsciiChecked("LOG2E"),
1725         factory->NewNumber(base::ieee754::log2(kE)),
1726         static_cast<PropertyAttributes>(DONT_DELETE | DONT_ENUM | READ_ONLY));
1727   }
1728 
1729   {  // -- A r r a y B u f f e r
1730     Handle<JSFunction> array_buffer_fun =
1731         InstallArrayBuffer(global, "ArrayBuffer");
1732     InstallWithIntrinsicDefaultProto(isolate, array_buffer_fun,
1733                                      Context::ARRAY_BUFFER_FUN_INDEX);
1734   }
1735 
1736   {  // -- T y p e d A r r a y
1737     Handle<JSObject> prototype =
1738         factory->NewJSObject(isolate->object_function(), TENURED);
1739     native_context()->set_typed_array_prototype(*prototype);
1740 
1741     Handle<JSFunction> typed_array_fun =
1742         CreateFunction(isolate, factory->InternalizeUtf8String("TypedArray"),
1743                        JS_TYPED_ARRAY_TYPE, JSTypedArray::kSize, prototype,
1744                        Builtins::kIllegal);
1745 
1746     // Install the "constructor" property on the {prototype}.
1747     JSObject::AddProperty(prototype, factory->constructor_string(),
1748                           typed_array_fun, DONT_ENUM);
1749     native_context()->set_typed_array_function(*typed_array_fun);
1750 
1751     // Install the "buffer", "byteOffset", "byteLength" and "length"
1752     // getters on the {prototype}.
1753     SimpleInstallGetter(prototype, factory->buffer_string(),
1754                         Builtins::kTypedArrayPrototypeBuffer, false);
1755     SimpleInstallGetter(prototype, factory->byte_length_string(),
1756                         Builtins::kTypedArrayPrototypeByteLength, true,
1757                         kTypedArrayByteLength);
1758     SimpleInstallGetter(prototype, factory->byte_offset_string(),
1759                         Builtins::kTypedArrayPrototypeByteOffset, true,
1760                         kTypedArrayByteOffset);
1761     SimpleInstallGetter(prototype, factory->length_string(),
1762                         Builtins::kTypedArrayPrototypeLength, true,
1763                         kTypedArrayLength);
1764   }
1765 
1766   {  // -- T y p e d A r r a y s
1767 #define INSTALL_TYPED_ARRAY(Type, type, TYPE, ctype, size)             \
1768   {                                                                    \
1769     Handle<JSFunction> fun;                                            \
1770     InstallTypedArray(#Type "Array", TYPE##_ELEMENTS, &fun);           \
1771     InstallWithIntrinsicDefaultProto(isolate, fun,                     \
1772                                      Context::TYPE##_ARRAY_FUN_INDEX); \
1773   }
1774     TYPED_ARRAYS(INSTALL_TYPED_ARRAY)
1775 #undef INSTALL_TYPED_ARRAY
1776   }
1777 
1778   {  // -- D a t a V i e w
1779     Handle<JSObject> prototype =
1780         factory->NewJSObject(isolate->object_function(), TENURED);
1781     Handle<JSFunction> data_view_fun =
1782         InstallFunction(global, "DataView", JS_DATA_VIEW_TYPE,
1783                         JSDataView::kSizeWithInternalFields, prototype,
1784                         Builtins::kDataViewConstructor);
1785     InstallWithIntrinsicDefaultProto(isolate, data_view_fun,
1786                                      Context::DATA_VIEW_FUN_INDEX);
1787     data_view_fun->shared()->set_construct_stub(
1788         *isolate->builtins()->DataViewConstructor_ConstructStub());
1789     data_view_fun->shared()->set_length(3);
1790     data_view_fun->shared()->DontAdaptArguments();
1791 
1792     // Install the @@toStringTag property on the {prototype}.
1793     JSObject::AddProperty(
1794         prototype, factory->to_string_tag_symbol(),
1795         factory->NewStringFromAsciiChecked("DataView"),
1796         static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
1797 
1798     // Install the "constructor" property on the {prototype}.
1799     JSObject::AddProperty(prototype, factory->constructor_string(),
1800                           data_view_fun, DONT_ENUM);
1801 
1802     // Install the "buffer", "byteOffset" and "byteLength" getters
1803     // on the {prototype}.
1804     SimpleInstallGetter(prototype, factory->buffer_string(),
1805                         Builtins::kDataViewPrototypeGetBuffer, false,
1806                         kDataViewBuffer);
1807     SimpleInstallGetter(prototype, factory->byte_length_string(),
1808                         Builtins::kDataViewPrototypeGetByteLength, false,
1809                         kDataViewByteLength);
1810     SimpleInstallGetter(prototype, factory->byte_offset_string(),
1811                         Builtins::kDataViewPrototypeGetByteOffset, false,
1812                         kDataViewByteOffset);
1813   }
1814 
1815   {  // -- M a p
1816     Handle<JSFunction> js_map_fun = InstallFunction(
1817         global, "Map", JS_MAP_TYPE, JSMap::kSize,
1818         isolate->initial_object_prototype(), Builtins::kIllegal);
1819     InstallWithIntrinsicDefaultProto(isolate, js_map_fun,
1820                                      Context::JS_MAP_FUN_INDEX);
1821   }
1822 
1823   {  // -- S e t
1824     Handle<JSFunction> js_set_fun = InstallFunction(
1825         global, "Set", JS_SET_TYPE, JSSet::kSize,
1826         isolate->initial_object_prototype(), Builtins::kIllegal);
1827     InstallWithIntrinsicDefaultProto(isolate, js_set_fun,
1828                                      Context::JS_SET_FUN_INDEX);
1829   }
1830 
1831   {  // -- I t e r a t o r R e s u l t
1832     Handle<Map> map =
1833         factory->NewMap(JS_OBJECT_TYPE, JSIteratorResult::kSize);
1834     Map::SetPrototype(map, isolate->initial_object_prototype());
1835     Map::EnsureDescriptorSlack(map, 2);
1836 
1837     {  // value
1838       DataDescriptor d(factory->value_string(), JSIteratorResult::kValueIndex,
1839                        NONE, Representation::Tagged());
1840       map->AppendDescriptor(&d);
1841     }
1842 
1843     {  // done
1844       DataDescriptor d(factory->done_string(), JSIteratorResult::kDoneIndex,
1845                        NONE, Representation::Tagged());
1846       map->AppendDescriptor(&d);
1847     }
1848 
1849     map->SetConstructor(native_context()->object_function());
1850     map->SetInObjectProperties(2);
1851     native_context()->set_iterator_result_map(*map);
1852   }
1853 
1854   {  // -- W e a k M a p
1855     Handle<JSFunction> js_weak_map_fun = InstallFunction(
1856         global, "WeakMap", JS_WEAK_MAP_TYPE, JSWeakMap::kSize,
1857         isolate->initial_object_prototype(), Builtins::kIllegal);
1858     InstallWithIntrinsicDefaultProto(isolate, js_weak_map_fun,
1859                                      Context::JS_WEAK_MAP_FUN_INDEX);
1860   }
1861 
1862   {  // -- W e a k S e t
1863     Handle<JSFunction> js_weak_set_fun = InstallFunction(
1864         global, "WeakSet", JS_WEAK_SET_TYPE, JSWeakSet::kSize,
1865         isolate->initial_object_prototype(), Builtins::kIllegal);
1866     InstallWithIntrinsicDefaultProto(isolate, js_weak_set_fun,
1867                                      Context::JS_WEAK_SET_FUN_INDEX);
1868   }
1869 
1870   {  // -- P r o x y
1871     CreateJSProxyMaps();
1872 
1873     Handle<String> name = factory->Proxy_string();
1874     Handle<Code> code(isolate->builtins()->ProxyConstructor());
1875 
1876     Handle<JSFunction> proxy_function =
1877         factory->NewFunction(isolate->proxy_function_map(),
1878                              factory->Proxy_string(), MaybeHandle<Code>(code));
1879 
1880     JSFunction::SetInitialMap(
1881         proxy_function, Handle<Map>(native_context()->proxy_map(), isolate),
1882         factory->null_value());
1883 
1884     proxy_function->shared()->set_construct_stub(
1885         *isolate->builtins()->ProxyConstructor_ConstructStub());
1886     proxy_function->shared()->set_internal_formal_parameter_count(2);
1887     proxy_function->shared()->set_length(2);
1888 
1889     native_context()->set_proxy_function(*proxy_function);
1890     InstallFunction(global, name, proxy_function, factory->Object_string());
1891   }
1892 
1893   {  // -- R e f l e c t
1894     Handle<String> reflect_string = factory->InternalizeUtf8String("Reflect");
1895     Handle<JSObject> reflect =
1896         factory->NewJSObject(isolate->object_function(), TENURED);
1897     JSObject::AddProperty(global, reflect_string, reflect, DONT_ENUM);
1898 
1899     Handle<JSFunction> define_property =
1900         SimpleInstallFunction(reflect, factory->defineProperty_string(),
1901                               Builtins::kReflectDefineProperty, 3, true);
1902     native_context()->set_reflect_define_property(*define_property);
1903 
1904     Handle<JSFunction> delete_property =
1905         SimpleInstallFunction(reflect, factory->deleteProperty_string(),
1906                               Builtins::kReflectDeleteProperty, 2, true);
1907     native_context()->set_reflect_delete_property(*delete_property);
1908 
1909     Handle<JSFunction> apply = SimpleInstallFunction(
1910         reflect, factory->apply_string(), Builtins::kReflectApply, 3, false);
1911     native_context()->set_reflect_apply(*apply);
1912 
1913     Handle<JSFunction> construct =
1914         SimpleInstallFunction(reflect, factory->construct_string(),
1915                               Builtins::kReflectConstruct, 2, false);
1916     native_context()->set_reflect_construct(*construct);
1917 
1918     SimpleInstallFunction(reflect, factory->get_string(), Builtins::kReflectGet,
1919                           2, false);
1920     SimpleInstallFunction(reflect, factory->getOwnPropertyDescriptor_string(),
1921                           Builtins::kReflectGetOwnPropertyDescriptor, 2, true);
1922     SimpleInstallFunction(reflect, factory->getPrototypeOf_string(),
1923                           Builtins::kReflectGetPrototypeOf, 1, true);
1924     SimpleInstallFunction(reflect, factory->has_string(), Builtins::kReflectHas,
1925                           2, true);
1926     SimpleInstallFunction(reflect, factory->isExtensible_string(),
1927                           Builtins::kReflectIsExtensible, 1, true);
1928     SimpleInstallFunction(reflect, factory->ownKeys_string(),
1929                           Builtins::kReflectOwnKeys, 1, true);
1930     SimpleInstallFunction(reflect, factory->preventExtensions_string(),
1931                           Builtins::kReflectPreventExtensions, 1, true);
1932     SimpleInstallFunction(reflect, factory->set_string(), Builtins::kReflectSet,
1933                           3, false);
1934     SimpleInstallFunction(reflect, factory->setPrototypeOf_string(),
1935                           Builtins::kReflectSetPrototypeOf, 2, true);
1936   }
1937 
1938   {  // --- B o u n d F u n c t i o n
1939     Handle<Map> map =
1940         factory->NewMap(JS_BOUND_FUNCTION_TYPE, JSBoundFunction::kSize);
1941     map->set_is_callable();
1942     Map::SetPrototype(map, empty_function);
1943 
1944     PropertyAttributes roc_attribs =
1945         static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY);
1946     Map::EnsureDescriptorSlack(map, 2);
1947 
1948     Handle<AccessorInfo> bound_length =
1949         Accessors::BoundFunctionLengthInfo(isolate, roc_attribs);
1950     {  // length
1951       AccessorConstantDescriptor d(factory->length_string(), bound_length,
1952                                    roc_attribs);
1953       map->AppendDescriptor(&d);
1954     }
1955     Handle<AccessorInfo> bound_name =
1956         Accessors::BoundFunctionNameInfo(isolate, roc_attribs);
1957     {  // length
1958       AccessorConstantDescriptor d(factory->name_string(), bound_name,
1959                                    roc_attribs);
1960       map->AppendDescriptor(&d);
1961     }
1962     map->SetInObjectProperties(0);
1963     native_context()->set_bound_function_without_constructor_map(*map);
1964 
1965     map = Map::Copy(map, "IsConstructor");
1966     map->set_is_constructor(true);
1967     native_context()->set_bound_function_with_constructor_map(*map);
1968   }
1969 
1970   {  // --- sloppy arguments map
1971     // Make sure we can recognize argument objects at runtime.
1972     // This is done by introducing an anonymous function with
1973     // class_name equals 'Arguments'.
1974     Handle<String> arguments_string = factory->Arguments_string();
1975     Handle<Code> code = isolate->builtins()->Illegal();
1976     Handle<JSFunction> function = factory->NewFunctionWithoutPrototype(
1977         arguments_string, code);
1978     function->shared()->set_instance_class_name(*arguments_string);
1979 
1980     Handle<Map> map = factory->NewMap(
1981         JS_ARGUMENTS_TYPE, JSSloppyArgumentsObject::kSize, FAST_ELEMENTS);
1982     // Create the descriptor array for the arguments object.
1983     Map::EnsureDescriptorSlack(map, 2);
1984 
1985     {  // length
1986       DataDescriptor d(factory->length_string(),
1987                        JSSloppyArgumentsObject::kLengthIndex, DONT_ENUM,
1988                        Representation::Tagged());
1989       map->AppendDescriptor(&d);
1990     }
1991     {  // callee
1992       DataDescriptor d(factory->callee_string(),
1993                        JSSloppyArgumentsObject::kCalleeIndex, DONT_ENUM,
1994                        Representation::Tagged());
1995       map->AppendDescriptor(&d);
1996     }
1997     // @@iterator method is added later.
1998 
1999     map->SetInObjectProperties(2);
2000     native_context()->set_sloppy_arguments_map(*map);
2001 
2002     DCHECK(!function->has_initial_map());
2003     JSFunction::SetInitialMap(function, map,
2004                               isolate->initial_object_prototype());
2005 
2006     DCHECK(!map->is_dictionary_map());
2007     DCHECK(IsFastObjectElementsKind(map->elements_kind()));
2008   }
2009 
2010   {  // --- fast and slow aliased arguments map
2011     Handle<Map> map = isolate->sloppy_arguments_map();
2012     map = Map::Copy(map, "FastAliasedArguments");
2013     map->set_elements_kind(FAST_SLOPPY_ARGUMENTS_ELEMENTS);
2014     DCHECK_EQ(2, map->GetInObjectProperties());
2015     native_context()->set_fast_aliased_arguments_map(*map);
2016 
2017     map = Map::Copy(map, "SlowAliasedArguments");
2018     map->set_elements_kind(SLOW_SLOPPY_ARGUMENTS_ELEMENTS);
2019     DCHECK_EQ(2, map->GetInObjectProperties());
2020     native_context()->set_slow_aliased_arguments_map(*map);
2021   }
2022 
2023   {  // --- strict mode arguments map
2024     const PropertyAttributes attributes =
2025       static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
2026 
2027     // Create the ThrowTypeError functions.
2028     Handle<AccessorPair> callee = factory->NewAccessorPair();
2029     Handle<AccessorPair> caller = factory->NewAccessorPair();
2030 
2031     Handle<JSFunction> poison = GetStrictArgumentsPoisonFunction();
2032 
2033     // Install the ThrowTypeError functions.
2034     callee->set_getter(*poison);
2035     callee->set_setter(*poison);
2036     caller->set_getter(*poison);
2037     caller->set_setter(*poison);
2038 
2039     // Create the map. Allocate one in-object field for length.
2040     Handle<Map> map = factory->NewMap(
2041         JS_ARGUMENTS_TYPE, JSStrictArgumentsObject::kSize, FAST_ELEMENTS);
2042     // Create the descriptor array for the arguments object.
2043     Map::EnsureDescriptorSlack(map, 3);
2044 
2045     {  // length
2046       DataDescriptor d(factory->length_string(),
2047                        JSStrictArgumentsObject::kLengthIndex, DONT_ENUM,
2048                        Representation::Tagged());
2049       map->AppendDescriptor(&d);
2050     }
2051     {  // callee
2052       AccessorConstantDescriptor d(factory->callee_string(), callee,
2053                                    attributes);
2054       map->AppendDescriptor(&d);
2055     }
2056     {  // caller
2057       AccessorConstantDescriptor d(factory->caller_string(), caller,
2058                                    attributes);
2059       map->AppendDescriptor(&d);
2060     }
2061     // @@iterator method is added later.
2062 
2063     DCHECK_EQ(native_context()->object_function()->prototype(),
2064               *isolate->initial_object_prototype());
2065     Map::SetPrototype(map, isolate->initial_object_prototype());
2066     map->SetInObjectProperties(1);
2067 
2068     // Copy constructor from the sloppy arguments boilerplate.
2069     map->SetConstructor(
2070         native_context()->sloppy_arguments_map()->GetConstructor());
2071 
2072     native_context()->set_strict_arguments_map(*map);
2073 
2074     DCHECK(!map->is_dictionary_map());
2075     DCHECK(IsFastObjectElementsKind(map->elements_kind()));
2076   }
2077 
2078   {  // --- context extension
2079     // Create a function for the context extension objects.
2080     Handle<Code> code = isolate->builtins()->Illegal();
2081     Handle<JSFunction> context_extension_fun = factory->NewFunction(
2082         factory->empty_string(), code, JS_CONTEXT_EXTENSION_OBJECT_TYPE,
2083         JSObject::kHeaderSize);
2084 
2085     Handle<String> name = factory->InternalizeOneByteString(
2086         STATIC_CHAR_VECTOR("context_extension"));
2087     context_extension_fun->shared()->set_instance_class_name(*name);
2088     native_context()->set_context_extension_function(*context_extension_fun);
2089   }
2090 
2091 
2092   {
2093     // Set up the call-as-function delegate.
2094     Handle<Code> code = isolate->builtins()->HandleApiCallAsFunction();
2095     Handle<JSFunction> delegate = factory->NewFunction(
2096         factory->empty_string(), code, JS_OBJECT_TYPE, JSObject::kHeaderSize);
2097     native_context()->set_call_as_function_delegate(*delegate);
2098     delegate->shared()->DontAdaptArguments();
2099   }
2100 
2101   {
2102     // Set up the call-as-constructor delegate.
2103     Handle<Code> code = isolate->builtins()->HandleApiCallAsConstructor();
2104     Handle<JSFunction> delegate = factory->NewFunction(
2105         factory->empty_string(), code, JS_OBJECT_TYPE, JSObject::kHeaderSize);
2106     native_context()->set_call_as_constructor_delegate(*delegate);
2107     delegate->shared()->DontAdaptArguments();
2108   }
2109 }  // NOLINT(readability/fn_size)
2110 
InstallTypedArray(const char * name,ElementsKind elements_kind,Handle<JSFunction> * fun)2111 void Genesis::InstallTypedArray(const char* name, ElementsKind elements_kind,
2112                                 Handle<JSFunction>* fun) {
2113   Handle<JSObject> global = Handle<JSObject>(native_context()->global_object());
2114 
2115   Handle<JSObject> typed_array_prototype =
2116       Handle<JSObject>(isolate()->typed_array_prototype());
2117   Handle<JSFunction> typed_array_function =
2118       Handle<JSFunction>(isolate()->typed_array_function());
2119 
2120   Handle<JSObject> prototype =
2121       factory()->NewJSObject(isolate()->object_function(), TENURED);
2122   Handle<JSFunction> result =
2123       InstallFunction(global, name, JS_TYPED_ARRAY_TYPE, JSTypedArray::kSize,
2124                       prototype, Builtins::kIllegal);
2125 
2126   Handle<Map> initial_map = isolate()->factory()->NewMap(
2127       JS_TYPED_ARRAY_TYPE,
2128       JSTypedArray::kSizeWithInternalFields,
2129       elements_kind);
2130   JSFunction::SetInitialMap(result, initial_map,
2131                             handle(initial_map->prototype(), isolate()));
2132 
2133   CHECK(JSObject::SetPrototype(result, typed_array_function, false,
2134                                Object::DONT_THROW)
2135             .FromJust());
2136 
2137   CHECK(JSObject::SetPrototype(prototype, typed_array_prototype, false,
2138                                Object::DONT_THROW)
2139             .FromJust());
2140   *fun = result;
2141 }
2142 
2143 
InitializeExperimentalGlobal()2144 void Genesis::InitializeExperimentalGlobal() {
2145 #define FEATURE_INITIALIZE_GLOBAL(id, descr) InitializeGlobal_##id();
2146 
2147   HARMONY_INPROGRESS(FEATURE_INITIALIZE_GLOBAL)
2148   HARMONY_STAGED(FEATURE_INITIALIZE_GLOBAL)
2149   HARMONY_SHIPPING(FEATURE_INITIALIZE_GLOBAL)
2150   FEATURE_INITIALIZE_GLOBAL(promise_extra, "")
2151   FEATURE_INITIALIZE_GLOBAL(intl_extra, "")
2152 #undef FEATURE_INITIALIZE_GLOBAL
2153 }
2154 
2155 
CompileBuiltin(Isolate * isolate,int index)2156 bool Bootstrapper::CompileBuiltin(Isolate* isolate, int index) {
2157   Vector<const char> name = Natives::GetScriptName(index);
2158   Handle<String> source_code =
2159       isolate->bootstrapper()->SourceLookup<Natives>(index);
2160 
2161   // We pass in extras_utils so that builtin code can set it up for later use
2162   // by actual extras code, compiled with CompileExtraBuiltin.
2163   Handle<Object> global = isolate->global_object();
2164   Handle<Object> utils = isolate->natives_utils_object();
2165   Handle<Object> extras_utils = isolate->extras_utils_object();
2166   Handle<Object> args[] = {global, utils, extras_utils};
2167 
2168   return Bootstrapper::CompileNative(isolate, name, source_code,
2169                                      arraysize(args), args, NATIVES_CODE);
2170 }
2171 
2172 
CompileExperimentalBuiltin(Isolate * isolate,int index)2173 bool Bootstrapper::CompileExperimentalBuiltin(Isolate* isolate, int index) {
2174   HandleScope scope(isolate);
2175   Vector<const char> name = ExperimentalNatives::GetScriptName(index);
2176   Handle<String> source_code =
2177       isolate->bootstrapper()->SourceLookup<ExperimentalNatives>(index);
2178   Handle<Object> global = isolate->global_object();
2179   Handle<Object> utils = isolate->natives_utils_object();
2180   Handle<Object> args[] = {global, utils};
2181   return Bootstrapper::CompileNative(isolate, name, source_code,
2182                                      arraysize(args), args, NATIVES_CODE);
2183 }
2184 
2185 
CompileExtraBuiltin(Isolate * isolate,int index)2186 bool Bootstrapper::CompileExtraBuiltin(Isolate* isolate, int index) {
2187   HandleScope scope(isolate);
2188   Vector<const char> name = ExtraNatives::GetScriptName(index);
2189   Handle<String> source_code =
2190       isolate->bootstrapper()->SourceLookup<ExtraNatives>(index);
2191   Handle<Object> global = isolate->global_object();
2192   Handle<Object> binding = isolate->extras_binding_object();
2193   Handle<Object> extras_utils = isolate->extras_utils_object();
2194   Handle<Object> args[] = {global, binding, extras_utils};
2195   return Bootstrapper::CompileNative(isolate, name, source_code,
2196                                      arraysize(args), args, EXTENSION_CODE);
2197 }
2198 
2199 
CompileExperimentalExtraBuiltin(Isolate * isolate,int index)2200 bool Bootstrapper::CompileExperimentalExtraBuiltin(Isolate* isolate,
2201                                                    int index) {
2202   HandleScope scope(isolate);
2203   Vector<const char> name = ExperimentalExtraNatives::GetScriptName(index);
2204   Handle<String> source_code =
2205       isolate->bootstrapper()->SourceLookup<ExperimentalExtraNatives>(index);
2206   Handle<Object> global = isolate->global_object();
2207   Handle<Object> binding = isolate->extras_binding_object();
2208   Handle<Object> extras_utils = isolate->extras_utils_object();
2209   Handle<Object> args[] = {global, binding, extras_utils};
2210   return Bootstrapper::CompileNative(isolate, name, source_code,
2211                                      arraysize(args), args, EXTENSION_CODE);
2212 }
2213 
CompileNative(Isolate * isolate,Vector<const char> name,Handle<String> source,int argc,Handle<Object> argv[],NativesFlag natives_flag)2214 bool Bootstrapper::CompileNative(Isolate* isolate, Vector<const char> name,
2215                                  Handle<String> source, int argc,
2216                                  Handle<Object> argv[],
2217                                  NativesFlag natives_flag) {
2218   SuppressDebug compiling_natives(isolate->debug());
2219   // During genesis, the boilerplate for stack overflow won't work until the
2220   // environment has been at least partially initialized. Add a stack check
2221   // before entering JS code to catch overflow early.
2222   StackLimitCheck check(isolate);
2223   if (check.JsHasOverflowed(1 * KB)) {
2224     isolate->StackOverflow();
2225     return false;
2226   }
2227 
2228   Handle<Context> context(isolate->context());
2229 
2230   Handle<String> script_name =
2231       isolate->factory()->NewStringFromUtf8(name).ToHandleChecked();
2232   Handle<SharedFunctionInfo> function_info =
2233       Compiler::GetSharedFunctionInfoForScript(
2234           source, script_name, 0, 0, ScriptOriginOptions(), Handle<Object>(),
2235           context, NULL, NULL, ScriptCompiler::kNoCompileOptions, natives_flag,
2236           false);
2237   if (function_info.is_null()) return false;
2238 
2239   DCHECK(context->IsNativeContext());
2240 
2241   Handle<JSFunction> fun =
2242       isolate->factory()->NewFunctionFromSharedFunctionInfo(function_info,
2243                                                             context);
2244   Handle<Object> receiver = isolate->factory()->undefined_value();
2245 
2246   // For non-extension scripts, run script to get the function wrapper.
2247   Handle<Object> wrapper;
2248   if (!Execution::Call(isolate, fun, receiver, 0, NULL).ToHandle(&wrapper)) {
2249     return false;
2250   }
2251   // Then run the function wrapper.
2252   return !Execution::Call(isolate, Handle<JSFunction>::cast(wrapper), receiver,
2253                           argc, argv).is_null();
2254 }
2255 
2256 
CallUtilsFunction(Isolate * isolate,const char * name)2257 bool Genesis::CallUtilsFunction(Isolate* isolate, const char* name) {
2258   Handle<JSObject> utils =
2259       Handle<JSObject>::cast(isolate->natives_utils_object());
2260   Handle<String> name_string =
2261       isolate->factory()->NewStringFromAsciiChecked(name);
2262   Handle<Object> fun = JSObject::GetDataProperty(utils, name_string);
2263   Handle<Object> receiver = isolate->factory()->undefined_value();
2264   Handle<Object> args[] = {utils};
2265   return !Execution::Call(isolate, fun, receiver, 1, args).is_null();
2266 }
2267 
2268 
CompileExtension(Isolate * isolate,v8::Extension * extension)2269 bool Genesis::CompileExtension(Isolate* isolate, v8::Extension* extension) {
2270   Factory* factory = isolate->factory();
2271   HandleScope scope(isolate);
2272   Handle<SharedFunctionInfo> function_info;
2273 
2274   Handle<String> source =
2275       isolate->factory()
2276           ->NewExternalStringFromOneByte(extension->source())
2277           .ToHandleChecked();
2278   DCHECK(source->IsOneByteRepresentation());
2279 
2280   // If we can't find the function in the cache, we compile a new
2281   // function and insert it into the cache.
2282   Vector<const char> name = CStrVector(extension->name());
2283   SourceCodeCache* cache = isolate->bootstrapper()->extensions_cache();
2284   Handle<Context> context(isolate->context());
2285   DCHECK(context->IsNativeContext());
2286 
2287   if (!cache->Lookup(name, &function_info)) {
2288     Handle<String> script_name =
2289         factory->NewStringFromUtf8(name).ToHandleChecked();
2290     function_info = Compiler::GetSharedFunctionInfoForScript(
2291         source, script_name, 0, 0, ScriptOriginOptions(), Handle<Object>(),
2292         context, extension, NULL, ScriptCompiler::kNoCompileOptions,
2293         EXTENSION_CODE, false);
2294     if (function_info.is_null()) return false;
2295     cache->Add(name, function_info);
2296   }
2297 
2298   // Set up the function context. Conceptually, we should clone the
2299   // function before overwriting the context but since we're in a
2300   // single-threaded environment it is not strictly necessary.
2301   Handle<JSFunction> fun =
2302       factory->NewFunctionFromSharedFunctionInfo(function_info, context);
2303 
2304   // Call function using either the runtime object or the global
2305   // object as the receiver. Provide no parameters.
2306   Handle<Object> receiver = isolate->global_object();
2307   return !Execution::Call(isolate, fun, receiver, 0, NULL).is_null();
2308 }
2309 
2310 
ResolveBuiltinIdHolder(Handle<Context> native_context,const char * holder_expr)2311 static Handle<JSObject> ResolveBuiltinIdHolder(Handle<Context> native_context,
2312                                                const char* holder_expr) {
2313   Isolate* isolate = native_context->GetIsolate();
2314   Factory* factory = isolate->factory();
2315   Handle<JSGlobalObject> global(native_context->global_object());
2316   const char* period_pos = strchr(holder_expr, '.');
2317   if (period_pos == NULL) {
2318     return Handle<JSObject>::cast(
2319         Object::GetPropertyOrElement(
2320             global, factory->InternalizeUtf8String(holder_expr))
2321             .ToHandleChecked());
2322   }
2323   const char* inner = period_pos + 1;
2324   DCHECK(!strchr(inner, '.'));
2325   Vector<const char> property(holder_expr,
2326                               static_cast<int>(period_pos - holder_expr));
2327   Handle<String> property_string = factory->InternalizeUtf8String(property);
2328   DCHECK(!property_string.is_null());
2329   Handle<JSObject> object = Handle<JSObject>::cast(
2330       JSReceiver::GetProperty(global, property_string).ToHandleChecked());
2331   if (strcmp("prototype", inner) == 0) {
2332     Handle<JSFunction> function = Handle<JSFunction>::cast(object);
2333     return Handle<JSObject>(JSObject::cast(function->prototype()));
2334   }
2335   Handle<String> inner_string = factory->InternalizeUtf8String(inner);
2336   DCHECK(!inner_string.is_null());
2337   Handle<Object> value =
2338       JSReceiver::GetProperty(object, inner_string).ToHandleChecked();
2339   return Handle<JSObject>::cast(value);
2340 }
2341 
ConfigureUtilsObject(GlobalContextType context_type)2342 void Genesis::ConfigureUtilsObject(GlobalContextType context_type) {
2343   switch (context_type) {
2344     // We still need the utils object to find debug functions.
2345     case DEBUG_CONTEXT:
2346       return;
2347     // Expose the natives in global if a valid name for it is specified.
2348     case FULL_CONTEXT: {
2349       // We still need the utils object after deserialization.
2350       if (isolate()->serializer_enabled()) return;
2351       if (FLAG_expose_natives_as == NULL) break;
2352       if (strlen(FLAG_expose_natives_as) == 0) break;
2353       HandleScope scope(isolate());
2354       Handle<String> natives_key =
2355           factory()->InternalizeUtf8String(FLAG_expose_natives_as);
2356       uint32_t dummy_index;
2357       if (natives_key->AsArrayIndex(&dummy_index)) break;
2358       Handle<Object> utils = isolate()->natives_utils_object();
2359       Handle<JSObject> global = isolate()->global_object();
2360       JSObject::AddProperty(global, natives_key, utils, DONT_ENUM);
2361       break;
2362     }
2363   }
2364 
2365   // The utils object can be removed for cases that reach this point.
2366   native_context()->set_natives_utils_object(heap()->undefined_value());
2367 }
2368 
2369 
ExportFromRuntime(Isolate * isolate,Handle<JSObject> container)2370 void Bootstrapper::ExportFromRuntime(Isolate* isolate,
2371                                      Handle<JSObject> container) {
2372   Factory* factory = isolate->factory();
2373   HandleScope scope(isolate);
2374   Handle<Context> native_context = isolate->native_context();
2375 #define EXPORT_PRIVATE_SYMBOL(NAME)                                       \
2376   Handle<String> NAME##_name = factory->NewStringFromAsciiChecked(#NAME); \
2377   JSObject::AddProperty(container, NAME##_name, factory->NAME(), NONE);
2378   PRIVATE_SYMBOL_LIST(EXPORT_PRIVATE_SYMBOL)
2379 #undef EXPORT_PRIVATE_SYMBOL
2380 
2381 #define EXPORT_PUBLIC_SYMBOL(NAME, DESCRIPTION)                           \
2382   Handle<String> NAME##_name = factory->NewStringFromAsciiChecked(#NAME); \
2383   JSObject::AddProperty(container, NAME##_name, factory->NAME(), NONE);
2384   PUBLIC_SYMBOL_LIST(EXPORT_PUBLIC_SYMBOL)
2385   WELL_KNOWN_SYMBOL_LIST(EXPORT_PUBLIC_SYMBOL)
2386 #undef EXPORT_PUBLIC_SYMBOL
2387 
2388   {
2389     Handle<JSFunction> to_string = InstallFunction(
2390         container, "object_to_string", JS_OBJECT_TYPE, JSObject::kHeaderSize,
2391         MaybeHandle<JSObject>(), Builtins::kObjectProtoToString);
2392     to_string->shared()->DontAdaptArguments();
2393     to_string->shared()->set_length(0);
2394     native_context->set_object_to_string(*to_string);
2395   }
2396 
2397   Handle<JSObject> iterator_prototype;
2398 
2399   {
2400     PrototypeIterator iter(native_context->generator_object_prototype_map());
2401     iter.Advance();  // Advance to the prototype of generator_object_prototype.
2402     iterator_prototype = Handle<JSObject>(iter.GetCurrent<JSObject>());
2403 
2404     JSObject::AddProperty(container,
2405                           factory->InternalizeUtf8String("IteratorPrototype"),
2406                           iterator_prototype, NONE);
2407   }
2408 
2409   {
2410     PrototypeIterator iter(native_context->sloppy_generator_function_map());
2411     Handle<JSObject> generator_function_prototype(iter.GetCurrent<JSObject>());
2412 
2413     JSObject::AddProperty(
2414         container, factory->InternalizeUtf8String("GeneratorFunctionPrototype"),
2415         generator_function_prototype, NONE);
2416 
2417     static const bool kUseStrictFunctionMap = true;
2418     Handle<JSFunction> generator_function_function = InstallFunction(
2419         container, "GeneratorFunction", JS_FUNCTION_TYPE, JSFunction::kSize,
2420         generator_function_prototype, Builtins::kGeneratorFunctionConstructor,
2421         kUseStrictFunctionMap);
2422     generator_function_function->set_prototype_or_initial_map(
2423         native_context->sloppy_generator_function_map());
2424     generator_function_function->shared()->DontAdaptArguments();
2425     generator_function_function->shared()->set_construct_stub(
2426         *isolate->builtins()->GeneratorFunctionConstructor());
2427     generator_function_function->shared()->set_length(1);
2428     InstallWithIntrinsicDefaultProto(
2429         isolate, generator_function_function,
2430         Context::GENERATOR_FUNCTION_FUNCTION_INDEX);
2431 
2432     SetObjectPrototype(generator_function_function,
2433                        isolate->function_function());
2434     JSObject::AddProperty(
2435         generator_function_prototype, factory->constructor_string(),
2436         generator_function_function,
2437         static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
2438 
2439     native_context->sloppy_generator_function_map()->SetConstructor(
2440         *generator_function_function);
2441     native_context->strict_generator_function_map()->SetConstructor(
2442         *generator_function_function);
2443   }
2444 
2445   {  // -- S e t I t e r a t o r
2446     Handle<JSObject> set_iterator_prototype =
2447         isolate->factory()->NewJSObject(isolate->object_function(), TENURED);
2448     SetObjectPrototype(set_iterator_prototype, iterator_prototype);
2449     Handle<JSFunction> set_iterator_function = InstallFunction(
2450         container, "SetIterator", JS_SET_ITERATOR_TYPE, JSSetIterator::kSize,
2451         set_iterator_prototype, Builtins::kIllegal);
2452     native_context->set_set_iterator_map(set_iterator_function->initial_map());
2453   }
2454 
2455   {  // -- M a p I t e r a t o r
2456     Handle<JSObject> map_iterator_prototype =
2457         isolate->factory()->NewJSObject(isolate->object_function(), TENURED);
2458     SetObjectPrototype(map_iterator_prototype, iterator_prototype);
2459     Handle<JSFunction> map_iterator_function = InstallFunction(
2460         container, "MapIterator", JS_MAP_ITERATOR_TYPE, JSMapIterator::kSize,
2461         map_iterator_prototype, Builtins::kIllegal);
2462     native_context->set_map_iterator_map(map_iterator_function->initial_map());
2463   }
2464 
2465   {  // -- S c r i p t
2466     // Builtin functions for Script.
2467     Handle<JSFunction> script_fun = InstallFunction(
2468         container, "Script", JS_VALUE_TYPE, JSValue::kSize,
2469         isolate->initial_object_prototype(), Builtins::kIllegal);
2470     Handle<JSObject> prototype =
2471         factory->NewJSObject(isolate->object_function(), TENURED);
2472     Accessors::FunctionSetPrototype(script_fun, prototype).Assert();
2473     native_context->set_script_function(*script_fun);
2474 
2475     Handle<Map> script_map = Handle<Map>(script_fun->initial_map());
2476     Map::EnsureDescriptorSlack(script_map, 15);
2477 
2478     PropertyAttributes attribs =
2479         static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
2480 
2481     Handle<AccessorInfo> script_column =
2482         Accessors::ScriptColumnOffsetInfo(isolate, attribs);
2483     {
2484       AccessorConstantDescriptor d(
2485           Handle<Name>(Name::cast(script_column->name())), script_column,
2486           attribs);
2487       script_map->AppendDescriptor(&d);
2488     }
2489 
2490     Handle<AccessorInfo> script_id = Accessors::ScriptIdInfo(isolate, attribs);
2491     {
2492       AccessorConstantDescriptor d(Handle<Name>(Name::cast(script_id->name())),
2493                                    script_id, attribs);
2494       script_map->AppendDescriptor(&d);
2495     }
2496 
2497 
2498     Handle<AccessorInfo> script_name =
2499         Accessors::ScriptNameInfo(isolate, attribs);
2500     {
2501       AccessorConstantDescriptor d(
2502           Handle<Name>(Name::cast(script_name->name())), script_name, attribs);
2503       script_map->AppendDescriptor(&d);
2504     }
2505 
2506     Handle<AccessorInfo> script_line =
2507         Accessors::ScriptLineOffsetInfo(isolate, attribs);
2508     {
2509       AccessorConstantDescriptor d(
2510           Handle<Name>(Name::cast(script_line->name())), script_line, attribs);
2511       script_map->AppendDescriptor(&d);
2512     }
2513 
2514     Handle<AccessorInfo> script_source =
2515         Accessors::ScriptSourceInfo(isolate, attribs);
2516     {
2517       AccessorConstantDescriptor d(
2518           Handle<Name>(Name::cast(script_source->name())), script_source,
2519           attribs);
2520       script_map->AppendDescriptor(&d);
2521     }
2522 
2523     Handle<AccessorInfo> script_type =
2524         Accessors::ScriptTypeInfo(isolate, attribs);
2525     {
2526       AccessorConstantDescriptor d(
2527           Handle<Name>(Name::cast(script_type->name())), script_type, attribs);
2528       script_map->AppendDescriptor(&d);
2529     }
2530 
2531     Handle<AccessorInfo> script_compilation_type =
2532         Accessors::ScriptCompilationTypeInfo(isolate, attribs);
2533     {
2534       AccessorConstantDescriptor d(
2535           Handle<Name>(Name::cast(script_compilation_type->name())),
2536           script_compilation_type, attribs);
2537       script_map->AppendDescriptor(&d);
2538     }
2539 
2540     Handle<AccessorInfo> script_line_ends =
2541         Accessors::ScriptLineEndsInfo(isolate, attribs);
2542     {
2543       AccessorConstantDescriptor d(
2544           Handle<Name>(Name::cast(script_line_ends->name())), script_line_ends,
2545           attribs);
2546       script_map->AppendDescriptor(&d);
2547     }
2548 
2549     Handle<AccessorInfo> script_context_data =
2550         Accessors::ScriptContextDataInfo(isolate, attribs);
2551     {
2552       AccessorConstantDescriptor d(
2553           Handle<Name>(Name::cast(script_context_data->name())),
2554           script_context_data, attribs);
2555       script_map->AppendDescriptor(&d);
2556     }
2557 
2558     Handle<AccessorInfo> script_eval_from_script =
2559         Accessors::ScriptEvalFromScriptInfo(isolate, attribs);
2560     {
2561       AccessorConstantDescriptor d(
2562           Handle<Name>(Name::cast(script_eval_from_script->name())),
2563           script_eval_from_script, attribs);
2564       script_map->AppendDescriptor(&d);
2565     }
2566 
2567     Handle<AccessorInfo> script_eval_from_script_position =
2568         Accessors::ScriptEvalFromScriptPositionInfo(isolate, attribs);
2569     {
2570       AccessorConstantDescriptor d(
2571           Handle<Name>(Name::cast(script_eval_from_script_position->name())),
2572           script_eval_from_script_position, attribs);
2573       script_map->AppendDescriptor(&d);
2574     }
2575 
2576     Handle<AccessorInfo> script_eval_from_function_name =
2577         Accessors::ScriptEvalFromFunctionNameInfo(isolate, attribs);
2578     {
2579       AccessorConstantDescriptor d(
2580           Handle<Name>(Name::cast(script_eval_from_function_name->name())),
2581           script_eval_from_function_name, attribs);
2582       script_map->AppendDescriptor(&d);
2583     }
2584 
2585     Handle<AccessorInfo> script_source_url =
2586         Accessors::ScriptSourceUrlInfo(isolate, attribs);
2587     {
2588       AccessorConstantDescriptor d(
2589           Handle<Name>(Name::cast(script_source_url->name())),
2590           script_source_url, attribs);
2591       script_map->AppendDescriptor(&d);
2592     }
2593 
2594     Handle<AccessorInfo> script_source_mapping_url =
2595         Accessors::ScriptSourceMappingUrlInfo(isolate, attribs);
2596     {
2597       AccessorConstantDescriptor d(
2598           Handle<Name>(Name::cast(script_source_mapping_url->name())),
2599           script_source_mapping_url, attribs);
2600       script_map->AppendDescriptor(&d);
2601     }
2602 
2603     Handle<AccessorInfo> script_is_embedder_debug_script =
2604         Accessors::ScriptIsEmbedderDebugScriptInfo(isolate, attribs);
2605     {
2606       AccessorConstantDescriptor d(
2607           Handle<Name>(Name::cast(script_is_embedder_debug_script->name())),
2608           script_is_embedder_debug_script, attribs);
2609       script_map->AppendDescriptor(&d);
2610     }
2611 
2612     {
2613       // TODO(mvstanton): Remove this when MathSinh, MathCosh and MathTanh are
2614       // no longer implemented in fdlibm.js.
2615       SimpleInstallFunction(container, "MathExpm1", Builtins::kMathExpm1, 1,
2616                             true);
2617     }
2618 
2619     {
2620       PrototypeIterator iter(native_context->sloppy_async_function_map());
2621       Handle<JSObject> async_function_prototype(iter.GetCurrent<JSObject>());
2622 
2623       static const bool kUseStrictFunctionMap = true;
2624       Handle<JSFunction> async_function_constructor = InstallFunction(
2625           container, "AsyncFunction", JS_FUNCTION_TYPE, JSFunction::kSize,
2626           async_function_prototype, Builtins::kAsyncFunctionConstructor,
2627           kUseStrictFunctionMap);
2628       async_function_constructor->set_prototype_or_initial_map(
2629           native_context->sloppy_async_function_map());
2630       async_function_constructor->shared()->DontAdaptArguments();
2631       async_function_constructor->shared()->set_construct_stub(
2632           *isolate->builtins()->AsyncFunctionConstructor());
2633       async_function_constructor->shared()->set_length(1);
2634       InstallWithIntrinsicDefaultProto(isolate, async_function_constructor,
2635                                        Context::ASYNC_FUNCTION_FUNCTION_INDEX);
2636 
2637       JSObject::AddProperty(
2638           async_function_prototype, factory->constructor_string(),
2639           async_function_constructor,
2640           static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
2641 
2642       JSFunction::SetPrototype(async_function_constructor,
2643                                async_function_prototype);
2644 
2645       Handle<JSFunction> async_function_next =
2646           SimpleInstallFunction(container, "AsyncFunctionNext",
2647                                 Builtins::kGeneratorPrototypeNext, 1, true);
2648       Handle<JSFunction> async_function_throw =
2649           SimpleInstallFunction(container, "AsyncFunctionThrow",
2650                                 Builtins::kGeneratorPrototypeThrow, 1, true);
2651       async_function_next->shared()->set_native(false);
2652       async_function_throw->shared()->set_native(false);
2653     }
2654   }
2655 }
2656 
2657 
ExportExperimentalFromRuntime(Isolate * isolate,Handle<JSObject> container)2658 void Bootstrapper::ExportExperimentalFromRuntime(Isolate* isolate,
2659                                                  Handle<JSObject> container) {
2660   HandleScope scope(isolate);
2661 
2662 #define INITIALIZE_FLAG(FLAG)                                         \
2663   {                                                                   \
2664     Handle<String> name =                                             \
2665         isolate->factory()->NewStringFromAsciiChecked(#FLAG);         \
2666     JSObject::AddProperty(container, name,                            \
2667                           isolate->factory()->ToBoolean(FLAG), NONE); \
2668   }
2669 
2670   INITIALIZE_FLAG(FLAG_intl_extra)
2671 
2672 #undef INITIALIZE_FLAG
2673 }
2674 
2675 
2676 #define EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(id) \
2677   void Genesis::InitializeGlobal_##id() {}
2678 
2679 EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_do_expressions)
EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_for_in)2680 EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_for_in)
2681 EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_regexp_lookbehind)
2682 EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_regexp_named_captures)
2683 EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_regexp_property)
2684 EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_function_sent)
2685 EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(promise_extra)
2686 EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(intl_extra)
2687 EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_explicit_tailcalls)
2688 EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_tailcalls)
2689 EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_restrictive_declarations)
2690 EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_exponentiation_operator)
2691 EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_string_padding)
2692 #ifdef V8_I18N_SUPPORT
2693 EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(icu_case_mapping)
2694 #endif
2695 EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_async_await)
2696 EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_restrictive_generators)
2697 
2698 void InstallPublicSymbol(Factory* factory, Handle<Context> native_context,
2699                          const char* name, Handle<Symbol> value) {
2700   Handle<JSGlobalObject> global(
2701       JSGlobalObject::cast(native_context->global_object()));
2702   Handle<String> symbol_string = factory->InternalizeUtf8String("Symbol");
2703   Handle<JSObject> symbol = Handle<JSObject>::cast(
2704       JSObject::GetProperty(global, symbol_string).ToHandleChecked());
2705   Handle<String> name_string = factory->InternalizeUtf8String(name);
2706   PropertyAttributes attributes =
2707       static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
2708   JSObject::AddProperty(symbol, name_string, value, attributes);
2709 }
2710 
2711 
InitializeGlobal_harmony_sharedarraybuffer()2712 void Genesis::InitializeGlobal_harmony_sharedarraybuffer() {
2713   if (!FLAG_harmony_sharedarraybuffer) return;
2714 
2715   Handle<JSGlobalObject> global(native_context()->global_object());
2716   Isolate* isolate = global->GetIsolate();
2717   Factory* factory = isolate->factory();
2718 
2719   Handle<JSFunction> shared_array_buffer_fun =
2720       InstallArrayBuffer(global, "SharedArrayBuffer");
2721   native_context()->set_shared_array_buffer_fun(*shared_array_buffer_fun);
2722 
2723   Handle<String> name = factory->InternalizeUtf8String("Atomics");
2724   Handle<JSFunction> cons = factory->NewFunction(name);
2725   JSFunction::SetInstancePrototype(
2726       cons,
2727       Handle<Object>(native_context()->initial_object_prototype(), isolate));
2728   Handle<JSObject> atomics_object = factory->NewJSObject(cons, TENURED);
2729   DCHECK(atomics_object->IsJSObject());
2730   JSObject::AddProperty(global, name, atomics_object, DONT_ENUM);
2731 
2732   SimpleInstallFunction(atomics_object, factory->InternalizeUtf8String("load"),
2733                         Builtins::kAtomicsLoad, 2, true);
2734   SimpleInstallFunction(atomics_object, factory->InternalizeUtf8String("store"),
2735                         Builtins::kAtomicsStore, 3, true);
2736 }
2737 
2738 
InitializeGlobal_harmony_simd()2739 void Genesis::InitializeGlobal_harmony_simd() {
2740   if (!FLAG_harmony_simd) return;
2741 
2742   Handle<JSGlobalObject> global(
2743       JSGlobalObject::cast(native_context()->global_object()));
2744   Isolate* isolate = global->GetIsolate();
2745   Factory* factory = isolate->factory();
2746 
2747   Handle<String> name = factory->InternalizeUtf8String("SIMD");
2748   Handle<JSFunction> cons = factory->NewFunction(name);
2749   JSFunction::SetInstancePrototype(
2750       cons,
2751       Handle<Object>(native_context()->initial_object_prototype(), isolate));
2752   cons->shared()->set_instance_class_name(*name);
2753   Handle<JSObject> simd_object = factory->NewJSObject(cons, TENURED);
2754   DCHECK(simd_object->IsJSObject());
2755   JSObject::AddProperty(global, name, simd_object, DONT_ENUM);
2756 
2757 // Install SIMD type functions. Set the instance class names since
2758 // InstallFunction only does this when we install on the JSGlobalObject.
2759 #define SIMD128_INSTALL_FUNCTION(TYPE, Type, type, lane_count, lane_type) \
2760   Handle<JSFunction> type##_function = InstallFunction(                   \
2761       simd_object, #Type, JS_VALUE_TYPE, JSValue::kSize,                  \
2762       isolate->initial_object_prototype(), Builtins::kIllegal);           \
2763   native_context()->set_##type##_function(*type##_function);              \
2764   type##_function->shared()->set_instance_class_name(*factory->Type##_string());
2765   SIMD128_TYPES(SIMD128_INSTALL_FUNCTION)
2766 #undef SIMD128_INSTALL_FUNCTION
2767 }
2768 
2769 
InitializeGlobal_harmony_object_values_entries()2770 void Genesis::InitializeGlobal_harmony_object_values_entries() {
2771   if (!FLAG_harmony_object_values_entries) return;
2772 
2773   Handle<JSGlobalObject> global(
2774       JSGlobalObject::cast(native_context()->global_object()));
2775   Isolate* isolate = global->GetIsolate();
2776   Factory* factory = isolate->factory();
2777 
2778   Handle<JSFunction> object_function = isolate->object_function();
2779   SimpleInstallFunction(object_function, factory->entries_string(),
2780                         Builtins::kObjectEntries, 1, false);
2781   SimpleInstallFunction(object_function, factory->values_string(),
2782                         Builtins::kObjectValues, 1, false);
2783 }
2784 
InitializeGlobal_harmony_object_own_property_descriptors()2785 void Genesis::InitializeGlobal_harmony_object_own_property_descriptors() {
2786   if (!FLAG_harmony_object_own_property_descriptors) return;
2787 
2788   Handle<JSGlobalObject> global(
2789       JSGlobalObject::cast(native_context()->global_object()));
2790   Isolate* isolate = global->GetIsolate();
2791   Factory* factory = isolate->factory();
2792 
2793   Handle<JSFunction> object_function = isolate->object_function();
2794   SimpleInstallFunction(object_function,
2795                         factory->getOwnPropertyDescriptors_string(),
2796                         Builtins::kObjectGetOwnPropertyDescriptors, 1, false);
2797 }
2798 
InitializeGlobal_harmony_array_prototype_values()2799 void Genesis::InitializeGlobal_harmony_array_prototype_values() {
2800   if (!FLAG_harmony_array_prototype_values) return;
2801   Handle<JSFunction> array_constructor(native_context()->array_function());
2802   Handle<JSObject> array_prototype(
2803       JSObject::cast(array_constructor->instance_prototype()));
2804   Handle<Object> values_iterator =
2805       JSObject::GetProperty(array_prototype, factory()->iterator_symbol())
2806           .ToHandleChecked();
2807   DCHECK(values_iterator->IsJSFunction());
2808   JSObject::AddProperty(array_prototype, factory()->values_string(),
2809                         values_iterator, DONT_ENUM);
2810 
2811   Handle<Object> unscopables =
2812       JSObject::GetProperty(array_prototype, factory()->unscopables_symbol())
2813           .ToHandleChecked();
2814   DCHECK(unscopables->IsJSObject());
2815   JSObject::AddProperty(Handle<JSObject>::cast(unscopables),
2816                         factory()->values_string(), factory()->true_value(),
2817                         NONE);
2818 }
2819 
InstallArrayBuffer(Handle<JSObject> target,const char * name)2820 Handle<JSFunction> Genesis::InstallArrayBuffer(Handle<JSObject> target,
2821                                                const char* name) {
2822   // Setup the {prototype} with the given {name} for @@toStringTag.
2823   Handle<JSObject> prototype =
2824       factory()->NewJSObject(isolate()->object_function(), TENURED);
2825   JSObject::AddProperty(prototype, factory()->to_string_tag_symbol(),
2826                         factory()->NewStringFromAsciiChecked(name),
2827                         static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
2828 
2829   // Allocate the constructor with the given {prototype}.
2830   Handle<JSFunction> array_buffer_fun =
2831       InstallFunction(target, name, JS_ARRAY_BUFFER_TYPE,
2832                       JSArrayBuffer::kSizeWithInternalFields, prototype,
2833                       Builtins::kArrayBufferConstructor);
2834   array_buffer_fun->shared()->set_construct_stub(
2835       *isolate()->builtins()->ArrayBufferConstructor_ConstructStub());
2836   array_buffer_fun->shared()->DontAdaptArguments();
2837   array_buffer_fun->shared()->set_length(1);
2838 
2839   // Install the "constructor" property on the {prototype}.
2840   JSObject::AddProperty(prototype, factory()->constructor_string(),
2841                         array_buffer_fun, DONT_ENUM);
2842 
2843   SimpleInstallFunction(array_buffer_fun, factory()->isView_string(),
2844                         Builtins::kArrayBufferIsView, 1, true);
2845 
2846   return array_buffer_fun;
2847 }
2848 
2849 
InstallInternalArray(Handle<JSObject> target,const char * name,ElementsKind elements_kind)2850 Handle<JSFunction> Genesis::InstallInternalArray(Handle<JSObject> target,
2851                                                  const char* name,
2852                                                  ElementsKind elements_kind) {
2853   // --- I n t e r n a l   A r r a y ---
2854   // An array constructor on the builtins object that works like
2855   // the public Array constructor, except that its prototype
2856   // doesn't inherit from Object.prototype.
2857   // To be used only for internal work by builtins. Instances
2858   // must not be leaked to user code.
2859   Handle<JSObject> prototype =
2860       factory()->NewJSObject(isolate()->object_function(), TENURED);
2861   Handle<JSFunction> array_function =
2862       InstallFunction(target, name, JS_ARRAY_TYPE, JSArray::kSize, prototype,
2863                       Builtins::kInternalArrayCode);
2864 
2865   InternalArrayConstructorStub internal_array_constructor_stub(isolate());
2866   Handle<Code> code = internal_array_constructor_stub.GetCode();
2867   array_function->shared()->set_construct_stub(*code);
2868   array_function->shared()->DontAdaptArguments();
2869 
2870   Handle<Map> original_map(array_function->initial_map());
2871   Handle<Map> initial_map = Map::Copy(original_map, "InternalArray");
2872   initial_map->set_elements_kind(elements_kind);
2873   JSFunction::SetInitialMap(array_function, initial_map, prototype);
2874 
2875   // Make "length" magic on instances.
2876   Map::EnsureDescriptorSlack(initial_map, 1);
2877 
2878   PropertyAttributes attribs = static_cast<PropertyAttributes>(
2879       DONT_ENUM | DONT_DELETE);
2880 
2881   Handle<AccessorInfo> array_length =
2882       Accessors::ArrayLengthInfo(isolate(), attribs);
2883   {  // Add length.
2884     AccessorConstantDescriptor d(Handle<Name>(Name::cast(array_length->name())),
2885                                  array_length, attribs);
2886     initial_map->AppendDescriptor(&d);
2887   }
2888 
2889   return array_function;
2890 }
2891 
InstallNatives(GlobalContextType context_type)2892 bool Genesis::InstallNatives(GlobalContextType context_type) {
2893   HandleScope scope(isolate());
2894 
2895   // Set up the utils object as shared container between native scripts.
2896   Handle<JSObject> utils = factory()->NewJSObject(isolate()->object_function());
2897   JSObject::NormalizeProperties(utils, CLEAR_INOBJECT_PROPERTIES, 16,
2898                                 "utils container for native scripts");
2899   native_context()->set_natives_utils_object(*utils);
2900 
2901   // Set up the extras utils object as a shared container between native
2902   // scripts and extras. (Extras consume things added there by native scripts.)
2903   Handle<JSObject> extras_utils =
2904       factory()->NewJSObject(isolate()->object_function());
2905   native_context()->set_extras_utils_object(*extras_utils);
2906 
2907   InstallInternalArray(extras_utils, "InternalPackedArray", FAST_ELEMENTS);
2908 
2909   int builtin_index = Natives::GetDebuggerCount();
2910   // Only run prologue.js and runtime.js at this point.
2911   DCHECK_EQ(builtin_index, Natives::GetIndex("prologue"));
2912   if (!Bootstrapper::CompileBuiltin(isolate(), builtin_index++)) return false;
2913   DCHECK_EQ(builtin_index, Natives::GetIndex("runtime"));
2914   if (!Bootstrapper::CompileBuiltin(isolate(), builtin_index++)) return false;
2915 
2916   {
2917     // Builtin function for OpaqueReference -- a JSValue-based object,
2918     // that keeps its field isolated from JavaScript code. It may store
2919     // objects, that JavaScript code may not access.
2920     Handle<JSFunction> opaque_reference_fun = factory()->NewFunction(
2921         factory()->empty_string(), isolate()->builtins()->Illegal(),
2922         isolate()->initial_object_prototype(), JS_VALUE_TYPE, JSValue::kSize);
2923     Handle<JSObject> prototype =
2924         factory()->NewJSObject(isolate()->object_function(), TENURED);
2925     Accessors::FunctionSetPrototype(opaque_reference_fun, prototype).Assert();
2926     native_context()->set_opaque_reference_function(*opaque_reference_fun);
2927   }
2928 
2929   // InternalArrays should not use Smi-Only array optimizations. There are too
2930   // many places in the C++ runtime code (e.g. RegEx) that assume that
2931   // elements in InternalArrays can be set to non-Smi values without going
2932   // through a common bottleneck that would make the SMI_ONLY -> FAST_ELEMENT
2933   // transition easy to trap. Moreover, they rarely are smi-only.
2934   {
2935     HandleScope scope(isolate());
2936     Handle<JSObject> utils =
2937         Handle<JSObject>::cast(isolate()->natives_utils_object());
2938     Handle<JSFunction> array_function =
2939         InstallInternalArray(utils, "InternalArray", FAST_HOLEY_ELEMENTS);
2940     native_context()->set_internal_array_function(*array_function);
2941     InstallInternalArray(utils, "InternalPackedArray", FAST_ELEMENTS);
2942   }
2943 
2944   // Run the rest of the native scripts.
2945   while (builtin_index < Natives::GetBuiltinsCount()) {
2946     if (!Bootstrapper::CompileBuiltin(isolate(), builtin_index++)) return false;
2947   }
2948 
2949   if (!CallUtilsFunction(isolate(), "PostNatives")) return false;
2950 
2951   auto template_instantiations_cache = UnseededNumberDictionary::New(
2952       isolate(), ApiNatives::kInitialFunctionCacheSize);
2953   native_context()->set_template_instantiations_cache(
2954       *template_instantiations_cache);
2955 
2956   // Store the map for the %ObjectPrototype% after the natives has been compiled
2957   // and the Object function has been set up.
2958   Handle<JSFunction> object_function(native_context()->object_function());
2959   DCHECK(JSObject::cast(object_function->initial_map()->prototype())
2960              ->HasFastProperties());
2961   native_context()->set_object_function_prototype_map(
2962       HeapObject::cast(object_function->initial_map()->prototype())->map());
2963 
2964   // Set up the map for Object.create(null) instances.
2965   Handle<Map> object_with_null_prototype_map =
2966       Map::CopyInitialMap(handle(object_function->initial_map(), isolate()));
2967   Map::SetPrototype(object_with_null_prototype_map,
2968                     isolate()->factory()->null_value());
2969   native_context()->set_object_with_null_prototype_map(
2970       *object_with_null_prototype_map);
2971 
2972   // Store the map for the %StringPrototype% after the natives has been compiled
2973   // and the String function has been set up.
2974   Handle<JSFunction> string_function(native_context()->string_function());
2975   DCHECK(JSObject::cast(
2976       string_function->initial_map()->prototype())->HasFastProperties());
2977   native_context()->set_string_function_prototype_map(
2978       HeapObject::cast(string_function->initial_map()->prototype())->map());
2979 
2980   Handle<JSGlobalObject> global_object =
2981       handle(native_context()->global_object());
2982 
2983   // Install Global.decodeURI.
2984   SimpleInstallFunction(global_object, "decodeURI", Builtins::kGlobalDecodeURI,
2985                         1, false);
2986 
2987   // Install Global.decodeURIComponent.
2988   SimpleInstallFunction(global_object, "decodeURIComponent",
2989                         Builtins::kGlobalDecodeURIComponent, 1, false);
2990 
2991   // Install Global.encodeURI.
2992   SimpleInstallFunction(global_object, "encodeURI", Builtins::kGlobalEncodeURI,
2993                         1, false);
2994 
2995   // Install Global.encodeURIComponent.
2996   SimpleInstallFunction(global_object, "encodeURIComponent",
2997                         Builtins::kGlobalEncodeURIComponent, 1, false);
2998 
2999   // Install Global.escape.
3000   SimpleInstallFunction(global_object, "escape", Builtins::kGlobalEscape, 1,
3001                         false);
3002 
3003   // Install Global.unescape.
3004   SimpleInstallFunction(global_object, "unescape", Builtins::kGlobalUnescape, 1,
3005                         false);
3006 
3007   // Install Global.eval.
3008   {
3009     Handle<JSFunction> eval =
3010         SimpleInstallFunction(global_object, factory()->eval_string(),
3011                               Builtins::kGlobalEval, 1, false);
3012     native_context()->set_global_eval_fun(*eval);
3013   }
3014 
3015   // Install Array.prototype.concat
3016   {
3017     Handle<JSFunction> array_constructor(native_context()->array_function());
3018     Handle<JSObject> proto(JSObject::cast(array_constructor->prototype()));
3019     Handle<JSFunction> concat =
3020         InstallFunction(proto, "concat", JS_OBJECT_TYPE, JSObject::kHeaderSize,
3021                         MaybeHandle<JSObject>(), Builtins::kArrayConcat);
3022 
3023     // Make sure that Array.prototype.concat appears to be compiled.
3024     // The code will never be called, but inline caching for call will
3025     // only work if it appears to be compiled.
3026     concat->shared()->DontAdaptArguments();
3027     DCHECK(concat->is_compiled());
3028     // Set the lengths for the functions to satisfy ECMA-262.
3029     concat->shared()->set_length(1);
3030   }
3031 
3032   // Install InternalArray.prototype.concat
3033   {
3034     Handle<JSFunction> array_constructor(
3035         native_context()->internal_array_function());
3036     Handle<JSObject> proto(JSObject::cast(array_constructor->prototype()));
3037     Handle<JSFunction> concat =
3038         InstallFunction(proto, "concat", JS_OBJECT_TYPE, JSObject::kHeaderSize,
3039                         MaybeHandle<JSObject>(), Builtins::kArrayConcat);
3040 
3041     // Make sure that InternalArray.prototype.concat appears to be compiled.
3042     // The code will never be called, but inline caching for call will
3043     // only work if it appears to be compiled.
3044     concat->shared()->DontAdaptArguments();
3045     DCHECK(concat->is_compiled());
3046     // Set the lengths for the functions to satisfy ECMA-262.
3047     concat->shared()->set_length(1);
3048   }
3049 
3050   // Set up the Promise constructor.
3051   {
3052     Handle<String> key = factory()->Promise_string();
3053     Handle<JSFunction> function = Handle<JSFunction>::cast(
3054         JSReceiver::GetProperty(global_object, key).ToHandleChecked());
3055     JSFunction::EnsureHasInitialMap(function);
3056     function->initial_map()->set_instance_type(JS_PROMISE_TYPE);
3057     function->shared()->set_construct_stub(
3058         *isolate()->builtins()->JSBuiltinsConstructStub());
3059     InstallWithIntrinsicDefaultProto(isolate(), function,
3060                                      Context::PROMISE_FUNCTION_INDEX);
3061   }
3062 
3063   InstallBuiltinFunctionIds();
3064 
3065   // Create a map for accessor property descriptors (a variant of JSObject
3066   // that predefines four properties get, set, configurable and enumerable).
3067   {
3068     // AccessorPropertyDescriptor initial map.
3069     Handle<Map> map =
3070         factory()->NewMap(JS_OBJECT_TYPE, JSAccessorPropertyDescriptor::kSize);
3071     // Create the descriptor array for the property descriptor object.
3072     Map::EnsureDescriptorSlack(map, 4);
3073 
3074     {  // get
3075       DataDescriptor d(factory()->get_string(),
3076                        JSAccessorPropertyDescriptor::kGetIndex, NONE,
3077                        Representation::Tagged());
3078       map->AppendDescriptor(&d);
3079     }
3080     {  // set
3081       DataDescriptor d(factory()->set_string(),
3082                        JSAccessorPropertyDescriptor::kSetIndex, NONE,
3083                        Representation::Tagged());
3084       map->AppendDescriptor(&d);
3085     }
3086     {  // enumerable
3087       DataDescriptor d(factory()->enumerable_string(),
3088                        JSAccessorPropertyDescriptor::kEnumerableIndex, NONE,
3089                        Representation::Tagged());
3090       map->AppendDescriptor(&d);
3091     }
3092     {  // configurable
3093       DataDescriptor d(factory()->configurable_string(),
3094                        JSAccessorPropertyDescriptor::kConfigurableIndex, NONE,
3095                        Representation::Tagged());
3096       map->AppendDescriptor(&d);
3097     }
3098 
3099     Map::SetPrototype(map, isolate()->initial_object_prototype());
3100     map->SetConstructor(native_context()->object_function());
3101     map->SetInObjectProperties(4);
3102     map->set_unused_property_fields(0);
3103 
3104     native_context()->set_accessor_property_descriptor_map(*map);
3105   }
3106 
3107   // Create a map for data property descriptors (a variant of JSObject
3108   // that predefines four properties value, writable, configurable and
3109   // enumerable).
3110   {
3111     // DataPropertyDescriptor initial map.
3112     Handle<Map> map =
3113         factory()->NewMap(JS_OBJECT_TYPE, JSDataPropertyDescriptor::kSize);
3114     // Create the descriptor array for the property descriptor object.
3115     Map::EnsureDescriptorSlack(map, 4);
3116 
3117     {  // value
3118       DataDescriptor d(factory()->value_string(),
3119                        JSDataPropertyDescriptor::kValueIndex, NONE,
3120                        Representation::Tagged());
3121       map->AppendDescriptor(&d);
3122     }
3123     {  // writable
3124       DataDescriptor d(factory()->writable_string(),
3125                        JSDataPropertyDescriptor::kWritableIndex, NONE,
3126                        Representation::Tagged());
3127       map->AppendDescriptor(&d);
3128     }
3129     {  // enumerable
3130       DataDescriptor d(factory()->enumerable_string(),
3131                        JSDataPropertyDescriptor::kEnumerableIndex, NONE,
3132                        Representation::Tagged());
3133       map->AppendDescriptor(&d);
3134     }
3135     {  // configurable
3136       DataDescriptor d(factory()->configurable_string(),
3137                        JSDataPropertyDescriptor::kConfigurableIndex, NONE,
3138                        Representation::Tagged());
3139       map->AppendDescriptor(&d);
3140     }
3141 
3142     Map::SetPrototype(map, isolate()->initial_object_prototype());
3143     map->SetConstructor(native_context()->object_function());
3144     map->SetInObjectProperties(4);
3145     map->set_unused_property_fields(0);
3146 
3147     native_context()->set_data_property_descriptor_map(*map);
3148   }
3149 
3150   // Create a constructor for RegExp results (a variant of Array that
3151   // predefines the two properties index and match).
3152   {
3153     // RegExpResult initial map.
3154 
3155     // Find global.Array.prototype to inherit from.
3156     Handle<JSFunction> array_constructor(native_context()->array_function());
3157     Handle<JSObject> array_prototype(
3158         JSObject::cast(array_constructor->instance_prototype()));
3159 
3160     // Add initial map.
3161     Handle<Map> initial_map =
3162         factory()->NewMap(JS_ARRAY_TYPE, JSRegExpResult::kSize);
3163     initial_map->SetConstructor(*array_constructor);
3164 
3165     // Set prototype on map.
3166     initial_map->set_non_instance_prototype(false);
3167     Map::SetPrototype(initial_map, array_prototype);
3168 
3169     // Update map with length accessor from Array and add "index" and "input".
3170     Map::EnsureDescriptorSlack(initial_map, 3);
3171 
3172     {
3173       JSFunction* array_function = native_context()->array_function();
3174       Handle<DescriptorArray> array_descriptors(
3175           array_function->initial_map()->instance_descriptors());
3176       Handle<String> length = factory()->length_string();
3177       int old = array_descriptors->SearchWithCache(
3178           isolate(), *length, array_function->initial_map());
3179       DCHECK(old != DescriptorArray::kNotFound);
3180       AccessorConstantDescriptor desc(
3181           length, handle(array_descriptors->GetValue(old), isolate()),
3182           array_descriptors->GetDetails(old).attributes());
3183       initial_map->AppendDescriptor(&desc);
3184     }
3185     {
3186       DataDescriptor index_field(factory()->index_string(),
3187                                  JSRegExpResult::kIndexIndex, NONE,
3188                                  Representation::Tagged());
3189       initial_map->AppendDescriptor(&index_field);
3190     }
3191 
3192     {
3193       DataDescriptor input_field(factory()->input_string(),
3194                                  JSRegExpResult::kInputIndex, NONE,
3195                                  Representation::Tagged());
3196       initial_map->AppendDescriptor(&input_field);
3197     }
3198 
3199     initial_map->SetInObjectProperties(2);
3200     initial_map->set_unused_property_fields(0);
3201 
3202     native_context()->set_regexp_result_map(*initial_map);
3203   }
3204 
3205   // Add @@iterator method to the arguments object maps.
3206   {
3207     PropertyAttributes attribs = DONT_ENUM;
3208     Handle<AccessorInfo> arguments_iterator =
3209         Accessors::ArgumentsIteratorInfo(isolate(), attribs);
3210     {
3211       AccessorConstantDescriptor d(factory()->iterator_symbol(),
3212                                    arguments_iterator, attribs);
3213       Handle<Map> map(native_context()->sloppy_arguments_map());
3214       Map::EnsureDescriptorSlack(map, 1);
3215       map->AppendDescriptor(&d);
3216     }
3217     {
3218       AccessorConstantDescriptor d(factory()->iterator_symbol(),
3219                                    arguments_iterator, attribs);
3220       Handle<Map> map(native_context()->fast_aliased_arguments_map());
3221       Map::EnsureDescriptorSlack(map, 1);
3222       map->AppendDescriptor(&d);
3223     }
3224     {
3225       AccessorConstantDescriptor d(factory()->iterator_symbol(),
3226                                    arguments_iterator, attribs);
3227       Handle<Map> map(native_context()->slow_aliased_arguments_map());
3228       Map::EnsureDescriptorSlack(map, 1);
3229       map->AppendDescriptor(&d);
3230     }
3231     {
3232       AccessorConstantDescriptor d(factory()->iterator_symbol(),
3233                                    arguments_iterator, attribs);
3234       Handle<Map> map(native_context()->strict_arguments_map());
3235       Map::EnsureDescriptorSlack(map, 1);
3236       map->AppendDescriptor(&d);
3237     }
3238   }
3239 
3240   return true;
3241 }
3242 
3243 
InstallExperimentalNatives()3244 bool Genesis::InstallExperimentalNatives() {
3245   static const char* harmony_explicit_tailcalls_natives[] = {nullptr};
3246   static const char* harmony_tailcalls_natives[] = {nullptr};
3247   static const char* harmony_sharedarraybuffer_natives[] = {
3248       "native harmony-sharedarraybuffer.js", "native harmony-atomics.js", NULL};
3249   static const char* harmony_simd_natives[] = {"native harmony-simd.js",
3250                                                nullptr};
3251   static const char* harmony_do_expressions_natives[] = {nullptr};
3252   static const char* harmony_for_in_natives[] = {nullptr};
3253   static const char* harmony_regexp_lookbehind_natives[] = {nullptr};
3254   static const char* harmony_restrictive_declarations_natives[] = {nullptr};
3255   static const char* harmony_regexp_named_captures_natives[] = {nullptr};
3256   static const char* harmony_regexp_property_natives[] = {nullptr};
3257   static const char* harmony_function_sent_natives[] = {nullptr};
3258   static const char* promise_extra_natives[] = {"native promise-extra.js",
3259                                                 nullptr};
3260   static const char* intl_extra_natives[] = {"native intl-extra.js", nullptr};
3261   static const char* harmony_object_values_entries_natives[] = {nullptr};
3262   static const char* harmony_object_own_property_descriptors_natives[] = {
3263       nullptr};
3264   static const char* harmony_array_prototype_values_natives[] = {nullptr};
3265   static const char* harmony_exponentiation_operator_natives[] = {nullptr};
3266   static const char* harmony_string_padding_natives[] = {
3267       "native harmony-string-padding.js", nullptr};
3268 #ifdef V8_I18N_SUPPORT
3269   static const char* icu_case_mapping_natives[] = {"native icu-case-mapping.js",
3270                                                    nullptr};
3271 #endif
3272   static const char* harmony_async_await_natives[] = {
3273       "native harmony-async-await.js", nullptr};
3274   static const char* harmony_restrictive_generators_natives[] = {nullptr};
3275 
3276   for (int i = ExperimentalNatives::GetDebuggerCount();
3277        i < ExperimentalNatives::GetBuiltinsCount(); i++) {
3278 #define INSTALL_EXPERIMENTAL_NATIVES(id, desc)                                \
3279   if (FLAG_##id) {                                                            \
3280     for (size_t j = 0; id##_natives[j] != NULL; j++) {                        \
3281       Vector<const char> script_name = ExperimentalNatives::GetScriptName(i); \
3282       if (strncmp(script_name.start(), id##_natives[j],                       \
3283                   script_name.length()) == 0) {                               \
3284         if (!Bootstrapper::CompileExperimentalBuiltin(isolate(), i)) {        \
3285           return false;                                                       \
3286         }                                                                     \
3287       }                                                                       \
3288     }                                                                         \
3289   }
3290     HARMONY_INPROGRESS(INSTALL_EXPERIMENTAL_NATIVES);
3291     HARMONY_STAGED(INSTALL_EXPERIMENTAL_NATIVES);
3292     HARMONY_SHIPPING(INSTALL_EXPERIMENTAL_NATIVES);
3293     INSTALL_EXPERIMENTAL_NATIVES(intl_extra, "");
3294     INSTALL_EXPERIMENTAL_NATIVES(promise_extra, "");
3295 #undef INSTALL_EXPERIMENTAL_NATIVES
3296   }
3297 
3298   if (!CallUtilsFunction(isolate(), "PostExperimentals")) return false;
3299 
3300   InstallExperimentalBuiltinFunctionIds();
3301   return true;
3302 }
3303 
3304 
InstallExtraNatives()3305 bool Genesis::InstallExtraNatives() {
3306   HandleScope scope(isolate());
3307 
3308   Handle<JSObject> extras_binding =
3309       factory()->NewJSObject(isolate()->object_function());
3310   native_context()->set_extras_binding_object(*extras_binding);
3311 
3312   for (int i = ExtraNatives::GetDebuggerCount();
3313        i < ExtraNatives::GetBuiltinsCount(); i++) {
3314     if (!Bootstrapper::CompileExtraBuiltin(isolate(), i)) return false;
3315   }
3316 
3317   return true;
3318 }
3319 
3320 
InstallExperimentalExtraNatives()3321 bool Genesis::InstallExperimentalExtraNatives() {
3322   for (int i = ExperimentalExtraNatives::GetDebuggerCount();
3323        i < ExperimentalExtraNatives::GetBuiltinsCount(); i++) {
3324     if (!Bootstrapper::CompileExperimentalExtraBuiltin(isolate(), i))
3325       return false;
3326   }
3327 
3328   return true;
3329 }
3330 
3331 
InstallDebuggerNatives()3332 bool Genesis::InstallDebuggerNatives() {
3333   for (int i = 0; i < Natives::GetDebuggerCount(); ++i) {
3334     if (!Bootstrapper::CompileBuiltin(isolate(), i)) return false;
3335   }
3336   return CallUtilsFunction(isolate(), "PostDebug");
3337 }
3338 
3339 
InstallBuiltinFunctionId(Handle<JSObject> holder,const char * function_name,BuiltinFunctionId id)3340 static void InstallBuiltinFunctionId(Handle<JSObject> holder,
3341                                      const char* function_name,
3342                                      BuiltinFunctionId id) {
3343   Isolate* isolate = holder->GetIsolate();
3344   Handle<Object> function_object =
3345       JSReceiver::GetProperty(isolate, holder, function_name).ToHandleChecked();
3346   Handle<JSFunction> function = Handle<JSFunction>::cast(function_object);
3347   function->shared()->set_builtin_function_id(id);
3348 }
3349 
3350 
3351 #define INSTALL_BUILTIN_ID(holder_expr, fun_name, name) \
3352   { #holder_expr, #fun_name, k##name }                  \
3353   ,
3354 
3355 
InstallBuiltinFunctionIds()3356 void Genesis::InstallBuiltinFunctionIds() {
3357   HandleScope scope(isolate());
3358   struct BuiltinFunctionIds {
3359     const char* holder_expr;
3360     const char* fun_name;
3361     BuiltinFunctionId id;
3362   };
3363 
3364   const BuiltinFunctionIds builtins[] = {
3365       FUNCTIONS_WITH_ID_LIST(INSTALL_BUILTIN_ID)};
3366 
3367   for (const BuiltinFunctionIds& builtin : builtins) {
3368     Handle<JSObject> holder =
3369         ResolveBuiltinIdHolder(native_context(), builtin.holder_expr);
3370     InstallBuiltinFunctionId(holder, builtin.fun_name, builtin.id);
3371   }
3372 }
3373 
3374 
InstallExperimentalBuiltinFunctionIds()3375 void Genesis::InstallExperimentalBuiltinFunctionIds() {
3376   if (FLAG_harmony_sharedarraybuffer) {
3377     struct BuiltinFunctionIds {
3378       const char* holder_expr;
3379       const char* fun_name;
3380       BuiltinFunctionId id;
3381     };
3382 
3383     const BuiltinFunctionIds atomic_builtins[] = {
3384         ATOMIC_FUNCTIONS_WITH_ID_LIST(INSTALL_BUILTIN_ID)};
3385 
3386     for (const BuiltinFunctionIds& builtin : atomic_builtins) {
3387       Handle<JSObject> holder =
3388           ResolveBuiltinIdHolder(native_context(), builtin.holder_expr);
3389       InstallBuiltinFunctionId(holder, builtin.fun_name, builtin.id);
3390     }
3391   }
3392 }
3393 
3394 
3395 #undef INSTALL_BUILTIN_ID
3396 
3397 
InitializeNormalizedMapCaches()3398 void Genesis::InitializeNormalizedMapCaches() {
3399   Handle<NormalizedMapCache> cache = NormalizedMapCache::New(isolate());
3400   native_context()->set_normalized_map_cache(*cache);
3401 }
3402 
3403 
InstallExtensions(Handle<Context> native_context,v8::ExtensionConfiguration * extensions)3404 bool Bootstrapper::InstallExtensions(Handle<Context> native_context,
3405                                      v8::ExtensionConfiguration* extensions) {
3406   BootstrapperActive active(this);
3407   SaveContext saved_context(isolate_);
3408   isolate_->set_context(*native_context);
3409   return Genesis::InstallExtensions(native_context, extensions) &&
3410       Genesis::InstallSpecialObjects(native_context);
3411 }
3412 
3413 
InstallSpecialObjects(Handle<Context> native_context)3414 bool Genesis::InstallSpecialObjects(Handle<Context> native_context) {
3415   Isolate* isolate = native_context->GetIsolate();
3416   // Don't install extensions into the snapshot.
3417   if (isolate->serializer_enabled()) return true;
3418 
3419   Factory* factory = isolate->factory();
3420   HandleScope scope(isolate);
3421   Handle<JSGlobalObject> global(JSGlobalObject::cast(
3422       native_context->global_object()));
3423 
3424   Handle<JSObject> Error = isolate->error_function();
3425   Handle<String> name =
3426       factory->InternalizeOneByteString(STATIC_CHAR_VECTOR("stackTraceLimit"));
3427   Handle<Smi> stack_trace_limit(Smi::FromInt(FLAG_stack_trace_limit), isolate);
3428   JSObject::AddProperty(Error, name, stack_trace_limit, NONE);
3429 
3430   // Expose the debug global object in global if a name for it is specified.
3431   if (FLAG_expose_debug_as != NULL && strlen(FLAG_expose_debug_as) != 0) {
3432     // If loading fails we just bail out without installing the
3433     // debugger but without tanking the whole context.
3434     Debug* debug = isolate->debug();
3435     if (!debug->Load()) return true;
3436     Handle<Context> debug_context = debug->debug_context();
3437     // Set the security token for the debugger context to the same as
3438     // the shell native context to allow calling between these (otherwise
3439     // exposing debug global object doesn't make much sense).
3440     debug_context->set_security_token(native_context->security_token());
3441     Handle<String> debug_string =
3442         factory->InternalizeUtf8String(FLAG_expose_debug_as);
3443     uint32_t index;
3444     if (debug_string->AsArrayIndex(&index)) return true;
3445     Handle<Object> global_proxy(debug_context->global_proxy(), isolate);
3446     JSObject::AddProperty(global, debug_string, global_proxy, DONT_ENUM);
3447   }
3448 
3449   if (FLAG_expose_wasm) {
3450     WasmJs::Install(isolate, global);
3451   }
3452 
3453   return true;
3454 }
3455 
3456 
Hash(RegisteredExtension * extension)3457 static uint32_t Hash(RegisteredExtension* extension) {
3458   return v8::internal::ComputePointerHash(extension);
3459 }
3460 
ExtensionStates()3461 Genesis::ExtensionStates::ExtensionStates()
3462     : map_(base::HashMap::PointersMatch, 8) {}
3463 
get_state(RegisteredExtension * extension)3464 Genesis::ExtensionTraversalState Genesis::ExtensionStates::get_state(
3465     RegisteredExtension* extension) {
3466   base::HashMap::Entry* entry = map_.Lookup(extension, Hash(extension));
3467   if (entry == NULL) {
3468     return UNVISITED;
3469   }
3470   return static_cast<ExtensionTraversalState>(
3471       reinterpret_cast<intptr_t>(entry->value));
3472 }
3473 
set_state(RegisteredExtension * extension,ExtensionTraversalState state)3474 void Genesis::ExtensionStates::set_state(RegisteredExtension* extension,
3475                                          ExtensionTraversalState state) {
3476   map_.LookupOrInsert(extension, Hash(extension))->value =
3477       reinterpret_cast<void*>(static_cast<intptr_t>(state));
3478 }
3479 
3480 
InstallExtensions(Handle<Context> native_context,v8::ExtensionConfiguration * extensions)3481 bool Genesis::InstallExtensions(Handle<Context> native_context,
3482                                 v8::ExtensionConfiguration* extensions) {
3483   Isolate* isolate = native_context->GetIsolate();
3484   ExtensionStates extension_states;  // All extensions have state UNVISITED.
3485   return InstallAutoExtensions(isolate, &extension_states) &&
3486          (!FLAG_expose_free_buffer ||
3487           InstallExtension(isolate, "v8/free-buffer", &extension_states)) &&
3488          (!FLAG_expose_gc ||
3489           InstallExtension(isolate, "v8/gc", &extension_states)) &&
3490          (!FLAG_expose_externalize_string ||
3491           InstallExtension(isolate, "v8/externalize", &extension_states)) &&
3492          (!FLAG_track_gc_object_stats ||
3493           InstallExtension(isolate, "v8/statistics", &extension_states)) &&
3494          (!FLAG_expose_trigger_failure ||
3495           InstallExtension(isolate, "v8/trigger-failure", &extension_states)) &&
3496          (!(FLAG_ignition && FLAG_trace_ignition_dispatches) ||
3497           InstallExtension(isolate, "v8/ignition-statistics",
3498                            &extension_states)) &&
3499          InstallRequestedExtensions(isolate, extensions, &extension_states);
3500 }
3501 
3502 
InstallAutoExtensions(Isolate * isolate,ExtensionStates * extension_states)3503 bool Genesis::InstallAutoExtensions(Isolate* isolate,
3504                                     ExtensionStates* extension_states) {
3505   for (v8::RegisteredExtension* it = v8::RegisteredExtension::first_extension();
3506        it != NULL;
3507        it = it->next()) {
3508     if (it->extension()->auto_enable() &&
3509         !InstallExtension(isolate, it, extension_states)) {
3510       return false;
3511     }
3512   }
3513   return true;
3514 }
3515 
3516 
InstallRequestedExtensions(Isolate * isolate,v8::ExtensionConfiguration * extensions,ExtensionStates * extension_states)3517 bool Genesis::InstallRequestedExtensions(Isolate* isolate,
3518                                          v8::ExtensionConfiguration* extensions,
3519                                          ExtensionStates* extension_states) {
3520   for (const char** it = extensions->begin(); it != extensions->end(); ++it) {
3521     if (!InstallExtension(isolate, *it, extension_states)) return false;
3522   }
3523   return true;
3524 }
3525 
3526 
3527 // Installs a named extension.  This methods is unoptimized and does
3528 // not scale well if we want to support a large number of extensions.
InstallExtension(Isolate * isolate,const char * name,ExtensionStates * extension_states)3529 bool Genesis::InstallExtension(Isolate* isolate,
3530                                const char* name,
3531                                ExtensionStates* extension_states) {
3532   for (v8::RegisteredExtension* it = v8::RegisteredExtension::first_extension();
3533        it != NULL;
3534        it = it->next()) {
3535     if (strcmp(name, it->extension()->name()) == 0) {
3536       return InstallExtension(isolate, it, extension_states);
3537     }
3538   }
3539   return Utils::ApiCheck(false,
3540                          "v8::Context::New()",
3541                          "Cannot find required extension");
3542 }
3543 
3544 
InstallExtension(Isolate * isolate,v8::RegisteredExtension * current,ExtensionStates * extension_states)3545 bool Genesis::InstallExtension(Isolate* isolate,
3546                                v8::RegisteredExtension* current,
3547                                ExtensionStates* extension_states) {
3548   HandleScope scope(isolate);
3549 
3550   if (extension_states->get_state(current) == INSTALLED) return true;
3551   // The current node has already been visited so there must be a
3552   // cycle in the dependency graph; fail.
3553   if (!Utils::ApiCheck(extension_states->get_state(current) != VISITED,
3554                        "v8::Context::New()",
3555                        "Circular extension dependency")) {
3556     return false;
3557   }
3558   DCHECK(extension_states->get_state(current) == UNVISITED);
3559   extension_states->set_state(current, VISITED);
3560   v8::Extension* extension = current->extension();
3561   // Install the extension's dependencies
3562   for (int i = 0; i < extension->dependency_count(); i++) {
3563     if (!InstallExtension(isolate,
3564                           extension->dependencies()[i],
3565                           extension_states)) {
3566       return false;
3567     }
3568   }
3569   // We do not expect this to throw an exception. Change this if it does.
3570   bool result = CompileExtension(isolate, extension);
3571   DCHECK(isolate->has_pending_exception() != result);
3572   if (!result) {
3573     // We print out the name of the extension that fail to install.
3574     // When an error is thrown during bootstrapping we automatically print
3575     // the line number at which this happened to the console in the isolate
3576     // error throwing functionality.
3577     base::OS::PrintError("Error installing extension '%s'.\n",
3578                          current->extension()->name());
3579     isolate->clear_pending_exception();
3580   }
3581   extension_states->set_state(current, INSTALLED);
3582   isolate->NotifyExtensionInstalled();
3583   return result;
3584 }
3585 
3586 
ConfigureGlobalObjects(v8::Local<v8::ObjectTemplate> global_proxy_template)3587 bool Genesis::ConfigureGlobalObjects(
3588     v8::Local<v8::ObjectTemplate> global_proxy_template) {
3589   Handle<JSObject> global_proxy(
3590       JSObject::cast(native_context()->global_proxy()));
3591   Handle<JSObject> global_object(
3592       JSObject::cast(native_context()->global_object()));
3593 
3594   if (!global_proxy_template.IsEmpty()) {
3595     // Configure the global proxy object.
3596     Handle<ObjectTemplateInfo> global_proxy_data =
3597         v8::Utils::OpenHandle(*global_proxy_template);
3598     if (!ConfigureApiObject(global_proxy, global_proxy_data)) return false;
3599 
3600     // Configure the global object.
3601     Handle<FunctionTemplateInfo> proxy_constructor(
3602         FunctionTemplateInfo::cast(global_proxy_data->constructor()));
3603     if (!proxy_constructor->prototype_template()->IsUndefined(isolate())) {
3604       Handle<ObjectTemplateInfo> global_object_data(
3605           ObjectTemplateInfo::cast(proxy_constructor->prototype_template()));
3606       if (!ConfigureApiObject(global_object, global_object_data)) return false;
3607     }
3608   }
3609 
3610   SetObjectPrototype(global_proxy, global_object);
3611 
3612   native_context()->set_initial_array_prototype(
3613       JSArray::cast(native_context()->array_function()->prototype()));
3614   native_context()->set_array_buffer_map(
3615       native_context()->array_buffer_fun()->initial_map());
3616   native_context()->set_js_map_map(
3617       native_context()->js_map_fun()->initial_map());
3618   native_context()->set_js_set_map(
3619       native_context()->js_set_fun()->initial_map());
3620 
3621   return true;
3622 }
3623 
3624 
ConfigureApiObject(Handle<JSObject> object,Handle<ObjectTemplateInfo> object_template)3625 bool Genesis::ConfigureApiObject(Handle<JSObject> object,
3626                                  Handle<ObjectTemplateInfo> object_template) {
3627   DCHECK(!object_template.is_null());
3628   DCHECK(FunctionTemplateInfo::cast(object_template->constructor())
3629              ->IsTemplateFor(object->map()));;
3630 
3631   MaybeHandle<JSObject> maybe_obj =
3632       ApiNatives::InstantiateObject(object_template);
3633   Handle<JSObject> obj;
3634   if (!maybe_obj.ToHandle(&obj)) {
3635     DCHECK(isolate()->has_pending_exception());
3636     isolate()->clear_pending_exception();
3637     return false;
3638   }
3639   TransferObject(obj, object);
3640   return true;
3641 }
3642 
3643 
TransferNamedProperties(Handle<JSObject> from,Handle<JSObject> to)3644 void Genesis::TransferNamedProperties(Handle<JSObject> from,
3645                                       Handle<JSObject> to) {
3646   // If JSObject::AddProperty asserts due to already existing property,
3647   // it is likely due to both global objects sharing property name(s).
3648   // Merging those two global objects is impossible.
3649   // The global template must not create properties that already exist
3650   // in the snapshotted global object.
3651   if (from->HasFastProperties()) {
3652     Handle<DescriptorArray> descs =
3653         Handle<DescriptorArray>(from->map()->instance_descriptors());
3654     for (int i = 0; i < from->map()->NumberOfOwnDescriptors(); i++) {
3655       PropertyDetails details = descs->GetDetails(i);
3656       switch (details.type()) {
3657         case DATA: {
3658           HandleScope inner(isolate());
3659           Handle<Name> key = Handle<Name>(descs->GetKey(i));
3660           FieldIndex index = FieldIndex::ForDescriptor(from->map(), i);
3661           DCHECK(!descs->GetDetails(i).representation().IsDouble());
3662           Handle<Object> value = Handle<Object>(from->RawFastPropertyAt(index),
3663                                                 isolate());
3664           JSObject::AddProperty(to, key, value, details.attributes());
3665           break;
3666         }
3667         case DATA_CONSTANT: {
3668           HandleScope inner(isolate());
3669           Handle<Name> key = Handle<Name>(descs->GetKey(i));
3670           Handle<Object> constant(descs->GetConstant(i), isolate());
3671           JSObject::AddProperty(to, key, constant, details.attributes());
3672           break;
3673         }
3674         case ACCESSOR:
3675           UNREACHABLE();
3676         case ACCESSOR_CONSTANT: {
3677           Handle<Name> key(descs->GetKey(i));
3678           LookupIterator it(to, key, LookupIterator::OWN_SKIP_INTERCEPTOR);
3679           CHECK_NE(LookupIterator::ACCESS_CHECK, it.state());
3680           // If the property is already there we skip it
3681           if (it.IsFound()) continue;
3682           HandleScope inner(isolate());
3683           DCHECK(!to->HasFastProperties());
3684           // Add to dictionary.
3685           Handle<Object> callbacks(descs->GetCallbacksObject(i), isolate());
3686           PropertyDetails d(details.attributes(), ACCESSOR_CONSTANT, i + 1,
3687                             PropertyCellType::kMutable);
3688           JSObject::SetNormalizedProperty(to, key, callbacks, d);
3689           break;
3690         }
3691       }
3692     }
3693   } else if (from->IsJSGlobalObject()) {
3694     Handle<GlobalDictionary> properties =
3695         Handle<GlobalDictionary>(from->global_dictionary());
3696     int capacity = properties->Capacity();
3697     for (int i = 0; i < capacity; i++) {
3698       Object* raw_key(properties->KeyAt(i));
3699       if (properties->IsKey(isolate(), raw_key)) {
3700         DCHECK(raw_key->IsName());
3701         // If the property is already there we skip it.
3702         Handle<Name> key(Name::cast(raw_key));
3703         LookupIterator it(to, key, LookupIterator::OWN_SKIP_INTERCEPTOR);
3704         CHECK_NE(LookupIterator::ACCESS_CHECK, it.state());
3705         if (it.IsFound()) continue;
3706         // Set the property.
3707         DCHECK(properties->ValueAt(i)->IsPropertyCell());
3708         Handle<PropertyCell> cell(PropertyCell::cast(properties->ValueAt(i)));
3709         Handle<Object> value(cell->value(), isolate());
3710         if (value->IsTheHole(isolate())) continue;
3711         PropertyDetails details = cell->property_details();
3712         DCHECK_EQ(kData, details.kind());
3713         JSObject::AddProperty(to, key, value, details.attributes());
3714       }
3715     }
3716   } else {
3717     Handle<NameDictionary> properties =
3718         Handle<NameDictionary>(from->property_dictionary());
3719     int capacity = properties->Capacity();
3720     for (int i = 0; i < capacity; i++) {
3721       Object* raw_key(properties->KeyAt(i));
3722       if (properties->IsKey(isolate(), raw_key)) {
3723         DCHECK(raw_key->IsName());
3724         // If the property is already there we skip it.
3725         Handle<Name> key(Name::cast(raw_key));
3726         LookupIterator it(to, key, LookupIterator::OWN_SKIP_INTERCEPTOR);
3727         CHECK_NE(LookupIterator::ACCESS_CHECK, it.state());
3728         if (it.IsFound()) continue;
3729         // Set the property.
3730         Handle<Object> value = Handle<Object>(properties->ValueAt(i),
3731                                               isolate());
3732         DCHECK(!value->IsCell());
3733         DCHECK(!value->IsTheHole(isolate()));
3734         PropertyDetails details = properties->DetailsAt(i);
3735         DCHECK_EQ(kData, details.kind());
3736         JSObject::AddProperty(to, key, value, details.attributes());
3737       }
3738     }
3739   }
3740 }
3741 
3742 
TransferIndexedProperties(Handle<JSObject> from,Handle<JSObject> to)3743 void Genesis::TransferIndexedProperties(Handle<JSObject> from,
3744                                         Handle<JSObject> to) {
3745   // Cloning the elements array is sufficient.
3746   Handle<FixedArray> from_elements =
3747       Handle<FixedArray>(FixedArray::cast(from->elements()));
3748   Handle<FixedArray> to_elements = factory()->CopyFixedArray(from_elements);
3749   to->set_elements(*to_elements);
3750 }
3751 
3752 
TransferObject(Handle<JSObject> from,Handle<JSObject> to)3753 void Genesis::TransferObject(Handle<JSObject> from, Handle<JSObject> to) {
3754   HandleScope outer(isolate());
3755 
3756   DCHECK(!from->IsJSArray());
3757   DCHECK(!to->IsJSArray());
3758 
3759   TransferNamedProperties(from, to);
3760   TransferIndexedProperties(from, to);
3761 
3762   // Transfer the prototype (new map is needed).
3763   Handle<Object> proto(from->map()->prototype(), isolate());
3764   SetObjectPrototype(to, proto);
3765 }
3766 
3767 
MakeFunctionInstancePrototypeWritable()3768 void Genesis::MakeFunctionInstancePrototypeWritable() {
3769   // The maps with writable prototype are created in CreateEmptyFunction
3770   // and CreateStrictModeFunctionMaps respectively. Initially the maps are
3771   // created with read-only prototype for JS builtins processing.
3772   DCHECK(!sloppy_function_map_writable_prototype_.is_null());
3773   DCHECK(!strict_function_map_writable_prototype_.is_null());
3774 
3775   // Replace function instance maps to make prototype writable.
3776   native_context()->set_sloppy_function_map(
3777       *sloppy_function_map_writable_prototype_);
3778   native_context()->set_strict_function_map(
3779       *strict_function_map_writable_prototype_);
3780 }
3781 
3782 
3783 class NoTrackDoubleFieldsForSerializerScope {
3784  public:
NoTrackDoubleFieldsForSerializerScope(Isolate * isolate)3785   explicit NoTrackDoubleFieldsForSerializerScope(Isolate* isolate)
3786       : flag_(FLAG_track_double_fields), enabled_(false) {
3787     if (isolate->serializer_enabled()) {
3788       // Disable tracking double fields because heap numbers treated as
3789       // immutable by the serializer.
3790       FLAG_track_double_fields = false;
3791       enabled_ = true;
3792     }
3793   }
3794 
~NoTrackDoubleFieldsForSerializerScope()3795   ~NoTrackDoubleFieldsForSerializerScope() {
3796     if (enabled_) {
3797       FLAG_track_double_fields = flag_;
3798     }
3799   }
3800 
3801  private:
3802   bool flag_;
3803   bool enabled_;
3804 };
3805 
Genesis(Isolate * isolate,MaybeHandle<JSGlobalProxy> maybe_global_proxy,v8::Local<v8::ObjectTemplate> global_proxy_template,v8::ExtensionConfiguration * extensions,size_t context_snapshot_index,GlobalContextType context_type)3806 Genesis::Genesis(Isolate* isolate,
3807                  MaybeHandle<JSGlobalProxy> maybe_global_proxy,
3808                  v8::Local<v8::ObjectTemplate> global_proxy_template,
3809                  v8::ExtensionConfiguration* extensions,
3810                  size_t context_snapshot_index, GlobalContextType context_type)
3811     : isolate_(isolate), active_(isolate->bootstrapper()) {
3812   NoTrackDoubleFieldsForSerializerScope disable_scope(isolate);
3813   result_ = Handle<Context>::null();
3814   // Before creating the roots we must save the context and restore it
3815   // on all function exits.
3816   SaveContext saved_context(isolate);
3817 
3818   // During genesis, the boilerplate for stack overflow won't work until the
3819   // environment has been at least partially initialized. Add a stack check
3820   // before entering JS code to catch overflow early.
3821   StackLimitCheck check(isolate);
3822   if (check.HasOverflowed()) {
3823     isolate->StackOverflow();
3824     return;
3825   }
3826 
3827   // The deserializer needs to hook up references to the global proxy.
3828   // Create an uninitialized global proxy now if we don't have one
3829   // and initialize it later in CreateNewGlobals.
3830   Handle<JSGlobalProxy> global_proxy;
3831   if (!maybe_global_proxy.ToHandle(&global_proxy)) {
3832     global_proxy = isolate->factory()->NewUninitializedJSGlobalProxy();
3833   }
3834 
3835   // We can only de-serialize a context if the isolate was initialized from
3836   // a snapshot. Otherwise we have to build the context from scratch.
3837   // Also create a context from scratch to expose natives, if required by flag.
3838   if (!isolate->initialized_from_snapshot() ||
3839       !Snapshot::NewContextFromSnapshot(isolate, global_proxy,
3840                                         context_snapshot_index)
3841            .ToHandle(&native_context_)) {
3842     native_context_ = Handle<Context>();
3843   }
3844 
3845   if (!native_context().is_null()) {
3846     AddToWeakNativeContextList(*native_context());
3847     isolate->set_context(*native_context());
3848     isolate->counters()->contexts_created_by_snapshot()->Increment();
3849 #if TRACE_MAPS
3850     if (FLAG_trace_maps) {
3851       Handle<JSFunction> object_fun = isolate->object_function();
3852       PrintF("[TraceMap: InitialMap map= %p SFI= %d_Object ]\n",
3853              reinterpret_cast<void*>(object_fun->initial_map()),
3854              object_fun->shared()->unique_id());
3855       Map::TraceAllTransitions(object_fun->initial_map());
3856     }
3857 #endif
3858     Handle<JSGlobalObject> global_object =
3859         CreateNewGlobals(global_proxy_template, global_proxy);
3860 
3861     HookUpGlobalProxy(global_object, global_proxy);
3862     HookUpGlobalObject(global_object);
3863 
3864     if (!ConfigureGlobalObjects(global_proxy_template)) return;
3865   } else {
3866     // We get here if there was no context snapshot.
3867     CreateRoots();
3868     Handle<JSFunction> empty_function = CreateEmptyFunction(isolate);
3869     CreateStrictModeFunctionMaps(empty_function);
3870     CreateIteratorMaps(empty_function);
3871     CreateAsyncFunctionMaps(empty_function);
3872     Handle<JSGlobalObject> global_object =
3873         CreateNewGlobals(global_proxy_template, global_proxy);
3874     HookUpGlobalProxy(global_object, global_proxy);
3875     InitializeGlobal(global_object, empty_function, context_type);
3876     InitializeNormalizedMapCaches();
3877 
3878     if (!InstallNatives(context_type)) return;
3879 
3880     MakeFunctionInstancePrototypeWritable();
3881 
3882     if (!InstallExtraNatives()) return;
3883     if (!ConfigureGlobalObjects(global_proxy_template)) return;
3884 
3885     isolate->counters()->contexts_created_from_scratch()->Increment();
3886     // Re-initialize the counter because it got incremented during snapshot
3887     // creation.
3888     isolate->native_context()->set_errors_thrown(Smi::FromInt(0));
3889   }
3890 
3891   // Install experimental natives. Do not include them into the
3892   // snapshot as we should be able to turn them off at runtime. Re-installing
3893   // them after they have already been deserialized would also fail.
3894   if (context_type == FULL_CONTEXT) {
3895     if (!isolate->serializer_enabled()) {
3896       InitializeExperimentalGlobal();
3897       if (!InstallExperimentalNatives()) return;
3898 
3899       if (FLAG_experimental_extras) {
3900         if (!InstallExperimentalExtraNatives()) return;
3901       }
3902     }
3903     // The serializer cannot serialize typed arrays. Reset those typed arrays
3904     // for each new context.
3905   } else if (context_type == DEBUG_CONTEXT) {
3906     DCHECK(!isolate->serializer_enabled());
3907     InitializeExperimentalGlobal();
3908     if (!InstallDebuggerNatives()) return;
3909   }
3910 
3911   ConfigureUtilsObject(context_type);
3912 
3913   // Check that the script context table is empty except for the 'this' binding.
3914   // We do not need script contexts for native scripts.
3915   if (!FLAG_global_var_shortcuts) {
3916     DCHECK_EQ(1, native_context()->script_context_table()->used());
3917   }
3918 
3919   result_ = native_context();
3920 }
3921 
3922 
3923 // Support for thread preemption.
3924 
3925 // Reserve space for statics needing saving and restoring.
ArchiveSpacePerThread()3926 int Bootstrapper::ArchiveSpacePerThread() {
3927   return sizeof(NestingCounterType);
3928 }
3929 
3930 
3931 // Archive statics that are thread-local.
ArchiveState(char * to)3932 char* Bootstrapper::ArchiveState(char* to) {
3933   *reinterpret_cast<NestingCounterType*>(to) = nesting_;
3934   nesting_ = 0;
3935   return to + sizeof(NestingCounterType);
3936 }
3937 
3938 
3939 // Restore statics that are thread-local.
RestoreState(char * from)3940 char* Bootstrapper::RestoreState(char* from) {
3941   nesting_ = *reinterpret_cast<NestingCounterType*>(from);
3942   return from + sizeof(NestingCounterType);
3943 }
3944 
3945 
3946 // Called when the top-level V8 mutex is destroyed.
FreeThreadResources()3947 void Bootstrapper::FreeThreadResources() {
3948   DCHECK(!IsActive());
3949 }
3950 
3951 }  // namespace internal
3952 }  // namespace v8
3953