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