OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
200 // triggered during environment creation there may be weak handle | 200 // triggered during environment creation there may be weak handle |
201 // processing callbacks which may create new environments. | 201 // processing callbacks which may create new environments. |
202 Genesis* previous_; | 202 Genesis* previous_; |
203 | 203 |
204 Handle<Context> global_context() { return global_context_; } | 204 Handle<Context> global_context() { return global_context_; } |
205 | 205 |
206 // Creates some basic objects. Used for creating a context from scratch. | 206 // Creates some basic objects. Used for creating a context from scratch. |
207 void CreateRoots(); | 207 void CreateRoots(); |
208 // Creates the empty function. Used for creating a context from scratch. | 208 // Creates the empty function. Used for creating a context from scratch. |
209 Handle<JSFunction> CreateEmptyFunction(); | 209 Handle<JSFunction> CreateEmptyFunction(); |
| 210 // Creates the ThrowTypeError function. ECMA 5th Ed. 13.2.3 |
| 211 Handle<JSFunction> CreateThrowTypeErrorFunction(Builtins::Name builtin); |
| 212 |
| 213 void CreateStrictModeFunctionMaps(Handle<JSFunction> empty); |
210 // Creates the global objects using the global and the template passed in | 214 // Creates the global objects using the global and the template passed in |
211 // through the API. We call this regardless of whether we are building a | 215 // through the API. We call this regardless of whether we are building a |
212 // context from scratch or using a deserialized one from the partial snapshot | 216 // context from scratch or using a deserialized one from the partial snapshot |
213 // but in the latter case we don't use the objects it produces directly, as | 217 // but in the latter case we don't use the objects it produces directly, as |
214 // we have to used the deserialized ones that are linked together with the | 218 // we have to used the deserialized ones that are linked together with the |
215 // rest of the context snapshot. | 219 // rest of the context snapshot. |
216 Handle<JSGlobalProxy> CreateNewGlobals( | 220 Handle<JSGlobalProxy> CreateNewGlobals( |
217 v8::Handle<v8::ObjectTemplate> global_template, | 221 v8::Handle<v8::ObjectTemplate> global_template, |
218 Handle<Object> global_object, | 222 Handle<Object> global_object, |
219 Handle<GlobalObject>* global_proxy_out); | 223 Handle<GlobalObject>* global_proxy_out); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
253 // 'from'. | 257 // 'from'. |
254 void TransferObject(Handle<JSObject> from, Handle<JSObject> to); | 258 void TransferObject(Handle<JSObject> from, Handle<JSObject> to); |
255 void TransferNamedProperties(Handle<JSObject> from, Handle<JSObject> to); | 259 void TransferNamedProperties(Handle<JSObject> from, Handle<JSObject> to); |
256 void TransferIndexedProperties(Handle<JSObject> from, Handle<JSObject> to); | 260 void TransferIndexedProperties(Handle<JSObject> from, Handle<JSObject> to); |
257 | 261 |
258 enum PrototypePropertyMode { | 262 enum PrototypePropertyMode { |
259 DONT_ADD_PROTOTYPE, | 263 DONT_ADD_PROTOTYPE, |
260 ADD_READONLY_PROTOTYPE, | 264 ADD_READONLY_PROTOTYPE, |
261 ADD_WRITEABLE_PROTOTYPE | 265 ADD_WRITEABLE_PROTOTYPE |
262 }; | 266 }; |
| 267 |
| 268 Handle<Map> CreateFunctionMap(PrototypePropertyMode prototype_mode); |
| 269 |
263 Handle<DescriptorArray> ComputeFunctionInstanceDescriptor( | 270 Handle<DescriptorArray> ComputeFunctionInstanceDescriptor( |
264 PrototypePropertyMode prototypeMode); | 271 PrototypePropertyMode prototypeMode); |
265 void MakeFunctionInstancePrototypeWritable(); | 272 void MakeFunctionInstancePrototypeWritable(); |
266 | 273 |
| 274 Handle<Map> CreateStrictModeFunctionMap( |
| 275 PrototypePropertyMode prototype_mode, |
| 276 Handle<JSFunction> empty_function, |
| 277 Handle<FixedArray> arguments_callbacks, |
| 278 Handle<FixedArray> caller_callbacks); |
| 279 |
| 280 Handle<DescriptorArray> ComputeStrictFunctionInstanceDescriptor( |
| 281 PrototypePropertyMode propertyMode, |
| 282 Handle<FixedArray> arguments, |
| 283 Handle<FixedArray> caller); |
| 284 |
267 static bool CompileBuiltin(int index); | 285 static bool CompileBuiltin(int index); |
268 static bool CompileNative(Vector<const char> name, Handle<String> source); | 286 static bool CompileNative(Vector<const char> name, Handle<String> source); |
269 static bool CompileScriptCached(Vector<const char> name, | 287 static bool CompileScriptCached(Vector<const char> name, |
270 Handle<String> source, | 288 Handle<String> source, |
271 SourceCodeCache* cache, | 289 SourceCodeCache* cache, |
272 v8::Extension* extension, | 290 v8::Extension* extension, |
273 Handle<Context> top_context, | 291 Handle<Context> top_context, |
274 bool use_runtime_context); | 292 bool use_runtime_context); |
275 | 293 |
276 Handle<Context> result_; | 294 Handle<Context> result_; |
277 Handle<JSFunction> empty_function_; | 295 |
| 296 // Function instance maps. Function literal maps are created initially with |
| 297 // a read only prototype for the processing of JS builtins. Later the function |
| 298 // instance maps are replaced in order to make prototype writable. |
| 299 // These are the final, writable prototype, maps. |
| 300 Handle<Map> function_instance_map_writable_prototype_; |
| 301 Handle<Map> strict_mode_function_instance_map_writable_prototype_; |
| 302 |
278 BootstrapperActive active_; | 303 BootstrapperActive active_; |
279 friend class Bootstrapper; | 304 friend class Bootstrapper; |
280 }; | 305 }; |
281 | 306 |
282 | 307 |
283 void Bootstrapper::Iterate(ObjectVisitor* v) { | 308 void Bootstrapper::Iterate(ObjectVisitor* v) { |
284 extensions_cache.Iterate(v); | 309 extensions_cache.Iterate(v); |
285 v->Synchronize("Extensions"); | 310 v->Synchronize("Extensions"); |
286 } | 311 } |
287 | 312 |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
352 SetLocalPropertyNoThrow(target, symbol, function, DONT_ENUM); | 377 SetLocalPropertyNoThrow(target, symbol, function, DONT_ENUM); |
353 if (is_ecma_native) { | 378 if (is_ecma_native) { |
354 function->shared()->set_instance_class_name(*symbol); | 379 function->shared()->set_instance_class_name(*symbol); |
355 } | 380 } |
356 return function; | 381 return function; |
357 } | 382 } |
358 | 383 |
359 | 384 |
360 Handle<DescriptorArray> Genesis::ComputeFunctionInstanceDescriptor( | 385 Handle<DescriptorArray> Genesis::ComputeFunctionInstanceDescriptor( |
361 PrototypePropertyMode prototypeMode) { | 386 PrototypePropertyMode prototypeMode) { |
362 Handle<DescriptorArray> result = Factory::empty_descriptor_array(); | 387 Handle<DescriptorArray> descriptors = |
363 | 388 Factory::NewDescriptorArray(prototypeMode == DONT_ADD_PROTOTYPE ? 4 : 5); |
364 if (prototypeMode != DONT_ADD_PROTOTYPE) { | |
365 PropertyAttributes attributes = static_cast<PropertyAttributes>( | |
366 DONT_ENUM | | |
367 DONT_DELETE | | |
368 (prototypeMode == ADD_READONLY_PROTOTYPE ? READ_ONLY : 0)); | |
369 result = | |
370 Factory::CopyAppendProxyDescriptor( | |
371 result, | |
372 Factory::prototype_symbol(), | |
373 Factory::NewProxy(&Accessors::FunctionPrototype), | |
374 attributes); | |
375 } | |
376 | |
377 PropertyAttributes attributes = | 389 PropertyAttributes attributes = |
378 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY); | 390 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY); |
379 // Add length. | |
380 result = | |
381 Factory::CopyAppendProxyDescriptor( | |
382 result, | |
383 Factory::length_symbol(), | |
384 Factory::NewProxy(&Accessors::FunctionLength), | |
385 attributes); | |
386 | 391 |
387 // Add name. | 392 { // Add length. |
388 result = | 393 Handle<Proxy> proxy = Factory::NewProxy(&Accessors::FunctionLength); |
389 Factory::CopyAppendProxyDescriptor( | 394 CallbacksDescriptor d(*Factory::length_symbol(), *proxy, attributes); |
390 result, | 395 descriptors->Set(0, &d); |
391 Factory::name_symbol(), | 396 } |
392 Factory::NewProxy(&Accessors::FunctionName), | 397 { // Add name. |
393 attributes); | 398 Handle<Proxy> proxy = Factory::NewProxy(&Accessors::FunctionName); |
| 399 CallbacksDescriptor d(*Factory::name_symbol(), *proxy, attributes); |
| 400 descriptors->Set(1, &d); |
| 401 } |
| 402 { // Add arguments. |
| 403 Handle<Proxy> proxy = Factory::NewProxy(&Accessors::FunctionArguments); |
| 404 CallbacksDescriptor d(*Factory::arguments_symbol(), *proxy, attributes); |
| 405 descriptors->Set(2, &d); |
| 406 } |
| 407 { // Add caller. |
| 408 Handle<Proxy> proxy = Factory::NewProxy(&Accessors::FunctionCaller); |
| 409 CallbacksDescriptor d(*Factory::caller_symbol(), *proxy, attributes); |
| 410 descriptors->Set(3, &d); |
| 411 } |
| 412 if (prototypeMode != DONT_ADD_PROTOTYPE) { |
| 413 // Add prototype. |
| 414 if (prototypeMode == ADD_WRITEABLE_PROTOTYPE) { |
| 415 attributes = static_cast<PropertyAttributes>(attributes & ~READ_ONLY); |
| 416 } |
| 417 Handle<Proxy> proxy = Factory::NewProxy(&Accessors::FunctionPrototype); |
| 418 CallbacksDescriptor d(*Factory::prototype_symbol(), *proxy, attributes); |
| 419 descriptors->Set(4, &d); |
| 420 } |
| 421 descriptors->Sort(); |
| 422 return descriptors; |
| 423 } |
394 | 424 |
395 // Add arguments. | |
396 result = | |
397 Factory::CopyAppendProxyDescriptor( | |
398 result, | |
399 Factory::arguments_symbol(), | |
400 Factory::NewProxy(&Accessors::FunctionArguments), | |
401 attributes); | |
402 | 425 |
403 // Add caller. | 426 Handle<Map> Genesis::CreateFunctionMap(PrototypePropertyMode prototype_mode) { |
404 result = | 427 Handle<Map> map = Factory::NewMap(JS_FUNCTION_TYPE, JSFunction::kSize); |
405 Factory::CopyAppendProxyDescriptor( | 428 Handle<DescriptorArray> descriptors = |
406 result, | 429 ComputeFunctionInstanceDescriptor(prototype_mode); |
407 Factory::caller_symbol(), | 430 map->set_instance_descriptors(*descriptors); |
408 Factory::NewProxy(&Accessors::FunctionCaller), | 431 map->set_function_with_prototype(prototype_mode != DONT_ADD_PROTOTYPE); |
409 attributes); | 432 return map; |
410 | |
411 return result; | |
412 } | 433 } |
413 | 434 |
414 | 435 |
415 Handle<JSFunction> Genesis::CreateEmptyFunction() { | 436 Handle<JSFunction> Genesis::CreateEmptyFunction() { |
416 // Allocate the map for function instances. | 437 // Allocate the map for function instances. Maps are allocated first and their |
417 Handle<Map> fm = Factory::NewMap(JS_FUNCTION_TYPE, JSFunction::kSize); | 438 // prototypes patched later, once empty function is created. |
418 global_context()->set_function_instance_map(*fm); | 439 |
419 // Please note that the prototype property for function instances must be | 440 // Please note that the prototype property for function instances must be |
420 // writable. | 441 // writable. |
421 Handle<DescriptorArray> function_map_descriptors = | 442 global_context()->set_function_instance_map( |
422 ComputeFunctionInstanceDescriptor(ADD_WRITEABLE_PROTOTYPE); | 443 *CreateFunctionMap(ADD_WRITEABLE_PROTOTYPE)); |
423 fm->set_instance_descriptors(*function_map_descriptors); | |
424 fm->set_function_with_prototype(true); | |
425 | 444 |
426 // Functions with this map will not have a 'prototype' property, and | 445 // Functions with this map will not have a 'prototype' property, and |
427 // can not be used as constructors. | 446 // can not be used as constructors. |
428 Handle<Map> function_without_prototype_map = | |
429 Factory::NewMap(JS_FUNCTION_TYPE, JSFunction::kSize); | |
430 global_context()->set_function_without_prototype_map( | 447 global_context()->set_function_without_prototype_map( |
431 *function_without_prototype_map); | 448 *CreateFunctionMap(DONT_ADD_PROTOTYPE)); |
432 Handle<DescriptorArray> function_without_prototype_map_descriptors = | |
433 ComputeFunctionInstanceDescriptor(DONT_ADD_PROTOTYPE); | |
434 function_without_prototype_map->set_instance_descriptors( | |
435 *function_without_prototype_map_descriptors); | |
436 function_without_prototype_map->set_function_with_prototype(false); | |
437 | 449 |
438 // Allocate the function map first and then patch the prototype later | 450 // Allocate the function map. This map is temporary, used only for processing |
439 fm = Factory::NewMap(JS_FUNCTION_TYPE, JSFunction::kSize); | 451 // of builtins. |
440 global_context()->set_function_map(*fm); | 452 // Later the map is replaced with writable prototype map, allocated below. |
441 function_map_descriptors = | 453 global_context()->set_function_map( |
442 ComputeFunctionInstanceDescriptor(ADD_READONLY_PROTOTYPE); | 454 *CreateFunctionMap(ADD_READONLY_PROTOTYPE)); |
443 fm->set_instance_descriptors(*function_map_descriptors); | 455 |
444 fm->set_function_with_prototype(true); | 456 // The final map for functions. Writeable prototype. |
| 457 // This map is installed in MakeFunctionInstancePrototypeWritable. |
| 458 function_instance_map_writable_prototype_ = |
| 459 CreateFunctionMap(ADD_WRITEABLE_PROTOTYPE); |
445 | 460 |
446 Handle<String> object_name = Handle<String>(Heap::Object_symbol()); | 461 Handle<String> object_name = Handle<String>(Heap::Object_symbol()); |
447 | 462 |
448 { // --- O b j e c t --- | 463 { // --- O b j e c t --- |
449 Handle<JSFunction> object_fun = | 464 Handle<JSFunction> object_fun = |
450 Factory::NewFunction(object_name, Factory::null_value()); | 465 Factory::NewFunction(object_name, Factory::null_value()); |
451 Handle<Map> object_function_map = | 466 Handle<Map> object_function_map = |
452 Factory::NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize); | 467 Factory::NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize); |
453 object_fun->set_initial_map(*object_function_map); | 468 object_fun->set_initial_map(*object_function_map); |
454 object_function_map->set_constructor(*object_fun); | 469 object_function_map->set_constructor(*object_fun); |
455 | 470 |
456 global_context()->set_object_function(*object_fun); | 471 global_context()->set_object_function(*object_fun); |
457 | 472 |
458 // Allocate a new prototype for the object function. | 473 // Allocate a new prototype for the object function. |
459 Handle<JSObject> prototype = Factory::NewJSObject(Top::object_function(), | 474 Handle<JSObject> prototype = Factory::NewJSObject(Top::object_function(), |
460 TENURED); | 475 TENURED); |
461 | 476 |
462 global_context()->set_initial_object_prototype(*prototype); | 477 global_context()->set_initial_object_prototype(*prototype); |
463 SetPrototype(object_fun, prototype); | 478 SetPrototype(object_fun, prototype); |
464 object_function_map-> | 479 object_function_map-> |
465 set_instance_descriptors(Heap::empty_descriptor_array()); | 480 set_instance_descriptors(Heap::empty_descriptor_array()); |
466 } | 481 } |
467 | 482 |
468 // Allocate the empty function as the prototype for function ECMAScript | 483 // Allocate the empty function as the prototype for function ECMAScript |
469 // 262 15.3.4. | 484 // 262 15.3.4. |
470 Handle<String> symbol = Factory::LookupAsciiSymbol("Empty"); | 485 Handle<String> symbol = Factory::LookupAsciiSymbol("Empty"); |
471 Handle<JSFunction> empty_function = | 486 Handle<JSFunction> empty_function = |
472 Factory::NewFunctionWithoutPrototype(symbol); | 487 Factory::NewFunctionWithoutPrototype(symbol, kNonStrictMode); |
473 | 488 |
474 // --- E m p t y --- | 489 // --- E m p t y --- |
475 Handle<Code> code = | 490 Handle<Code> code = |
476 Handle<Code>(Builtins::builtin(Builtins::EmptyFunction)); | 491 Handle<Code>(Builtins::builtin(Builtins::EmptyFunction)); |
477 empty_function->set_code(*code); | 492 empty_function->set_code(*code); |
478 empty_function->shared()->set_code(*code); | 493 empty_function->shared()->set_code(*code); |
479 Handle<String> source = Factory::NewStringFromAscii(CStrVector("() {}")); | 494 Handle<String> source = Factory::NewStringFromAscii(CStrVector("() {}")); |
480 Handle<Script> script = Factory::NewScript(source); | 495 Handle<Script> script = Factory::NewScript(source); |
481 script->set_type(Smi::FromInt(Script::TYPE_NATIVE)); | 496 script->set_type(Smi::FromInt(Script::TYPE_NATIVE)); |
482 empty_function->shared()->set_script(*script); | 497 empty_function->shared()->set_script(*script); |
483 empty_function->shared()->set_start_position(0); | 498 empty_function->shared()->set_start_position(0); |
484 empty_function->shared()->set_end_position(source->length()); | 499 empty_function->shared()->set_end_position(source->length()); |
485 empty_function->shared()->DontAdaptArguments(); | 500 empty_function->shared()->DontAdaptArguments(); |
| 501 |
| 502 // Set prototypes for the function maps. |
486 global_context()->function_map()->set_prototype(*empty_function); | 503 global_context()->function_map()->set_prototype(*empty_function); |
487 global_context()->function_instance_map()->set_prototype(*empty_function); | 504 global_context()->function_instance_map()->set_prototype(*empty_function); |
488 global_context()->function_without_prototype_map()-> | 505 global_context()->function_without_prototype_map()-> |
489 set_prototype(*empty_function); | 506 set_prototype(*empty_function); |
| 507 function_instance_map_writable_prototype_->set_prototype(*empty_function); |
490 | 508 |
491 // Allocate the function map first and then patch the prototype later | 509 // Allocate the function map first and then patch the prototype later |
| 510 Handle<Map> function_without_prototype_map( |
| 511 global_context()->function_without_prototype_map()); |
492 Handle<Map> empty_fm = Factory::CopyMapDropDescriptors( | 512 Handle<Map> empty_fm = Factory::CopyMapDropDescriptors( |
493 function_without_prototype_map); | 513 function_without_prototype_map); |
494 empty_fm->set_instance_descriptors( | 514 empty_fm->set_instance_descriptors( |
495 *function_without_prototype_map_descriptors); | 515 function_without_prototype_map->instance_descriptors()); |
496 empty_fm->set_prototype(global_context()->object_function()->prototype()); | 516 empty_fm->set_prototype(global_context()->object_function()->prototype()); |
497 empty_function->set_map(*empty_fm); | 517 empty_function->set_map(*empty_fm); |
498 return empty_function; | 518 return empty_function; |
499 } | 519 } |
500 | 520 |
501 | 521 |
| 522 Handle<DescriptorArray> Genesis::ComputeStrictFunctionInstanceDescriptor( |
| 523 PrototypePropertyMode prototypeMode, |
| 524 Handle<FixedArray> arguments, |
| 525 Handle<FixedArray> caller) { |
| 526 Handle<DescriptorArray> descriptors = |
| 527 Factory::NewDescriptorArray(prototypeMode == DONT_ADD_PROTOTYPE ? 4 : 5); |
| 528 PropertyAttributes attributes = static_cast<PropertyAttributes>( |
| 529 DONT_ENUM | DONT_DELETE | READ_ONLY); |
| 530 |
| 531 { // length |
| 532 Handle<Proxy> proxy = Factory::NewProxy(&Accessors::FunctionLength); |
| 533 CallbacksDescriptor d(*Factory::length_symbol(), *proxy, attributes); |
| 534 descriptors->Set(0, &d); |
| 535 } |
| 536 { // name |
| 537 Handle<Proxy> proxy = Factory::NewProxy(&Accessors::FunctionName); |
| 538 CallbacksDescriptor d(*Factory::name_symbol(), *proxy, attributes); |
| 539 descriptors->Set(1, &d); |
| 540 } |
| 541 { // arguments |
| 542 CallbacksDescriptor d(*Factory::arguments_symbol(), *arguments, attributes); |
| 543 descriptors->Set(2, &d); |
| 544 } |
| 545 { // caller |
| 546 CallbacksDescriptor d(*Factory::caller_symbol(), *caller, attributes); |
| 547 descriptors->Set(3, &d); |
| 548 } |
| 549 |
| 550 // prototype |
| 551 if (prototypeMode != DONT_ADD_PROTOTYPE) { |
| 552 if (prototypeMode == ADD_WRITEABLE_PROTOTYPE) { |
| 553 attributes = static_cast<PropertyAttributes>(attributes & ~READ_ONLY); |
| 554 } |
| 555 Handle<Proxy> proxy = Factory::NewProxy(&Accessors::FunctionPrototype); |
| 556 CallbacksDescriptor d(*Factory::prototype_symbol(), *proxy, attributes); |
| 557 descriptors->Set(4, &d); |
| 558 } |
| 559 |
| 560 descriptors->Sort(); |
| 561 return descriptors; |
| 562 } |
| 563 |
| 564 |
| 565 // ECMAScript 5th Edition, 13.2.3 |
| 566 Handle<JSFunction> Genesis::CreateThrowTypeErrorFunction( |
| 567 Builtins::Name builtin) { |
| 568 Handle<String> name = Factory::LookupAsciiSymbol("ThrowTypeError"); |
| 569 Handle<JSFunction> throw_type_error = |
| 570 Factory::NewFunctionWithoutPrototype(name, kStrictMode); |
| 571 Handle<Code> code = Handle<Code>(Builtins::builtin(builtin)); |
| 572 |
| 573 throw_type_error->set_map(global_context()->strict_mode_function_map()); |
| 574 throw_type_error->set_code(*code); |
| 575 throw_type_error->shared()->set_code(*code); |
| 576 throw_type_error->shared()->DontAdaptArguments(); |
| 577 |
| 578 PreventExtensions(throw_type_error); |
| 579 |
| 580 return throw_type_error; |
| 581 } |
| 582 |
| 583 |
| 584 Handle<Map> Genesis::CreateStrictModeFunctionMap( |
| 585 PrototypePropertyMode prototype_mode, |
| 586 Handle<JSFunction> empty_function, |
| 587 Handle<FixedArray> arguments_callbacks, |
| 588 Handle<FixedArray> caller_callbacks) { |
| 589 Handle<Map> map = Factory::NewMap(JS_FUNCTION_TYPE, JSFunction::kSize); |
| 590 Handle<DescriptorArray> descriptors = |
| 591 ComputeStrictFunctionInstanceDescriptor(prototype_mode, |
| 592 arguments_callbacks, |
| 593 caller_callbacks); |
| 594 map->set_instance_descriptors(*descriptors); |
| 595 map->set_function_with_prototype(prototype_mode != DONT_ADD_PROTOTYPE); |
| 596 map->set_prototype(*empty_function); |
| 597 return map; |
| 598 } |
| 599 |
| 600 |
| 601 void Genesis::CreateStrictModeFunctionMaps(Handle<JSFunction> empty) { |
| 602 // Create the callbacks arrays for ThrowTypeError functions. |
| 603 // The get/set callacks are filled in after the maps are created below. |
| 604 Handle<FixedArray> arguments = Factory::NewFixedArray(2, TENURED); |
| 605 Handle<FixedArray> caller = Factory::NewFixedArray(2, TENURED); |
| 606 |
| 607 // Allocate map for the strict mode function instances. |
| 608 global_context()->set_strict_mode_function_instance_map( |
| 609 *CreateStrictModeFunctionMap( |
| 610 ADD_WRITEABLE_PROTOTYPE, empty, arguments, caller)); |
| 611 |
| 612 // Allocate map for the prototype-less strict mode instances. |
| 613 global_context()->set_strict_mode_function_without_prototype_map( |
| 614 *CreateStrictModeFunctionMap( |
| 615 DONT_ADD_PROTOTYPE, empty, arguments, caller)); |
| 616 |
| 617 // Allocate map for the strict mode functions. This map is temporary, used |
| 618 // only for processing of builtins. |
| 619 // Later the map is replaced with writable prototype map, allocated below. |
| 620 global_context()->set_strict_mode_function_map( |
| 621 *CreateStrictModeFunctionMap( |
| 622 ADD_READONLY_PROTOTYPE, empty, arguments, caller)); |
| 623 |
| 624 // The final map for the strict mode functions. Writeable prototype. |
| 625 // This map is installed in MakeFunctionInstancePrototypeWritable. |
| 626 strict_mode_function_instance_map_writable_prototype_ = |
| 627 CreateStrictModeFunctionMap( |
| 628 ADD_WRITEABLE_PROTOTYPE, empty, arguments, caller); |
| 629 |
| 630 // Create the ThrowTypeError function instances. |
| 631 Handle<JSFunction> arguments_throw = |
| 632 CreateThrowTypeErrorFunction(Builtins::StrictFunctionArguments); |
| 633 Handle<JSFunction> caller_throw = |
| 634 CreateThrowTypeErrorFunction(Builtins::StrictFunctionCaller); |
| 635 |
| 636 // Complete the callback fixed arrays. |
| 637 arguments->set(0, *arguments_throw); |
| 638 arguments->set(1, *arguments_throw); |
| 639 caller->set(0, *caller_throw); |
| 640 caller->set(1, *caller_throw); |
| 641 } |
| 642 |
| 643 |
502 static void AddToWeakGlobalContextList(Context* context) { | 644 static void AddToWeakGlobalContextList(Context* context) { |
503 ASSERT(context->IsGlobalContext()); | 645 ASSERT(context->IsGlobalContext()); |
504 #ifdef DEBUG | 646 #ifdef DEBUG |
505 { // NOLINT | 647 { // NOLINT |
506 ASSERT(context->get(Context::NEXT_CONTEXT_LINK)->IsUndefined()); | 648 ASSERT(context->get(Context::NEXT_CONTEXT_LINK)->IsUndefined()); |
507 // Check that context is not in the list yet. | 649 // Check that context is not in the list yet. |
508 for (Object* current = Heap::global_contexts_list(); | 650 for (Object* current = Heap::global_contexts_list(); |
509 !current->IsUndefined(); | 651 !current->IsUndefined(); |
510 current = Context::cast(current)->get(Context::NEXT_CONTEXT_LINK)) { | 652 current = Context::cast(current)->get(Context::NEXT_CONTEXT_LINK)) { |
511 ASSERT(current != context); | 653 ASSERT(current != context); |
(...skipping 1290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1802 | 1944 |
1803 // Transfer the prototype (new map is needed). | 1945 // Transfer the prototype (new map is needed). |
1804 Handle<Map> old_to_map = Handle<Map>(to->map()); | 1946 Handle<Map> old_to_map = Handle<Map>(to->map()); |
1805 Handle<Map> new_to_map = Factory::CopyMapDropTransitions(old_to_map); | 1947 Handle<Map> new_to_map = Factory::CopyMapDropTransitions(old_to_map); |
1806 new_to_map->set_prototype(from->map()->prototype()); | 1948 new_to_map->set_prototype(from->map()->prototype()); |
1807 to->set_map(*new_to_map); | 1949 to->set_map(*new_to_map); |
1808 } | 1950 } |
1809 | 1951 |
1810 | 1952 |
1811 void Genesis::MakeFunctionInstancePrototypeWritable() { | 1953 void Genesis::MakeFunctionInstancePrototypeWritable() { |
1812 // Make a new function map so all future functions | 1954 // The maps with writable prototype are created in CreateEmptyFunction |
1813 // will have settable and enumerable prototype properties. | 1955 // and CreateStrictModeFunctionMaps respectively. Initially the maps are |
1814 HandleScope scope; | 1956 // created with read-only prototype for JS builtins processing. |
| 1957 ASSERT(!function_instance_map_writable_prototype_.is_null()); |
| 1958 ASSERT(!strict_mode_function_instance_map_writable_prototype_.is_null()); |
1815 | 1959 |
1816 Handle<DescriptorArray> function_map_descriptors = | 1960 // Replace function instance maps to make prototype writable. |
1817 ComputeFunctionInstanceDescriptor(ADD_WRITEABLE_PROTOTYPE); | 1961 global_context()->set_function_map( |
1818 Handle<Map> fm = Factory::CopyMapDropDescriptors(Top::function_map()); | 1962 *function_instance_map_writable_prototype_); |
1819 fm->set_instance_descriptors(*function_map_descriptors); | 1963 global_context()->set_strict_mode_function_map( |
1820 fm->set_function_with_prototype(true); | 1964 *strict_mode_function_instance_map_writable_prototype_); |
1821 Top::context()->global_context()->set_function_map(*fm); | |
1822 } | 1965 } |
1823 | 1966 |
1824 | 1967 |
1825 Genesis::Genesis(Handle<Object> global_object, | 1968 Genesis::Genesis(Handle<Object> global_object, |
1826 v8::Handle<v8::ObjectTemplate> global_template, | 1969 v8::Handle<v8::ObjectTemplate> global_template, |
1827 v8::ExtensionConfiguration* extensions) { | 1970 v8::ExtensionConfiguration* extensions) { |
1828 result_ = Handle<Context>::null(); | 1971 result_ = Handle<Context>::null(); |
1829 // If V8 isn't running and cannot be initialized, just return. | 1972 // If V8 isn't running and cannot be initialized, just return. |
1830 if (!V8::IsRunning() && !V8::Initialize(NULL)) return; | 1973 if (!V8::IsRunning() && !V8::Initialize(NULL)) return; |
1831 | 1974 |
1832 // Before creating the roots we must save the context and restore it | 1975 // Before creating the roots we must save the context and restore it |
1833 // on all function exits. | 1976 // on all function exits. |
1834 HandleScope scope; | 1977 HandleScope scope; |
1835 SaveContext saved_context; | 1978 SaveContext saved_context; |
1836 | 1979 |
1837 Handle<Context> new_context = Snapshot::NewContextFromSnapshot(); | 1980 Handle<Context> new_context = Snapshot::NewContextFromSnapshot(); |
1838 if (!new_context.is_null()) { | 1981 if (!new_context.is_null()) { |
1839 global_context_ = | 1982 global_context_ = |
1840 Handle<Context>::cast(GlobalHandles::Create(*new_context)); | 1983 Handle<Context>::cast(GlobalHandles::Create(*new_context)); |
1841 AddToWeakGlobalContextList(*global_context_); | 1984 AddToWeakGlobalContextList(*global_context_); |
1842 Top::set_context(*global_context_); | 1985 Top::set_context(*global_context_); |
1843 i::Counters::contexts_created_by_snapshot.Increment(); | 1986 i::Counters::contexts_created_by_snapshot.Increment(); |
1844 JSFunction* empty_function = | |
1845 JSFunction::cast(global_context_->function_map()->prototype()); | |
1846 empty_function_ = Handle<JSFunction>(empty_function); | |
1847 Handle<GlobalObject> inner_global; | 1987 Handle<GlobalObject> inner_global; |
1848 Handle<JSGlobalProxy> global_proxy = | 1988 Handle<JSGlobalProxy> global_proxy = |
1849 CreateNewGlobals(global_template, | 1989 CreateNewGlobals(global_template, |
1850 global_object, | 1990 global_object, |
1851 &inner_global); | 1991 &inner_global); |
1852 | 1992 |
1853 HookUpGlobalProxy(inner_global, global_proxy); | 1993 HookUpGlobalProxy(inner_global, global_proxy); |
1854 HookUpInnerGlobal(inner_global); | 1994 HookUpInnerGlobal(inner_global); |
1855 | 1995 |
1856 if (!ConfigureGlobalObjects(global_template)) return; | 1996 if (!ConfigureGlobalObjects(global_template)) return; |
1857 } else { | 1997 } else { |
1858 // We get here if there was no context snapshot. | 1998 // We get here if there was no context snapshot. |
1859 CreateRoots(); | 1999 CreateRoots(); |
1860 Handle<JSFunction> empty_function = CreateEmptyFunction(); | 2000 Handle<JSFunction> empty_function = CreateEmptyFunction(); |
| 2001 CreateStrictModeFunctionMaps(empty_function); |
1861 Handle<GlobalObject> inner_global; | 2002 Handle<GlobalObject> inner_global; |
1862 Handle<JSGlobalProxy> global_proxy = | 2003 Handle<JSGlobalProxy> global_proxy = |
1863 CreateNewGlobals(global_template, global_object, &inner_global); | 2004 CreateNewGlobals(global_template, global_object, &inner_global); |
1864 HookUpGlobalProxy(inner_global, global_proxy); | 2005 HookUpGlobalProxy(inner_global, global_proxy); |
1865 InitializeGlobal(inner_global, empty_function); | 2006 InitializeGlobal(inner_global, empty_function); |
1866 InstallJSFunctionResultCaches(); | 2007 InstallJSFunctionResultCaches(); |
1867 InitializeNormalizedMapCaches(); | 2008 InitializeNormalizedMapCaches(); |
1868 if (!InstallNatives()) return; | 2009 if (!InstallNatives()) return; |
1869 | 2010 |
1870 MakeFunctionInstancePrototypeWritable(); | 2011 MakeFunctionInstancePrototypeWritable(); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1917 } | 2058 } |
1918 | 2059 |
1919 | 2060 |
1920 // Restore statics that are thread local. | 2061 // Restore statics that are thread local. |
1921 char* BootstrapperActive::RestoreState(char* from) { | 2062 char* BootstrapperActive::RestoreState(char* from) { |
1922 nesting_ = *reinterpret_cast<int*>(from); | 2063 nesting_ = *reinterpret_cast<int*>(from); |
1923 return from + sizeof(nesting_); | 2064 return from + sizeof(nesting_); |
1924 } | 2065 } |
1925 | 2066 |
1926 } } // namespace v8::internal | 2067 } } // namespace v8::internal |
OLD | NEW |