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