| 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 |