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