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