Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/bootstrapper.h" | 5 #include "src/bootstrapper.h" |
| 6 | 6 |
| 7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
| 8 #include "src/isolate-inl.h" | 8 #include "src/isolate-inl.h" |
| 9 #include "src/natives.h" | 9 #include "src/natives.h" |
| 10 #include "src/snapshot.h" | 10 #include "src/snapshot.h" |
| (...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 261 void TransferObject(Handle<JSObject> from, Handle<JSObject> to); | 261 void TransferObject(Handle<JSObject> from, Handle<JSObject> to); |
| 262 void TransferNamedProperties(Handle<JSObject> from, Handle<JSObject> to); | 262 void TransferNamedProperties(Handle<JSObject> from, Handle<JSObject> to); |
| 263 void TransferIndexedProperties(Handle<JSObject> from, Handle<JSObject> to); | 263 void TransferIndexedProperties(Handle<JSObject> from, Handle<JSObject> to); |
| 264 | 264 |
| 265 enum PrototypePropertyMode { | 265 enum PrototypePropertyMode { |
| 266 DONT_ADD_PROTOTYPE, | 266 DONT_ADD_PROTOTYPE, |
| 267 ADD_READONLY_PROTOTYPE, | 267 ADD_READONLY_PROTOTYPE, |
| 268 ADD_WRITEABLE_PROTOTYPE | 268 ADD_WRITEABLE_PROTOTYPE |
| 269 }; | 269 }; |
| 270 | 270 |
| 271 enum ForBoundFunctionMode { | |
|
Toon Verwaest
2014/06/12 21:53:35
I'd rather name this
enum FunctionMapMode {
REG
Jakob Kummerow
2014/06/13 11:43:13
Done.
| |
| 272 FOR_REGULAR_FUNCTION, | |
| 273 FOR_BOUND_FUNCTION | |
| 274 }; | |
| 275 | |
| 271 Handle<Map> CreateFunctionMap(PrototypePropertyMode prototype_mode); | 276 Handle<Map> CreateFunctionMap(PrototypePropertyMode prototype_mode); |
| 272 | 277 |
| 273 void SetFunctionInstanceDescriptor(Handle<Map> map, | 278 void SetFunctionInstanceDescriptor(Handle<Map> map, |
| 274 PrototypePropertyMode prototypeMode); | 279 PrototypePropertyMode prototypeMode); |
| 275 void MakeFunctionInstancePrototypeWritable(); | 280 void MakeFunctionInstancePrototypeWritable(); |
| 276 | 281 |
| 277 Handle<Map> CreateStrictFunctionMap( | 282 Handle<Map> CreateStrictFunctionMap( |
| 278 PrototypePropertyMode prototype_mode, | 283 PrototypePropertyMode prototype_mode, |
| 279 Handle<JSFunction> empty_function); | 284 Handle<JSFunction> empty_function, |
| 285 ForBoundFunctionMode bound_mode = FOR_REGULAR_FUNCTION); | |
| 280 | 286 |
| 281 void SetStrictFunctionInstanceDescriptor(Handle<Map> map, | 287 void SetStrictFunctionInstanceDescriptor(Handle<Map> map, |
| 282 PrototypePropertyMode propertyMode); | 288 PrototypePropertyMode propertyMode, |
| 289 ForBoundFunctionMode bound_mode); | |
| 283 | 290 |
| 284 static bool CompileBuiltin(Isolate* isolate, int index); | 291 static bool CompileBuiltin(Isolate* isolate, int index); |
| 285 static bool CompileExperimentalBuiltin(Isolate* isolate, int index); | 292 static bool CompileExperimentalBuiltin(Isolate* isolate, int index); |
| 286 static bool CompileNative(Isolate* isolate, | 293 static bool CompileNative(Isolate* isolate, |
| 287 Vector<const char> name, | 294 Vector<const char> name, |
| 288 Handle<String> source); | 295 Handle<String> source); |
| 289 static bool CompileScriptCached(Isolate* isolate, | 296 static bool CompileScriptCached(Isolate* isolate, |
| 290 Vector<const char> name, | 297 Vector<const char> name, |
| 291 Handle<String> source, | 298 Handle<String> source, |
| 292 SourceCodeCache* cache, | 299 SourceCodeCache* cache, |
| (...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 516 // Allocate the function map first and then patch the prototype later | 523 // Allocate the function map first and then patch the prototype later |
| 517 Handle<Map> empty_function_map = CreateFunctionMap(DONT_ADD_PROTOTYPE); | 524 Handle<Map> empty_function_map = CreateFunctionMap(DONT_ADD_PROTOTYPE); |
| 518 empty_function_map->set_prototype( | 525 empty_function_map->set_prototype( |
| 519 native_context()->object_function()->prototype()); | 526 native_context()->object_function()->prototype()); |
| 520 empty_function->set_map(*empty_function_map); | 527 empty_function->set_map(*empty_function_map); |
| 521 return empty_function; | 528 return empty_function; |
| 522 } | 529 } |
| 523 | 530 |
| 524 | 531 |
| 525 void Genesis::SetStrictFunctionInstanceDescriptor( | 532 void Genesis::SetStrictFunctionInstanceDescriptor( |
| 526 Handle<Map> map, PrototypePropertyMode prototypeMode) { | 533 Handle<Map> map, PrototypePropertyMode prototypeMode, |
| 534 ForBoundFunctionMode bound_mode) { | |
| 527 int size = (prototypeMode == DONT_ADD_PROTOTYPE) ? 4 : 5; | 535 int size = (prototypeMode == DONT_ADD_PROTOTYPE) ? 4 : 5; |
| 528 Map::EnsureDescriptorSlack(map, size); | 536 Map::EnsureDescriptorSlack(map, size); |
| 529 | 537 |
| 530 Handle<AccessorPair> arguments(factory()->NewAccessorPair()); | 538 Handle<AccessorPair> arguments(factory()->NewAccessorPair()); |
| 531 Handle<AccessorPair> caller(factory()->NewAccessorPair()); | 539 Handle<AccessorPair> caller(factory()->NewAccessorPair()); |
| 532 PropertyAttributes rw_attribs = | 540 PropertyAttributes rw_attribs = |
| 533 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE); | 541 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE); |
| 534 PropertyAttributes ro_attribs = | 542 PropertyAttributes ro_attribs = |
| 535 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY); | 543 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY); |
| 536 | 544 |
| 537 Handle<AccessorInfo> length = | 545 // Add length. |
| 538 Accessors::FunctionLengthInfo(isolate(), ro_attribs); | 546 if (bound_mode == FOR_REGULAR_FUNCTION) { |
| 539 { // Add length. | 547 Handle<AccessorInfo> length = |
| 548 Accessors::FunctionLengthInfo(isolate(), ro_attribs); | |
| 540 CallbacksDescriptor d(Handle<Name>(Name::cast(length->name())), | 549 CallbacksDescriptor d(Handle<Name>(Name::cast(length->name())), |
| 541 length, ro_attribs); | 550 length, ro_attribs); |
| 542 map->AppendDescriptor(&d); | 551 map->AppendDescriptor(&d); |
| 552 } else { | |
| 553 ASSERT(bound_mode == FOR_BOUND_FUNCTION); | |
| 554 Handle<String> length_string = isolate()->factory()->length_string(); | |
| 555 PropertyAttributes attr = | |
| 556 static_cast<PropertyAttributes>(DONT_DELETE | DONT_ENUM | READ_ONLY); | |
| 557 FieldDescriptor d(length_string, 0, attr, Representation::Tagged()); | |
| 558 map->AppendDescriptor(&d); | |
| 543 } | 559 } |
| 544 Handle<AccessorInfo> name = | 560 Handle<AccessorInfo> name = |
| 545 Accessors::FunctionNameInfo(isolate(), ro_attribs); | 561 Accessors::FunctionNameInfo(isolate(), ro_attribs); |
| 546 { // Add name. | 562 { // Add name. |
| 547 CallbacksDescriptor d(Handle<Name>(Name::cast(name->name())), | 563 CallbacksDescriptor d(Handle<Name>(Name::cast(name->name())), |
| 548 name, ro_attribs); | 564 name, ro_attribs); |
| 549 map->AppendDescriptor(&d); | 565 map->AppendDescriptor(&d); |
| 550 } | 566 } |
| 551 { // Add arguments. | 567 { // Add arguments. |
| 552 CallbacksDescriptor d(factory()->arguments_string(), arguments, | 568 CallbacksDescriptor d(factory()->arguments_string(), arguments, |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 599 generator_poison_function->shared()->DontAdaptArguments(); | 615 generator_poison_function->shared()->DontAdaptArguments(); |
| 600 | 616 |
| 601 JSObject::PreventExtensions(generator_poison_function).Assert(); | 617 JSObject::PreventExtensions(generator_poison_function).Assert(); |
| 602 } | 618 } |
| 603 return generator_poison_function; | 619 return generator_poison_function; |
| 604 } | 620 } |
| 605 | 621 |
| 606 | 622 |
| 607 Handle<Map> Genesis::CreateStrictFunctionMap( | 623 Handle<Map> Genesis::CreateStrictFunctionMap( |
| 608 PrototypePropertyMode prototype_mode, | 624 PrototypePropertyMode prototype_mode, |
| 609 Handle<JSFunction> empty_function) { | 625 Handle<JSFunction> empty_function, |
| 626 ForBoundFunctionMode bound_mode) { | |
| 610 Handle<Map> map = factory()->NewMap(JS_FUNCTION_TYPE, JSFunction::kSize); | 627 Handle<Map> map = factory()->NewMap(JS_FUNCTION_TYPE, JSFunction::kSize); |
| 611 SetStrictFunctionInstanceDescriptor(map, prototype_mode); | 628 SetStrictFunctionInstanceDescriptor(map, prototype_mode, bound_mode); |
| 612 map->set_function_with_prototype(prototype_mode != DONT_ADD_PROTOTYPE); | 629 map->set_function_with_prototype(prototype_mode != DONT_ADD_PROTOTYPE); |
| 613 map->set_prototype(*empty_function); | 630 map->set_prototype(*empty_function); |
| 614 return map; | 631 return map; |
| 615 } | 632 } |
| 616 | 633 |
| 617 | 634 |
| 618 void Genesis::CreateStrictModeFunctionMaps(Handle<JSFunction> empty) { | 635 void Genesis::CreateStrictModeFunctionMaps(Handle<JSFunction> empty) { |
| 619 // Allocate map for the prototype-less strict mode instances. | 636 // Allocate map for the prototype-less strict mode instances. |
| 620 Handle<Map> strict_function_without_prototype_map = | 637 Handle<Map> strict_function_without_prototype_map = |
| 621 CreateStrictFunctionMap(DONT_ADD_PROTOTYPE, empty); | 638 CreateStrictFunctionMap(DONT_ADD_PROTOTYPE, empty); |
| 622 native_context()->set_strict_function_without_prototype_map( | 639 native_context()->set_strict_function_without_prototype_map( |
| 623 *strict_function_without_prototype_map); | 640 *strict_function_without_prototype_map); |
| 624 | 641 |
| 625 // Allocate map for the strict mode functions. This map is temporary, used | 642 // Allocate map for the strict mode functions. This map is temporary, used |
| 626 // only for processing of builtins. | 643 // only for processing of builtins. |
| 627 // Later the map is replaced with writable prototype map, allocated below. | 644 // Later the map is replaced with writable prototype map, allocated below. |
| 628 Handle<Map> strict_function_map = | 645 Handle<Map> strict_function_map = |
| 629 CreateStrictFunctionMap(ADD_READONLY_PROTOTYPE, empty); | 646 CreateStrictFunctionMap(ADD_READONLY_PROTOTYPE, empty); |
| 630 native_context()->set_strict_function_map(*strict_function_map); | 647 native_context()->set_strict_function_map(*strict_function_map); |
| 631 | 648 |
| 632 // The final map for the strict mode functions. Writeable prototype. | 649 // The final map for the strict mode functions. Writeable prototype. |
| 633 // This map is installed in MakeFunctionInstancePrototypeWritable. | 650 // This map is installed in MakeFunctionInstancePrototypeWritable. |
| 634 strict_function_map_writable_prototype_ = | 651 strict_function_map_writable_prototype_ = |
| 635 CreateStrictFunctionMap(ADD_WRITEABLE_PROTOTYPE, empty); | 652 CreateStrictFunctionMap(ADD_WRITEABLE_PROTOTYPE, empty); |
| 653 // Special map for bound functions. | |
| 654 Handle<Map> bound_function_map = | |
| 655 CreateStrictFunctionMap(DONT_ADD_PROTOTYPE, empty, FOR_BOUND_FUNCTION); | |
| 656 native_context()->set_bound_function_map(*bound_function_map); | |
| 636 | 657 |
| 637 // Complete the callbacks. | 658 // Complete the callbacks. |
| 638 PoisonArgumentsAndCaller(strict_function_without_prototype_map); | 659 PoisonArgumentsAndCaller(strict_function_without_prototype_map); |
| 639 PoisonArgumentsAndCaller(strict_function_map); | 660 PoisonArgumentsAndCaller(strict_function_map); |
| 640 PoisonArgumentsAndCaller(strict_function_map_writable_prototype_); | 661 PoisonArgumentsAndCaller(strict_function_map_writable_prototype_); |
| 662 PoisonArgumentsAndCaller(bound_function_map); | |
| 641 } | 663 } |
| 642 | 664 |
| 643 | 665 |
| 644 static void SetAccessors(Handle<Map> map, | 666 static void SetAccessors(Handle<Map> map, |
| 645 Handle<String> name, | 667 Handle<String> name, |
| 646 Handle<JSFunction> func) { | 668 Handle<JSFunction> func) { |
| 647 DescriptorArray* descs = map->instance_descriptors(); | 669 DescriptorArray* descs = map->instance_descriptors(); |
| 648 int number = descs->SearchWithCache(*name, *map); | 670 int number = descs->SearchWithCache(*name, *map); |
| 649 AccessorPair* accessors = AccessorPair::cast(descs->GetValue(number)); | 671 AccessorPair* accessors = AccessorPair::cast(descs->GetValue(number)); |
| 650 accessors->set_getter(*func); | 672 accessors->set_getter(*func); |
| (...skipping 2063 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2714 return from + sizeof(NestingCounterType); | 2736 return from + sizeof(NestingCounterType); |
| 2715 } | 2737 } |
| 2716 | 2738 |
| 2717 | 2739 |
| 2718 // Called when the top-level V8 mutex is destroyed. | 2740 // Called when the top-level V8 mutex is destroyed. |
| 2719 void Bootstrapper::FreeThreadResources() { | 2741 void Bootstrapper::FreeThreadResources() { |
| 2720 ASSERT(!IsActive()); | 2742 ASSERT(!IsActive()); |
| 2721 } | 2743 } |
| 2722 | 2744 |
| 2723 } } // namespace v8::internal | 2745 } } // namespace v8::internal |
| OLD | NEW |