1 // Copyright 2006-2008 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 "macro-assembler.h" 38 #include "natives.h" 39 #include "objects-visiting.h" 40 #include "snapshot.h" 41 #include "extensions/externalize-string-extension.h" 42 #include "extensions/gc-extension.h" 43 44 namespace v8 { 45 namespace internal { 46 47 48 NativesExternalStringResource::NativesExternalStringResource( 49 Bootstrapper* bootstrapper, 50 const char* source) 51 : data_(source), length_(StrLength(source)) { 52 if (bootstrapper->delete_these_non_arrays_on_tear_down_ == NULL) { 53 bootstrapper->delete_these_non_arrays_on_tear_down_ = new List<char*>(2); 54 } 55 // The resources are small objects and we only make a fixed number of 56 // them, but let's clean them up on exit for neatness. 57 bootstrapper->delete_these_non_arrays_on_tear_down_-> 58 Add(reinterpret_cast<char*>(this)); 59 } 60 61 62 Bootstrapper::Bootstrapper() 63 : nesting_(0), 64 extensions_cache_(Script::TYPE_EXTENSION), 65 delete_these_non_arrays_on_tear_down_(NULL), 66 delete_these_arrays_on_tear_down_(NULL) { 67 } 68 69 70 Handle<String> Bootstrapper::NativesSourceLookup(int index) { 71 ASSERT(0 <= index && index < Natives::GetBuiltinsCount()); 72 Isolate* isolate = Isolate::Current(); 73 Factory* factory = isolate->factory(); 74 Heap* heap = isolate->heap(); 75 if (heap->natives_source_cache()->get(index)->IsUndefined()) { 76 if (!Snapshot::IsEnabled() || FLAG_new_snapshot) { 77 // We can use external strings for the natives. 78 NativesExternalStringResource* resource = 79 new NativesExternalStringResource(this, 80 Natives::GetScriptSource(index).start()); 81 Handle<String> source_code = 82 factory->NewExternalStringFromAscii(resource); 83 heap->natives_source_cache()->set(index, *source_code); 84 } else { 85 // Old snapshot code can't cope with external strings at all. 86 Handle<String> source_code = 87 factory->NewStringFromAscii(Natives::GetScriptSource(index)); 88 heap->natives_source_cache()->set(index, *source_code); 89 } 90 } 91 Handle<Object> cached_source(heap->natives_source_cache()->get(index)); 92 return Handle<String>::cast(cached_source); 93 } 94 95 96 void Bootstrapper::Initialize(bool create_heap_objects) { 97 extensions_cache_.Initialize(create_heap_objects); 98 GCExtension::Register(); 99 ExternalizeStringExtension::Register(); 100 } 101 102 103 char* Bootstrapper::AllocateAutoDeletedArray(int bytes) { 104 char* memory = new char[bytes]; 105 if (memory != NULL) { 106 if (delete_these_arrays_on_tear_down_ == NULL) { 107 delete_these_arrays_on_tear_down_ = new List<char*>(2); 108 } 109 delete_these_arrays_on_tear_down_->Add(memory); 110 } 111 return memory; 112 } 113 114 115 void Bootstrapper::TearDown() { 116 if (delete_these_non_arrays_on_tear_down_ != NULL) { 117 int len = delete_these_non_arrays_on_tear_down_->length(); 118 ASSERT(len < 20); // Don't use this mechanism for unbounded allocations. 119 for (int i = 0; i < len; i++) { 120 delete delete_these_non_arrays_on_tear_down_->at(i); 121 delete_these_non_arrays_on_tear_down_->at(i) = NULL; 122 } 123 delete delete_these_non_arrays_on_tear_down_; 124 delete_these_non_arrays_on_tear_down_ = NULL; 125 } 126 127 if (delete_these_arrays_on_tear_down_ != NULL) { 128 int len = delete_these_arrays_on_tear_down_->length(); 129 ASSERT(len < 1000); // Don't use this mechanism for unbounded allocations. 130 for (int i = 0; i < len; i++) { 131 delete[] delete_these_arrays_on_tear_down_->at(i); 132 delete_these_arrays_on_tear_down_->at(i) = NULL; 133 } 134 delete delete_these_arrays_on_tear_down_; 135 delete_these_arrays_on_tear_down_ = NULL; 136 } 137 138 extensions_cache_.Initialize(false); // Yes, symmetrical 139 } 140 141 142 class Genesis BASE_EMBEDDED { 143 public: 144 Genesis(Handle<Object> global_object, 145 v8::Handle<v8::ObjectTemplate> global_template, 146 v8::ExtensionConfiguration* extensions); 147 ~Genesis() { } 148 149 Handle<Context> result() { return result_; } 150 151 Genesis* previous() { return previous_; } 152 153 private: 154 Handle<Context> global_context_; 155 156 // There may be more than one active genesis object: When GC is 157 // triggered during environment creation there may be weak handle 158 // processing callbacks which may create new environments. 159 Genesis* previous_; 160 161 Handle<Context> global_context() { return global_context_; } 162 163 // Creates some basic objects. Used for creating a context from scratch. 164 void CreateRoots(); 165 // Creates the empty function. Used for creating a context from scratch. 166 Handle<JSFunction> CreateEmptyFunction(); 167 // Creates the ThrowTypeError function. ECMA 5th Ed. 13.2.3 168 Handle<JSFunction> CreateThrowTypeErrorFunction(Builtins::Name builtin); 169 170 void CreateStrictModeFunctionMaps(Handle<JSFunction> empty); 171 // Creates the global objects using the global and the template passed in 172 // through the API. We call this regardless of whether we are building a 173 // context from scratch or using a deserialized one from the partial snapshot 174 // but in the latter case we don't use the objects it produces directly, as 175 // we have to used the deserialized ones that are linked together with the 176 // rest of the context snapshot. 177 Handle<JSGlobalProxy> CreateNewGlobals( 178 v8::Handle<v8::ObjectTemplate> global_template, 179 Handle<Object> global_object, 180 Handle<GlobalObject>* global_proxy_out); 181 // Hooks the given global proxy into the context. If the context was created 182 // by deserialization then this will unhook the global proxy that was 183 // deserialized, leaving the GC to pick it up. 184 void HookUpGlobalProxy(Handle<GlobalObject> inner_global, 185 Handle<JSGlobalProxy> global_proxy); 186 // Similarly, we want to use the inner global that has been created by the 187 // templates passed through the API. The inner global from the snapshot is 188 // detached from the other objects in the snapshot. 189 void HookUpInnerGlobal(Handle<GlobalObject> inner_global); 190 // New context initialization. Used for creating a context from scratch. 191 void InitializeGlobal(Handle<GlobalObject> inner_global, 192 Handle<JSFunction> empty_function); 193 // Installs the contents of the native .js files on the global objects. 194 // Used for creating a context from scratch. 195 void InstallNativeFunctions(); 196 bool InstallNatives(); 197 void InstallBuiltinFunctionIds(); 198 void InstallJSFunctionResultCaches(); 199 void InitializeNormalizedMapCaches(); 200 // Used both for deserialized and from-scratch contexts to add the extensions 201 // provided. 202 static bool InstallExtensions(Handle<Context> global_context, 203 v8::ExtensionConfiguration* extensions); 204 static bool InstallExtension(const char* name); 205 static bool InstallExtension(v8::RegisteredExtension* current); 206 static void InstallSpecialObjects(Handle<Context> global_context); 207 bool InstallJSBuiltins(Handle<JSBuiltinsObject> builtins); 208 bool ConfigureApiObject(Handle<JSObject> object, 209 Handle<ObjectTemplateInfo> object_template); 210 bool ConfigureGlobalObjects(v8::Handle<v8::ObjectTemplate> global_template); 211 212 // Migrates all properties from the 'from' object to the 'to' 213 // object and overrides the prototype in 'to' with the one from 214 // 'from'. 215 void TransferObject(Handle<JSObject> from, Handle<JSObject> to); 216 void TransferNamedProperties(Handle<JSObject> from, Handle<JSObject> to); 217 void TransferIndexedProperties(Handle<JSObject> from, Handle<JSObject> to); 218 219 enum PrototypePropertyMode { 220 DONT_ADD_PROTOTYPE, 221 ADD_READONLY_PROTOTYPE, 222 ADD_WRITEABLE_PROTOTYPE 223 }; 224 225 Handle<Map> CreateFunctionMap(PrototypePropertyMode prototype_mode); 226 227 Handle<DescriptorArray> ComputeFunctionInstanceDescriptor( 228 PrototypePropertyMode prototypeMode); 229 void MakeFunctionInstancePrototypeWritable(); 230 231 Handle<Map> CreateStrictModeFunctionMap( 232 PrototypePropertyMode prototype_mode, 233 Handle<JSFunction> empty_function, 234 Handle<FixedArray> arguments_callbacks, 235 Handle<FixedArray> caller_callbacks); 236 237 Handle<DescriptorArray> ComputeStrictFunctionInstanceDescriptor( 238 PrototypePropertyMode propertyMode, 239 Handle<FixedArray> arguments, 240 Handle<FixedArray> caller); 241 242 static bool CompileBuiltin(int index); 243 static bool CompileNative(Vector<const char> name, Handle<String> source); 244 static bool CompileScriptCached(Vector<const char> name, 245 Handle<String> source, 246 SourceCodeCache* cache, 247 v8::Extension* extension, 248 Handle<Context> top_context, 249 bool use_runtime_context); 250 251 Handle<Context> result_; 252 253 // Function instance maps. Function literal maps are created initially with 254 // a read only prototype for the processing of JS builtins. Later the function 255 // instance maps are replaced in order to make prototype writable. 256 // These are the final, writable prototype, maps. 257 Handle<Map> function_instance_map_writable_prototype_; 258 Handle<Map> strict_mode_function_instance_map_writable_prototype_; 259 260 BootstrapperActive active_; 261 friend class Bootstrapper; 262 }; 263 264 265 void Bootstrapper::Iterate(ObjectVisitor* v) { 266 extensions_cache_.Iterate(v); 267 v->Synchronize("Extensions"); 268 } 269 270 271 Handle<Context> Bootstrapper::CreateEnvironment( 272 Handle<Object> global_object, 273 v8::Handle<v8::ObjectTemplate> global_template, 274 v8::ExtensionConfiguration* extensions) { 275 HandleScope scope; 276 Handle<Context> env; 277 Genesis genesis(global_object, global_template, extensions); 278 env = genesis.result(); 279 if (!env.is_null()) { 280 if (InstallExtensions(env, extensions)) { 281 return env; 282 } 283 } 284 return Handle<Context>(); 285 } 286 287 288 static void SetObjectPrototype(Handle<JSObject> object, Handle<Object> proto) { 289 // object.__proto__ = proto; 290 Handle<Map> old_to_map = Handle<Map>(object->map()); 291 Handle<Map> new_to_map = FACTORY->CopyMapDropTransitions(old_to_map); 292 new_to_map->set_prototype(*proto); 293 object->set_map(*new_to_map); 294 } 295 296 297 void Bootstrapper::DetachGlobal(Handle<Context> env) { 298 Factory* factory = Isolate::Current()->factory(); 299 JSGlobalProxy::cast(env->global_proxy())->set_context(*factory->null_value()); 300 SetObjectPrototype(Handle<JSObject>(env->global_proxy()), 301 factory->null_value()); 302 env->set_global_proxy(env->global()); 303 env->global()->set_global_receiver(env->global()); 304 } 305 306 307 void Bootstrapper::ReattachGlobal(Handle<Context> env, 308 Handle<Object> global_object) { 309 ASSERT(global_object->IsJSGlobalProxy()); 310 Handle<JSGlobalProxy> global = Handle<JSGlobalProxy>::cast(global_object); 311 env->global()->set_global_receiver(*global); 312 env->set_global_proxy(*global); 313 SetObjectPrototype(global, Handle<JSObject>(env->global())); 314 global->set_context(*env); 315 } 316 317 318 static Handle<JSFunction> InstallFunction(Handle<JSObject> target, 319 const char* name, 320 InstanceType type, 321 int instance_size, 322 Handle<JSObject> prototype, 323 Builtins::Name call, 324 bool is_ecma_native) { 325 Isolate* isolate = Isolate::Current(); 326 Factory* factory = isolate->factory(); 327 Handle<String> symbol = factory->LookupAsciiSymbol(name); 328 Handle<Code> call_code = Handle<Code>(isolate->builtins()->builtin(call)); 329 Handle<JSFunction> function = prototype.is_null() ? 330 factory->NewFunctionWithoutPrototype(symbol, call_code) : 331 factory->NewFunctionWithPrototype(symbol, 332 type, 333 instance_size, 334 prototype, 335 call_code, 336 is_ecma_native); 337 SetLocalPropertyNoThrow(target, symbol, function, DONT_ENUM); 338 if (is_ecma_native) { 339 function->shared()->set_instance_class_name(*symbol); 340 } 341 return function; 342 } 343 344 345 Handle<DescriptorArray> Genesis::ComputeFunctionInstanceDescriptor( 346 PrototypePropertyMode prototypeMode) { 347 Factory* factory = Isolate::Current()->factory(); 348 Handle<DescriptorArray> descriptors = 349 factory->NewDescriptorArray(prototypeMode == DONT_ADD_PROTOTYPE ? 4 : 5); 350 PropertyAttributes attributes = 351 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY); 352 353 { // Add length. 354 Handle<Proxy> proxy = factory->NewProxy(&Accessors::FunctionLength); 355 CallbacksDescriptor d(*factory->length_symbol(), *proxy, attributes); 356 descriptors->Set(0, &d); 357 } 358 { // Add name. 359 Handle<Proxy> proxy = factory->NewProxy(&Accessors::FunctionName); 360 CallbacksDescriptor d(*factory->name_symbol(), *proxy, attributes); 361 descriptors->Set(1, &d); 362 } 363 { // Add arguments. 364 Handle<Proxy> proxy = factory->NewProxy(&Accessors::FunctionArguments); 365 CallbacksDescriptor d(*factory->arguments_symbol(), *proxy, attributes); 366 descriptors->Set(2, &d); 367 } 368 { // Add caller. 369 Handle<Proxy> proxy = factory->NewProxy(&Accessors::FunctionCaller); 370 CallbacksDescriptor d(*factory->caller_symbol(), *proxy, attributes); 371 descriptors->Set(3, &d); 372 } 373 if (prototypeMode != DONT_ADD_PROTOTYPE) { 374 // Add prototype. 375 if (prototypeMode == ADD_WRITEABLE_PROTOTYPE) { 376 attributes = static_cast<PropertyAttributes>(attributes & ~READ_ONLY); 377 } 378 Handle<Proxy> proxy = factory->NewProxy(&Accessors::FunctionPrototype); 379 CallbacksDescriptor d(*factory->prototype_symbol(), *proxy, attributes); 380 descriptors->Set(4, &d); 381 } 382 descriptors->Sort(); 383 return descriptors; 384 } 385 386 387 Handle<Map> Genesis::CreateFunctionMap(PrototypePropertyMode prototype_mode) { 388 Handle<Map> map = FACTORY->NewMap(JS_FUNCTION_TYPE, JSFunction::kSize); 389 Handle<DescriptorArray> descriptors = 390 ComputeFunctionInstanceDescriptor(prototype_mode); 391 map->set_instance_descriptors(*descriptors); 392 map->set_function_with_prototype(prototype_mode != DONT_ADD_PROTOTYPE); 393 return map; 394 } 395 396 397 Handle<JSFunction> Genesis::CreateEmptyFunction() { 398 // Allocate the map for function instances. Maps are allocated first and their 399 // prototypes patched later, once empty function is created. 400 401 // Please note that the prototype property for function instances must be 402 // writable. 403 Handle<Map> function_instance_map = 404 CreateFunctionMap(ADD_WRITEABLE_PROTOTYPE); 405 global_context()->set_function_instance_map(*function_instance_map); 406 407 // Functions with this map will not have a 'prototype' property, and 408 // can not be used as constructors. 409 Handle<Map> function_without_prototype_map = 410 CreateFunctionMap(DONT_ADD_PROTOTYPE); 411 global_context()->set_function_without_prototype_map( 412 *function_without_prototype_map); 413 414 // Allocate the function map. This map is temporary, used only for processing 415 // of builtins. 416 // Later the map is replaced with writable prototype map, allocated below. 417 Handle<Map> function_map = CreateFunctionMap(ADD_READONLY_PROTOTYPE); 418 global_context()->set_function_map(*function_map); 419 420 // The final map for functions. Writeable prototype. 421 // This map is installed in MakeFunctionInstancePrototypeWritable. 422 function_instance_map_writable_prototype_ = 423 CreateFunctionMap(ADD_WRITEABLE_PROTOTYPE); 424 425 Isolate* isolate = Isolate::Current(); 426 Factory* factory = isolate->factory(); 427 Heap* heap = isolate->heap(); 428 429 Handle<String> object_name = Handle<String>(heap->Object_symbol()); 430 431 { // --- O b j e c t --- 432 Handle<JSFunction> object_fun = 433 factory->NewFunction(object_name, factory->null_value()); 434 Handle<Map> object_function_map = 435 factory->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize); 436 object_fun->set_initial_map(*object_function_map); 437 object_function_map->set_constructor(*object_fun); 438 439 global_context()->set_object_function(*object_fun); 440 441 // Allocate a new prototype for the object function. 442 Handle<JSObject> prototype = factory->NewJSObject( 443 isolate->object_function(), 444 TENURED); 445 446 global_context()->set_initial_object_prototype(*prototype); 447 SetPrototype(object_fun, prototype); 448 object_function_map-> 449 set_instance_descriptors(heap->empty_descriptor_array()); 450 } 451 452 // Allocate the empty function as the prototype for function ECMAScript 453 // 262 15.3.4. 454 Handle<String> symbol = factory->LookupAsciiSymbol("Empty"); 455 Handle<JSFunction> empty_function = 456 factory->NewFunctionWithoutPrototype(symbol, kNonStrictMode); 457 458 // --- E m p t y --- 459 Handle<Code> code = 460 Handle<Code>(isolate->builtins()->builtin( 461 Builtins::kEmptyFunction)); 462 empty_function->set_code(*code); 463 empty_function->shared()->set_code(*code); 464 Handle<String> source = factory->NewStringFromAscii(CStrVector("() {}")); 465 Handle<Script> script = factory->NewScript(source); 466 script->set_type(Smi::FromInt(Script::TYPE_NATIVE)); 467 empty_function->shared()->set_script(*script); 468 empty_function->shared()->set_start_position(0); 469 empty_function->shared()->set_end_position(source->length()); 470 empty_function->shared()->DontAdaptArguments(); 471 472 // Set prototypes for the function maps. 473 global_context()->function_map()->set_prototype(*empty_function); 474 global_context()->function_instance_map()->set_prototype(*empty_function); 475 global_context()->function_without_prototype_map()-> 476 set_prototype(*empty_function); 477 function_instance_map_writable_prototype_->set_prototype(*empty_function); 478 479 // Allocate the function map first and then patch the prototype later 480 Handle<Map> empty_fm = factory->CopyMapDropDescriptors( 481 function_without_prototype_map); 482 empty_fm->set_instance_descriptors( 483 function_without_prototype_map->instance_descriptors()); 484 empty_fm->set_prototype(global_context()->object_function()->prototype()); 485 empty_function->set_map(*empty_fm); 486 return empty_function; 487 } 488 489 490 Handle<DescriptorArray> Genesis::ComputeStrictFunctionInstanceDescriptor( 491 PrototypePropertyMode prototypeMode, 492 Handle<FixedArray> arguments, 493 Handle<FixedArray> caller) { 494 Factory* factory = Isolate::Current()->factory(); 495 Handle<DescriptorArray> descriptors = 496 factory->NewDescriptorArray(prototypeMode == DONT_ADD_PROTOTYPE ? 4 : 5); 497 PropertyAttributes attributes = static_cast<PropertyAttributes>( 498 DONT_ENUM | DONT_DELETE | READ_ONLY); 499 500 { // length 501 Handle<Proxy> proxy = factory->NewProxy(&Accessors::FunctionLength); 502 CallbacksDescriptor d(*factory->length_symbol(), *proxy, attributes); 503 descriptors->Set(0, &d); 504 } 505 { // name 506 Handle<Proxy> proxy = factory->NewProxy(&Accessors::FunctionName); 507 CallbacksDescriptor d(*factory->name_symbol(), *proxy, attributes); 508 descriptors->Set(1, &d); 509 } 510 { // arguments 511 CallbacksDescriptor d(*factory->arguments_symbol(), *arguments, attributes); 512 descriptors->Set(2, &d); 513 } 514 { // caller 515 CallbacksDescriptor d(*factory->caller_symbol(), *caller, attributes); 516 descriptors->Set(3, &d); 517 } 518 519 // prototype 520 if (prototypeMode != DONT_ADD_PROTOTYPE) { 521 if (prototypeMode == ADD_WRITEABLE_PROTOTYPE) { 522 attributes = static_cast<PropertyAttributes>(attributes & ~READ_ONLY); 523 } 524 Handle<Proxy> proxy = factory->NewProxy(&Accessors::FunctionPrototype); 525 CallbacksDescriptor d(*factory->prototype_symbol(), *proxy, attributes); 526 descriptors->Set(4, &d); 527 } 528 529 descriptors->Sort(); 530 return descriptors; 531 } 532 533 534 // ECMAScript 5th Edition, 13.2.3 535 Handle<JSFunction> Genesis::CreateThrowTypeErrorFunction( 536 Builtins::Name builtin) { 537 Isolate* isolate = Isolate::Current(); 538 Factory* factory = isolate->factory(); 539 540 Handle<String> name = factory->LookupAsciiSymbol("ThrowTypeError"); 541 Handle<JSFunction> throw_type_error = 542 factory->NewFunctionWithoutPrototype(name, kStrictMode); 543 Handle<Code> code = Handle<Code>( 544 isolate->builtins()->builtin(builtin)); 545 546 throw_type_error->set_map(global_context()->strict_mode_function_map()); 547 throw_type_error->set_code(*code); 548 throw_type_error->shared()->set_code(*code); 549 throw_type_error->shared()->DontAdaptArguments(); 550 551 PreventExtensions(throw_type_error); 552 553 return throw_type_error; 554 } 555 556 557 Handle<Map> Genesis::CreateStrictModeFunctionMap( 558 PrototypePropertyMode prototype_mode, 559 Handle<JSFunction> empty_function, 560 Handle<FixedArray> arguments_callbacks, 561 Handle<FixedArray> caller_callbacks) { 562 Handle<Map> map = FACTORY->NewMap(JS_FUNCTION_TYPE, JSFunction::kSize); 563 Handle<DescriptorArray> descriptors = 564 ComputeStrictFunctionInstanceDescriptor(prototype_mode, 565 arguments_callbacks, 566 caller_callbacks); 567 map->set_instance_descriptors(*descriptors); 568 map->set_function_with_prototype(prototype_mode != DONT_ADD_PROTOTYPE); 569 map->set_prototype(*empty_function); 570 return map; 571 } 572 573 574 void Genesis::CreateStrictModeFunctionMaps(Handle<JSFunction> empty) { 575 // Create the callbacks arrays for ThrowTypeError functions. 576 // The get/set callacks are filled in after the maps are created below. 577 Factory* factory = Isolate::Current()->factory(); 578 Handle<FixedArray> arguments = factory->NewFixedArray(2, TENURED); 579 Handle<FixedArray> caller = factory->NewFixedArray(2, TENURED); 580 581 // Allocate map for the strict mode function instances. 582 Handle<Map> strict_mode_function_instance_map = 583 CreateStrictModeFunctionMap( 584 ADD_WRITEABLE_PROTOTYPE, empty, arguments, caller); 585 global_context()->set_strict_mode_function_instance_map( 586 *strict_mode_function_instance_map); 587 588 // Allocate map for the prototype-less strict mode instances. 589 Handle<Map> strict_mode_function_without_prototype_map = 590 CreateStrictModeFunctionMap( 591 DONT_ADD_PROTOTYPE, empty, arguments, caller); 592 global_context()->set_strict_mode_function_without_prototype_map( 593 *strict_mode_function_without_prototype_map); 594 595 // Allocate map for the strict mode functions. This map is temporary, used 596 // only for processing of builtins. 597 // Later the map is replaced with writable prototype map, allocated below. 598 Handle<Map> strict_mode_function_map = 599 CreateStrictModeFunctionMap( 600 ADD_READONLY_PROTOTYPE, empty, arguments, caller); 601 global_context()->set_strict_mode_function_map( 602 *strict_mode_function_map); 603 604 // The final map for the strict mode functions. Writeable prototype. 605 // This map is installed in MakeFunctionInstancePrototypeWritable. 606 strict_mode_function_instance_map_writable_prototype_ = 607 CreateStrictModeFunctionMap( 608 ADD_WRITEABLE_PROTOTYPE, empty, arguments, caller); 609 610 // Create the ThrowTypeError function instances. 611 Handle<JSFunction> arguments_throw = 612 CreateThrowTypeErrorFunction(Builtins::kStrictFunctionArguments); 613 Handle<JSFunction> caller_throw = 614 CreateThrowTypeErrorFunction(Builtins::kStrictFunctionCaller); 615 616 // Complete the callback fixed arrays. 617 arguments->set(0, *arguments_throw); 618 arguments->set(1, *arguments_throw); 619 caller->set(0, *caller_throw); 620 caller->set(1, *caller_throw); 621 } 622 623 624 static void AddToWeakGlobalContextList(Context* context) { 625 ASSERT(context->IsGlobalContext()); 626 Heap* heap = Isolate::Current()->heap(); 627 #ifdef DEBUG 628 { // NOLINT 629 ASSERT(context->get(Context::NEXT_CONTEXT_LINK)->IsUndefined()); 630 // Check that context is not in the list yet. 631 for (Object* current = heap->global_contexts_list(); 632 !current->IsUndefined(); 633 current = Context::cast(current)->get(Context::NEXT_CONTEXT_LINK)) { 634 ASSERT(current != context); 635 } 636 } 637 #endif 638 context->set(Context::NEXT_CONTEXT_LINK, heap->global_contexts_list()); 639 heap->set_global_contexts_list(context); 640 } 641 642 643 void Genesis::CreateRoots() { 644 Isolate* isolate = Isolate::Current(); 645 // Allocate the global context FixedArray first and then patch the 646 // closure and extension object later (we need the empty function 647 // and the global object, but in order to create those, we need the 648 // global context). 649 global_context_ = Handle<Context>::cast(isolate->global_handles()->Create( 650 *isolate->factory()->NewGlobalContext())); 651 AddToWeakGlobalContextList(*global_context_); 652 isolate->set_context(*global_context()); 653 654 // Allocate the message listeners object. 655 { 656 v8::NeanderArray listeners; 657 global_context()->set_message_listeners(*listeners.value()); 658 } 659 } 660 661 662 Handle<JSGlobalProxy> Genesis::CreateNewGlobals( 663 v8::Handle<v8::ObjectTemplate> global_template, 664 Handle<Object> global_object, 665 Handle<GlobalObject>* inner_global_out) { 666 // The argument global_template aka data is an ObjectTemplateInfo. 667 // It has a constructor pointer that points at global_constructor which is a 668 // FunctionTemplateInfo. 669 // The global_constructor is used to create or reinitialize the global_proxy. 670 // The global_constructor also has a prototype_template pointer that points at 671 // js_global_template which is an ObjectTemplateInfo. 672 // That in turn has a constructor pointer that points at 673 // js_global_constructor which is a FunctionTemplateInfo. 674 // js_global_constructor is used to make js_global_function 675 // js_global_function is used to make the new inner_global. 676 // 677 // --- G l o b a l --- 678 // Step 1: Create a fresh inner JSGlobalObject. 679 Handle<JSFunction> js_global_function; 680 Handle<ObjectTemplateInfo> js_global_template; 681 if (!global_template.IsEmpty()) { 682 // Get prototype template of the global_template. 683 Handle<ObjectTemplateInfo> data = 684 v8::Utils::OpenHandle(*global_template); 685 Handle<FunctionTemplateInfo> global_constructor = 686 Handle<FunctionTemplateInfo>( 687 FunctionTemplateInfo::cast(data->constructor())); 688 Handle<Object> proto_template(global_constructor->prototype_template()); 689 if (!proto_template->IsUndefined()) { 690 js_global_template = 691 Handle<ObjectTemplateInfo>::cast(proto_template); 692 } 693 } 694 695 Isolate* isolate = Isolate::Current(); 696 Factory* factory = isolate->factory(); 697 Heap* heap = isolate->heap(); 698 699 if (js_global_template.is_null()) { 700 Handle<String> name = Handle<String>(heap->empty_symbol()); 701 Handle<Code> code = Handle<Code>(isolate->builtins()->builtin( 702 Builtins::kIllegal)); 703 js_global_function = 704 factory->NewFunction(name, JS_GLOBAL_OBJECT_TYPE, 705 JSGlobalObject::kSize, code, true); 706 // Change the constructor property of the prototype of the 707 // hidden global function to refer to the Object function. 708 Handle<JSObject> prototype = 709 Handle<JSObject>( 710 JSObject::cast(js_global_function->instance_prototype())); 711 SetLocalPropertyNoThrow( 712 prototype, 713 factory->constructor_symbol(), 714 isolate->object_function(), 715 NONE); 716 } else { 717 Handle<FunctionTemplateInfo> js_global_constructor( 718 FunctionTemplateInfo::cast(js_global_template->constructor())); 719 js_global_function = 720 factory->CreateApiFunction(js_global_constructor, 721 factory->InnerGlobalObject); 722 } 723 724 js_global_function->initial_map()->set_is_hidden_prototype(); 725 Handle<GlobalObject> inner_global = 726 factory->NewGlobalObject(js_global_function); 727 if (inner_global_out != NULL) { 728 *inner_global_out = inner_global; 729 } 730 731 // Step 2: create or re-initialize the global proxy object. 732 Handle<JSFunction> global_proxy_function; 733 if (global_template.IsEmpty()) { 734 Handle<String> name = Handle<String>(heap->empty_symbol()); 735 Handle<Code> code = Handle<Code>(isolate->builtins()->builtin( 736 Builtins::kIllegal)); 737 global_proxy_function = 738 factory->NewFunction(name, JS_GLOBAL_PROXY_TYPE, 739 JSGlobalProxy::kSize, code, true); 740 } else { 741 Handle<ObjectTemplateInfo> data = 742 v8::Utils::OpenHandle(*global_template); 743 Handle<FunctionTemplateInfo> global_constructor( 744 FunctionTemplateInfo::cast(data->constructor())); 745 global_proxy_function = 746 factory->CreateApiFunction(global_constructor, 747 factory->OuterGlobalObject); 748 } 749 750 Handle<String> global_name = factory->LookupAsciiSymbol("global"); 751 global_proxy_function->shared()->set_instance_class_name(*global_name); 752 global_proxy_function->initial_map()->set_is_access_check_needed(true); 753 754 // Set global_proxy.__proto__ to js_global after ConfigureGlobalObjects 755 // Return the global proxy. 756 757 if (global_object.location() != NULL) { 758 ASSERT(global_object->IsJSGlobalProxy()); 759 return ReinitializeJSGlobalProxy( 760 global_proxy_function, 761 Handle<JSGlobalProxy>::cast(global_object)); 762 } else { 763 return Handle<JSGlobalProxy>::cast( 764 factory->NewJSObject(global_proxy_function, TENURED)); 765 } 766 } 767 768 769 void Genesis::HookUpGlobalProxy(Handle<GlobalObject> inner_global, 770 Handle<JSGlobalProxy> global_proxy) { 771 // Set the global context for the global object. 772 inner_global->set_global_context(*global_context()); 773 inner_global->set_global_receiver(*global_proxy); 774 global_proxy->set_context(*global_context()); 775 global_context()->set_global_proxy(*global_proxy); 776 } 777 778 779 void Genesis::HookUpInnerGlobal(Handle<GlobalObject> inner_global) { 780 Handle<GlobalObject> inner_global_from_snapshot( 781 GlobalObject::cast(global_context_->extension())); 782 Handle<JSBuiltinsObject> builtins_global(global_context_->builtins()); 783 global_context_->set_extension(*inner_global); 784 global_context_->set_global(*inner_global); 785 global_context_->set_security_token(*inner_global); 786 static const PropertyAttributes attributes = 787 static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE); 788 ForceSetProperty(builtins_global, 789 FACTORY->LookupAsciiSymbol("global"), 790 inner_global, 791 attributes); 792 // Setup the reference from the global object to the builtins object. 793 JSGlobalObject::cast(*inner_global)->set_builtins(*builtins_global); 794 TransferNamedProperties(inner_global_from_snapshot, inner_global); 795 TransferIndexedProperties(inner_global_from_snapshot, inner_global); 796 } 797 798 799 // This is only called if we are not using snapshots. The equivalent 800 // work in the snapshot case is done in HookUpInnerGlobal. 801 void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global, 802 Handle<JSFunction> empty_function) { 803 // --- G l o b a l C o n t e x t --- 804 // Use the empty function as closure (no scope info). 805 global_context()->set_closure(*empty_function); 806 global_context()->set_fcontext(*global_context()); 807 global_context()->set_previous(NULL); 808 // Set extension and global object. 809 global_context()->set_extension(*inner_global); 810 global_context()->set_global(*inner_global); 811 // Security setup: Set the security token of the global object to 812 // its the inner global. This makes the security check between two 813 // different contexts fail by default even in case of global 814 // object reinitialization. 815 global_context()->set_security_token(*inner_global); 816 817 Isolate* isolate = Isolate::Current(); 818 Factory* factory = isolate->factory(); 819 Heap* heap = isolate->heap(); 820 821 Handle<String> object_name = Handle<String>(heap->Object_symbol()); 822 SetLocalPropertyNoThrow(inner_global, object_name, 823 isolate->object_function(), DONT_ENUM); 824 825 Handle<JSObject> global = Handle<JSObject>(global_context()->global()); 826 827 // Install global Function object 828 InstallFunction(global, "Function", JS_FUNCTION_TYPE, JSFunction::kSize, 829 empty_function, Builtins::kIllegal, true); // ECMA native. 830 831 { // --- A r r a y --- 832 Handle<JSFunction> array_function = 833 InstallFunction(global, "Array", JS_ARRAY_TYPE, JSArray::kSize, 834 isolate->initial_object_prototype(), 835 Builtins::kArrayCode, true); 836 array_function->shared()->set_construct_stub( 837 isolate->builtins()->builtin(Builtins::kArrayConstructCode)); 838 array_function->shared()->DontAdaptArguments(); 839 840 // This seems a bit hackish, but we need to make sure Array.length 841 // is 1. 842 array_function->shared()->set_length(1); 843 Handle<DescriptorArray> array_descriptors = 844 factory->CopyAppendProxyDescriptor( 845 factory->empty_descriptor_array(), 846 factory->length_symbol(), 847 factory->NewProxy(&Accessors::ArrayLength), 848 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE)); 849 850 // Cache the fast JavaScript array map 851 global_context()->set_js_array_map(array_function->initial_map()); 852 global_context()->js_array_map()->set_instance_descriptors( 853 *array_descriptors); 854 // array_function is used internally. JS code creating array object should 855 // search for the 'Array' property on the global object and use that one 856 // as the constructor. 'Array' property on a global object can be 857 // overwritten by JS code. 858 global_context()->set_array_function(*array_function); 859 } 860 861 { // --- N u m b e r --- 862 Handle<JSFunction> number_fun = 863 InstallFunction(global, "Number", JS_VALUE_TYPE, JSValue::kSize, 864 isolate->initial_object_prototype(), 865 Builtins::kIllegal, true); 866 global_context()->set_number_function(*number_fun); 867 } 868 869 { // --- B o o l e a n --- 870 Handle<JSFunction> boolean_fun = 871 InstallFunction(global, "Boolean", JS_VALUE_TYPE, JSValue::kSize, 872 isolate->initial_object_prototype(), 873 Builtins::kIllegal, true); 874 global_context()->set_boolean_function(*boolean_fun); 875 } 876 877 { // --- S t r i n g --- 878 Handle<JSFunction> string_fun = 879 InstallFunction(global, "String", JS_VALUE_TYPE, JSValue::kSize, 880 isolate->initial_object_prototype(), 881 Builtins::kIllegal, true); 882 string_fun->shared()->set_construct_stub( 883 isolate->builtins()->builtin(Builtins::kStringConstructCode)); 884 global_context()->set_string_function(*string_fun); 885 // Add 'length' property to strings. 886 Handle<DescriptorArray> string_descriptors = 887 factory->CopyAppendProxyDescriptor( 888 factory->empty_descriptor_array(), 889 factory->length_symbol(), 890 factory->NewProxy(&Accessors::StringLength), 891 static_cast<PropertyAttributes>(DONT_ENUM | 892 DONT_DELETE | 893 READ_ONLY)); 894 895 Handle<Map> string_map = 896 Handle<Map>(global_context()->string_function()->initial_map()); 897 string_map->set_instance_descriptors(*string_descriptors); 898 } 899 900 { // --- D a t e --- 901 // Builtin functions for Date.prototype. 902 Handle<JSFunction> date_fun = 903 InstallFunction(global, "Date", JS_VALUE_TYPE, JSValue::kSize, 904 isolate->initial_object_prototype(), 905 Builtins::kIllegal, true); 906 907 global_context()->set_date_function(*date_fun); 908 } 909 910 911 { // -- R e g E x p 912 // Builtin functions for RegExp.prototype. 913 Handle<JSFunction> regexp_fun = 914 InstallFunction(global, "RegExp", JS_REGEXP_TYPE, JSRegExp::kSize, 915 isolate->initial_object_prototype(), 916 Builtins::kIllegal, true); 917 global_context()->set_regexp_function(*regexp_fun); 918 919 ASSERT(regexp_fun->has_initial_map()); 920 Handle<Map> initial_map(regexp_fun->initial_map()); 921 922 ASSERT_EQ(0, initial_map->inobject_properties()); 923 924 Handle<DescriptorArray> descriptors = factory->NewDescriptorArray(5); 925 PropertyAttributes final = 926 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY); 927 int enum_index = 0; 928 { 929 // ECMA-262, section 15.10.7.1. 930 FieldDescriptor field(heap->source_symbol(), 931 JSRegExp::kSourceFieldIndex, 932 final, 933 enum_index++); 934 descriptors->Set(0, &field); 935 } 936 { 937 // ECMA-262, section 15.10.7.2. 938 FieldDescriptor field(heap->global_symbol(), 939 JSRegExp::kGlobalFieldIndex, 940 final, 941 enum_index++); 942 descriptors->Set(1, &field); 943 } 944 { 945 // ECMA-262, section 15.10.7.3. 946 FieldDescriptor field(heap->ignore_case_symbol(), 947 JSRegExp::kIgnoreCaseFieldIndex, 948 final, 949 enum_index++); 950 descriptors->Set(2, &field); 951 } 952 { 953 // ECMA-262, section 15.10.7.4. 954 FieldDescriptor field(heap->multiline_symbol(), 955 JSRegExp::kMultilineFieldIndex, 956 final, 957 enum_index++); 958 descriptors->Set(3, &field); 959 } 960 { 961 // ECMA-262, section 15.10.7.5. 962 PropertyAttributes writable = 963 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE); 964 FieldDescriptor field(heap->last_index_symbol(), 965 JSRegExp::kLastIndexFieldIndex, 966 writable, 967 enum_index++); 968 descriptors->Set(4, &field); 969 } 970 descriptors->SetNextEnumerationIndex(enum_index); 971 descriptors->Sort(); 972 973 initial_map->set_inobject_properties(5); 974 initial_map->set_pre_allocated_property_fields(5); 975 initial_map->set_unused_property_fields(0); 976 initial_map->set_instance_size( 977 initial_map->instance_size() + 5 * kPointerSize); 978 initial_map->set_instance_descriptors(*descriptors); 979 initial_map->set_visitor_id(StaticVisitorBase::GetVisitorId(*initial_map)); 980 } 981 982 { // -- J S O N 983 Handle<String> name = factory->NewStringFromAscii(CStrVector("JSON")); 984 Handle<JSFunction> cons = factory->NewFunction( 985 name, 986 factory->the_hole_value()); 987 cons->SetInstancePrototype(global_context()->initial_object_prototype()); 988 cons->SetInstanceClassName(*name); 989 Handle<JSObject> json_object = factory->NewJSObject(cons, TENURED); 990 ASSERT(json_object->IsJSObject()); 991 SetLocalPropertyNoThrow(global, name, json_object, DONT_ENUM); 992 global_context()->set_json_object(*json_object); 993 } 994 995 { // --- arguments_boilerplate_ 996 // Make sure we can recognize argument objects at runtime. 997 // This is done by introducing an anonymous function with 998 // class_name equals 'Arguments'. 999 Handle<String> symbol = factory->LookupAsciiSymbol("Arguments"); 1000 Handle<Code> code = Handle<Code>( 1001 isolate->builtins()->builtin(Builtins::kIllegal)); 1002 Handle<JSObject> prototype = 1003 Handle<JSObject>( 1004 JSObject::cast(global_context()->object_function()->prototype())); 1005 1006 Handle<JSFunction> function = 1007 factory->NewFunctionWithPrototype(symbol, 1008 JS_OBJECT_TYPE, 1009 JSObject::kHeaderSize, 1010 prototype, 1011 code, 1012 false); 1013 ASSERT(!function->has_initial_map()); 1014 function->shared()->set_instance_class_name(*symbol); 1015 function->shared()->set_expected_nof_properties(2); 1016 Handle<JSObject> result = factory->NewJSObject(function); 1017 1018 global_context()->set_arguments_boilerplate(*result); 1019 // Note: length must be added as the first property and 1020 // callee must be added as the second property. 1021 SetLocalPropertyNoThrow(result, factory->length_symbol(), 1022 factory->undefined_value(), 1023 DONT_ENUM); 1024 SetLocalPropertyNoThrow(result, factory->callee_symbol(), 1025 factory->undefined_value(), 1026 DONT_ENUM); 1027 1028 #ifdef DEBUG 1029 LookupResult lookup; 1030 result->LocalLookup(heap->callee_symbol(), &lookup); 1031 ASSERT(lookup.IsProperty() && (lookup.type() == FIELD)); 1032 ASSERT(lookup.GetFieldIndex() == Heap::kArgumentsCalleeIndex); 1033 1034 result->LocalLookup(heap->length_symbol(), &lookup); 1035 ASSERT(lookup.IsProperty() && (lookup.type() == FIELD)); 1036 ASSERT(lookup.GetFieldIndex() == Heap::kArgumentsLengthIndex); 1037 1038 ASSERT(result->map()->inobject_properties() > Heap::kArgumentsCalleeIndex); 1039 ASSERT(result->map()->inobject_properties() > Heap::kArgumentsLengthIndex); 1040 1041 // Check the state of the object. 1042 ASSERT(result->HasFastProperties()); 1043 ASSERT(result->HasFastElements()); 1044 #endif 1045 } 1046 1047 { // --- strict mode arguments boilerplate 1048 const PropertyAttributes attributes = 1049 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY); 1050 1051 // Create the ThrowTypeError functions. 1052 Handle<FixedArray> callee = factory->NewFixedArray(2, TENURED); 1053 Handle<FixedArray> caller = factory->NewFixedArray(2, TENURED); 1054 1055 Handle<JSFunction> callee_throw = 1056 CreateThrowTypeErrorFunction(Builtins::kStrictArgumentsCallee); 1057 Handle<JSFunction> caller_throw = 1058 CreateThrowTypeErrorFunction(Builtins::kStrictArgumentsCaller); 1059 1060 // Install the ThrowTypeError functions. 1061 callee->set(0, *callee_throw); 1062 callee->set(1, *callee_throw); 1063 caller->set(0, *caller_throw); 1064 caller->set(1, *caller_throw); 1065 1066 // Create the descriptor array for the arguments object. 1067 Handle<DescriptorArray> descriptors = factory->NewDescriptorArray(3); 1068 { // length 1069 FieldDescriptor d(*factory->length_symbol(), 0, DONT_ENUM); 1070 descriptors->Set(0, &d); 1071 } 1072 { // callee 1073 CallbacksDescriptor d(*factory->callee_symbol(), *callee, attributes); 1074 descriptors->Set(1, &d); 1075 } 1076 { // caller 1077 CallbacksDescriptor d(*factory->caller_symbol(), *caller, attributes); 1078 descriptors->Set(2, &d); 1079 } 1080 descriptors->Sort(); 1081 1082 // Create the map. Allocate one in-object field for length. 1083 Handle<Map> map = factory->NewMap(JS_OBJECT_TYPE, 1084 Heap::kArgumentsObjectSizeStrict); 1085 map->set_instance_descriptors(*descriptors); 1086 map->set_function_with_prototype(true); 1087 map->set_prototype(global_context()->object_function()->prototype()); 1088 map->set_pre_allocated_property_fields(1); 1089 map->set_inobject_properties(1); 1090 1091 // Copy constructor from the non-strict arguments boilerplate. 1092 map->set_constructor( 1093 global_context()->arguments_boilerplate()->map()->constructor()); 1094 1095 // Allocate the arguments boilerplate object. 1096 Handle<JSObject> result = factory->NewJSObjectFromMap(map); 1097 global_context()->set_strict_mode_arguments_boilerplate(*result); 1098 1099 // Add length property only for strict mode boilerplate. 1100 SetLocalPropertyNoThrow(result, factory->length_symbol(), 1101 factory->undefined_value(), 1102 DONT_ENUM); 1103 1104 #ifdef DEBUG 1105 LookupResult lookup; 1106 result->LocalLookup(heap->length_symbol(), &lookup); 1107 ASSERT(lookup.IsProperty() && (lookup.type() == FIELD)); 1108 ASSERT(lookup.GetFieldIndex() == Heap::kArgumentsLengthIndex); 1109 1110 ASSERT(result->map()->inobject_properties() > Heap::kArgumentsLengthIndex); 1111 1112 // Check the state of the object. 1113 ASSERT(result->HasFastProperties()); 1114 ASSERT(result->HasFastElements()); 1115 #endif 1116 } 1117 1118 { // --- context extension 1119 // Create a function for the context extension objects. 1120 Handle<Code> code = Handle<Code>( 1121 isolate->builtins()->builtin(Builtins::kIllegal)); 1122 Handle<JSFunction> context_extension_fun = 1123 factory->NewFunction(factory->empty_symbol(), 1124 JS_CONTEXT_EXTENSION_OBJECT_TYPE, 1125 JSObject::kHeaderSize, 1126 code, 1127 true); 1128 1129 Handle<String> name = factory->LookupAsciiSymbol("context_extension"); 1130 context_extension_fun->shared()->set_instance_class_name(*name); 1131 global_context()->set_context_extension_function(*context_extension_fun); 1132 } 1133 1134 1135 { 1136 // Setup the call-as-function delegate. 1137 Handle<Code> code = 1138 Handle<Code>(isolate->builtins()->builtin( 1139 Builtins::kHandleApiCallAsFunction)); 1140 Handle<JSFunction> delegate = 1141 factory->NewFunction(factory->empty_symbol(), JS_OBJECT_TYPE, 1142 JSObject::kHeaderSize, code, true); 1143 global_context()->set_call_as_function_delegate(*delegate); 1144 delegate->shared()->DontAdaptArguments(); 1145 } 1146 1147 { 1148 // Setup the call-as-constructor delegate. 1149 Handle<Code> code = 1150 Handle<Code>(isolate->builtins()->builtin( 1151 Builtins::kHandleApiCallAsConstructor)); 1152 Handle<JSFunction> delegate = 1153 factory->NewFunction(factory->empty_symbol(), JS_OBJECT_TYPE, 1154 JSObject::kHeaderSize, code, true); 1155 global_context()->set_call_as_constructor_delegate(*delegate); 1156 delegate->shared()->DontAdaptArguments(); 1157 } 1158 1159 // Initialize the out of memory slot. 1160 global_context()->set_out_of_memory(heap->false_value()); 1161 1162 // Initialize the data slot. 1163 global_context()->set_data(heap->undefined_value()); 1164 } 1165 1166 1167 bool Genesis::CompileBuiltin(int index) { 1168 Vector<const char> name = Natives::GetScriptName(index); 1169 Handle<String> source_code = 1170 Isolate::Current()->bootstrapper()->NativesSourceLookup(index); 1171 return CompileNative(name, source_code); 1172 } 1173 1174 1175 bool Genesis::CompileNative(Vector<const char> name, Handle<String> source) { 1176 HandleScope scope; 1177 Isolate* isolate = Isolate::Current(); 1178 #ifdef ENABLE_DEBUGGER_SUPPORT 1179 isolate->debugger()->set_compiling_natives(true); 1180 #endif 1181 bool result = CompileScriptCached(name, 1182 source, 1183 NULL, 1184 NULL, 1185 Handle<Context>(isolate->context()), 1186 true); 1187 ASSERT(isolate->has_pending_exception() != result); 1188 if (!result) isolate->clear_pending_exception(); 1189 #ifdef ENABLE_DEBUGGER_SUPPORT 1190 isolate->debugger()->set_compiling_natives(false); 1191 #endif 1192 return result; 1193 } 1194 1195 1196 bool Genesis::CompileScriptCached(Vector<const char> name, 1197 Handle<String> source, 1198 SourceCodeCache* cache, 1199 v8::Extension* extension, 1200 Handle<Context> top_context, 1201 bool use_runtime_context) { 1202 Factory* factory = Isolate::Current()->factory(); 1203 HandleScope scope; 1204 Handle<SharedFunctionInfo> function_info; 1205 1206 // If we can't find the function in the cache, we compile a new 1207 // function and insert it into the cache. 1208 if (cache == NULL || !cache->Lookup(name, &function_info)) { 1209 ASSERT(source->IsAsciiRepresentation()); 1210 Handle<String> script_name = factory->NewStringFromUtf8(name); 1211 function_info = Compiler::Compile( 1212 source, 1213 script_name, 1214 0, 1215 0, 1216 extension, 1217 NULL, 1218 Handle<String>::null(), 1219 use_runtime_context ? NATIVES_CODE : NOT_NATIVES_CODE); 1220 if (function_info.is_null()) return false; 1221 if (cache != NULL) cache->Add(name, function_info); 1222 } 1223 1224 // Setup the function context. Conceptually, we should clone the 1225 // function before overwriting the context but since we're in a 1226 // single-threaded environment it is not strictly necessary. 1227 ASSERT(top_context->IsGlobalContext()); 1228 Handle<Context> context = 1229 Handle<Context>(use_runtime_context 1230 ? Handle<Context>(top_context->runtime_context()) 1231 : top_context); 1232 Handle<JSFunction> fun = 1233 factory->NewFunctionFromSharedFunctionInfo(function_info, context); 1234 1235 // Call function using either the runtime object or the global 1236 // object as the receiver. Provide no parameters. 1237 Handle<Object> receiver = 1238 Handle<Object>(use_runtime_context 1239 ? top_context->builtins() 1240 : top_context->global()); 1241 bool has_pending_exception; 1242 Handle<Object> result = 1243 Execution::Call(fun, receiver, 0, NULL, &has_pending_exception); 1244 if (has_pending_exception) return false; 1245 return true; 1246 } 1247 1248 1249 #define INSTALL_NATIVE(Type, name, var) \ 1250 Handle<String> var##_name = factory->LookupAsciiSymbol(name); \ 1251 Object* var##_native = \ 1252 global_context()->builtins()->GetPropertyNoExceptionThrown(*var##_name); \ 1253 global_context()->set_##var(Type::cast(var##_native)); 1254 1255 1256 void Genesis::InstallNativeFunctions() { 1257 Factory* factory = Isolate::Current()->factory(); 1258 HandleScope scope; 1259 INSTALL_NATIVE(JSFunction, "CreateDate", create_date_fun); 1260 INSTALL_NATIVE(JSFunction, "ToNumber", to_number_fun); 1261 INSTALL_NATIVE(JSFunction, "ToString", to_string_fun); 1262 INSTALL_NATIVE(JSFunction, "ToDetailString", to_detail_string_fun); 1263 INSTALL_NATIVE(JSFunction, "ToObject", to_object_fun); 1264 INSTALL_NATIVE(JSFunction, "ToInteger", to_integer_fun); 1265 INSTALL_NATIVE(JSFunction, "ToUint32", to_uint32_fun); 1266 INSTALL_NATIVE(JSFunction, "ToInt32", to_int32_fun); 1267 INSTALL_NATIVE(JSFunction, "GlobalEval", global_eval_fun); 1268 INSTALL_NATIVE(JSFunction, "Instantiate", instantiate_fun); 1269 INSTALL_NATIVE(JSFunction, "ConfigureTemplateInstance", 1270 configure_instance_fun); 1271 INSTALL_NATIVE(JSFunction, "GetStackTraceLine", get_stack_trace_line_fun); 1272 INSTALL_NATIVE(JSObject, "functionCache", function_cache); 1273 } 1274 1275 #undef INSTALL_NATIVE 1276 1277 1278 bool Genesis::InstallNatives() { 1279 HandleScope scope; 1280 Isolate* isolate = Isolate::Current(); 1281 Factory* factory = isolate->factory(); 1282 Heap* heap = isolate->heap(); 1283 1284 // Create a function for the builtins object. Allocate space for the 1285 // JavaScript builtins, a reference to the builtins object 1286 // (itself) and a reference to the global_context directly in the object. 1287 Handle<Code> code = Handle<Code>( 1288 isolate->builtins()->builtin(Builtins::kIllegal)); 1289 Handle<JSFunction> builtins_fun = 1290 factory->NewFunction(factory->empty_symbol(), JS_BUILTINS_OBJECT_TYPE, 1291 JSBuiltinsObject::kSize, code, true); 1292 1293 Handle<String> name = factory->LookupAsciiSymbol("builtins"); 1294 builtins_fun->shared()->set_instance_class_name(*name); 1295 1296 // Allocate the builtins object. 1297 Handle<JSBuiltinsObject> builtins = 1298 Handle<JSBuiltinsObject>::cast(factory->NewGlobalObject(builtins_fun)); 1299 builtins->set_builtins(*builtins); 1300 builtins->set_global_context(*global_context()); 1301 builtins->set_global_receiver(*builtins); 1302 1303 // Setup the 'global' properties of the builtins object. The 1304 // 'global' property that refers to the global object is the only 1305 // way to get from code running in the builtins context to the 1306 // global object. 1307 static const PropertyAttributes attributes = 1308 static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE); 1309 Handle<String> global_symbol = factory->LookupAsciiSymbol("global"); 1310 Handle<Object> global_obj(global_context()->global()); 1311 SetLocalPropertyNoThrow(builtins, global_symbol, global_obj, attributes); 1312 1313 // Setup the reference from the global object to the builtins object. 1314 JSGlobalObject::cast(global_context()->global())->set_builtins(*builtins); 1315 1316 // Create a bridge function that has context in the global context. 1317 Handle<JSFunction> bridge = 1318 factory->NewFunction(factory->empty_symbol(), factory->undefined_value()); 1319 ASSERT(bridge->context() == *isolate->global_context()); 1320 1321 // Allocate the builtins context. 1322 Handle<Context> context = 1323 factory->NewFunctionContext(Context::MIN_CONTEXT_SLOTS, bridge); 1324 context->set_global(*builtins); // override builtins global object 1325 1326 global_context()->set_runtime_context(*context); 1327 1328 { // -- S c r i p t 1329 // Builtin functions for Script. 1330 Handle<JSFunction> script_fun = 1331 InstallFunction(builtins, "Script", JS_VALUE_TYPE, JSValue::kSize, 1332 isolate->initial_object_prototype(), 1333 Builtins::kIllegal, false); 1334 Handle<JSObject> prototype = 1335 factory->NewJSObject(isolate->object_function(), TENURED); 1336 SetPrototype(script_fun, prototype); 1337 global_context()->set_script_function(*script_fun); 1338 1339 // Add 'source' and 'data' property to scripts. 1340 PropertyAttributes common_attributes = 1341 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY); 1342 Handle<Proxy> proxy_source = factory->NewProxy(&Accessors::ScriptSource); 1343 Handle<DescriptorArray> script_descriptors = 1344 factory->CopyAppendProxyDescriptor( 1345 factory->empty_descriptor_array(), 1346 factory->LookupAsciiSymbol("source"), 1347 proxy_source, 1348 common_attributes); 1349 Handle<Proxy> proxy_name = factory->NewProxy(&Accessors::ScriptName); 1350 script_descriptors = 1351 factory->CopyAppendProxyDescriptor( 1352 script_descriptors, 1353 factory->LookupAsciiSymbol("name"), 1354 proxy_name, 1355 common_attributes); 1356 Handle<Proxy> proxy_id = factory->NewProxy(&Accessors::ScriptId); 1357 script_descriptors = 1358 factory->CopyAppendProxyDescriptor( 1359 script_descriptors, 1360 factory->LookupAsciiSymbol("id"), 1361 proxy_id, 1362 common_attributes); 1363 Handle<Proxy> proxy_line_offset = 1364 factory->NewProxy(&Accessors::ScriptLineOffset); 1365 script_descriptors = 1366 factory->CopyAppendProxyDescriptor( 1367 script_descriptors, 1368 factory->LookupAsciiSymbol("line_offset"), 1369 proxy_line_offset, 1370 common_attributes); 1371 Handle<Proxy> proxy_column_offset = 1372 factory->NewProxy(&Accessors::ScriptColumnOffset); 1373 script_descriptors = 1374 factory->CopyAppendProxyDescriptor( 1375 script_descriptors, 1376 factory->LookupAsciiSymbol("column_offset"), 1377 proxy_column_offset, 1378 common_attributes); 1379 Handle<Proxy> proxy_data = factory->NewProxy(&Accessors::ScriptData); 1380 script_descriptors = 1381 factory->CopyAppendProxyDescriptor( 1382 script_descriptors, 1383 factory->LookupAsciiSymbol("data"), 1384 proxy_data, 1385 common_attributes); 1386 Handle<Proxy> proxy_type = factory->NewProxy(&Accessors::ScriptType); 1387 script_descriptors = 1388 factory->CopyAppendProxyDescriptor( 1389 script_descriptors, 1390 factory->LookupAsciiSymbol("type"), 1391 proxy_type, 1392 common_attributes); 1393 Handle<Proxy> proxy_compilation_type = 1394 factory->NewProxy(&Accessors::ScriptCompilationType); 1395 script_descriptors = 1396 factory->CopyAppendProxyDescriptor( 1397 script_descriptors, 1398 factory->LookupAsciiSymbol("compilation_type"), 1399 proxy_compilation_type, 1400 common_attributes); 1401 Handle<Proxy> proxy_line_ends = 1402 factory->NewProxy(&Accessors::ScriptLineEnds); 1403 script_descriptors = 1404 factory->CopyAppendProxyDescriptor( 1405 script_descriptors, 1406 factory->LookupAsciiSymbol("line_ends"), 1407 proxy_line_ends, 1408 common_attributes); 1409 Handle<Proxy> proxy_context_data = 1410 factory->NewProxy(&Accessors::ScriptContextData); 1411 script_descriptors = 1412 factory->CopyAppendProxyDescriptor( 1413 script_descriptors, 1414 factory->LookupAsciiSymbol("context_data"), 1415 proxy_context_data, 1416 common_attributes); 1417 Handle<Proxy> proxy_eval_from_script = 1418 factory->NewProxy(&Accessors::ScriptEvalFromScript); 1419 script_descriptors = 1420 factory->CopyAppendProxyDescriptor( 1421 script_descriptors, 1422 factory->LookupAsciiSymbol("eval_from_script"), 1423 proxy_eval_from_script, 1424 common_attributes); 1425 Handle<Proxy> proxy_eval_from_script_position = 1426 factory->NewProxy(&Accessors::ScriptEvalFromScriptPosition); 1427 script_descriptors = 1428 factory->CopyAppendProxyDescriptor( 1429 script_descriptors, 1430 factory->LookupAsciiSymbol("eval_from_script_position"), 1431 proxy_eval_from_script_position, 1432 common_attributes); 1433 Handle<Proxy> proxy_eval_from_function_name = 1434 factory->NewProxy(&Accessors::ScriptEvalFromFunctionName); 1435 script_descriptors = 1436 factory->CopyAppendProxyDescriptor( 1437 script_descriptors, 1438 factory->LookupAsciiSymbol("eval_from_function_name"), 1439 proxy_eval_from_function_name, 1440 common_attributes); 1441 1442 Handle<Map> script_map = Handle<Map>(script_fun->initial_map()); 1443 script_map->set_instance_descriptors(*script_descriptors); 1444 1445 // Allocate the empty script. 1446 Handle<Script> script = factory->NewScript(factory->empty_string()); 1447 script->set_type(Smi::FromInt(Script::TYPE_NATIVE)); 1448 heap->public_set_empty_script(*script); 1449 } 1450 { 1451 // Builtin function for OpaqueReference -- a JSValue-based object, 1452 // that keeps its field isolated from JavaScript code. It may store 1453 // objects, that JavaScript code may not access. 1454 Handle<JSFunction> opaque_reference_fun = 1455 InstallFunction(builtins, "OpaqueReference", JS_VALUE_TYPE, 1456 JSValue::kSize, 1457 isolate->initial_object_prototype(), 1458 Builtins::kIllegal, false); 1459 Handle<JSObject> prototype = 1460 factory->NewJSObject(isolate->object_function(), TENURED); 1461 SetPrototype(opaque_reference_fun, prototype); 1462 global_context()->set_opaque_reference_function(*opaque_reference_fun); 1463 } 1464 1465 { // --- I n t e r n a l A r r a y --- 1466 // An array constructor on the builtins object that works like 1467 // the public Array constructor, except that its prototype 1468 // doesn't inherit from Object.prototype. 1469 // To be used only for internal work by builtins. Instances 1470 // must not be leaked to user code. 1471 // Only works correctly when called as a constructor. The normal 1472 // Array code uses Array.prototype as prototype when called as 1473 // a function. 1474 Handle<JSFunction> array_function = 1475 InstallFunction(builtins, 1476 "InternalArray", 1477 JS_ARRAY_TYPE, 1478 JSArray::kSize, 1479 isolate->initial_object_prototype(), 1480 Builtins::kArrayCode, 1481 true); 1482 Handle<JSObject> prototype = 1483 factory->NewJSObject(isolate->object_function(), TENURED); 1484 SetPrototype(array_function, prototype); 1485 1486 array_function->shared()->set_construct_stub( 1487 isolate->builtins()->builtin(Builtins::kArrayConstructCode)); 1488 array_function->shared()->DontAdaptArguments(); 1489 1490 // Make "length" magic on instances. 1491 Handle<DescriptorArray> array_descriptors = 1492 factory->CopyAppendProxyDescriptor( 1493 factory->empty_descriptor_array(), 1494 factory->length_symbol(), 1495 factory->NewProxy(&Accessors::ArrayLength), 1496 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE)); 1497 1498 array_function->initial_map()->set_instance_descriptors( 1499 *array_descriptors); 1500 } 1501 1502 if (FLAG_disable_native_files) { 1503 PrintF("Warning: Running without installed natives!\n"); 1504 return true; 1505 } 1506 1507 // Install natives. 1508 for (int i = Natives::GetDebuggerCount(); 1509 i < Natives::GetBuiltinsCount(); 1510 i++) { 1511 Vector<const char> name = Natives::GetScriptName(i); 1512 if (!CompileBuiltin(i)) return false; 1513 // TODO(ager): We really only need to install the JS builtin 1514 // functions on the builtins object after compiling and running 1515 // runtime.js. 1516 if (!InstallJSBuiltins(builtins)) return false; 1517 } 1518 1519 InstallNativeFunctions(); 1520 1521 // Store the map for the string prototype after the natives has been compiled 1522 // and the String function has been setup. 1523 Handle<JSFunction> string_function(global_context()->string_function()); 1524 ASSERT(JSObject::cast( 1525 string_function->initial_map()->prototype())->HasFastProperties()); 1526 global_context()->set_string_function_prototype_map( 1527 HeapObject::cast(string_function->initial_map()->prototype())->map()); 1528 1529 // Install Function.prototype.call and apply. 1530 { Handle<String> key = factory->function_class_symbol(); 1531 Handle<JSFunction> function = 1532 Handle<JSFunction>::cast(GetProperty(isolate->global(), key)); 1533 Handle<JSObject> proto = 1534 Handle<JSObject>(JSObject::cast(function->instance_prototype())); 1535 1536 // Install the call and the apply functions. 1537 Handle<JSFunction> call = 1538 InstallFunction(proto, "call", JS_OBJECT_TYPE, JSObject::kHeaderSize, 1539 Handle<JSObject>::null(), 1540 Builtins::kFunctionCall, 1541 false); 1542 Handle<JSFunction> apply = 1543 InstallFunction(proto, "apply", JS_OBJECT_TYPE, JSObject::kHeaderSize, 1544 Handle<JSObject>::null(), 1545 Builtins::kFunctionApply, 1546 false); 1547 1548 // Make sure that Function.prototype.call appears to be compiled. 1549 // The code will never be called, but inline caching for call will 1550 // only work if it appears to be compiled. 1551 call->shared()->DontAdaptArguments(); 1552 ASSERT(call->is_compiled()); 1553 1554 // Set the expected parameters for apply to 2; required by builtin. 1555 apply->shared()->set_formal_parameter_count(2); 1556 1557 // Set the lengths for the functions to satisfy ECMA-262. 1558 call->shared()->set_length(1); 1559 apply->shared()->set_length(2); 1560 } 1561 1562 InstallBuiltinFunctionIds(); 1563 1564 // Create a constructor for RegExp results (a variant of Array that 1565 // predefines the two properties index and match). 1566 { 1567 // RegExpResult initial map. 1568 1569 // Find global.Array.prototype to inherit from. 1570 Handle<JSFunction> array_constructor(global_context()->array_function()); 1571 Handle<JSObject> array_prototype( 1572 JSObject::cast(array_constructor->instance_prototype())); 1573 1574 // Add initial map. 1575 Handle<Map> initial_map = 1576 factory->NewMap(JS_ARRAY_TYPE, JSRegExpResult::kSize); 1577 initial_map->set_constructor(*array_constructor); 1578 1579 // Set prototype on map. 1580 initial_map->set_non_instance_prototype(false); 1581 initial_map->set_prototype(*array_prototype); 1582 1583 // Update map with length accessor from Array and add "index" and "input". 1584 Handle<Map> array_map(global_context()->js_array_map()); 1585 Handle<DescriptorArray> array_descriptors( 1586 array_map->instance_descriptors()); 1587 ASSERT_EQ(1, array_descriptors->number_of_descriptors()); 1588 1589 Handle<DescriptorArray> reresult_descriptors = 1590 factory->NewDescriptorArray(3); 1591 1592 reresult_descriptors->CopyFrom(0, *array_descriptors, 0); 1593 1594 int enum_index = 0; 1595 { 1596 FieldDescriptor index_field(heap->index_symbol(), 1597 JSRegExpResult::kIndexIndex, 1598 NONE, 1599 enum_index++); 1600 reresult_descriptors->Set(1, &index_field); 1601 } 1602 1603 { 1604 FieldDescriptor input_field(heap->input_symbol(), 1605 JSRegExpResult::kInputIndex, 1606 NONE, 1607 enum_index++); 1608 reresult_descriptors->Set(2, &input_field); 1609 } 1610 reresult_descriptors->Sort(); 1611 1612 initial_map->set_inobject_properties(2); 1613 initial_map->set_pre_allocated_property_fields(2); 1614 initial_map->set_unused_property_fields(0); 1615 initial_map->set_instance_descriptors(*reresult_descriptors); 1616 1617 global_context()->set_regexp_result_map(*initial_map); 1618 } 1619 1620 1621 #ifdef DEBUG 1622 builtins->Verify(); 1623 #endif 1624 1625 return true; 1626 } 1627 1628 1629 static Handle<JSObject> ResolveBuiltinIdHolder( 1630 Handle<Context> global_context, 1631 const char* holder_expr) { 1632 Factory* factory = Isolate::Current()->factory(); 1633 Handle<GlobalObject> global(global_context->global()); 1634 const char* period_pos = strchr(holder_expr, '.'); 1635 if (period_pos == NULL) { 1636 return Handle<JSObject>::cast( 1637 GetProperty(global, factory->LookupAsciiSymbol(holder_expr))); 1638 } 1639 ASSERT_EQ(".prototype", period_pos); 1640 Vector<const char> property(holder_expr, 1641 static_cast<int>(period_pos - holder_expr)); 1642 Handle<JSFunction> function = Handle<JSFunction>::cast( 1643 GetProperty(global, factory->LookupSymbol(property))); 1644 return Handle<JSObject>(JSObject::cast(function->prototype())); 1645 } 1646 1647 1648 static void InstallBuiltinFunctionId(Handle<JSObject> holder, 1649 const char* function_name, 1650 BuiltinFunctionId id) { 1651 Handle<String> name = FACTORY->LookupAsciiSymbol(function_name); 1652 Object* function_object = holder->GetProperty(*name)->ToObjectUnchecked(); 1653 Handle<JSFunction> function(JSFunction::cast(function_object)); 1654 function->shared()->set_function_data(Smi::FromInt(id)); 1655 } 1656 1657 1658 void Genesis::InstallBuiltinFunctionIds() { 1659 HandleScope scope; 1660 #define INSTALL_BUILTIN_ID(holder_expr, fun_name, name) \ 1661 { \ 1662 Handle<JSObject> holder = ResolveBuiltinIdHolder( \ 1663 global_context(), #holder_expr); \ 1664 BuiltinFunctionId id = k##name; \ 1665 InstallBuiltinFunctionId(holder, #fun_name, id); \ 1666 } 1667 FUNCTIONS_WITH_ID_LIST(INSTALL_BUILTIN_ID) 1668 #undef INSTALL_BUILTIN_ID 1669 } 1670 1671 1672 // Do not forget to update macros.py with named constant 1673 // of cache id. 1674 #define JSFUNCTION_RESULT_CACHE_LIST(F) \ 1675 F(16, global_context()->regexp_function()) 1676 1677 1678 static FixedArray* CreateCache(int size, JSFunction* factory) { 1679 // Caches are supposed to live for a long time, allocate in old space. 1680 int array_size = JSFunctionResultCache::kEntriesIndex + 2 * size; 1681 // Cannot use cast as object is not fully initialized yet. 1682 JSFunctionResultCache* cache = reinterpret_cast<JSFunctionResultCache*>( 1683 *FACTORY->NewFixedArrayWithHoles(array_size, TENURED)); 1684 cache->set(JSFunctionResultCache::kFactoryIndex, factory); 1685 cache->MakeZeroSize(); 1686 return cache; 1687 } 1688 1689 1690 void Genesis::InstallJSFunctionResultCaches() { 1691 const int kNumberOfCaches = 0 + 1692 #define F(size, func) + 1 1693 JSFUNCTION_RESULT_CACHE_LIST(F) 1694 #undef F 1695 ; 1696 1697 Handle<FixedArray> caches = FACTORY->NewFixedArray(kNumberOfCaches, TENURED); 1698 1699 int index = 0; 1700 1701 #define F(size, func) do { \ 1702 FixedArray* cache = CreateCache((size), (func)); \ 1703 caches->set(index++, cache); \ 1704 } while (false) 1705 1706 JSFUNCTION_RESULT_CACHE_LIST(F); 1707 1708 #undef F 1709 1710 global_context()->set_jsfunction_result_caches(*caches); 1711 } 1712 1713 1714 void Genesis::InitializeNormalizedMapCaches() { 1715 Handle<FixedArray> array( 1716 FACTORY->NewFixedArray(NormalizedMapCache::kEntries, TENURED)); 1717 global_context()->set_normalized_map_cache(NormalizedMapCache::cast(*array)); 1718 } 1719 1720 1721 bool Bootstrapper::InstallExtensions(Handle<Context> global_context, 1722 v8::ExtensionConfiguration* extensions) { 1723 Isolate* isolate = Isolate::Current(); 1724 BootstrapperActive active; 1725 SaveContext saved_context(isolate); 1726 isolate->set_context(*global_context); 1727 if (!Genesis::InstallExtensions(global_context, extensions)) return false; 1728 Genesis::InstallSpecialObjects(global_context); 1729 return true; 1730 } 1731 1732 1733 void Genesis::InstallSpecialObjects(Handle<Context> global_context) { 1734 Factory* factory = Isolate::Current()->factory(); 1735 HandleScope scope; 1736 Handle<JSGlobalObject> js_global( 1737 JSGlobalObject::cast(global_context->global())); 1738 // Expose the natives in global if a name for it is specified. 1739 if (FLAG_expose_natives_as != NULL && strlen(FLAG_expose_natives_as) != 0) { 1740 Handle<String> natives_string = 1741 factory->LookupAsciiSymbol(FLAG_expose_natives_as); 1742 SetLocalPropertyNoThrow(js_global, natives_string, 1743 Handle<JSObject>(js_global->builtins()), DONT_ENUM); 1744 } 1745 1746 Handle<Object> Error = GetProperty(js_global, "Error"); 1747 if (Error->IsJSObject()) { 1748 Handle<String> name = factory->LookupAsciiSymbol("stackTraceLimit"); 1749 SetLocalPropertyNoThrow(Handle<JSObject>::cast(Error), 1750 name, 1751 Handle<Smi>(Smi::FromInt(FLAG_stack_trace_limit)), 1752 NONE); 1753 } 1754 1755 #ifdef ENABLE_DEBUGGER_SUPPORT 1756 // Expose the debug global object in global if a name for it is specified. 1757 if (FLAG_expose_debug_as != NULL && strlen(FLAG_expose_debug_as) != 0) { 1758 Debug* debug = Isolate::Current()->debug(); 1759 // If loading fails we just bail out without installing the 1760 // debugger but without tanking the whole context. 1761 if (!debug->Load()) return; 1762 // Set the security token for the debugger context to the same as 1763 // the shell global context to allow calling between these (otherwise 1764 // exposing debug global object doesn't make much sense). 1765 debug->debug_context()->set_security_token( 1766 global_context->security_token()); 1767 1768 Handle<String> debug_string = 1769 factory->LookupAsciiSymbol(FLAG_expose_debug_as); 1770 Handle<Object> global_proxy(debug->debug_context()->global_proxy()); 1771 SetLocalPropertyNoThrow(js_global, debug_string, global_proxy, DONT_ENUM); 1772 } 1773 #endif 1774 } 1775 1776 1777 bool Genesis::InstallExtensions(Handle<Context> global_context, 1778 v8::ExtensionConfiguration* extensions) { 1779 // TODO(isolates): Extensions on multiple isolates may take a little more 1780 // effort. (The external API reads 'ignore'-- does that mean 1781 // we can break the interface?) 1782 1783 // Clear coloring of extension list 1784 v8::RegisteredExtension* current = v8::RegisteredExtension::first_extension(); 1785 while (current != NULL) { 1786 current->set_state(v8::UNVISITED); 1787 current = current->next(); 1788 } 1789 // Install auto extensions. 1790 current = v8::RegisteredExtension::first_extension(); 1791 while (current != NULL) { 1792 if (current->extension()->auto_enable()) 1793 InstallExtension(current); 1794 current = current->next(); 1795 } 1796 1797 if (FLAG_expose_gc) InstallExtension("v8/gc"); 1798 if (FLAG_expose_externalize_string) InstallExtension("v8/externalize"); 1799 1800 if (extensions == NULL) return true; 1801 // Install required extensions 1802 int count = v8::ImplementationUtilities::GetNameCount(extensions); 1803 const char** names = v8::ImplementationUtilities::GetNames(extensions); 1804 for (int i = 0; i < count; i++) { 1805 if (!InstallExtension(names[i])) 1806 return false; 1807 } 1808 1809 return true; 1810 } 1811 1812 1813 // Installs a named extension. This methods is unoptimized and does 1814 // not scale well if we want to support a large number of extensions. 1815 bool Genesis::InstallExtension(const char* name) { 1816 v8::RegisteredExtension* current = v8::RegisteredExtension::first_extension(); 1817 // Loop until we find the relevant extension 1818 while (current != NULL) { 1819 if (strcmp(name, current->extension()->name()) == 0) break; 1820 current = current->next(); 1821 } 1822 // Didn't find the extension; fail. 1823 if (current == NULL) { 1824 v8::Utils::ReportApiFailure( 1825 "v8::Context::New()", "Cannot find required extension"); 1826 return false; 1827 } 1828 return InstallExtension(current); 1829 } 1830 1831 1832 bool Genesis::InstallExtension(v8::RegisteredExtension* current) { 1833 HandleScope scope; 1834 1835 if (current->state() == v8::INSTALLED) return true; 1836 // The current node has already been visited so there must be a 1837 // cycle in the dependency graph; fail. 1838 if (current->state() == v8::VISITED) { 1839 v8::Utils::ReportApiFailure( 1840 "v8::Context::New()", "Circular extension dependency"); 1841 return false; 1842 } 1843 ASSERT(current->state() == v8::UNVISITED); 1844 current->set_state(v8::VISITED); 1845 v8::Extension* extension = current->extension(); 1846 // Install the extension's dependencies 1847 for (int i = 0; i < extension->dependency_count(); i++) { 1848 if (!InstallExtension(extension->dependencies()[i])) return false; 1849 } 1850 Isolate* isolate = Isolate::Current(); 1851 Vector<const char> source = CStrVector(extension->source()); 1852 Handle<String> source_code = isolate->factory()->NewStringFromAscii(source); 1853 bool result = CompileScriptCached(CStrVector(extension->name()), 1854 source_code, 1855 isolate->bootstrapper()->extensions_cache(), 1856 extension, 1857 Handle<Context>(isolate->context()), 1858 false); 1859 ASSERT(isolate->has_pending_exception() != result); 1860 if (!result) { 1861 isolate->clear_pending_exception(); 1862 } 1863 current->set_state(v8::INSTALLED); 1864 return result; 1865 } 1866 1867 1868 bool Genesis::InstallJSBuiltins(Handle<JSBuiltinsObject> builtins) { 1869 HandleScope scope; 1870 for (int i = 0; i < Builtins::NumberOfJavaScriptBuiltins(); i++) { 1871 Builtins::JavaScript id = static_cast<Builtins::JavaScript>(i); 1872 Handle<String> name = FACTORY->LookupAsciiSymbol(Builtins::GetName(id)); 1873 Object* function_object = builtins->GetPropertyNoExceptionThrown(*name); 1874 Handle<JSFunction> function 1875 = Handle<JSFunction>(JSFunction::cast(function_object)); 1876 builtins->set_javascript_builtin(id, *function); 1877 Handle<SharedFunctionInfo> shared 1878 = Handle<SharedFunctionInfo>(function->shared()); 1879 if (!EnsureCompiled(shared, CLEAR_EXCEPTION)) return false; 1880 // Set the code object on the function object. 1881 function->ReplaceCode(function->shared()->code()); 1882 builtins->set_javascript_builtin_code(id, shared->code()); 1883 } 1884 return true; 1885 } 1886 1887 1888 bool Genesis::ConfigureGlobalObjects( 1889 v8::Handle<v8::ObjectTemplate> global_proxy_template) { 1890 Handle<JSObject> global_proxy( 1891 JSObject::cast(global_context()->global_proxy())); 1892 Handle<JSObject> inner_global(JSObject::cast(global_context()->global())); 1893 1894 if (!global_proxy_template.IsEmpty()) { 1895 // Configure the global proxy object. 1896 Handle<ObjectTemplateInfo> proxy_data = 1897 v8::Utils::OpenHandle(*global_proxy_template); 1898 if (!ConfigureApiObject(global_proxy, proxy_data)) return false; 1899 1900 // Configure the inner global object. 1901 Handle<FunctionTemplateInfo> proxy_constructor( 1902 FunctionTemplateInfo::cast(proxy_data->constructor())); 1903 if (!proxy_constructor->prototype_template()->IsUndefined()) { 1904 Handle<ObjectTemplateInfo> inner_data( 1905 ObjectTemplateInfo::cast(proxy_constructor->prototype_template())); 1906 if (!ConfigureApiObject(inner_global, inner_data)) return false; 1907 } 1908 } 1909 1910 SetObjectPrototype(global_proxy, inner_global); 1911 return true; 1912 } 1913 1914 1915 bool Genesis::ConfigureApiObject(Handle<JSObject> object, 1916 Handle<ObjectTemplateInfo> object_template) { 1917 ASSERT(!object_template.is_null()); 1918 ASSERT(object->IsInstanceOf( 1919 FunctionTemplateInfo::cast(object_template->constructor()))); 1920 1921 Isolate* isolate = Isolate::Current(); 1922 bool pending_exception = false; 1923 Handle<JSObject> obj = 1924 Execution::InstantiateObject(object_template, &pending_exception); 1925 if (pending_exception) { 1926 ASSERT(isolate->has_pending_exception()); 1927 isolate->clear_pending_exception(); 1928 return false; 1929 } 1930 TransferObject(obj, object); 1931 return true; 1932 } 1933 1934 1935 void Genesis::TransferNamedProperties(Handle<JSObject> from, 1936 Handle<JSObject> to) { 1937 if (from->HasFastProperties()) { 1938 Handle<DescriptorArray> descs = 1939 Handle<DescriptorArray>(from->map()->instance_descriptors()); 1940 for (int i = 0; i < descs->number_of_descriptors(); i++) { 1941 PropertyDetails details = PropertyDetails(descs->GetDetails(i)); 1942 switch (details.type()) { 1943 case FIELD: { 1944 HandleScope inner; 1945 Handle<String> key = Handle<String>(descs->GetKey(i)); 1946 int index = descs->GetFieldIndex(i); 1947 Handle<Object> value = Handle<Object>(from->FastPropertyAt(index)); 1948 SetLocalPropertyNoThrow(to, key, value, details.attributes()); 1949 break; 1950 } 1951 case CONSTANT_FUNCTION: { 1952 HandleScope inner; 1953 Handle<String> key = Handle<String>(descs->GetKey(i)); 1954 Handle<JSFunction> fun = 1955 Handle<JSFunction>(descs->GetConstantFunction(i)); 1956 SetLocalPropertyNoThrow(to, key, fun, details.attributes()); 1957 break; 1958 } 1959 case CALLBACKS: { 1960 LookupResult result; 1961 to->LocalLookup(descs->GetKey(i), &result); 1962 // If the property is already there we skip it 1963 if (result.IsProperty()) continue; 1964 HandleScope inner; 1965 ASSERT(!to->HasFastProperties()); 1966 // Add to dictionary. 1967 Handle<String> key = Handle<String>(descs->GetKey(i)); 1968 Handle<Object> callbacks(descs->GetCallbacksObject(i)); 1969 PropertyDetails d = 1970 PropertyDetails(details.attributes(), CALLBACKS, details.index()); 1971 SetNormalizedProperty(to, key, callbacks, d); 1972 break; 1973 } 1974 case MAP_TRANSITION: 1975 case EXTERNAL_ARRAY_TRANSITION: 1976 case CONSTANT_TRANSITION: 1977 case NULL_DESCRIPTOR: 1978 // Ignore non-properties. 1979 break; 1980 case NORMAL: 1981 // Do not occur since the from object has fast properties. 1982 case INTERCEPTOR: 1983 // No element in instance descriptors have interceptor type. 1984 UNREACHABLE(); 1985 break; 1986 } 1987 } 1988 } else { 1989 Handle<StringDictionary> properties = 1990 Handle<StringDictionary>(from->property_dictionary()); 1991 int capacity = properties->Capacity(); 1992 for (int i = 0; i < capacity; i++) { 1993 Object* raw_key(properties->KeyAt(i)); 1994 if (properties->IsKey(raw_key)) { 1995 ASSERT(raw_key->IsString()); 1996 // If the property is already there we skip it. 1997 LookupResult result; 1998 to->LocalLookup(String::cast(raw_key), &result); 1999 if (result.IsProperty()) continue; 2000 // Set the property. 2001 Handle<String> key = Handle<String>(String::cast(raw_key)); 2002 Handle<Object> value = Handle<Object>(properties->ValueAt(i)); 2003 if (value->IsJSGlobalPropertyCell()) { 2004 value = Handle<Object>(JSGlobalPropertyCell::cast(*value)->value()); 2005 } 2006 PropertyDetails details = properties->DetailsAt(i); 2007 SetLocalPropertyNoThrow(to, key, value, details.attributes()); 2008 } 2009 } 2010 } 2011 } 2012 2013 2014 void Genesis::TransferIndexedProperties(Handle<JSObject> from, 2015 Handle<JSObject> to) { 2016 // Cloning the elements array is sufficient. 2017 Handle<FixedArray> from_elements = 2018 Handle<FixedArray>(FixedArray::cast(from->elements())); 2019 Handle<FixedArray> to_elements = FACTORY->CopyFixedArray(from_elements); 2020 to->set_elements(*to_elements); 2021 } 2022 2023 2024 void Genesis::TransferObject(Handle<JSObject> from, Handle<JSObject> to) { 2025 HandleScope outer; 2026 2027 ASSERT(!from->IsJSArray()); 2028 ASSERT(!to->IsJSArray()); 2029 2030 TransferNamedProperties(from, to); 2031 TransferIndexedProperties(from, to); 2032 2033 // Transfer the prototype (new map is needed). 2034 Handle<Map> old_to_map = Handle<Map>(to->map()); 2035 Handle<Map> new_to_map = FACTORY->CopyMapDropTransitions(old_to_map); 2036 new_to_map->set_prototype(from->map()->prototype()); 2037 to->set_map(*new_to_map); 2038 } 2039 2040 2041 void Genesis::MakeFunctionInstancePrototypeWritable() { 2042 // The maps with writable prototype are created in CreateEmptyFunction 2043 // and CreateStrictModeFunctionMaps respectively. Initially the maps are 2044 // created with read-only prototype for JS builtins processing. 2045 ASSERT(!function_instance_map_writable_prototype_.is_null()); 2046 ASSERT(!strict_mode_function_instance_map_writable_prototype_.is_null()); 2047 2048 // Replace function instance maps to make prototype writable. 2049 global_context()->set_function_map( 2050 *function_instance_map_writable_prototype_); 2051 global_context()->set_strict_mode_function_map( 2052 *strict_mode_function_instance_map_writable_prototype_); 2053 } 2054 2055 2056 Genesis::Genesis(Handle<Object> global_object, 2057 v8::Handle<v8::ObjectTemplate> global_template, 2058 v8::ExtensionConfiguration* extensions) { 2059 Isolate* isolate = Isolate::Current(); 2060 result_ = Handle<Context>::null(); 2061 // If V8 isn't running and cannot be initialized, just return. 2062 if (!V8::IsRunning() && !V8::Initialize(NULL)) return; 2063 2064 // Before creating the roots we must save the context and restore it 2065 // on all function exits. 2066 HandleScope scope; 2067 SaveContext saved_context(isolate); 2068 2069 Handle<Context> new_context = Snapshot::NewContextFromSnapshot(); 2070 if (!new_context.is_null()) { 2071 global_context_ = 2072 Handle<Context>::cast(isolate->global_handles()->Create(*new_context)); 2073 AddToWeakGlobalContextList(*global_context_); 2074 isolate->set_context(*global_context_); 2075 isolate->counters()->contexts_created_by_snapshot()->Increment(); 2076 Handle<GlobalObject> inner_global; 2077 Handle<JSGlobalProxy> global_proxy = 2078 CreateNewGlobals(global_template, 2079 global_object, 2080 &inner_global); 2081 2082 HookUpGlobalProxy(inner_global, global_proxy); 2083 HookUpInnerGlobal(inner_global); 2084 2085 if (!ConfigureGlobalObjects(global_template)) return; 2086 } else { 2087 // We get here if there was no context snapshot. 2088 CreateRoots(); 2089 Handle<JSFunction> empty_function = CreateEmptyFunction(); 2090 CreateStrictModeFunctionMaps(empty_function); 2091 Handle<GlobalObject> inner_global; 2092 Handle<JSGlobalProxy> global_proxy = 2093 CreateNewGlobals(global_template, global_object, &inner_global); 2094 HookUpGlobalProxy(inner_global, global_proxy); 2095 InitializeGlobal(inner_global, empty_function); 2096 InstallJSFunctionResultCaches(); 2097 InitializeNormalizedMapCaches(); 2098 if (!InstallNatives()) return; 2099 2100 MakeFunctionInstancePrototypeWritable(); 2101 2102 if (!ConfigureGlobalObjects(global_template)) return; 2103 isolate->counters()->contexts_created_from_scratch()->Increment(); 2104 } 2105 2106 result_ = global_context_; 2107 } 2108 2109 2110 // Support for thread preemption. 2111 2112 // Reserve space for statics needing saving and restoring. 2113 int Bootstrapper::ArchiveSpacePerThread() { 2114 return sizeof(NestingCounterType); 2115 } 2116 2117 2118 // Archive statics that are thread local. 2119 char* Bootstrapper::ArchiveState(char* to) { 2120 *reinterpret_cast<NestingCounterType*>(to) = nesting_; 2121 nesting_ = 0; 2122 return to + sizeof(NestingCounterType); 2123 } 2124 2125 2126 // Restore statics that are thread local. 2127 char* Bootstrapper::RestoreState(char* from) { 2128 nesting_ = *reinterpret_cast<NestingCounterType*>(from); 2129 return from + sizeof(NestingCounterType); 2130 } 2131 2132 2133 // Called when the top-level V8 mutex is destroyed. 2134 void Bootstrapper::FreeThreadResources() { 2135 ASSERT(!IsActive()); 2136 } 2137 2138 } } // namespace v8::internal 2139