1// Copyright 2012 the V8 project authors. All rights reserved. 2// Redistribution and use in source and binary forms, with or without 3// modification, are permitted provided that the following conditions are 4// met: 5// 6// * Redistributions of source code must retain the above copyright 7// notice, this list of conditions and the following disclaimer. 8// * Redistributions in binary form must reproduce the above 9// copyright notice, this list of conditions and the following 10// disclaimer in the documentation and/or other materials provided 11// with the distribution. 12// * Neither the name of Google Inc. nor the names of its 13// contributors may be used to endorse or promote products derived 14// from this software without specific prior written permission. 15// 16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 28#include "v8.h" 29 30#include "accessors.h" 31#include "api.h" 32#include "bootstrapper.h" 33#include "compiler.h" 34#include "debug.h" 35#include "execution.h" 36#include "global-handles.h" 37#include "isolate-inl.h" 38#include "macro-assembler.h" 39#include "natives.h" 40#include "objects-visiting.h" 41#include "platform.h" 42#include "snapshot.h" 43#include "trig-table.h" 44#include "extensions/free-buffer-extension.h" 45#include "extensions/externalize-string-extension.h" 46#include "extensions/gc-extension.h" 47#include "extensions/statistics-extension.h" 48#include "code-stubs.h" 49 50namespace v8 { 51namespace internal { 52 53 54NativesExternalStringResource::NativesExternalStringResource( 55 Bootstrapper* bootstrapper, 56 const char* source, 57 size_t length) 58 : data_(source), length_(length) { 59 if (bootstrapper->delete_these_non_arrays_on_tear_down_ == NULL) { 60 bootstrapper->delete_these_non_arrays_on_tear_down_ = new List<char*>(2); 61 } 62 // The resources are small objects and we only make a fixed number of 63 // them, but let's clean them up on exit for neatness. 64 bootstrapper->delete_these_non_arrays_on_tear_down_-> 65 Add(reinterpret_cast<char*>(this)); 66} 67 68 69Bootstrapper::Bootstrapper(Isolate* isolate) 70 : isolate_(isolate), 71 nesting_(0), 72 extensions_cache_(Script::TYPE_EXTENSION), 73 delete_these_non_arrays_on_tear_down_(NULL), 74 delete_these_arrays_on_tear_down_(NULL) { 75} 76 77 78Handle<String> Bootstrapper::NativesSourceLookup(int index) { 79 ASSERT(0 <= index && index < Natives::GetBuiltinsCount()); 80 Heap* heap = isolate_->heap(); 81 if (heap->natives_source_cache()->get(index)->IsUndefined()) { 82 // We can use external strings for the natives. 83 Vector<const char> source = Natives::GetRawScriptSource(index); 84 NativesExternalStringResource* resource = 85 new NativesExternalStringResource(this, 86 source.start(), 87 source.length()); 88 Handle<String> source_code = 89 isolate_->factory()->NewExternalStringFromAscii(resource); 90 heap->natives_source_cache()->set(index, *source_code); 91 } 92 Handle<Object> cached_source(heap->natives_source_cache()->get(index), 93 isolate_); 94 return Handle<String>::cast(cached_source); 95} 96 97 98void Bootstrapper::Initialize(bool create_heap_objects) { 99 extensions_cache_.Initialize(isolate_, create_heap_objects); 100} 101 102 103void Bootstrapper::InitializeOncePerProcess() { 104#ifdef ADDRESS_SANITIZER 105 FreeBufferExtension::Register(); 106#endif 107 GCExtension::Register(); 108 ExternalizeStringExtension::Register(); 109 StatisticsExtension::Register(); 110} 111 112 113char* Bootstrapper::AllocateAutoDeletedArray(int bytes) { 114 char* memory = new char[bytes]; 115 if (memory != NULL) { 116 if (delete_these_arrays_on_tear_down_ == NULL) { 117 delete_these_arrays_on_tear_down_ = new List<char*>(2); 118 } 119 delete_these_arrays_on_tear_down_->Add(memory); 120 } 121 return memory; 122} 123 124 125void Bootstrapper::TearDown() { 126 if (delete_these_non_arrays_on_tear_down_ != NULL) { 127 int len = delete_these_non_arrays_on_tear_down_->length(); 128 ASSERT(len < 20); // Don't use this mechanism for unbounded allocations. 129 for (int i = 0; i < len; i++) { 130 delete delete_these_non_arrays_on_tear_down_->at(i); 131 delete_these_non_arrays_on_tear_down_->at(i) = NULL; 132 } 133 delete delete_these_non_arrays_on_tear_down_; 134 delete_these_non_arrays_on_tear_down_ = NULL; 135 } 136 137 if (delete_these_arrays_on_tear_down_ != NULL) { 138 int len = delete_these_arrays_on_tear_down_->length(); 139 ASSERT(len < 1000); // Don't use this mechanism for unbounded allocations. 140 for (int i = 0; i < len; i++) { 141 delete[] delete_these_arrays_on_tear_down_->at(i); 142 delete_these_arrays_on_tear_down_->at(i) = NULL; 143 } 144 delete delete_these_arrays_on_tear_down_; 145 delete_these_arrays_on_tear_down_ = NULL; 146 } 147 148 extensions_cache_.Initialize(isolate_, false); // Yes, symmetrical 149} 150 151 152class Genesis BASE_EMBEDDED { 153 public: 154 Genesis(Isolate* isolate, 155 Handle<Object> global_object, 156 v8::Handle<v8::ObjectTemplate> global_template, 157 v8::ExtensionConfiguration* extensions); 158 ~Genesis() { } 159 160 Isolate* isolate() const { return isolate_; } 161 Factory* factory() const { return isolate_->factory(); } 162 Heap* heap() const { return isolate_->heap(); } 163 164 Handle<Context> result() { return result_; } 165 166 private: 167 Handle<Context> native_context() { return native_context_; } 168 169 // Creates some basic objects. Used for creating a context from scratch. 170 void CreateRoots(); 171 // Creates the empty function. Used for creating a context from scratch. 172 Handle<JSFunction> CreateEmptyFunction(Isolate* isolate); 173 // Creates the ThrowTypeError function. ECMA 5th Ed. 13.2.3 174 Handle<JSFunction> GetThrowTypeErrorFunction(); 175 176 void CreateStrictModeFunctionMaps(Handle<JSFunction> empty); 177 178 // Make the "arguments" and "caller" properties throw a TypeError on access. 179 void PoisonArgumentsAndCaller(Handle<Map> map); 180 181 // Creates the global objects using the global and the template passed in 182 // through the API. We call this regardless of whether we are building a 183 // context from scratch or using a deserialized one from the partial snapshot 184 // but in the latter case we don't use the objects it produces directly, as 185 // we have to used the deserialized ones that are linked together with the 186 // rest of the context snapshot. 187 Handle<JSGlobalProxy> CreateNewGlobals( 188 v8::Handle<v8::ObjectTemplate> global_template, 189 Handle<Object> global_object, 190 Handle<GlobalObject>* global_proxy_out); 191 // Hooks the given global proxy into the context. If the context was created 192 // by deserialization then this will unhook the global proxy that was 193 // deserialized, leaving the GC to pick it up. 194 void HookUpGlobalProxy(Handle<GlobalObject> inner_global, 195 Handle<JSGlobalProxy> global_proxy); 196 // Similarly, we want to use the inner global that has been created by the 197 // templates passed through the API. The inner global from the snapshot is 198 // detached from the other objects in the snapshot. 199 void HookUpInnerGlobal(Handle<GlobalObject> inner_global); 200 // New context initialization. Used for creating a context from scratch. 201 void InitializeGlobal(Handle<GlobalObject> inner_global, 202 Handle<JSFunction> empty_function); 203 void InitializeExperimentalGlobal(); 204 // Installs the contents of the native .js files on the global objects. 205 // Used for creating a context from scratch. 206 void InstallNativeFunctions(); 207 void InstallExperimentalNativeFunctions(); 208 Handle<JSFunction> InstallInternalArray(Handle<JSBuiltinsObject> builtins, 209 const char* name, 210 ElementsKind elements_kind); 211 bool InstallNatives(); 212 213 Handle<JSFunction> InstallTypedArray(const char* name, 214 ElementsKind elementsKind); 215 bool InstallExperimentalNatives(); 216 void InstallBuiltinFunctionIds(); 217 void InstallJSFunctionResultCaches(); 218 void InitializeNormalizedMapCaches(); 219 220 enum ExtensionTraversalState { 221 UNVISITED, VISITED, INSTALLED 222 }; 223 224 class ExtensionStates { 225 public: 226 ExtensionStates(); 227 ExtensionTraversalState get_state(RegisteredExtension* extension); 228 void set_state(RegisteredExtension* extension, 229 ExtensionTraversalState state); 230 private: 231 HashMap map_; 232 DISALLOW_COPY_AND_ASSIGN(ExtensionStates); 233 }; 234 235 // Used both for deserialized and from-scratch contexts to add the extensions 236 // provided. 237 static bool InstallExtensions(Handle<Context> native_context, 238 v8::ExtensionConfiguration* extensions); 239 static bool InstallExtension(Isolate* isolate, 240 const char* name, 241 ExtensionStates* extension_states); 242 static bool InstallExtension(Isolate* isolate, 243 v8::RegisteredExtension* current, 244 ExtensionStates* extension_states); 245 static void InstallSpecialObjects(Handle<Context> native_context); 246 bool InstallJSBuiltins(Handle<JSBuiltinsObject> builtins); 247 bool ConfigureApiObject(Handle<JSObject> object, 248 Handle<ObjectTemplateInfo> object_template); 249 bool ConfigureGlobalObjects(v8::Handle<v8::ObjectTemplate> global_template); 250 251 // Migrates all properties from the 'from' object to the 'to' 252 // object and overrides the prototype in 'to' with the one from 253 // 'from'. 254 void TransferObject(Handle<JSObject> from, Handle<JSObject> to); 255 void TransferNamedProperties(Handle<JSObject> from, Handle<JSObject> to); 256 void TransferIndexedProperties(Handle<JSObject> from, Handle<JSObject> to); 257 258 enum PrototypePropertyMode { 259 DONT_ADD_PROTOTYPE, 260 ADD_READONLY_PROTOTYPE, 261 ADD_WRITEABLE_PROTOTYPE 262 }; 263 264 Handle<Map> CreateFunctionMap(PrototypePropertyMode prototype_mode); 265 266 void SetFunctionInstanceDescriptor(Handle<Map> map, 267 PrototypePropertyMode prototypeMode); 268 void MakeFunctionInstancePrototypeWritable(); 269 270 Handle<Map> CreateStrictModeFunctionMap( 271 PrototypePropertyMode prototype_mode, 272 Handle<JSFunction> empty_function); 273 274 void SetStrictFunctionInstanceDescriptor(Handle<Map> map, 275 PrototypePropertyMode propertyMode); 276 277 static bool CompileBuiltin(Isolate* isolate, int index); 278 static bool CompileExperimentalBuiltin(Isolate* isolate, int index); 279 static bool CompileNative(Isolate* isolate, 280 Vector<const char> name, 281 Handle<String> source); 282 static bool CompileScriptCached(Isolate* isolate, 283 Vector<const char> name, 284 Handle<String> source, 285 SourceCodeCache* cache, 286 v8::Extension* extension, 287 Handle<Context> top_context, 288 bool use_runtime_context); 289 290 Isolate* isolate_; 291 Handle<Context> result_; 292 Handle<Context> native_context_; 293 294 // Function maps. Function maps are created initially with a read only 295 // prototype for the processing of JS builtins. Later the function maps are 296 // replaced in order to make prototype writable. These are the final, writable 297 // prototype, maps. 298 Handle<Map> function_map_writable_prototype_; 299 Handle<Map> strict_mode_function_map_writable_prototype_; 300 Handle<JSFunction> throw_type_error_function; 301 302 BootstrapperActive active_; 303 friend class Bootstrapper; 304}; 305 306 307void Bootstrapper::Iterate(ObjectVisitor* v) { 308 extensions_cache_.Iterate(v); 309 v->Synchronize(VisitorSynchronization::kExtensions); 310} 311 312 313Handle<Context> Bootstrapper::CreateEnvironment( 314 Handle<Object> global_object, 315 v8::Handle<v8::ObjectTemplate> global_template, 316 v8::ExtensionConfiguration* extensions) { 317 HandleScope scope(isolate_); 318 Genesis genesis(isolate_, global_object, global_template, extensions); 319 Handle<Context> env = genesis.result(); 320 if (env.is_null() || !InstallExtensions(env, extensions)) { 321 return Handle<Context>(); 322 } 323 return scope.CloseAndEscape(env); 324} 325 326 327static void SetObjectPrototype(Handle<JSObject> object, Handle<Object> proto) { 328 // object.__proto__ = proto; 329 Factory* factory = object->GetIsolate()->factory(); 330 Handle<Map> old_to_map = Handle<Map>(object->map()); 331 Handle<Map> new_to_map = factory->CopyMap(old_to_map); 332 new_to_map->set_prototype(*proto); 333 object->set_map(*new_to_map); 334} 335 336 337void Bootstrapper::DetachGlobal(Handle<Context> env) { 338 Factory* factory = env->GetIsolate()->factory(); 339 Handle<JSGlobalProxy> global_proxy(JSGlobalProxy::cast(env->global_proxy())); 340 global_proxy->set_native_context(*factory->null_value()); 341 SetObjectPrototype(global_proxy, factory->null_value()); 342} 343 344 345static Handle<JSFunction> InstallFunction(Handle<JSObject> target, 346 const char* name, 347 InstanceType type, 348 int instance_size, 349 Handle<JSObject> prototype, 350 Builtins::Name call, 351 bool install_initial_map, 352 bool set_instance_class_name) { 353 Isolate* isolate = target->GetIsolate(); 354 Factory* factory = isolate->factory(); 355 Handle<String> internalized_name = factory->InternalizeUtf8String(name); 356 Handle<Code> call_code = Handle<Code>(isolate->builtins()->builtin(call)); 357 Handle<JSFunction> function = prototype.is_null() ? 358 factory->NewFunctionWithoutPrototype(internalized_name, call_code) : 359 factory->NewFunctionWithPrototype(internalized_name, 360 type, 361 instance_size, 362 prototype, 363 call_code, 364 install_initial_map); 365 PropertyAttributes attributes; 366 if (target->IsJSBuiltinsObject()) { 367 attributes = 368 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY); 369 } else { 370 attributes = DONT_ENUM; 371 } 372 CHECK_NOT_EMPTY_HANDLE(isolate, 373 JSObject::SetLocalPropertyIgnoreAttributes( 374 target, internalized_name, function, attributes)); 375 if (set_instance_class_name) { 376 function->shared()->set_instance_class_name(*internalized_name); 377 } 378 function->shared()->set_native(true); 379 return function; 380} 381 382 383void Genesis::SetFunctionInstanceDescriptor( 384 Handle<Map> map, PrototypePropertyMode prototypeMode) { 385 int size = (prototypeMode == DONT_ADD_PROTOTYPE) ? 4 : 5; 386 Handle<DescriptorArray> descriptors(factory()->NewDescriptorArray(0, size)); 387 DescriptorArray::WhitenessWitness witness(*descriptors); 388 389 Handle<Foreign> length(factory()->NewForeign(&Accessors::FunctionLength)); 390 Handle<Foreign> name(factory()->NewForeign(&Accessors::FunctionName)); 391 Handle<Foreign> args(factory()->NewForeign(&Accessors::FunctionArguments)); 392 Handle<Foreign> caller(factory()->NewForeign(&Accessors::FunctionCaller)); 393 Handle<Foreign> prototype; 394 if (prototypeMode != DONT_ADD_PROTOTYPE) { 395 prototype = factory()->NewForeign(&Accessors::FunctionPrototype); 396 } 397 PropertyAttributes attribs = static_cast<PropertyAttributes>( 398 DONT_ENUM | DONT_DELETE | READ_ONLY); 399 map->set_instance_descriptors(*descriptors); 400 401 { // Add length. 402 CallbacksDescriptor d(*factory()->length_string(), *length, attribs); 403 map->AppendDescriptor(&d, witness); 404 } 405 { // Add name. 406 CallbacksDescriptor d(*factory()->name_string(), *name, attribs); 407 map->AppendDescriptor(&d, witness); 408 } 409 { // Add arguments. 410 CallbacksDescriptor d(*factory()->arguments_string(), *args, attribs); 411 map->AppendDescriptor(&d, witness); 412 } 413 { // Add caller. 414 CallbacksDescriptor d(*factory()->caller_string(), *caller, attribs); 415 map->AppendDescriptor(&d, witness); 416 } 417 if (prototypeMode != DONT_ADD_PROTOTYPE) { 418 // Add prototype. 419 if (prototypeMode == ADD_WRITEABLE_PROTOTYPE) { 420 attribs = static_cast<PropertyAttributes>(attribs & ~READ_ONLY); 421 } 422 CallbacksDescriptor d(*factory()->prototype_string(), *prototype, attribs); 423 map->AppendDescriptor(&d, witness); 424 } 425} 426 427 428Handle<Map> Genesis::CreateFunctionMap(PrototypePropertyMode prototype_mode) { 429 Handle<Map> map = factory()->NewMap(JS_FUNCTION_TYPE, JSFunction::kSize); 430 SetFunctionInstanceDescriptor(map, prototype_mode); 431 map->set_function_with_prototype(prototype_mode != DONT_ADD_PROTOTYPE); 432 return map; 433} 434 435 436Handle<JSFunction> Genesis::CreateEmptyFunction(Isolate* isolate) { 437 // Allocate the map for function instances. Maps are allocated first and their 438 // prototypes patched later, once empty function is created. 439 440 // Functions with this map will not have a 'prototype' property, and 441 // can not be used as constructors. 442 Handle<Map> function_without_prototype_map = 443 CreateFunctionMap(DONT_ADD_PROTOTYPE); 444 native_context()->set_function_without_prototype_map( 445 *function_without_prototype_map); 446 447 // Allocate the function map. This map is temporary, used only for processing 448 // of builtins. 449 // Later the map is replaced with writable prototype map, allocated below. 450 Handle<Map> function_map = CreateFunctionMap(ADD_READONLY_PROTOTYPE); 451 native_context()->set_function_map(*function_map); 452 453 // The final map for functions. Writeable prototype. 454 // This map is installed in MakeFunctionInstancePrototypeWritable. 455 function_map_writable_prototype_ = CreateFunctionMap(ADD_WRITEABLE_PROTOTYPE); 456 457 Factory* factory = isolate->factory(); 458 459 Handle<String> object_name = factory->Object_string(); 460 461 { // --- O b j e c t --- 462 Handle<JSFunction> object_fun = 463 factory->NewFunction(object_name, factory->null_value()); 464 Handle<Map> object_function_map = 465 factory->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize); 466 object_fun->set_initial_map(*object_function_map); 467 object_function_map->set_constructor(*object_fun); 468 469 native_context()->set_object_function(*object_fun); 470 471 // Allocate a new prototype for the object function. 472 Handle<JSObject> prototype = factory->NewJSObject( 473 isolate->object_function(), 474 TENURED); 475 476 native_context()->set_initial_object_prototype(*prototype); 477 // For bootstrapping set the array prototype to be the same as the object 478 // prototype, otherwise the missing initial_array_prototype will cause 479 // assertions during startup. 480 native_context()->set_initial_array_prototype(*prototype); 481 Accessors::FunctionSetPrototype(object_fun, prototype); 482 } 483 484 // Allocate the empty function as the prototype for function ECMAScript 485 // 262 15.3.4. 486 Handle<String> empty_string = 487 factory->InternalizeOneByteString(STATIC_ASCII_VECTOR("Empty")); 488 Handle<JSFunction> empty_function = 489 factory->NewFunctionWithoutPrototype(empty_string, CLASSIC_MODE); 490 491 // --- E m p t y --- 492 Handle<Code> code = 493 Handle<Code>(isolate->builtins()->builtin( 494 Builtins::kEmptyFunction)); 495 empty_function->set_code(*code); 496 empty_function->shared()->set_code(*code); 497 Handle<String> source = 498 factory->NewStringFromOneByte(STATIC_ASCII_VECTOR("() {}")); 499 Handle<Script> script = factory->NewScript(source); 500 script->set_type(Smi::FromInt(Script::TYPE_NATIVE)); 501 empty_function->shared()->set_script(*script); 502 empty_function->shared()->set_start_position(0); 503 empty_function->shared()->set_end_position(source->length()); 504 empty_function->shared()->DontAdaptArguments(); 505 506 // Set prototypes for the function maps. 507 native_context()->function_map()->set_prototype(*empty_function); 508 native_context()->function_without_prototype_map()-> 509 set_prototype(*empty_function); 510 function_map_writable_prototype_->set_prototype(*empty_function); 511 512 // Allocate the function map first and then patch the prototype later 513 Handle<Map> empty_function_map = CreateFunctionMap(DONT_ADD_PROTOTYPE); 514 empty_function_map->set_prototype( 515 native_context()->object_function()->prototype()); 516 empty_function->set_map(*empty_function_map); 517 return empty_function; 518} 519 520 521void Genesis::SetStrictFunctionInstanceDescriptor( 522 Handle<Map> map, PrototypePropertyMode prototypeMode) { 523 int size = (prototypeMode == DONT_ADD_PROTOTYPE) ? 4 : 5; 524 Handle<DescriptorArray> descriptors(factory()->NewDescriptorArray(0, size)); 525 DescriptorArray::WhitenessWitness witness(*descriptors); 526 527 Handle<Foreign> length(factory()->NewForeign(&Accessors::FunctionLength)); 528 Handle<Foreign> name(factory()->NewForeign(&Accessors::FunctionName)); 529 Handle<AccessorPair> arguments(factory()->NewAccessorPair()); 530 Handle<AccessorPair> caller(factory()->NewAccessorPair()); 531 Handle<Foreign> prototype; 532 if (prototypeMode != DONT_ADD_PROTOTYPE) { 533 prototype = factory()->NewForeign(&Accessors::FunctionPrototype); 534 } 535 PropertyAttributes rw_attribs = 536 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE); 537 PropertyAttributes ro_attribs = 538 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY); 539 map->set_instance_descriptors(*descriptors); 540 541 { // Add length. 542 CallbacksDescriptor d(*factory()->length_string(), *length, ro_attribs); 543 map->AppendDescriptor(&d, witness); 544 } 545 { // Add name. 546 CallbacksDescriptor d(*factory()->name_string(), *name, rw_attribs); 547 map->AppendDescriptor(&d, witness); 548 } 549 { // Add arguments. 550 CallbacksDescriptor d(*factory()->arguments_string(), *arguments, 551 rw_attribs); 552 map->AppendDescriptor(&d, witness); 553 } 554 { // Add caller. 555 CallbacksDescriptor d(*factory()->caller_string(), *caller, rw_attribs); 556 map->AppendDescriptor(&d, witness); 557 } 558 if (prototypeMode != DONT_ADD_PROTOTYPE) { 559 // Add prototype. 560 PropertyAttributes attribs = 561 prototypeMode == ADD_WRITEABLE_PROTOTYPE ? rw_attribs : ro_attribs; 562 CallbacksDescriptor d(*factory()->prototype_string(), *prototype, attribs); 563 map->AppendDescriptor(&d, witness); 564 } 565} 566 567 568// ECMAScript 5th Edition, 13.2.3 569Handle<JSFunction> Genesis::GetThrowTypeErrorFunction() { 570 if (throw_type_error_function.is_null()) { 571 Handle<String> name = factory()->InternalizeOneByteString( 572 STATIC_ASCII_VECTOR("ThrowTypeError")); 573 throw_type_error_function = 574 factory()->NewFunctionWithoutPrototype(name, CLASSIC_MODE); 575 Handle<Code> code(isolate()->builtins()->builtin( 576 Builtins::kStrictModePoisonPill)); 577 throw_type_error_function->set_map( 578 native_context()->function_map()); 579 throw_type_error_function->set_code(*code); 580 throw_type_error_function->shared()->set_code(*code); 581 throw_type_error_function->shared()->DontAdaptArguments(); 582 583 JSObject::PreventExtensions(throw_type_error_function); 584 } 585 return throw_type_error_function; 586} 587 588 589Handle<Map> Genesis::CreateStrictModeFunctionMap( 590 PrototypePropertyMode prototype_mode, 591 Handle<JSFunction> empty_function) { 592 Handle<Map> map = factory()->NewMap(JS_FUNCTION_TYPE, JSFunction::kSize); 593 SetStrictFunctionInstanceDescriptor(map, prototype_mode); 594 map->set_function_with_prototype(prototype_mode != DONT_ADD_PROTOTYPE); 595 map->set_prototype(*empty_function); 596 return map; 597} 598 599 600void Genesis::CreateStrictModeFunctionMaps(Handle<JSFunction> empty) { 601 // Allocate map for the prototype-less strict mode instances. 602 Handle<Map> strict_mode_function_without_prototype_map = 603 CreateStrictModeFunctionMap(DONT_ADD_PROTOTYPE, empty); 604 native_context()->set_strict_mode_function_without_prototype_map( 605 *strict_mode_function_without_prototype_map); 606 607 // Allocate map for the strict mode functions. This map is temporary, used 608 // only for processing of builtins. 609 // Later the map is replaced with writable prototype map, allocated below. 610 Handle<Map> strict_mode_function_map = 611 CreateStrictModeFunctionMap(ADD_READONLY_PROTOTYPE, empty); 612 native_context()->set_strict_mode_function_map( 613 *strict_mode_function_map); 614 615 // The final map for the strict mode functions. Writeable prototype. 616 // This map is installed in MakeFunctionInstancePrototypeWritable. 617 strict_mode_function_map_writable_prototype_ = 618 CreateStrictModeFunctionMap(ADD_WRITEABLE_PROTOTYPE, empty); 619 620 // Complete the callbacks. 621 PoisonArgumentsAndCaller(strict_mode_function_without_prototype_map); 622 PoisonArgumentsAndCaller(strict_mode_function_map); 623 PoisonArgumentsAndCaller(strict_mode_function_map_writable_prototype_); 624} 625 626 627static void SetAccessors(Handle<Map> map, 628 Handle<String> name, 629 Handle<JSFunction> func) { 630 DescriptorArray* descs = map->instance_descriptors(); 631 int number = descs->SearchWithCache(*name, *map); 632 AccessorPair* accessors = AccessorPair::cast(descs->GetValue(number)); 633 accessors->set_getter(*func); 634 accessors->set_setter(*func); 635} 636 637 638void Genesis::PoisonArgumentsAndCaller(Handle<Map> map) { 639 SetAccessors(map, factory()->arguments_string(), GetThrowTypeErrorFunction()); 640 SetAccessors(map, factory()->caller_string(), GetThrowTypeErrorFunction()); 641} 642 643 644static void AddToWeakNativeContextList(Context* context) { 645 ASSERT(context->IsNativeContext()); 646 Heap* heap = context->GetIsolate()->heap(); 647#ifdef DEBUG 648 { // NOLINT 649 ASSERT(context->get(Context::NEXT_CONTEXT_LINK)->IsUndefined()); 650 // Check that context is not in the list yet. 651 for (Object* current = heap->native_contexts_list(); 652 !current->IsUndefined(); 653 current = Context::cast(current)->get(Context::NEXT_CONTEXT_LINK)) { 654 ASSERT(current != context); 655 } 656 } 657#endif 658 context->set(Context::NEXT_CONTEXT_LINK, heap->native_contexts_list()); 659 heap->set_native_contexts_list(context); 660} 661 662 663void Genesis::CreateRoots() { 664 // Allocate the native context FixedArray first and then patch the 665 // closure and extension object later (we need the empty function 666 // and the global object, but in order to create those, we need the 667 // native context). 668 native_context_ = factory()->NewNativeContext(); 669 AddToWeakNativeContextList(*native_context()); 670 isolate()->set_context(*native_context()); 671 672 // Allocate the message listeners object. 673 { 674 v8::NeanderArray listeners; 675 native_context()->set_message_listeners(*listeners.value()); 676 } 677} 678 679 680Handle<JSGlobalProxy> Genesis::CreateNewGlobals( 681 v8::Handle<v8::ObjectTemplate> global_template, 682 Handle<Object> global_object, 683 Handle<GlobalObject>* inner_global_out) { 684 // The argument global_template aka data is an ObjectTemplateInfo. 685 // It has a constructor pointer that points at global_constructor which is a 686 // FunctionTemplateInfo. 687 // The global_constructor is used to create or reinitialize the global_proxy. 688 // The global_constructor also has a prototype_template pointer that points at 689 // js_global_template which is an ObjectTemplateInfo. 690 // That in turn has a constructor pointer that points at 691 // js_global_constructor which is a FunctionTemplateInfo. 692 // js_global_constructor is used to make js_global_function 693 // js_global_function is used to make the new inner_global. 694 // 695 // --- G l o b a l --- 696 // Step 1: Create a fresh inner JSGlobalObject. 697 Handle<JSFunction> js_global_function; 698 Handle<ObjectTemplateInfo> js_global_template; 699 if (!global_template.IsEmpty()) { 700 // Get prototype template of the global_template. 701 Handle<ObjectTemplateInfo> data = 702 v8::Utils::OpenHandle(*global_template); 703 Handle<FunctionTemplateInfo> global_constructor = 704 Handle<FunctionTemplateInfo>( 705 FunctionTemplateInfo::cast(data->constructor())); 706 Handle<Object> proto_template(global_constructor->prototype_template(), 707 isolate()); 708 if (!proto_template->IsUndefined()) { 709 js_global_template = 710 Handle<ObjectTemplateInfo>::cast(proto_template); 711 } 712 } 713 714 if (js_global_template.is_null()) { 715 Handle<String> name = Handle<String>(heap()->empty_string()); 716 Handle<Code> code = Handle<Code>(isolate()->builtins()->builtin( 717 Builtins::kIllegal)); 718 js_global_function = 719 factory()->NewFunction(name, JS_GLOBAL_OBJECT_TYPE, 720 JSGlobalObject::kSize, code, true); 721 // Change the constructor property of the prototype of the 722 // hidden global function to refer to the Object function. 723 Handle<JSObject> prototype = 724 Handle<JSObject>( 725 JSObject::cast(js_global_function->instance_prototype())); 726 CHECK_NOT_EMPTY_HANDLE(isolate(), 727 JSObject::SetLocalPropertyIgnoreAttributes( 728 prototype, factory()->constructor_string(), 729 isolate()->object_function(), NONE)); 730 } else { 731 Handle<FunctionTemplateInfo> js_global_constructor( 732 FunctionTemplateInfo::cast(js_global_template->constructor())); 733 js_global_function = 734 factory()->CreateApiFunction(js_global_constructor, 735 factory()->InnerGlobalObject); 736 } 737 738 js_global_function->initial_map()->set_is_hidden_prototype(); 739 js_global_function->initial_map()->set_dictionary_map(true); 740 Handle<GlobalObject> inner_global = 741 factory()->NewGlobalObject(js_global_function); 742 if (inner_global_out != NULL) { 743 *inner_global_out = inner_global; 744 } 745 746 // Step 2: create or re-initialize the global proxy object. 747 Handle<JSFunction> global_proxy_function; 748 if (global_template.IsEmpty()) { 749 Handle<String> name = Handle<String>(heap()->empty_string()); 750 Handle<Code> code = Handle<Code>(isolate()->builtins()->builtin( 751 Builtins::kIllegal)); 752 global_proxy_function = 753 factory()->NewFunction(name, JS_GLOBAL_PROXY_TYPE, 754 JSGlobalProxy::kSize, code, true); 755 } else { 756 Handle<ObjectTemplateInfo> data = 757 v8::Utils::OpenHandle(*global_template); 758 Handle<FunctionTemplateInfo> global_constructor( 759 FunctionTemplateInfo::cast(data->constructor())); 760 global_proxy_function = 761 factory()->CreateApiFunction(global_constructor, 762 factory()->OuterGlobalObject); 763 } 764 765 Handle<String> global_name = factory()->InternalizeOneByteString( 766 STATIC_ASCII_VECTOR("global")); 767 global_proxy_function->shared()->set_instance_class_name(*global_name); 768 global_proxy_function->initial_map()->set_is_access_check_needed(true); 769 770 // Set global_proxy.__proto__ to js_global after ConfigureGlobalObjects 771 // Return the global proxy. 772 773 if (global_object.location() != NULL) { 774 ASSERT(global_object->IsJSGlobalProxy()); 775 return ReinitializeJSGlobalProxy( 776 global_proxy_function, 777 Handle<JSGlobalProxy>::cast(global_object)); 778 } else { 779 return Handle<JSGlobalProxy>::cast( 780 factory()->NewJSObject(global_proxy_function, TENURED)); 781 } 782} 783 784 785void Genesis::HookUpGlobalProxy(Handle<GlobalObject> inner_global, 786 Handle<JSGlobalProxy> global_proxy) { 787 // Set the native context for the global object. 788 inner_global->set_native_context(*native_context()); 789 inner_global->set_global_context(*native_context()); 790 inner_global->set_global_receiver(*global_proxy); 791 global_proxy->set_native_context(*native_context()); 792 native_context()->set_global_proxy(*global_proxy); 793} 794 795 796void Genesis::HookUpInnerGlobal(Handle<GlobalObject> inner_global) { 797 Handle<GlobalObject> inner_global_from_snapshot( 798 GlobalObject::cast(native_context()->extension())); 799 Handle<JSBuiltinsObject> builtins_global(native_context()->builtins()); 800 native_context()->set_extension(*inner_global); 801 native_context()->set_global_object(*inner_global); 802 native_context()->set_security_token(*inner_global); 803 static const PropertyAttributes attributes = 804 static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE); 805 ForceSetProperty(builtins_global, 806 factory()->InternalizeOneByteString( 807 STATIC_ASCII_VECTOR("global")), 808 inner_global, 809 attributes); 810 // Set up the reference from the global object to the builtins object. 811 JSGlobalObject::cast(*inner_global)->set_builtins(*builtins_global); 812 TransferNamedProperties(inner_global_from_snapshot, inner_global); 813 TransferIndexedProperties(inner_global_from_snapshot, inner_global); 814} 815 816 817// This is only called if we are not using snapshots. The equivalent 818// work in the snapshot case is done in HookUpInnerGlobal. 819void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global, 820 Handle<JSFunction> empty_function) { 821 // --- N a t i v e C o n t e x t --- 822 // Use the empty function as closure (no scope info). 823 native_context()->set_closure(*empty_function); 824 native_context()->set_previous(NULL); 825 // Set extension and global object. 826 native_context()->set_extension(*inner_global); 827 native_context()->set_global_object(*inner_global); 828 // Security setup: Set the security token of the global object to 829 // its the inner global. This makes the security check between two 830 // different contexts fail by default even in case of global 831 // object reinitialization. 832 native_context()->set_security_token(*inner_global); 833 834 Isolate* isolate = inner_global->GetIsolate(); 835 Factory* factory = isolate->factory(); 836 Heap* heap = isolate->heap(); 837 838 Handle<String> object_name = factory->Object_string(); 839 CHECK_NOT_EMPTY_HANDLE(isolate, 840 JSObject::SetLocalPropertyIgnoreAttributes( 841 inner_global, object_name, 842 isolate->object_function(), DONT_ENUM)); 843 844 Handle<JSObject> global = Handle<JSObject>(native_context()->global_object()); 845 846 // Install global Function object 847 InstallFunction(global, "Function", JS_FUNCTION_TYPE, JSFunction::kSize, 848 empty_function, Builtins::kIllegal, true, true); 849 850 { // --- A r r a y --- 851 Handle<JSFunction> array_function = 852 InstallFunction(global, "Array", JS_ARRAY_TYPE, JSArray::kSize, 853 isolate->initial_object_prototype(), 854 Builtins::kArrayCode, true, true); 855 array_function->shared()->DontAdaptArguments(); 856 array_function->shared()->set_function_data(Smi::FromInt(kArrayCode)); 857 858 // This seems a bit hackish, but we need to make sure Array.length 859 // is 1. 860 array_function->shared()->set_length(1); 861 862 Handle<Map> initial_map(array_function->initial_map()); 863 864 // This assert protects an optimization in 865 // HGraphBuilder::JSArrayBuilder::EmitMapCode() 866 ASSERT(initial_map->elements_kind() == GetInitialFastElementsKind()); 867 868 Handle<DescriptorArray> array_descriptors( 869 factory->NewDescriptorArray(0, 1)); 870 DescriptorArray::WhitenessWitness witness(*array_descriptors); 871 872 Handle<Foreign> array_length(factory->NewForeign(&Accessors::ArrayLength)); 873 PropertyAttributes attribs = static_cast<PropertyAttributes>( 874 DONT_ENUM | DONT_DELETE); 875 initial_map->set_instance_descriptors(*array_descriptors); 876 877 { // Add length. 878 CallbacksDescriptor d(*factory->length_string(), *array_length, attribs); 879 array_function->initial_map()->AppendDescriptor(&d, witness); 880 } 881 882 // array_function is used internally. JS code creating array object should 883 // search for the 'Array' property on the global object and use that one 884 // as the constructor. 'Array' property on a global object can be 885 // overwritten by JS code. 886 native_context()->set_array_function(*array_function); 887 888 // Cache the array maps, needed by ArrayConstructorStub 889 CacheInitialJSArrayMaps(native_context(), initial_map); 890 ArrayConstructorStub array_constructor_stub(isolate); 891 Handle<Code> code = array_constructor_stub.GetCode(isolate); 892 array_function->shared()->set_construct_stub(*code); 893 } 894 895 { // --- N u m b e r --- 896 Handle<JSFunction> number_fun = 897 InstallFunction(global, "Number", JS_VALUE_TYPE, JSValue::kSize, 898 isolate->initial_object_prototype(), 899 Builtins::kIllegal, true, true); 900 native_context()->set_number_function(*number_fun); 901 } 902 903 { // --- B o o l e a n --- 904 Handle<JSFunction> boolean_fun = 905 InstallFunction(global, "Boolean", JS_VALUE_TYPE, JSValue::kSize, 906 isolate->initial_object_prototype(), 907 Builtins::kIllegal, true, true); 908 native_context()->set_boolean_function(*boolean_fun); 909 } 910 911 { // --- S t r i n g --- 912 Handle<JSFunction> string_fun = 913 InstallFunction(global, "String", JS_VALUE_TYPE, JSValue::kSize, 914 isolate->initial_object_prototype(), 915 Builtins::kIllegal, true, true); 916 string_fun->shared()->set_construct_stub( 917 isolate->builtins()->builtin(Builtins::kStringConstructCode)); 918 native_context()->set_string_function(*string_fun); 919 920 Handle<Map> string_map = 921 Handle<Map>(native_context()->string_function()->initial_map()); 922 Handle<DescriptorArray> string_descriptors( 923 factory->NewDescriptorArray(0, 1)); 924 DescriptorArray::WhitenessWitness witness(*string_descriptors); 925 926 Handle<Foreign> string_length( 927 factory->NewForeign(&Accessors::StringLength)); 928 PropertyAttributes attribs = static_cast<PropertyAttributes>( 929 DONT_ENUM | DONT_DELETE | READ_ONLY); 930 string_map->set_instance_descriptors(*string_descriptors); 931 932 { // Add length. 933 CallbacksDescriptor d(*factory->length_string(), *string_length, attribs); 934 string_map->AppendDescriptor(&d, witness); 935 } 936 } 937 938 { // --- D a t e --- 939 // Builtin functions for Date.prototype. 940 Handle<JSFunction> date_fun = 941 InstallFunction(global, "Date", JS_DATE_TYPE, JSDate::kSize, 942 isolate->initial_object_prototype(), 943 Builtins::kIllegal, true, true); 944 945 native_context()->set_date_function(*date_fun); 946 } 947 948 949 { // -- R e g E x p 950 // Builtin functions for RegExp.prototype. 951 Handle<JSFunction> regexp_fun = 952 InstallFunction(global, "RegExp", JS_REGEXP_TYPE, JSRegExp::kSize, 953 isolate->initial_object_prototype(), 954 Builtins::kIllegal, true, true); 955 native_context()->set_regexp_function(*regexp_fun); 956 957 ASSERT(regexp_fun->has_initial_map()); 958 Handle<Map> initial_map(regexp_fun->initial_map()); 959 960 ASSERT_EQ(0, initial_map->inobject_properties()); 961 962 PropertyAttributes final = 963 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY); 964 Handle<DescriptorArray> descriptors = factory->NewDescriptorArray(0, 5); 965 DescriptorArray::WhitenessWitness witness(*descriptors); 966 initial_map->set_instance_descriptors(*descriptors); 967 968 { 969 // ECMA-262, section 15.10.7.1. 970 FieldDescriptor field(heap->source_string(), 971 JSRegExp::kSourceFieldIndex, 972 final, 973 Representation::Tagged()); 974 initial_map->AppendDescriptor(&field, witness); 975 } 976 { 977 // ECMA-262, section 15.10.7.2. 978 FieldDescriptor field(heap->global_string(), 979 JSRegExp::kGlobalFieldIndex, 980 final, 981 Representation::Tagged()); 982 initial_map->AppendDescriptor(&field, witness); 983 } 984 { 985 // ECMA-262, section 15.10.7.3. 986 FieldDescriptor field(heap->ignore_case_string(), 987 JSRegExp::kIgnoreCaseFieldIndex, 988 final, 989 Representation::Tagged()); 990 initial_map->AppendDescriptor(&field, witness); 991 } 992 { 993 // ECMA-262, section 15.10.7.4. 994 FieldDescriptor field(heap->multiline_string(), 995 JSRegExp::kMultilineFieldIndex, 996 final, 997 Representation::Tagged()); 998 initial_map->AppendDescriptor(&field, witness); 999 } 1000 { 1001 // ECMA-262, section 15.10.7.5. 1002 PropertyAttributes writable = 1003 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE); 1004 FieldDescriptor field(heap->last_index_string(), 1005 JSRegExp::kLastIndexFieldIndex, 1006 writable, 1007 Representation::Tagged()); 1008 initial_map->AppendDescriptor(&field, witness); 1009 } 1010 1011 initial_map->set_inobject_properties(5); 1012 initial_map->set_pre_allocated_property_fields(5); 1013 initial_map->set_unused_property_fields(0); 1014 initial_map->set_instance_size( 1015 initial_map->instance_size() + 5 * kPointerSize); 1016 initial_map->set_visitor_id(StaticVisitorBase::GetVisitorId(*initial_map)); 1017 1018 // RegExp prototype object is itself a RegExp. 1019 Handle<Map> proto_map = factory->CopyMap(initial_map); 1020 proto_map->set_prototype(native_context()->initial_object_prototype()); 1021 Handle<JSObject> proto = factory->NewJSObjectFromMap(proto_map); 1022 proto->InObjectPropertyAtPut(JSRegExp::kSourceFieldIndex, 1023 heap->query_colon_string()); 1024 proto->InObjectPropertyAtPut(JSRegExp::kGlobalFieldIndex, 1025 heap->false_value()); 1026 proto->InObjectPropertyAtPut(JSRegExp::kIgnoreCaseFieldIndex, 1027 heap->false_value()); 1028 proto->InObjectPropertyAtPut(JSRegExp::kMultilineFieldIndex, 1029 heap->false_value()); 1030 proto->InObjectPropertyAtPut(JSRegExp::kLastIndexFieldIndex, 1031 Smi::FromInt(0), 1032 SKIP_WRITE_BARRIER); // It's a Smi. 1033 initial_map->set_prototype(*proto); 1034 factory->SetRegExpIrregexpData(Handle<JSRegExp>::cast(proto), 1035 JSRegExp::IRREGEXP, factory->empty_string(), 1036 JSRegExp::Flags(0), 0); 1037 } 1038 1039 { // -- J S O N 1040 Handle<String> name = factory->InternalizeUtf8String("JSON"); 1041 Handle<JSFunction> cons = factory->NewFunction(name, 1042 factory->the_hole_value()); 1043 JSFunction::SetInstancePrototype(cons, 1044 Handle<Object>(native_context()->initial_object_prototype(), isolate)); 1045 cons->SetInstanceClassName(*name); 1046 Handle<JSObject> json_object = factory->NewJSObject(cons, TENURED); 1047 ASSERT(json_object->IsJSObject()); 1048 CHECK_NOT_EMPTY_HANDLE(isolate, 1049 JSObject::SetLocalPropertyIgnoreAttributes( 1050 global, name, json_object, DONT_ENUM)); 1051 native_context()->set_json_object(*json_object); 1052 } 1053 1054 { // -- A r r a y B u f f e r 1055 Handle<JSFunction> array_buffer_fun = 1056 InstallFunction( 1057 global, "ArrayBuffer", JS_ARRAY_BUFFER_TYPE, 1058 JSArrayBuffer::kSizeWithInternalFields, 1059 isolate->initial_object_prototype(), 1060 Builtins::kIllegal, true, true); 1061 native_context()->set_array_buffer_fun(*array_buffer_fun); 1062 } 1063 1064 { // -- T y p e d A r r a y s 1065 Handle<JSFunction> int8_fun = InstallTypedArray("Int8Array", 1066 EXTERNAL_BYTE_ELEMENTS); 1067 native_context()->set_int8_array_fun(*int8_fun); 1068 Handle<JSFunction> uint8_fun = InstallTypedArray("Uint8Array", 1069 EXTERNAL_UNSIGNED_BYTE_ELEMENTS); 1070 native_context()->set_uint8_array_fun(*uint8_fun); 1071 Handle<JSFunction> int16_fun = InstallTypedArray("Int16Array", 1072 EXTERNAL_SHORT_ELEMENTS); 1073 native_context()->set_int16_array_fun(*int16_fun); 1074 Handle<JSFunction> uint16_fun = InstallTypedArray("Uint16Array", 1075 EXTERNAL_UNSIGNED_SHORT_ELEMENTS); 1076 native_context()->set_uint16_array_fun(*uint16_fun); 1077 Handle<JSFunction> int32_fun = InstallTypedArray("Int32Array", 1078 EXTERNAL_INT_ELEMENTS); 1079 native_context()->set_int32_array_fun(*int32_fun); 1080 Handle<JSFunction> uint32_fun = InstallTypedArray("Uint32Array", 1081 EXTERNAL_UNSIGNED_INT_ELEMENTS); 1082 native_context()->set_uint32_array_fun(*uint32_fun); 1083 Handle<JSFunction> float_fun = InstallTypedArray("Float32Array", 1084 EXTERNAL_FLOAT_ELEMENTS); 1085 native_context()->set_float_array_fun(*float_fun); 1086 Handle<JSFunction> double_fun = InstallTypedArray("Float64Array", 1087 EXTERNAL_DOUBLE_ELEMENTS); 1088 native_context()->set_double_array_fun(*double_fun); 1089 Handle<JSFunction> uint8c_fun = InstallTypedArray("Uint8ClampedArray", 1090 EXTERNAL_PIXEL_ELEMENTS); 1091 native_context()->set_uint8c_array_fun(*uint8c_fun); 1092 1093 Handle<JSFunction> data_view_fun = 1094 InstallFunction( 1095 global, "DataView", JS_DATA_VIEW_TYPE, 1096 JSDataView::kSizeWithInternalFields, 1097 isolate->initial_object_prototype(), 1098 Builtins::kIllegal, true, true); 1099 native_context()->set_data_view_fun(*data_view_fun); 1100 } 1101 1102 { // --- arguments_boilerplate_ 1103 // Make sure we can recognize argument objects at runtime. 1104 // This is done by introducing an anonymous function with 1105 // class_name equals 'Arguments'. 1106 Handle<String> arguments_string = factory->InternalizeOneByteString( 1107 STATIC_ASCII_VECTOR("Arguments")); 1108 Handle<Code> code = Handle<Code>( 1109 isolate->builtins()->builtin(Builtins::kIllegal)); 1110 Handle<JSObject> prototype = 1111 Handle<JSObject>( 1112 JSObject::cast(native_context()->object_function()->prototype())); 1113 1114 Handle<JSFunction> function = 1115 factory->NewFunctionWithPrototype(arguments_string, 1116 JS_OBJECT_TYPE, 1117 JSObject::kHeaderSize, 1118 prototype, 1119 code, 1120 false); 1121 ASSERT(!function->has_initial_map()); 1122 function->shared()->set_instance_class_name(*arguments_string); 1123 function->shared()->set_expected_nof_properties(2); 1124 Handle<JSObject> result = factory->NewJSObject(function); 1125 1126 native_context()->set_arguments_boilerplate(*result); 1127 // Note: length must be added as the first property and 1128 // callee must be added as the second property. 1129 CHECK_NOT_EMPTY_HANDLE(isolate, 1130 JSObject::SetLocalPropertyIgnoreAttributes( 1131 result, factory->length_string(), 1132 factory->undefined_value(), DONT_ENUM, 1133 Object::FORCE_TAGGED, FORCE_FIELD)); 1134 CHECK_NOT_EMPTY_HANDLE(isolate, 1135 JSObject::SetLocalPropertyIgnoreAttributes( 1136 result, factory->callee_string(), 1137 factory->undefined_value(), DONT_ENUM, 1138 Object::FORCE_TAGGED, FORCE_FIELD)); 1139 1140#ifdef DEBUG 1141 LookupResult lookup(isolate); 1142 result->LocalLookup(heap->callee_string(), &lookup); 1143 ASSERT(lookup.IsField()); 1144 ASSERT(lookup.GetFieldIndex().field_index() == Heap::kArgumentsCalleeIndex); 1145 1146 result->LocalLookup(heap->length_string(), &lookup); 1147 ASSERT(lookup.IsField()); 1148 ASSERT(lookup.GetFieldIndex().field_index() == Heap::kArgumentsLengthIndex); 1149 1150 ASSERT(result->map()->inobject_properties() > Heap::kArgumentsCalleeIndex); 1151 ASSERT(result->map()->inobject_properties() > Heap::kArgumentsLengthIndex); 1152 1153 // Check the state of the object. 1154 ASSERT(result->HasFastProperties()); 1155 ASSERT(result->HasFastObjectElements()); 1156#endif 1157 } 1158 1159 { // --- aliased_arguments_boilerplate_ 1160 // Set up a well-formed parameter map to make assertions happy. 1161 Handle<FixedArray> elements = factory->NewFixedArray(2); 1162 elements->set_map(heap->non_strict_arguments_elements_map()); 1163 Handle<FixedArray> array; 1164 array = factory->NewFixedArray(0); 1165 elements->set(0, *array); 1166 array = factory->NewFixedArray(0); 1167 elements->set(1, *array); 1168 1169 Handle<Map> old_map(native_context()->arguments_boilerplate()->map()); 1170 Handle<Map> new_map = factory->CopyMap(old_map); 1171 new_map->set_pre_allocated_property_fields(2); 1172 Handle<JSObject> result = factory->NewJSObjectFromMap(new_map); 1173 // Set elements kind after allocating the object because 1174 // NewJSObjectFromMap assumes a fast elements map. 1175 new_map->set_elements_kind(NON_STRICT_ARGUMENTS_ELEMENTS); 1176 result->set_elements(*elements); 1177 ASSERT(result->HasNonStrictArgumentsElements()); 1178 native_context()->set_aliased_arguments_boilerplate(*result); 1179 } 1180 1181 { // --- strict mode arguments boilerplate 1182 const PropertyAttributes attributes = 1183 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY); 1184 1185 // Create the ThrowTypeError functions. 1186 Handle<AccessorPair> callee = factory->NewAccessorPair(); 1187 Handle<AccessorPair> caller = factory->NewAccessorPair(); 1188 1189 Handle<JSFunction> throw_function = 1190 GetThrowTypeErrorFunction(); 1191 1192 // Install the ThrowTypeError functions. 1193 callee->set_getter(*throw_function); 1194 callee->set_setter(*throw_function); 1195 caller->set_getter(*throw_function); 1196 caller->set_setter(*throw_function); 1197 1198 // Create the map. Allocate one in-object field for length. 1199 Handle<Map> map = factory->NewMap(JS_OBJECT_TYPE, 1200 Heap::kArgumentsObjectSizeStrict); 1201 // Create the descriptor array for the arguments object. 1202 Handle<DescriptorArray> descriptors = factory->NewDescriptorArray(0, 3); 1203 DescriptorArray::WhitenessWitness witness(*descriptors); 1204 map->set_instance_descriptors(*descriptors); 1205 1206 { // length 1207 FieldDescriptor d( 1208 *factory->length_string(), 0, DONT_ENUM, Representation::Tagged()); 1209 map->AppendDescriptor(&d, witness); 1210 } 1211 { // callee 1212 CallbacksDescriptor d(*factory->callee_string(), 1213 *callee, 1214 attributes); 1215 map->AppendDescriptor(&d, witness); 1216 } 1217 { // caller 1218 CallbacksDescriptor d(*factory->caller_string(), 1219 *caller, 1220 attributes); 1221 map->AppendDescriptor(&d, witness); 1222 } 1223 1224 map->set_function_with_prototype(true); 1225 map->set_prototype(native_context()->object_function()->prototype()); 1226 map->set_pre_allocated_property_fields(1); 1227 map->set_inobject_properties(1); 1228 1229 // Copy constructor from the non-strict arguments boilerplate. 1230 map->set_constructor( 1231 native_context()->arguments_boilerplate()->map()->constructor()); 1232 1233 // Allocate the arguments boilerplate object. 1234 Handle<JSObject> result = factory->NewJSObjectFromMap(map); 1235 native_context()->set_strict_mode_arguments_boilerplate(*result); 1236 1237 // Add length property only for strict mode boilerplate. 1238 CHECK_NOT_EMPTY_HANDLE(isolate, 1239 JSObject::SetLocalPropertyIgnoreAttributes( 1240 result, factory->length_string(), 1241 factory->undefined_value(), DONT_ENUM)); 1242 1243#ifdef DEBUG 1244 LookupResult lookup(isolate); 1245 result->LocalLookup(heap->length_string(), &lookup); 1246 ASSERT(lookup.IsField()); 1247 ASSERT(lookup.GetFieldIndex().field_index() == Heap::kArgumentsLengthIndex); 1248 1249 ASSERT(result->map()->inobject_properties() > Heap::kArgumentsLengthIndex); 1250 1251 // Check the state of the object. 1252 ASSERT(result->HasFastProperties()); 1253 ASSERT(result->HasFastObjectElements()); 1254#endif 1255 } 1256 1257 { // --- context extension 1258 // Create a function for the context extension objects. 1259 Handle<Code> code = Handle<Code>( 1260 isolate->builtins()->builtin(Builtins::kIllegal)); 1261 Handle<JSFunction> context_extension_fun = 1262 factory->NewFunction(factory->empty_string(), 1263 JS_CONTEXT_EXTENSION_OBJECT_TYPE, 1264 JSObject::kHeaderSize, 1265 code, 1266 true); 1267 1268 Handle<String> name = factory->InternalizeOneByteString( 1269 STATIC_ASCII_VECTOR("context_extension")); 1270 context_extension_fun->shared()->set_instance_class_name(*name); 1271 native_context()->set_context_extension_function(*context_extension_fun); 1272 } 1273 1274 1275 { 1276 // Set up the call-as-function delegate. 1277 Handle<Code> code = 1278 Handle<Code>(isolate->builtins()->builtin( 1279 Builtins::kHandleApiCallAsFunction)); 1280 Handle<JSFunction> delegate = 1281 factory->NewFunction(factory->empty_string(), JS_OBJECT_TYPE, 1282 JSObject::kHeaderSize, code, true); 1283 native_context()->set_call_as_function_delegate(*delegate); 1284 delegate->shared()->DontAdaptArguments(); 1285 } 1286 1287 { 1288 // Set up the call-as-constructor delegate. 1289 Handle<Code> code = 1290 Handle<Code>(isolate->builtins()->builtin( 1291 Builtins::kHandleApiCallAsConstructor)); 1292 Handle<JSFunction> delegate = 1293 factory->NewFunction(factory->empty_string(), JS_OBJECT_TYPE, 1294 JSObject::kHeaderSize, code, true); 1295 native_context()->set_call_as_constructor_delegate(*delegate); 1296 delegate->shared()->DontAdaptArguments(); 1297 } 1298 1299 // Initialize the out of memory slot. 1300 native_context()->set_out_of_memory(heap->false_value()); 1301 1302 // Initialize the embedder data slot. 1303 Handle<FixedArray> embedder_data = factory->NewFixedArray(2); 1304 native_context()->set_embedder_data(*embedder_data); 1305} 1306 1307 1308Handle<JSFunction> Genesis::InstallTypedArray( 1309 const char* name, ElementsKind elementsKind) { 1310 Handle<JSObject> global = Handle<JSObject>(native_context()->global_object()); 1311 Handle<JSFunction> result = InstallFunction(global, name, JS_TYPED_ARRAY_TYPE, 1312 JSTypedArray::kSize, isolate()->initial_object_prototype(), 1313 Builtins::kIllegal, false, true); 1314 1315 Handle<Map> initial_map = isolate()->factory()->NewMap( 1316 JS_TYPED_ARRAY_TYPE, JSTypedArray::kSizeWithInternalFields, elementsKind); 1317 result->set_initial_map(*initial_map); 1318 initial_map->set_constructor(*result); 1319 return result; 1320} 1321 1322 1323void Genesis::InitializeExperimentalGlobal() { 1324 Handle<JSObject> global = Handle<JSObject>(native_context()->global_object()); 1325 1326 // TODO(mstarzinger): Move this into Genesis::InitializeGlobal once we no 1327 // longer need to live behind flags, so functions get added to the snapshot. 1328 1329 if (FLAG_harmony_symbols) { 1330 // --- S y m b o l --- 1331 Handle<JSFunction> symbol_fun = 1332 InstallFunction(global, "Symbol", JS_VALUE_TYPE, JSValue::kSize, 1333 isolate()->initial_object_prototype(), 1334 Builtins::kIllegal, true, true); 1335 native_context()->set_symbol_function(*symbol_fun); 1336 } 1337 1338 if (FLAG_harmony_collections) { 1339 { // -- S e t 1340 InstallFunction(global, "Set", JS_SET_TYPE, JSSet::kSize, 1341 isolate()->initial_object_prototype(), 1342 Builtins::kIllegal, true, true); 1343 } 1344 { // -- M a p 1345 InstallFunction(global, "Map", JS_MAP_TYPE, JSMap::kSize, 1346 isolate()->initial_object_prototype(), 1347 Builtins::kIllegal, true, true); 1348 } 1349 { // -- W e a k M a p 1350 InstallFunction(global, "WeakMap", JS_WEAK_MAP_TYPE, JSWeakMap::kSize, 1351 isolate()->initial_object_prototype(), 1352 Builtins::kIllegal, true, true); 1353 } 1354 { // -- W e a k S e t 1355 InstallFunction(global, "WeakSet", JS_WEAK_SET_TYPE, JSWeakSet::kSize, 1356 isolate()->initial_object_prototype(), 1357 Builtins::kIllegal, true, true); 1358 } 1359 } 1360 1361 if (FLAG_harmony_generators) { 1362 // Create generator meta-objects and install them on the builtins object. 1363 Handle<JSObject> builtins(native_context()->builtins()); 1364 Handle<JSObject> generator_object_prototype = 1365 factory()->NewJSObject(isolate()->object_function(), TENURED); 1366 Handle<JSFunction> generator_function_prototype = 1367 InstallFunction(builtins, "GeneratorFunctionPrototype", 1368 JS_FUNCTION_TYPE, JSFunction::kHeaderSize, 1369 generator_object_prototype, Builtins::kIllegal, 1370 false, false); 1371 InstallFunction(builtins, "GeneratorFunction", 1372 JS_FUNCTION_TYPE, JSFunction::kSize, 1373 generator_function_prototype, Builtins::kIllegal, 1374 false, false); 1375 1376 // Create maps for generator functions and their prototypes. Store those 1377 // maps in the native context. 1378 Handle<Map> function_map(native_context()->function_map()); 1379 Handle<Map> generator_function_map = factory()->CopyMap(function_map); 1380 generator_function_map->set_prototype(*generator_function_prototype); 1381 native_context()->set_generator_function_map(*generator_function_map); 1382 1383 Handle<Map> strict_mode_function_map( 1384 native_context()->strict_mode_function_map()); 1385 Handle<Map> strict_mode_generator_function_map = factory()->CopyMap( 1386 strict_mode_function_map); 1387 strict_mode_generator_function_map->set_prototype( 1388 *generator_function_prototype); 1389 native_context()->set_strict_mode_generator_function_map( 1390 *strict_mode_generator_function_map); 1391 1392 Handle<Map> object_map(native_context()->object_function()->initial_map()); 1393 Handle<Map> generator_object_prototype_map = factory()->CopyMap( 1394 object_map, 0); 1395 generator_object_prototype_map->set_prototype( 1396 *generator_object_prototype); 1397 native_context()->set_generator_object_prototype_map( 1398 *generator_object_prototype_map); 1399 1400 // Create a map for generator result objects. 1401 ASSERT(object_map->inobject_properties() == 0); 1402 STATIC_ASSERT(JSGeneratorObject::kResultPropertyCount == 2); 1403 Handle<Map> generator_result_map = factory()->CopyMap(object_map, 1404 JSGeneratorObject::kResultPropertyCount); 1405 ASSERT(generator_result_map->inobject_properties() == 1406 JSGeneratorObject::kResultPropertyCount); 1407 1408 Handle<DescriptorArray> descriptors = factory()->NewDescriptorArray(0, 1409 JSGeneratorObject::kResultPropertyCount); 1410 DescriptorArray::WhitenessWitness witness(*descriptors); 1411 generator_result_map->set_instance_descriptors(*descriptors); 1412 1413 Handle<String> value_string = factory()->InternalizeOneByteString( 1414 STATIC_ASCII_VECTOR("value")); 1415 FieldDescriptor value_descr(*value_string, 1416 JSGeneratorObject::kResultValuePropertyIndex, 1417 NONE, 1418 Representation::Tagged()); 1419 generator_result_map->AppendDescriptor(&value_descr, witness); 1420 1421 Handle<String> done_string = factory()->InternalizeOneByteString( 1422 STATIC_ASCII_VECTOR("done")); 1423 FieldDescriptor done_descr(*done_string, 1424 JSGeneratorObject::kResultDonePropertyIndex, 1425 NONE, 1426 Representation::Tagged()); 1427 generator_result_map->AppendDescriptor(&done_descr, witness); 1428 1429 generator_result_map->set_unused_property_fields(0); 1430 ASSERT_EQ(JSGeneratorObject::kResultSize, 1431 generator_result_map->instance_size()); 1432 native_context()->set_generator_result_map(*generator_result_map); 1433 } 1434} 1435 1436 1437bool Genesis::CompileBuiltin(Isolate* isolate, int index) { 1438 Vector<const char> name = Natives::GetScriptName(index); 1439 Handle<String> source_code = 1440 isolate->bootstrapper()->NativesSourceLookup(index); 1441 return CompileNative(isolate, name, source_code); 1442} 1443 1444 1445bool Genesis::CompileExperimentalBuiltin(Isolate* isolate, int index) { 1446 Vector<const char> name = ExperimentalNatives::GetScriptName(index); 1447 Factory* factory = isolate->factory(); 1448 Handle<String> source_code = 1449 factory->NewStringFromAscii( 1450 ExperimentalNatives::GetRawScriptSource(index)); 1451 return CompileNative(isolate, name, source_code); 1452} 1453 1454 1455bool Genesis::CompileNative(Isolate* isolate, 1456 Vector<const char> name, 1457 Handle<String> source) { 1458 HandleScope scope(isolate); 1459#ifdef ENABLE_DEBUGGER_SUPPORT 1460 isolate->debugger()->set_compiling_natives(true); 1461#endif 1462 // During genesis, the boilerplate for stack overflow won't work until the 1463 // environment has been at least partially initialized. Add a stack check 1464 // before entering JS code to catch overflow early. 1465 StackLimitCheck check(isolate); 1466 if (check.HasOverflowed()) return false; 1467 1468 bool result = CompileScriptCached(isolate, 1469 name, 1470 source, 1471 NULL, 1472 NULL, 1473 Handle<Context>(isolate->context()), 1474 true); 1475 ASSERT(isolate->has_pending_exception() != result); 1476 if (!result) isolate->clear_pending_exception(); 1477#ifdef ENABLE_DEBUGGER_SUPPORT 1478 isolate->debugger()->set_compiling_natives(false); 1479#endif 1480 return result; 1481} 1482 1483 1484bool Genesis::CompileScriptCached(Isolate* isolate, 1485 Vector<const char> name, 1486 Handle<String> source, 1487 SourceCodeCache* cache, 1488 v8::Extension* extension, 1489 Handle<Context> top_context, 1490 bool use_runtime_context) { 1491 Factory* factory = isolate->factory(); 1492 HandleScope scope(isolate); 1493 Handle<SharedFunctionInfo> function_info; 1494 1495 // If we can't find the function in the cache, we compile a new 1496 // function and insert it into the cache. 1497 if (cache == NULL || !cache->Lookup(name, &function_info)) { 1498 ASSERT(source->IsOneByteRepresentation()); 1499 Handle<String> script_name = factory->NewStringFromUtf8(name); 1500 function_info = Compiler::Compile( 1501 source, 1502 script_name, 1503 0, 1504 0, 1505 false, 1506 top_context, 1507 extension, 1508 NULL, 1509 Handle<String>::null(), 1510 use_runtime_context ? NATIVES_CODE : NOT_NATIVES_CODE); 1511 if (function_info.is_null()) return false; 1512 if (cache != NULL) cache->Add(name, function_info); 1513 } 1514 1515 // Set up the function context. Conceptually, we should clone the 1516 // function before overwriting the context but since we're in a 1517 // single-threaded environment it is not strictly necessary. 1518 ASSERT(top_context->IsNativeContext()); 1519 Handle<Context> context = 1520 Handle<Context>(use_runtime_context 1521 ? Handle<Context>(top_context->runtime_context()) 1522 : top_context); 1523 Handle<JSFunction> fun = 1524 factory->NewFunctionFromSharedFunctionInfo(function_info, context); 1525 1526 // Call function using either the runtime object or the global 1527 // object as the receiver. Provide no parameters. 1528 Handle<Object> receiver = 1529 Handle<Object>(use_runtime_context 1530 ? top_context->builtins() 1531 : top_context->global_object(), 1532 isolate); 1533 bool has_pending_exception; 1534 Execution::Call(isolate, fun, receiver, 0, NULL, &has_pending_exception); 1535 if (has_pending_exception) return false; 1536 return true; 1537} 1538 1539 1540#define INSTALL_NATIVE(Type, name, var) \ 1541 Handle<String> var##_name = \ 1542 factory()->InternalizeOneByteString(STATIC_ASCII_VECTOR(name)); \ 1543 Object* var##_native = \ 1544 native_context()->builtins()->GetPropertyNoExceptionThrown( \ 1545 *var##_name); \ 1546 native_context()->set_##var(Type::cast(var##_native)); 1547 1548 1549void Genesis::InstallNativeFunctions() { 1550 HandleScope scope(isolate()); 1551 INSTALL_NATIVE(JSFunction, "CreateDate", create_date_fun); 1552 INSTALL_NATIVE(JSFunction, "ToNumber", to_number_fun); 1553 INSTALL_NATIVE(JSFunction, "ToString", to_string_fun); 1554 INSTALL_NATIVE(JSFunction, "ToDetailString", to_detail_string_fun); 1555 INSTALL_NATIVE(JSFunction, "ToObject", to_object_fun); 1556 INSTALL_NATIVE(JSFunction, "ToInteger", to_integer_fun); 1557 INSTALL_NATIVE(JSFunction, "ToUint32", to_uint32_fun); 1558 INSTALL_NATIVE(JSFunction, "ToInt32", to_int32_fun); 1559 INSTALL_NATIVE(JSFunction, "GlobalEval", global_eval_fun); 1560 INSTALL_NATIVE(JSFunction, "Instantiate", instantiate_fun); 1561 INSTALL_NATIVE(JSFunction, "ConfigureTemplateInstance", 1562 configure_instance_fun); 1563 INSTALL_NATIVE(JSFunction, "GetStackTraceLine", get_stack_trace_line_fun); 1564 INSTALL_NATIVE(JSObject, "functionCache", function_cache); 1565 INSTALL_NATIVE(JSFunction, "ToCompletePropertyDescriptor", 1566 to_complete_property_descriptor); 1567} 1568 1569 1570void Genesis::InstallExperimentalNativeFunctions() { 1571 INSTALL_NATIVE(JSFunction, "RunMicrotasks", run_microtasks); 1572 if (FLAG_harmony_proxies) { 1573 INSTALL_NATIVE(JSFunction, "DerivedHasTrap", derived_has_trap); 1574 INSTALL_NATIVE(JSFunction, "DerivedGetTrap", derived_get_trap); 1575 INSTALL_NATIVE(JSFunction, "DerivedSetTrap", derived_set_trap); 1576 INSTALL_NATIVE(JSFunction, "ProxyEnumerate", proxy_enumerate); 1577 } 1578 if (FLAG_harmony_observation) { 1579 INSTALL_NATIVE(JSFunction, "NotifyChange", observers_notify_change); 1580 INSTALL_NATIVE(JSFunction, "EnqueueSpliceRecord", observers_enqueue_splice); 1581 INSTALL_NATIVE(JSFunction, "BeginPerformSplice", 1582 observers_begin_perform_splice); 1583 INSTALL_NATIVE(JSFunction, "EndPerformSplice", 1584 observers_end_perform_splice); 1585 } 1586} 1587 1588#undef INSTALL_NATIVE 1589 1590 1591Handle<JSFunction> Genesis::InstallInternalArray( 1592 Handle<JSBuiltinsObject> builtins, 1593 const char* name, 1594 ElementsKind elements_kind) { 1595 // --- I n t e r n a l A r r a y --- 1596 // An array constructor on the builtins object that works like 1597 // the public Array constructor, except that its prototype 1598 // doesn't inherit from Object.prototype. 1599 // To be used only for internal work by builtins. Instances 1600 // must not be leaked to user code. 1601 Handle<JSFunction> array_function = 1602 InstallFunction(builtins, 1603 name, 1604 JS_ARRAY_TYPE, 1605 JSArray::kSize, 1606 isolate()->initial_object_prototype(), 1607 Builtins::kInternalArrayCode, 1608 true, true); 1609 Handle<JSObject> prototype = 1610 factory()->NewJSObject(isolate()->object_function(), TENURED); 1611 Accessors::FunctionSetPrototype(array_function, prototype); 1612 1613 InternalArrayConstructorStub internal_array_constructor_stub(isolate()); 1614 Handle<Code> code = internal_array_constructor_stub.GetCode(isolate()); 1615 array_function->shared()->set_construct_stub(*code); 1616 array_function->shared()->DontAdaptArguments(); 1617 1618 Handle<Map> original_map(array_function->initial_map()); 1619 Handle<Map> initial_map = factory()->CopyMap(original_map); 1620 initial_map->set_elements_kind(elements_kind); 1621 array_function->set_initial_map(*initial_map); 1622 1623 // Make "length" magic on instances. 1624 Handle<DescriptorArray> array_descriptors( 1625 factory()->NewDescriptorArray(0, 1)); 1626 DescriptorArray::WhitenessWitness witness(*array_descriptors); 1627 1628 Handle<Foreign> array_length(factory()->NewForeign( 1629 &Accessors::ArrayLength)); 1630 PropertyAttributes attribs = static_cast<PropertyAttributes>( 1631 DONT_ENUM | DONT_DELETE); 1632 initial_map->set_instance_descriptors(*array_descriptors); 1633 1634 { // Add length. 1635 CallbacksDescriptor d( 1636 *factory()->length_string(), *array_length, attribs); 1637 array_function->initial_map()->AppendDescriptor(&d, witness); 1638 } 1639 1640 return array_function; 1641} 1642 1643 1644bool Genesis::InstallNatives() { 1645 HandleScope scope(isolate()); 1646 1647 // Create a function for the builtins object. Allocate space for the 1648 // JavaScript builtins, a reference to the builtins object 1649 // (itself) and a reference to the native_context directly in the object. 1650 Handle<Code> code = Handle<Code>( 1651 isolate()->builtins()->builtin(Builtins::kIllegal)); 1652 Handle<JSFunction> builtins_fun = 1653 factory()->NewFunction(factory()->empty_string(), 1654 JS_BUILTINS_OBJECT_TYPE, 1655 JSBuiltinsObject::kSize, code, true); 1656 1657 Handle<String> name = 1658 factory()->InternalizeOneByteString(STATIC_ASCII_VECTOR("builtins")); 1659 builtins_fun->shared()->set_instance_class_name(*name); 1660 builtins_fun->initial_map()->set_dictionary_map(true); 1661 builtins_fun->initial_map()->set_prototype(heap()->null_value()); 1662 1663 // Allocate the builtins object. 1664 Handle<JSBuiltinsObject> builtins = 1665 Handle<JSBuiltinsObject>::cast(factory()->NewGlobalObject(builtins_fun)); 1666 builtins->set_builtins(*builtins); 1667 builtins->set_native_context(*native_context()); 1668 builtins->set_global_context(*native_context()); 1669 builtins->set_global_receiver(*builtins); 1670 1671 // Set up the 'global' properties of the builtins object. The 1672 // 'global' property that refers to the global object is the only 1673 // way to get from code running in the builtins context to the 1674 // global object. 1675 static const PropertyAttributes attributes = 1676 static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE); 1677 Handle<String> global_string = 1678 factory()->InternalizeOneByteString(STATIC_ASCII_VECTOR("global")); 1679 Handle<Object> global_obj(native_context()->global_object(), isolate()); 1680 CHECK_NOT_EMPTY_HANDLE(isolate(), 1681 JSObject::SetLocalPropertyIgnoreAttributes( 1682 builtins, global_string, global_obj, attributes)); 1683 1684 // Set up the reference from the global object to the builtins object. 1685 JSGlobalObject::cast(native_context()->global_object())-> 1686 set_builtins(*builtins); 1687 1688 // Create a bridge function that has context in the native context. 1689 Handle<JSFunction> bridge = 1690 factory()->NewFunction(factory()->empty_string(), 1691 factory()->undefined_value()); 1692 ASSERT(bridge->context() == *isolate()->native_context()); 1693 1694 // Allocate the builtins context. 1695 Handle<Context> context = 1696 factory()->NewFunctionContext(Context::MIN_CONTEXT_SLOTS, bridge); 1697 context->set_global_object(*builtins); // override builtins global object 1698 1699 native_context()->set_runtime_context(*context); 1700 1701 { // -- S c r i p t 1702 // Builtin functions for Script. 1703 Handle<JSFunction> script_fun = 1704 InstallFunction(builtins, "Script", JS_VALUE_TYPE, JSValue::kSize, 1705 isolate()->initial_object_prototype(), 1706 Builtins::kIllegal, false, false); 1707 Handle<JSObject> prototype = 1708 factory()->NewJSObject(isolate()->object_function(), TENURED); 1709 Accessors::FunctionSetPrototype(script_fun, prototype); 1710 native_context()->set_script_function(*script_fun); 1711 1712 Handle<Map> script_map = Handle<Map>(script_fun->initial_map()); 1713 1714 Handle<DescriptorArray> script_descriptors( 1715 factory()->NewDescriptorArray(0, 13)); 1716 DescriptorArray::WhitenessWitness witness(*script_descriptors); 1717 1718 Handle<Foreign> script_source( 1719 factory()->NewForeign(&Accessors::ScriptSource)); 1720 Handle<Foreign> script_name(factory()->NewForeign(&Accessors::ScriptName)); 1721 Handle<String> id_string(factory()->InternalizeOneByteString( 1722 STATIC_ASCII_VECTOR("id"))); 1723 Handle<Foreign> script_id(factory()->NewForeign(&Accessors::ScriptId)); 1724 Handle<String> line_offset_string( 1725 factory()->InternalizeOneByteString( 1726 STATIC_ASCII_VECTOR("line_offset"))); 1727 Handle<Foreign> script_line_offset( 1728 factory()->NewForeign(&Accessors::ScriptLineOffset)); 1729 Handle<String> column_offset_string( 1730 factory()->InternalizeOneByteString( 1731 STATIC_ASCII_VECTOR("column_offset"))); 1732 Handle<Foreign> script_column_offset( 1733 factory()->NewForeign(&Accessors::ScriptColumnOffset)); 1734 Handle<String> data_string(factory()->InternalizeOneByteString( 1735 STATIC_ASCII_VECTOR("data"))); 1736 Handle<Foreign> script_data(factory()->NewForeign(&Accessors::ScriptData)); 1737 Handle<String> type_string(factory()->InternalizeOneByteString( 1738 STATIC_ASCII_VECTOR("type"))); 1739 Handle<Foreign> script_type(factory()->NewForeign(&Accessors::ScriptType)); 1740 Handle<String> compilation_type_string( 1741 factory()->InternalizeOneByteString( 1742 STATIC_ASCII_VECTOR("compilation_type"))); 1743 Handle<Foreign> script_compilation_type( 1744 factory()->NewForeign(&Accessors::ScriptCompilationType)); 1745 Handle<String> line_ends_string(factory()->InternalizeOneByteString( 1746 STATIC_ASCII_VECTOR("line_ends"))); 1747 Handle<Foreign> script_line_ends( 1748 factory()->NewForeign(&Accessors::ScriptLineEnds)); 1749 Handle<String> context_data_string( 1750 factory()->InternalizeOneByteString( 1751 STATIC_ASCII_VECTOR("context_data"))); 1752 Handle<Foreign> script_context_data( 1753 factory()->NewForeign(&Accessors::ScriptContextData)); 1754 Handle<String> eval_from_script_string( 1755 factory()->InternalizeOneByteString( 1756 STATIC_ASCII_VECTOR("eval_from_script"))); 1757 Handle<Foreign> script_eval_from_script( 1758 factory()->NewForeign(&Accessors::ScriptEvalFromScript)); 1759 Handle<String> eval_from_script_position_string( 1760 factory()->InternalizeOneByteString( 1761 STATIC_ASCII_VECTOR("eval_from_script_position"))); 1762 Handle<Foreign> script_eval_from_script_position( 1763 factory()->NewForeign(&Accessors::ScriptEvalFromScriptPosition)); 1764 Handle<String> eval_from_function_name_string( 1765 factory()->InternalizeOneByteString( 1766 STATIC_ASCII_VECTOR("eval_from_function_name"))); 1767 Handle<Foreign> script_eval_from_function_name( 1768 factory()->NewForeign(&Accessors::ScriptEvalFromFunctionName)); 1769 PropertyAttributes attribs = 1770 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY); 1771 script_map->set_instance_descriptors(*script_descriptors); 1772 1773 { 1774 CallbacksDescriptor d( 1775 *factory()->source_string(), *script_source, attribs); 1776 script_map->AppendDescriptor(&d, witness); 1777 } 1778 1779 { 1780 CallbacksDescriptor d(*factory()->name_string(), *script_name, attribs); 1781 script_map->AppendDescriptor(&d, witness); 1782 } 1783 1784 { 1785 CallbacksDescriptor d(*id_string, *script_id, attribs); 1786 script_map->AppendDescriptor(&d, witness); 1787 } 1788 1789 { 1790 CallbacksDescriptor d(*line_offset_string, *script_line_offset, attribs); 1791 script_map->AppendDescriptor(&d, witness); 1792 } 1793 1794 { 1795 CallbacksDescriptor d( 1796 *column_offset_string, *script_column_offset, attribs); 1797 script_map->AppendDescriptor(&d, witness); 1798 } 1799 1800 { 1801 CallbacksDescriptor d(*data_string, *script_data, attribs); 1802 script_map->AppendDescriptor(&d, witness); 1803 } 1804 1805 { 1806 CallbacksDescriptor d(*type_string, *script_type, attribs); 1807 script_map->AppendDescriptor(&d, witness); 1808 } 1809 1810 { 1811 CallbacksDescriptor d( 1812 *compilation_type_string, *script_compilation_type, attribs); 1813 script_map->AppendDescriptor(&d, witness); 1814 } 1815 1816 { 1817 CallbacksDescriptor d(*line_ends_string, *script_line_ends, attribs); 1818 script_map->AppendDescriptor(&d, witness); 1819 } 1820 1821 { 1822 CallbacksDescriptor d( 1823 *context_data_string, *script_context_data, attribs); 1824 script_map->AppendDescriptor(&d, witness); 1825 } 1826 1827 { 1828 CallbacksDescriptor d( 1829 *eval_from_script_string, *script_eval_from_script, attribs); 1830 script_map->AppendDescriptor(&d, witness); 1831 } 1832 1833 { 1834 CallbacksDescriptor d( 1835 *eval_from_script_position_string, 1836 *script_eval_from_script_position, 1837 attribs); 1838 script_map->AppendDescriptor(&d, witness); 1839 } 1840 1841 { 1842 CallbacksDescriptor d( 1843 *eval_from_function_name_string, 1844 *script_eval_from_function_name, 1845 attribs); 1846 script_map->AppendDescriptor(&d, witness); 1847 } 1848 1849 // Allocate the empty script. 1850 Handle<Script> script = factory()->NewScript(factory()->empty_string()); 1851 script->set_type(Smi::FromInt(Script::TYPE_NATIVE)); 1852 heap()->public_set_empty_script(*script); 1853 } 1854 { 1855 // Builtin function for OpaqueReference -- a JSValue-based object, 1856 // that keeps its field isolated from JavaScript code. It may store 1857 // objects, that JavaScript code may not access. 1858 Handle<JSFunction> opaque_reference_fun = 1859 InstallFunction(builtins, "OpaqueReference", JS_VALUE_TYPE, 1860 JSValue::kSize, 1861 isolate()->initial_object_prototype(), 1862 Builtins::kIllegal, false, false); 1863 Handle<JSObject> prototype = 1864 factory()->NewJSObject(isolate()->object_function(), TENURED); 1865 Accessors::FunctionSetPrototype(opaque_reference_fun, prototype); 1866 native_context()->set_opaque_reference_function(*opaque_reference_fun); 1867 } 1868 1869 // InternalArrays should not use Smi-Only array optimizations. There are too 1870 // many places in the C++ runtime code (e.g. RegEx) that assume that 1871 // elements in InternalArrays can be set to non-Smi values without going 1872 // through a common bottleneck that would make the SMI_ONLY -> FAST_ELEMENT 1873 // transition easy to trap. Moreover, they rarely are smi-only. 1874 { 1875 Handle<JSFunction> array_function = 1876 InstallInternalArray(builtins, "InternalArray", FAST_HOLEY_ELEMENTS); 1877 native_context()->set_internal_array_function(*array_function); 1878 } 1879 1880 { 1881 InstallInternalArray(builtins, "InternalPackedArray", FAST_ELEMENTS); 1882 } 1883 1884 if (FLAG_disable_native_files) { 1885 PrintF("Warning: Running without installed natives!\n"); 1886 return true; 1887 } 1888 1889 // Install natives. 1890 for (int i = Natives::GetDebuggerCount(); 1891 i < Natives::GetBuiltinsCount(); 1892 i++) { 1893 if (!CompileBuiltin(isolate(), i)) return false; 1894 // TODO(ager): We really only need to install the JS builtin 1895 // functions on the builtins object after compiling and running 1896 // runtime.js. 1897 if (!InstallJSBuiltins(builtins)) return false; 1898 } 1899 1900 InstallNativeFunctions(); 1901 1902 // Store the map for the string prototype after the natives has been compiled 1903 // and the String function has been set up. 1904 Handle<JSFunction> string_function(native_context()->string_function()); 1905 ASSERT(JSObject::cast( 1906 string_function->initial_map()->prototype())->HasFastProperties()); 1907 native_context()->set_string_function_prototype_map( 1908 HeapObject::cast(string_function->initial_map()->prototype())->map()); 1909 1910 // Install Function.prototype.call and apply. 1911 { Handle<String> key = factory()->function_class_string(); 1912 Handle<JSFunction> function = 1913 Handle<JSFunction>::cast( 1914 GetProperty(isolate(), isolate()->global_object(), key)); 1915 Handle<JSObject> proto = 1916 Handle<JSObject>(JSObject::cast(function->instance_prototype())); 1917 1918 // Install the call and the apply functions. 1919 Handle<JSFunction> call = 1920 InstallFunction(proto, "call", JS_OBJECT_TYPE, JSObject::kHeaderSize, 1921 Handle<JSObject>::null(), 1922 Builtins::kFunctionCall, 1923 false, false); 1924 Handle<JSFunction> apply = 1925 InstallFunction(proto, "apply", JS_OBJECT_TYPE, JSObject::kHeaderSize, 1926 Handle<JSObject>::null(), 1927 Builtins::kFunctionApply, 1928 false, false); 1929 1930 // Make sure that Function.prototype.call appears to be compiled. 1931 // The code will never be called, but inline caching for call will 1932 // only work if it appears to be compiled. 1933 call->shared()->DontAdaptArguments(); 1934 ASSERT(call->is_compiled()); 1935 1936 // Set the expected parameters for apply to 2; required by builtin. 1937 apply->shared()->set_formal_parameter_count(2); 1938 1939 // Set the lengths for the functions to satisfy ECMA-262. 1940 call->shared()->set_length(1); 1941 apply->shared()->set_length(2); 1942 } 1943 1944 InstallBuiltinFunctionIds(); 1945 1946 // Create a constructor for RegExp results (a variant of Array that 1947 // predefines the two properties index and match). 1948 { 1949 // RegExpResult initial map. 1950 1951 // Find global.Array.prototype to inherit from. 1952 Handle<JSFunction> array_constructor(native_context()->array_function()); 1953 Handle<JSObject> array_prototype( 1954 JSObject::cast(array_constructor->instance_prototype())); 1955 1956 // Add initial map. 1957 Handle<Map> initial_map = 1958 factory()->NewMap(JS_ARRAY_TYPE, JSRegExpResult::kSize); 1959 initial_map->set_constructor(*array_constructor); 1960 1961 // Set prototype on map. 1962 initial_map->set_non_instance_prototype(false); 1963 initial_map->set_prototype(*array_prototype); 1964 1965 // Update map with length accessor from Array and add "index" and "input". 1966 Handle<DescriptorArray> reresult_descriptors = 1967 factory()->NewDescriptorArray(0, 3); 1968 DescriptorArray::WhitenessWitness witness(*reresult_descriptors); 1969 initial_map->set_instance_descriptors(*reresult_descriptors); 1970 1971 { 1972 JSFunction* array_function = native_context()->array_function(); 1973 Handle<DescriptorArray> array_descriptors( 1974 array_function->initial_map()->instance_descriptors()); 1975 String* length = heap()->length_string(); 1976 int old = array_descriptors->SearchWithCache( 1977 length, array_function->initial_map()); 1978 ASSERT(old != DescriptorArray::kNotFound); 1979 CallbacksDescriptor desc(length, 1980 array_descriptors->GetValue(old), 1981 array_descriptors->GetDetails(old).attributes()); 1982 initial_map->AppendDescriptor(&desc, witness); 1983 } 1984 { 1985 FieldDescriptor index_field(heap()->index_string(), 1986 JSRegExpResult::kIndexIndex, 1987 NONE, 1988 Representation::Tagged()); 1989 initial_map->AppendDescriptor(&index_field, witness); 1990 } 1991 1992 { 1993 FieldDescriptor input_field(heap()->input_string(), 1994 JSRegExpResult::kInputIndex, 1995 NONE, 1996 Representation::Tagged()); 1997 initial_map->AppendDescriptor(&input_field, witness); 1998 } 1999 2000 initial_map->set_inobject_properties(2); 2001 initial_map->set_pre_allocated_property_fields(2); 2002 initial_map->set_unused_property_fields(0); 2003 2004 native_context()->set_regexp_result_map(*initial_map); 2005 } 2006 2007#ifdef VERIFY_HEAP 2008 builtins->Verify(); 2009#endif 2010 2011 return true; 2012} 2013 2014 2015#define INSTALL_EXPERIMENTAL_NATIVE(i, flag, file) \ 2016 if (FLAG_harmony_##flag && \ 2017 strcmp(ExperimentalNatives::GetScriptName(i).start(), \ 2018 "native " file) == 0) { \ 2019 if (!CompileExperimentalBuiltin(isolate(), i)) return false; \ 2020 } 2021 2022 2023bool Genesis::InstallExperimentalNatives() { 2024 for (int i = ExperimentalNatives::GetDebuggerCount(); 2025 i < ExperimentalNatives::GetBuiltinsCount(); 2026 i++) { 2027 INSTALL_EXPERIMENTAL_NATIVE(i, symbols, "symbol.js") 2028 INSTALL_EXPERIMENTAL_NATIVE(i, proxies, "proxy.js") 2029 INSTALL_EXPERIMENTAL_NATIVE(i, collections, "collection.js") 2030 INSTALL_EXPERIMENTAL_NATIVE(i, observation, "object-observe.js") 2031 INSTALL_EXPERIMENTAL_NATIVE(i, promises, "promise.js") 2032 INSTALL_EXPERIMENTAL_NATIVE(i, generators, "generator.js") 2033 INSTALL_EXPERIMENTAL_NATIVE(i, iteration, "array-iterator.js") 2034 INSTALL_EXPERIMENTAL_NATIVE(i, strings, "harmony-string.js") 2035 INSTALL_EXPERIMENTAL_NATIVE(i, arrays, "harmony-array.js") 2036 INSTALL_EXPERIMENTAL_NATIVE(i, maths, "harmony-math.js") 2037 } 2038 2039 InstallExperimentalNativeFunctions(); 2040 2041 return true; 2042} 2043 2044 2045static Handle<JSObject> ResolveBuiltinIdHolder( 2046 Handle<Context> native_context, 2047 const char* holder_expr) { 2048 Isolate* isolate = native_context->GetIsolate(); 2049 Factory* factory = isolate->factory(); 2050 Handle<GlobalObject> global(native_context->global_object()); 2051 const char* period_pos = strchr(holder_expr, '.'); 2052 if (period_pos == NULL) { 2053 return Handle<JSObject>::cast(GetProperty( 2054 isolate, global, factory->InternalizeUtf8String(holder_expr))); 2055 } 2056 ASSERT_EQ(".prototype", period_pos); 2057 Vector<const char> property(holder_expr, 2058 static_cast<int>(period_pos - holder_expr)); 2059 Handle<JSFunction> function = Handle<JSFunction>::cast( 2060 GetProperty(isolate, global, factory->InternalizeUtf8String(property))); 2061 return Handle<JSObject>(JSObject::cast(function->prototype())); 2062} 2063 2064 2065static void InstallBuiltinFunctionId(Handle<JSObject> holder, 2066 const char* function_name, 2067 BuiltinFunctionId id) { 2068 Factory* factory = holder->GetIsolate()->factory(); 2069 Handle<String> name = factory->InternalizeUtf8String(function_name); 2070 Object* function_object = holder->GetProperty(*name)->ToObjectUnchecked(); 2071 Handle<JSFunction> function(JSFunction::cast(function_object)); 2072 function->shared()->set_function_data(Smi::FromInt(id)); 2073} 2074 2075 2076void Genesis::InstallBuiltinFunctionIds() { 2077 HandleScope scope(isolate()); 2078#define INSTALL_BUILTIN_ID(holder_expr, fun_name, name) \ 2079 { \ 2080 Handle<JSObject> holder = ResolveBuiltinIdHolder( \ 2081 native_context(), #holder_expr); \ 2082 BuiltinFunctionId id = k##name; \ 2083 InstallBuiltinFunctionId(holder, #fun_name, id); \ 2084 } 2085 FUNCTIONS_WITH_ID_LIST(INSTALL_BUILTIN_ID) 2086#undef INSTALL_BUILTIN_ID 2087} 2088 2089 2090// Do not forget to update macros.py with named constant 2091// of cache id. 2092#define JSFUNCTION_RESULT_CACHE_LIST(F) \ 2093 F(16, native_context()->regexp_function()) 2094 2095 2096static FixedArray* CreateCache(int size, Handle<JSFunction> factory_function) { 2097 Factory* factory = factory_function->GetIsolate()->factory(); 2098 // Caches are supposed to live for a long time, allocate in old space. 2099 int array_size = JSFunctionResultCache::kEntriesIndex + 2 * size; 2100 // Cannot use cast as object is not fully initialized yet. 2101 JSFunctionResultCache* cache = reinterpret_cast<JSFunctionResultCache*>( 2102 *factory->NewFixedArrayWithHoles(array_size, TENURED)); 2103 cache->set(JSFunctionResultCache::kFactoryIndex, *factory_function); 2104 cache->MakeZeroSize(); 2105 return cache; 2106} 2107 2108 2109void Genesis::InstallJSFunctionResultCaches() { 2110 const int kNumberOfCaches = 0 + 2111#define F(size, func) + 1 2112 JSFUNCTION_RESULT_CACHE_LIST(F) 2113#undef F 2114 ; 2115 2116 Handle<FixedArray> caches = 2117 factory()->NewFixedArray(kNumberOfCaches, TENURED); 2118 2119 int index = 0; 2120 2121#define F(size, func) do { \ 2122 FixedArray* cache = CreateCache((size), Handle<JSFunction>(func)); \ 2123 caches->set(index++, cache); \ 2124 } while (false) 2125 2126 JSFUNCTION_RESULT_CACHE_LIST(F); 2127 2128#undef F 2129 2130 native_context()->set_jsfunction_result_caches(*caches); 2131} 2132 2133 2134void Genesis::InitializeNormalizedMapCaches() { 2135 Handle<FixedArray> array( 2136 factory()->NewFixedArray(NormalizedMapCache::kEntries, TENURED)); 2137 native_context()->set_normalized_map_cache(NormalizedMapCache::cast(*array)); 2138} 2139 2140 2141bool Bootstrapper::InstallExtensions(Handle<Context> native_context, 2142 v8::ExtensionConfiguration* extensions) { 2143 BootstrapperActive active(this); 2144 SaveContext saved_context(isolate_); 2145 isolate_->set_context(*native_context); 2146 if (!Genesis::InstallExtensions(native_context, extensions)) return false; 2147 Genesis::InstallSpecialObjects(native_context); 2148 return true; 2149} 2150 2151 2152void Genesis::InstallSpecialObjects(Handle<Context> native_context) { 2153 Isolate* isolate = native_context->GetIsolate(); 2154 Factory* factory = isolate->factory(); 2155 HandleScope scope(isolate); 2156 Handle<JSGlobalObject> global(JSGlobalObject::cast( 2157 native_context->global_object())); 2158 // Expose the natives in global if a name for it is specified. 2159 if (FLAG_expose_natives_as != NULL && strlen(FLAG_expose_natives_as) != 0) { 2160 Handle<String> natives = 2161 factory->InternalizeUtf8String(FLAG_expose_natives_as); 2162 CHECK_NOT_EMPTY_HANDLE(isolate, 2163 JSObject::SetLocalPropertyIgnoreAttributes( 2164 global, natives, 2165 Handle<JSObject>(global->builtins()), 2166 DONT_ENUM)); 2167 } 2168 2169 Handle<Object> Error = GetProperty(global, "Error"); 2170 if (Error->IsJSObject()) { 2171 Handle<String> name = factory->InternalizeOneByteString( 2172 STATIC_ASCII_VECTOR("stackTraceLimit")); 2173 Handle<Smi> stack_trace_limit( 2174 Smi::FromInt(FLAG_stack_trace_limit), isolate); 2175 CHECK_NOT_EMPTY_HANDLE(isolate, 2176 JSObject::SetLocalPropertyIgnoreAttributes( 2177 Handle<JSObject>::cast(Error), name, 2178 stack_trace_limit, NONE)); 2179 } 2180 2181#ifdef ENABLE_DEBUGGER_SUPPORT 2182 // Expose the debug global object in global if a name for it is specified. 2183 if (FLAG_expose_debug_as != NULL && strlen(FLAG_expose_debug_as) != 0) { 2184 Debug* debug = isolate->debug(); 2185 // If loading fails we just bail out without installing the 2186 // debugger but without tanking the whole context. 2187 if (!debug->Load()) return; 2188 // Set the security token for the debugger context to the same as 2189 // the shell native context to allow calling between these (otherwise 2190 // exposing debug global object doesn't make much sense). 2191 debug->debug_context()->set_security_token( 2192 native_context->security_token()); 2193 2194 Handle<String> debug_string = 2195 factory->InternalizeUtf8String(FLAG_expose_debug_as); 2196 Handle<Object> global_proxy( 2197 debug->debug_context()->global_proxy(), isolate); 2198 CHECK_NOT_EMPTY_HANDLE(isolate, 2199 JSObject::SetLocalPropertyIgnoreAttributes( 2200 global, debug_string, global_proxy, DONT_ENUM)); 2201 } 2202#endif 2203} 2204 2205 2206static uint32_t Hash(RegisteredExtension* extension) { 2207 return v8::internal::ComputePointerHash(extension); 2208} 2209 2210 2211static bool MatchRegisteredExtensions(void* key1, void* key2) { 2212 return key1 == key2; 2213} 2214 2215Genesis::ExtensionStates::ExtensionStates() 2216 : map_(MatchRegisteredExtensions, 8) { } 2217 2218Genesis::ExtensionTraversalState Genesis::ExtensionStates::get_state( 2219 RegisteredExtension* extension) { 2220 i::HashMap::Entry* entry = map_.Lookup(extension, Hash(extension), false); 2221 if (entry == NULL) { 2222 return UNVISITED; 2223 } 2224 return static_cast<ExtensionTraversalState>( 2225 reinterpret_cast<intptr_t>(entry->value)); 2226} 2227 2228void Genesis::ExtensionStates::set_state(RegisteredExtension* extension, 2229 ExtensionTraversalState state) { 2230 map_.Lookup(extension, Hash(extension), true)->value = 2231 reinterpret_cast<void*>(static_cast<intptr_t>(state)); 2232} 2233 2234bool Genesis::InstallExtensions(Handle<Context> native_context, 2235 v8::ExtensionConfiguration* extensions) { 2236 Isolate* isolate = native_context->GetIsolate(); 2237 ExtensionStates extension_states; // All extensions have state UNVISITED. 2238 // Install auto extensions. 2239 v8::RegisteredExtension* current = v8::RegisteredExtension::first_extension(); 2240 while (current != NULL) { 2241 if (current->extension()->auto_enable()) 2242 InstallExtension(isolate, current, &extension_states); 2243 current = current->next(); 2244 } 2245 2246#ifdef ADDRESS_SANITIZER 2247 if (FLAG_expose_free_buffer) { 2248 InstallExtension(isolate, "v8/free-buffer", &extension_states); 2249 } 2250#endif 2251 if (FLAG_expose_gc) InstallExtension(isolate, "v8/gc", &extension_states); 2252 if (FLAG_expose_externalize_string) { 2253 InstallExtension(isolate, "v8/externalize", &extension_states); 2254 } 2255 if (FLAG_track_gc_object_stats) { 2256 InstallExtension(isolate, "v8/statistics", &extension_states); 2257 } 2258 2259 if (extensions == NULL) return true; 2260 // Install required extensions 2261 int count = v8::ImplementationUtilities::GetNameCount(extensions); 2262 const char** names = v8::ImplementationUtilities::GetNames(extensions); 2263 for (int i = 0; i < count; i++) { 2264 if (!InstallExtension(isolate, names[i], &extension_states)) 2265 return false; 2266 } 2267 2268 return true; 2269} 2270 2271 2272// Installs a named extension. This methods is unoptimized and does 2273// not scale well if we want to support a large number of extensions. 2274bool Genesis::InstallExtension(Isolate* isolate, 2275 const char* name, 2276 ExtensionStates* extension_states) { 2277 v8::RegisteredExtension* current = v8::RegisteredExtension::first_extension(); 2278 // Loop until we find the relevant extension 2279 while (current != NULL) { 2280 if (strcmp(name, current->extension()->name()) == 0) break; 2281 current = current->next(); 2282 } 2283 // Didn't find the extension; fail. 2284 if (current == NULL) { 2285 v8::Utils::ReportApiFailure( 2286 "v8::Context::New()", "Cannot find required extension"); 2287 return false; 2288 } 2289 return InstallExtension(isolate, current, extension_states); 2290} 2291 2292 2293bool Genesis::InstallExtension(Isolate* isolate, 2294 v8::RegisteredExtension* current, 2295 ExtensionStates* extension_states) { 2296 HandleScope scope(isolate); 2297 2298 if (extension_states->get_state(current) == INSTALLED) return true; 2299 // The current node has already been visited so there must be a 2300 // cycle in the dependency graph; fail. 2301 if (extension_states->get_state(current) == VISITED) { 2302 v8::Utils::ReportApiFailure( 2303 "v8::Context::New()", "Circular extension dependency"); 2304 return false; 2305 } 2306 ASSERT(extension_states->get_state(current) == UNVISITED); 2307 extension_states->set_state(current, VISITED); 2308 v8::Extension* extension = current->extension(); 2309 // Install the extension's dependencies 2310 for (int i = 0; i < extension->dependency_count(); i++) { 2311 if (!InstallExtension(isolate, 2312 extension->dependencies()[i], 2313 extension_states)) { 2314 return false; 2315 } 2316 } 2317 Handle<String> source_code = 2318 isolate->factory()->NewExternalStringFromAscii(extension->source()); 2319 bool result = CompileScriptCached(isolate, 2320 CStrVector(extension->name()), 2321 source_code, 2322 isolate->bootstrapper()->extensions_cache(), 2323 extension, 2324 Handle<Context>(isolate->context()), 2325 false); 2326 ASSERT(isolate->has_pending_exception() != result); 2327 if (!result) { 2328 // We print out the name of the extension that fail to install. 2329 // When an error is thrown during bootstrapping we automatically print 2330 // the line number at which this happened to the console in the isolate 2331 // error throwing functionality. 2332 OS::PrintError("Error installing extension '%s'.\n", 2333 current->extension()->name()); 2334 isolate->clear_pending_exception(); 2335 } 2336 extension_states->set_state(current, INSTALLED); 2337 isolate->NotifyExtensionInstalled(); 2338 return result; 2339} 2340 2341 2342bool Genesis::InstallJSBuiltins(Handle<JSBuiltinsObject> builtins) { 2343 HandleScope scope(isolate()); 2344 for (int i = 0; i < Builtins::NumberOfJavaScriptBuiltins(); i++) { 2345 Builtins::JavaScript id = static_cast<Builtins::JavaScript>(i); 2346 Handle<String> name = 2347 factory()->InternalizeUtf8String(Builtins::GetName(id)); 2348 Object* function_object = builtins->GetPropertyNoExceptionThrown(*name); 2349 Handle<JSFunction> function 2350 = Handle<JSFunction>(JSFunction::cast(function_object)); 2351 builtins->set_javascript_builtin(id, *function); 2352 if (!JSFunction::CompileLazy(function, CLEAR_EXCEPTION)) { 2353 return false; 2354 } 2355 builtins->set_javascript_builtin_code(id, function->shared()->code()); 2356 } 2357 return true; 2358} 2359 2360 2361bool Genesis::ConfigureGlobalObjects( 2362 v8::Handle<v8::ObjectTemplate> global_proxy_template) { 2363 Handle<JSObject> global_proxy( 2364 JSObject::cast(native_context()->global_proxy())); 2365 Handle<JSObject> inner_global( 2366 JSObject::cast(native_context()->global_object())); 2367 2368 if (!global_proxy_template.IsEmpty()) { 2369 // Configure the global proxy object. 2370 Handle<ObjectTemplateInfo> proxy_data = 2371 v8::Utils::OpenHandle(*global_proxy_template); 2372 if (!ConfigureApiObject(global_proxy, proxy_data)) return false; 2373 2374 // Configure the inner global object. 2375 Handle<FunctionTemplateInfo> proxy_constructor( 2376 FunctionTemplateInfo::cast(proxy_data->constructor())); 2377 if (!proxy_constructor->prototype_template()->IsUndefined()) { 2378 Handle<ObjectTemplateInfo> inner_data( 2379 ObjectTemplateInfo::cast(proxy_constructor->prototype_template())); 2380 if (!ConfigureApiObject(inner_global, inner_data)) return false; 2381 } 2382 } 2383 2384 SetObjectPrototype(global_proxy, inner_global); 2385 2386 native_context()->set_initial_array_prototype( 2387 JSArray::cast(native_context()->array_function()->prototype())); 2388 2389 return true; 2390} 2391 2392 2393bool Genesis::ConfigureApiObject(Handle<JSObject> object, 2394 Handle<ObjectTemplateInfo> object_template) { 2395 ASSERT(!object_template.is_null()); 2396 ASSERT(FunctionTemplateInfo::cast(object_template->constructor()) 2397 ->IsTemplateFor(object->map()));; 2398 2399 bool pending_exception = false; 2400 Handle<JSObject> obj = 2401 Execution::InstantiateObject(object_template, &pending_exception); 2402 if (pending_exception) { 2403 ASSERT(isolate()->has_pending_exception()); 2404 isolate()->clear_pending_exception(); 2405 return false; 2406 } 2407 TransferObject(obj, object); 2408 return true; 2409} 2410 2411 2412void Genesis::TransferNamedProperties(Handle<JSObject> from, 2413 Handle<JSObject> to) { 2414 if (from->HasFastProperties()) { 2415 Handle<DescriptorArray> descs = 2416 Handle<DescriptorArray>(from->map()->instance_descriptors()); 2417 for (int i = 0; i < from->map()->NumberOfOwnDescriptors(); i++) { 2418 PropertyDetails details = descs->GetDetails(i); 2419 switch (details.type()) { 2420 case FIELD: { 2421 HandleScope inner(isolate()); 2422 Handle<Name> key = Handle<Name>(descs->GetKey(i)); 2423 int index = descs->GetFieldIndex(i); 2424 ASSERT(!descs->GetDetails(i).representation().IsDouble()); 2425 Handle<Object> value = Handle<Object>(from->RawFastPropertyAt(index), 2426 isolate()); 2427 CHECK_NOT_EMPTY_HANDLE(isolate(), 2428 JSObject::SetLocalPropertyIgnoreAttributes( 2429 to, key, value, details.attributes())); 2430 break; 2431 } 2432 case CONSTANT: { 2433 HandleScope inner(isolate()); 2434 Handle<Name> key = Handle<Name>(descs->GetKey(i)); 2435 Handle<Object> constant(descs->GetConstant(i), isolate()); 2436 CHECK_NOT_EMPTY_HANDLE(isolate(), 2437 JSObject::SetLocalPropertyIgnoreAttributes( 2438 to, key, constant, details.attributes())); 2439 break; 2440 } 2441 case CALLBACKS: { 2442 LookupResult result(isolate()); 2443 to->LocalLookup(descs->GetKey(i), &result); 2444 // If the property is already there we skip it 2445 if (result.IsFound()) continue; 2446 HandleScope inner(isolate()); 2447 ASSERT(!to->HasFastProperties()); 2448 // Add to dictionary. 2449 Handle<Name> key = Handle<Name>(descs->GetKey(i)); 2450 Handle<Object> callbacks(descs->GetCallbacksObject(i), isolate()); 2451 PropertyDetails d = PropertyDetails( 2452 details.attributes(), CALLBACKS, i + 1); 2453 JSObject::SetNormalizedProperty(to, key, callbacks, d); 2454 break; 2455 } 2456 case NORMAL: 2457 // Do not occur since the from object has fast properties. 2458 case HANDLER: 2459 case INTERCEPTOR: 2460 case TRANSITION: 2461 case NONEXISTENT: 2462 // No element in instance descriptors have proxy or interceptor type. 2463 UNREACHABLE(); 2464 break; 2465 } 2466 } 2467 } else { 2468 Handle<NameDictionary> properties = 2469 Handle<NameDictionary>(from->property_dictionary()); 2470 int capacity = properties->Capacity(); 2471 for (int i = 0; i < capacity; i++) { 2472 Object* raw_key(properties->KeyAt(i)); 2473 if (properties->IsKey(raw_key)) { 2474 ASSERT(raw_key->IsName()); 2475 // If the property is already there we skip it. 2476 LookupResult result(isolate()); 2477 to->LocalLookup(Name::cast(raw_key), &result); 2478 if (result.IsFound()) continue; 2479 // Set the property. 2480 Handle<Name> key = Handle<Name>(Name::cast(raw_key)); 2481 Handle<Object> value = Handle<Object>(properties->ValueAt(i), 2482 isolate()); 2483 ASSERT(!value->IsCell()); 2484 if (value->IsPropertyCell()) { 2485 value = Handle<Object>(PropertyCell::cast(*value)->value(), 2486 isolate()); 2487 } 2488 PropertyDetails details = properties->DetailsAt(i); 2489 CHECK_NOT_EMPTY_HANDLE(isolate(), 2490 JSObject::SetLocalPropertyIgnoreAttributes( 2491 to, key, value, details.attributes())); 2492 } 2493 } 2494 } 2495} 2496 2497 2498void Genesis::TransferIndexedProperties(Handle<JSObject> from, 2499 Handle<JSObject> to) { 2500 // Cloning the elements array is sufficient. 2501 Handle<FixedArray> from_elements = 2502 Handle<FixedArray>(FixedArray::cast(from->elements())); 2503 Handle<FixedArray> to_elements = factory()->CopyFixedArray(from_elements); 2504 to->set_elements(*to_elements); 2505} 2506 2507 2508void Genesis::TransferObject(Handle<JSObject> from, Handle<JSObject> to) { 2509 HandleScope outer(isolate()); 2510 2511 ASSERT(!from->IsJSArray()); 2512 ASSERT(!to->IsJSArray()); 2513 2514 TransferNamedProperties(from, to); 2515 TransferIndexedProperties(from, to); 2516 2517 // Transfer the prototype (new map is needed). 2518 Handle<Map> old_to_map = Handle<Map>(to->map()); 2519 Handle<Map> new_to_map = factory()->CopyMap(old_to_map); 2520 new_to_map->set_prototype(from->map()->prototype()); 2521 to->set_map(*new_to_map); 2522} 2523 2524 2525void Genesis::MakeFunctionInstancePrototypeWritable() { 2526 // The maps with writable prototype are created in CreateEmptyFunction 2527 // and CreateStrictModeFunctionMaps respectively. Initially the maps are 2528 // created with read-only prototype for JS builtins processing. 2529 ASSERT(!function_map_writable_prototype_.is_null()); 2530 ASSERT(!strict_mode_function_map_writable_prototype_.is_null()); 2531 2532 // Replace function instance maps to make prototype writable. 2533 native_context()->set_function_map(*function_map_writable_prototype_); 2534 native_context()->set_strict_mode_function_map( 2535 *strict_mode_function_map_writable_prototype_); 2536} 2537 2538 2539Genesis::Genesis(Isolate* isolate, 2540 Handle<Object> global_object, 2541 v8::Handle<v8::ObjectTemplate> global_template, 2542 v8::ExtensionConfiguration* extensions) 2543 : isolate_(isolate), 2544 active_(isolate->bootstrapper()) { 2545 result_ = Handle<Context>::null(); 2546 // If V8 cannot be initialized, just return. 2547 if (!V8::Initialize(NULL)) return; 2548 2549 // Before creating the roots we must save the context and restore it 2550 // on all function exits. 2551 SaveContext saved_context(isolate); 2552 2553 // During genesis, the boilerplate for stack overflow won't work until the 2554 // environment has been at least partially initialized. Add a stack check 2555 // before entering JS code to catch overflow early. 2556 StackLimitCheck check(isolate); 2557 if (check.HasOverflowed()) return; 2558 2559 // We can only de-serialize a context if the isolate was initialized from 2560 // a snapshot. Otherwise we have to build the context from scratch. 2561 if (isolate->initialized_from_snapshot()) { 2562 native_context_ = Snapshot::NewContextFromSnapshot(isolate); 2563 } else { 2564 native_context_ = Handle<Context>(); 2565 } 2566 2567 if (!native_context().is_null()) { 2568 AddToWeakNativeContextList(*native_context()); 2569 isolate->set_context(*native_context()); 2570 isolate->counters()->contexts_created_by_snapshot()->Increment(); 2571 Handle<GlobalObject> inner_global; 2572 Handle<JSGlobalProxy> global_proxy = 2573 CreateNewGlobals(global_template, 2574 global_object, 2575 &inner_global); 2576 2577 HookUpGlobalProxy(inner_global, global_proxy); 2578 HookUpInnerGlobal(inner_global); 2579 2580 if (!ConfigureGlobalObjects(global_template)) return; 2581 } else { 2582 // We get here if there was no context snapshot. 2583 CreateRoots(); 2584 Handle<JSFunction> empty_function = CreateEmptyFunction(isolate); 2585 CreateStrictModeFunctionMaps(empty_function); 2586 Handle<GlobalObject> inner_global; 2587 Handle<JSGlobalProxy> global_proxy = 2588 CreateNewGlobals(global_template, global_object, &inner_global); 2589 HookUpGlobalProxy(inner_global, global_proxy); 2590 InitializeGlobal(inner_global, empty_function); 2591 InstallJSFunctionResultCaches(); 2592 InitializeNormalizedMapCaches(); 2593 if (!InstallNatives()) return; 2594 2595 MakeFunctionInstancePrototypeWritable(); 2596 2597 if (!ConfigureGlobalObjects(global_template)) return; 2598 isolate->counters()->contexts_created_from_scratch()->Increment(); 2599 } 2600 2601 // Initialize experimental globals and install experimental natives. 2602 InitializeExperimentalGlobal(); 2603 if (!InstallExperimentalNatives()) return; 2604 2605 // We can't (de-)serialize typed arrays currently, but we are lucky: The state 2606 // of the random number generator needs no initialization during snapshot 2607 // creation time and we don't need trigonometric functions then. 2608 if (!Serializer::enabled()) { 2609 // Initially seed the per-context random number generator using the 2610 // per-isolate random number generator. 2611 const int num_elems = 2; 2612 const int num_bytes = num_elems * sizeof(uint32_t); 2613 uint32_t* state = reinterpret_cast<uint32_t*>(malloc(num_bytes)); 2614 2615 do { 2616 isolate->random_number_generator()->NextBytes(state, num_bytes); 2617 } while (state[0] == 0 || state[1] == 0); 2618 2619 v8::Local<v8::ArrayBuffer> buffer = v8::ArrayBuffer::New( 2620 reinterpret_cast<v8::Isolate*>(isolate), state, num_bytes); 2621 Utils::OpenHandle(*buffer)->set_should_be_freed(true); 2622 v8::Local<v8::Uint32Array> ta = v8::Uint32Array::New(buffer, 0, num_elems); 2623 Handle<JSBuiltinsObject> builtins(native_context()->builtins()); 2624 ForceSetProperty(builtins, 2625 factory()->InternalizeOneByteString( 2626 STATIC_ASCII_VECTOR("rngstate")), 2627 Utils::OpenHandle(*ta), 2628 NONE); 2629 2630 // Initialize trigonometric lookup tables and constants. 2631 const int table_num_bytes = TrigonometricLookupTable::table_num_bytes(); 2632 v8::Local<v8::ArrayBuffer> sin_buffer = v8::ArrayBuffer::New( 2633 reinterpret_cast<v8::Isolate*>(isolate), 2634 TrigonometricLookupTable::sin_table(), table_num_bytes); 2635 v8::Local<v8::ArrayBuffer> cos_buffer = v8::ArrayBuffer::New( 2636 reinterpret_cast<v8::Isolate*>(isolate), 2637 TrigonometricLookupTable::cos_x_interval_table(), table_num_bytes); 2638 v8::Local<v8::Float64Array> sin_table = v8::Float64Array::New( 2639 sin_buffer, 0, TrigonometricLookupTable::table_size()); 2640 v8::Local<v8::Float64Array> cos_table = v8::Float64Array::New( 2641 cos_buffer, 0, TrigonometricLookupTable::table_size()); 2642 2643 ForceSetProperty(builtins, 2644 factory()->InternalizeOneByteString( 2645 STATIC_ASCII_VECTOR("kSinTable")), 2646 Utils::OpenHandle(*sin_table), 2647 NONE); 2648 ForceSetProperty(builtins, 2649 factory()->InternalizeOneByteString( 2650 STATIC_ASCII_VECTOR("kCosXIntervalTable")), 2651 Utils::OpenHandle(*cos_table), 2652 NONE); 2653 ForceSetProperty(builtins, 2654 factory()->InternalizeOneByteString( 2655 STATIC_ASCII_VECTOR("kSamples")), 2656 factory()->NewHeapNumber( 2657 TrigonometricLookupTable::samples()), 2658 NONE); 2659 ForceSetProperty(builtins, 2660 factory()->InternalizeOneByteString( 2661 STATIC_ASCII_VECTOR("kIndexConvert")), 2662 factory()->NewHeapNumber( 2663 TrigonometricLookupTable::samples_over_pi_half()), 2664 NONE); 2665 } 2666 2667 result_ = native_context(); 2668} 2669 2670 2671// Support for thread preemption. 2672 2673// Reserve space for statics needing saving and restoring. 2674int Bootstrapper::ArchiveSpacePerThread() { 2675 return sizeof(NestingCounterType); 2676} 2677 2678 2679// Archive statics that are thread local. 2680char* Bootstrapper::ArchiveState(char* to) { 2681 *reinterpret_cast<NestingCounterType*>(to) = nesting_; 2682 nesting_ = 0; 2683 return to + sizeof(NestingCounterType); 2684} 2685 2686 2687// Restore statics that are thread local. 2688char* Bootstrapper::RestoreState(char* from) { 2689 nesting_ = *reinterpret_cast<NestingCounterType*>(from); 2690 return from + sizeof(NestingCounterType); 2691} 2692 2693 2694// Called when the top-level V8 mutex is destroyed. 2695void Bootstrapper::FreeThreadResources() { 2696 ASSERT(!IsActive()); 2697} 2698 2699} } // namespace v8::internal 2700