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 26 Bootstrapper::Bootstrapper(Isolate* isolate) 27 : isolate_(isolate), 28 nesting_(0), 29 extensions_cache_(Script::TYPE_EXTENSION) {} 30 31 template <class Source> 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 60 void Bootstrapper::Initialize(bool create_heap_objects) { 61 extensions_cache_.Initialize(isolate_, create_heap_objects); 62 } 63 64 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 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 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 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 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); 144 ~Genesis() { } 145 146 Isolate* isolate() const { return isolate_; } 147 Factory* factory() const { return isolate_->factory(); } 148 Heap* heap() const { return isolate_->heap(); } 149 150 Handle<Context> result() { return result_; } 151 152 private: 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 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 320 void Bootstrapper::Iterate(ObjectVisitor* v) { 321 extensions_cache_.Iterate(v); 322 v->Synchronize(VisitorSynchronization::kExtensions); 323 } 324 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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. 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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. 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 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 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 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 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 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 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 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 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 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 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 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 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 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) 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 3398 void Genesis::InitializeNormalizedMapCaches() { 3399 Handle<NormalizedMapCache> cache = NormalizedMapCache::New(isolate()); 3400 native_context()->set_normalized_map_cache(*cache); 3401 } 3402 3403 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 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 3457 static uint32_t Hash(RegisteredExtension* extension) { 3458 return v8::internal::ComputePointerHash(extension); 3459 } 3460 3461 Genesis::ExtensionStates::ExtensionStates() 3462 : map_(base::HashMap::PointersMatch, 8) {} 3463 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 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 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 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 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. 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 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 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 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 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 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 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 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: 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 3795 ~NoTrackDoubleFieldsForSerializerScope() { 3796 if (enabled_) { 3797 FLAG_track_double_fields = flag_; 3798 } 3799 } 3800 3801 private: 3802 bool flag_; 3803 bool enabled_; 3804 }; 3805 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. 3926 int Bootstrapper::ArchiveSpacePerThread() { 3927 return sizeof(NestingCounterType); 3928 } 3929 3930 3931 // Archive statics that are thread-local. 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. 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. 3947 void Bootstrapper::FreeThreadResources() { 3948 DCHECK(!IsActive()); 3949 } 3950 3951 } // namespace internal 3952 } // namespace v8 3953