OLD | NEW |
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 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 456 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
467 Object* V = args[1]; | 467 Object* V = args[1]; |
468 while (true) { | 468 while (true) { |
469 Object* prototype = V->GetPrototype(); | 469 Object* prototype = V->GetPrototype(); |
470 if (prototype->IsNull()) return Heap::false_value(); | 470 if (prototype->IsNull()) return Heap::false_value(); |
471 if (O == prototype) return Heap::true_value(); | 471 if (O == prototype) return Heap::true_value(); |
472 V = prototype; | 472 V = prototype; |
473 } | 473 } |
474 } | 474 } |
475 | 475 |
476 | 476 |
| 477 // Inserts an object as the hidden prototype of another object. |
| 478 static Object* Runtime_SetHiddenPrototype(Arguments args) { |
| 479 NoHandleAllocation ha; |
| 480 ASSERT(args.length() == 2); |
| 481 CONVERT_CHECKED(JSObject, jsobject, args[0]); |
| 482 CONVERT_CHECKED(JSObject, proto, args[1]); |
| 483 |
| 484 // Sanity checks. The old prototype (that we are replacing) could |
| 485 // theoretically be null, but if it is not null then check that we |
| 486 // didn't already install a hidden prototype here. |
| 487 RUNTIME_ASSERT(!jsobject->GetPrototype()->IsHeapObject() || |
| 488 !HeapObject::cast(jsobject->GetPrototype())->map()->is_hidden_prototype()); |
| 489 RUNTIME_ASSERT(!proto->map()->is_hidden_prototype()); |
| 490 |
| 491 // Allocate up front before we start altering state in case we get a GC. |
| 492 Object* map_or_failure = proto->map()->CopyDropTransitions(); |
| 493 if (map_or_failure->IsFailure()) return map_or_failure; |
| 494 Map* new_proto_map = Map::cast(map_or_failure); |
| 495 |
| 496 map_or_failure = jsobject->map()->CopyDropTransitions(); |
| 497 if (map_or_failure->IsFailure()) return map_or_failure; |
| 498 Map* new_map = Map::cast(map_or_failure); |
| 499 |
| 500 // Set proto's prototype to be the old prototype of the object. |
| 501 new_proto_map->set_prototype(jsobject->GetPrototype()); |
| 502 proto->set_map(new_proto_map); |
| 503 new_proto_map->set_is_hidden_prototype(); |
| 504 |
| 505 // Set the object's prototype to proto. |
| 506 new_map->set_prototype(proto); |
| 507 jsobject->set_map(new_map); |
| 508 |
| 509 return Heap::undefined_value(); |
| 510 } |
| 511 |
| 512 |
477 static Object* Runtime_IsConstructCall(Arguments args) { | 513 static Object* Runtime_IsConstructCall(Arguments args) { |
478 NoHandleAllocation ha; | 514 NoHandleAllocation ha; |
479 ASSERT(args.length() == 0); | 515 ASSERT(args.length() == 0); |
480 JavaScriptFrameIterator it; | 516 JavaScriptFrameIterator it; |
481 return Heap::ToBoolean(it.frame()->IsConstructor()); | 517 return Heap::ToBoolean(it.frame()->IsConstructor()); |
482 } | 518 } |
483 | 519 |
484 | 520 |
485 static Object* Runtime_RegExpCompile(Arguments args) { | 521 static Object* Runtime_RegExpCompile(Arguments args) { |
486 HandleScope scope; | 522 HandleScope scope; |
(...skipping 2302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2789 static Object* Runtime_DeleteProperty(Arguments args) { | 2825 static Object* Runtime_DeleteProperty(Arguments args) { |
2790 NoHandleAllocation ha; | 2826 NoHandleAllocation ha; |
2791 ASSERT(args.length() == 2); | 2827 ASSERT(args.length() == 2); |
2792 | 2828 |
2793 CONVERT_CHECKED(JSObject, object, args[0]); | 2829 CONVERT_CHECKED(JSObject, object, args[0]); |
2794 CONVERT_CHECKED(String, key, args[1]); | 2830 CONVERT_CHECKED(String, key, args[1]); |
2795 return object->DeleteProperty(key); | 2831 return object->DeleteProperty(key); |
2796 } | 2832 } |
2797 | 2833 |
2798 | 2834 |
2799 static Object* Runtime_HasLocalProperty(Arguments args) { | 2835 static Object* HasLocalPropertyImplementation(Object* obj, String* key) { |
2800 NoHandleAllocation ha; | |
2801 ASSERT(args.length() == 2); | |
2802 CONVERT_CHECKED(String, key, args[1]); | |
2803 | |
2804 // Only JS objects can have properties. | 2836 // Only JS objects can have properties. |
2805 if (args[0]->IsJSObject()) { | 2837 if (obj->IsJSObject()) { |
2806 JSObject* object = JSObject::cast(args[0]); | 2838 JSObject* object = JSObject::cast(obj); |
2807 if (object->HasLocalProperty(key)) return Heap::true_value(); | 2839 if (object->HasLocalProperty(key)) return Heap::true_value(); |
2808 } else if (args[0]->IsString()) { | 2840 // Handle hidden prototypes. If there's a hidden prototype above this thing |
| 2841 // then we have to check it for properties, because they are supposed to |
| 2842 // look like they are on this object. |
| 2843 Object* proto = object->GetPrototype(); |
| 2844 if (proto->IsJSObject() && |
| 2845 JSObject::cast(proto)->map()->is_hidden_prototype()) { |
| 2846 return HasLocalPropertyImplementation(object->GetPrototype(), key); |
| 2847 } |
| 2848 } else if (obj->IsString()) { |
2809 // Well, there is one exception: Handle [] on strings. | 2849 // Well, there is one exception: Handle [] on strings. |
2810 uint32_t index; | 2850 uint32_t index; |
2811 if (key->AsArrayIndex(&index)) { | 2851 if (key->AsArrayIndex(&index)) { |
2812 String* string = String::cast(args[0]); | 2852 String* string = String::cast(obj); |
2813 if (index < static_cast<uint32_t>(string->length())) | 2853 if (index < static_cast<uint32_t>(string->length())) |
2814 return Heap::true_value(); | 2854 return Heap::true_value(); |
2815 } | 2855 } |
2816 } | 2856 } |
2817 return Heap::false_value(); | 2857 return Heap::false_value(); |
2818 } | 2858 } |
2819 | 2859 |
2820 | 2860 |
| 2861 static Object* Runtime_HasLocalProperty(Arguments args) { |
| 2862 NoHandleAllocation ha; |
| 2863 ASSERT(args.length() == 2); |
| 2864 CONVERT_CHECKED(String, key, args[1]); |
| 2865 |
| 2866 return HasLocalPropertyImplementation(args[0], key); |
| 2867 } |
| 2868 |
| 2869 |
2821 static Object* Runtime_HasProperty(Arguments args) { | 2870 static Object* Runtime_HasProperty(Arguments args) { |
2822 NoHandleAllocation na; | 2871 NoHandleAllocation na; |
2823 ASSERT(args.length() == 2); | 2872 ASSERT(args.length() == 2); |
2824 | 2873 |
2825 // Only JS objects can have properties. | 2874 // Only JS objects can have properties. |
2826 if (args[0]->IsJSObject()) { | 2875 if (args[0]->IsJSObject()) { |
2827 JSObject* object = JSObject::cast(args[0]); | 2876 JSObject* object = JSObject::cast(args[0]); |
2828 CONVERT_CHECKED(String, key, args[1]); | 2877 CONVERT_CHECKED(String, key, args[1]); |
2829 if (object->HasProperty(key)) return Heap::true_value(); | 2878 if (object->HasProperty(key)) return Heap::true_value(); |
2830 } | 2879 } |
(...skipping 4173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7004 } else { | 7053 } else { |
7005 // Handle last resort GC and make sure to allow future allocations | 7054 // Handle last resort GC and make sure to allow future allocations |
7006 // to grow the heap without causing GCs (if possible). | 7055 // to grow the heap without causing GCs (if possible). |
7007 Counters::gc_last_resort_from_js.Increment(); | 7056 Counters::gc_last_resort_from_js.Increment(); |
7008 Heap::CollectAllGarbage(); | 7057 Heap::CollectAllGarbage(); |
7009 } | 7058 } |
7010 } | 7059 } |
7011 | 7060 |
7012 | 7061 |
7013 } } // namespace v8::internal | 7062 } } // namespace v8::internal |
OLD | NEW |