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 |