| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 657 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 668 if (!result->IsProperty()) { | 668 if (!result->IsProperty()) { |
| 669 Object* proto = obj->GetPrototype(); | 669 Object* proto = obj->GetPrototype(); |
| 670 if (proto->IsJSObject() && | 670 if (proto->IsJSObject() && |
| 671 JSObject::cast(proto)->map()->is_hidden_prototype()) | 671 JSObject::cast(proto)->map()->is_hidden_prototype()) |
| 672 GetOwnPropertyImplementation(JSObject::cast(proto), | 672 GetOwnPropertyImplementation(JSObject::cast(proto), |
| 673 name, result); | 673 name, result); |
| 674 } | 674 } |
| 675 } | 675 } |
| 676 | 676 |
| 677 | 677 |
| 678 static bool CheckAccessException(LookupResult* result, |
| 679 v8::AccessType access_type) { |
| 680 if (result->type() == CALLBACKS) { |
| 681 Object* callback = result->GetCallbackObject(); |
| 682 if (callback->IsAccessorInfo()) { |
| 683 AccessorInfo* info = AccessorInfo::cast(callback); |
| 684 bool can_access = |
| 685 (access_type == v8::ACCESS_HAS && |
| 686 (info->all_can_read() || info->all_can_write())) || |
| 687 (access_type == v8::ACCESS_GET && info->all_can_read()) || |
| 688 (access_type == v8::ACCESS_SET && info->all_can_write()); |
| 689 return can_access; |
| 690 } |
| 691 } |
| 692 |
| 693 return false; |
| 694 } |
| 695 |
| 696 |
| 697 static bool CheckAccess(Isolate* isolate, |
| 698 JSObject* obj, |
| 699 String* name, |
| 700 LookupResult* result, |
| 701 v8::AccessType access_type) { |
| 702 ASSERT(result->IsProperty()); |
| 703 |
| 704 JSObject* holder = result->holder(); |
| 705 JSObject* current = obj; |
| 706 while (true) { |
| 707 if (current->IsAccessCheckNeeded() && |
| 708 !isolate->MayNamedAccess(current, name, access_type)) { |
| 709 // Access check callback denied the access, but some properties |
| 710 // can have a special permissions which override callbacks descision |
| 711 // (currently see v8::AccessControl). |
| 712 break; |
| 713 } |
| 714 |
| 715 if (current == holder) { |
| 716 return true; |
| 717 } |
| 718 |
| 719 current = JSObject::cast(current->GetPrototype()); |
| 720 } |
| 721 |
| 722 // API callbacks can have per callback access exceptions. |
| 723 switch (result->type()) { |
| 724 case CALLBACKS: { |
| 725 if (CheckAccessException(result, access_type)) { |
| 726 return true; |
| 727 } |
| 728 break; |
| 729 } |
| 730 case INTERCEPTOR: { |
| 731 // If the object has an interceptor, try real named properties. |
| 732 // Overwrite the result to fetch the correct property later. |
| 733 holder->LookupRealNamedProperty(name, result); |
| 734 if (result->IsProperty()) { |
| 735 if (CheckAccessException(result, access_type)) { |
| 736 return true; |
| 737 } |
| 738 } |
| 739 break; |
| 740 } |
| 741 default: |
| 742 break; |
| 743 } |
| 744 |
| 745 isolate->ReportFailedAccessCheck(current, access_type); |
| 746 return false; |
| 747 } |
| 748 |
| 749 |
| 678 // Enumerator used as indices into the array returned from GetOwnProperty | 750 // Enumerator used as indices into the array returned from GetOwnProperty |
| 679 enum PropertyDescriptorIndices { | 751 enum PropertyDescriptorIndices { |
| 680 IS_ACCESSOR_INDEX, | 752 IS_ACCESSOR_INDEX, |
| 681 VALUE_INDEX, | 753 VALUE_INDEX, |
| 682 GETTER_INDEX, | 754 GETTER_INDEX, |
| 683 SETTER_INDEX, | 755 SETTER_INDEX, |
| 684 WRITABLE_INDEX, | 756 WRITABLE_INDEX, |
| 685 ENUMERABLE_INDEX, | 757 ENUMERABLE_INDEX, |
| 686 CONFIGURABLE_INDEX, | 758 CONFIGURABLE_INDEX, |
| 687 DESCRIPTOR_SIZE | 759 DESCRIPTOR_SIZE |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 771 } | 843 } |
| 772 } | 844 } |
| 773 } | 845 } |
| 774 | 846 |
| 775 // Use recursive implementation to also traverse hidden prototypes | 847 // Use recursive implementation to also traverse hidden prototypes |
| 776 GetOwnPropertyImplementation(*obj, *name, &result); | 848 GetOwnPropertyImplementation(*obj, *name, &result); |
| 777 | 849 |
| 778 if (!result.IsProperty()) { | 850 if (!result.IsProperty()) { |
| 779 return heap->undefined_value(); | 851 return heap->undefined_value(); |
| 780 } | 852 } |
| 781 if (result.type() == CALLBACKS) { | 853 |
| 782 Object* structure = result.GetCallbackObject(); | 854 if (!CheckAccess(isolate, *obj, *name, &result, v8::ACCESS_HAS)) { |
| 783 if (structure->IsProxy() || structure->IsAccessorInfo()) { | 855 return heap->undefined_value(); |
| 784 // Property that is internally implemented as a callback or | |
| 785 // an API defined callback. | |
| 786 Object* value; | |
| 787 { MaybeObject* maybe_value = obj->GetPropertyWithCallback( | |
| 788 *obj, structure, *name, result.holder()); | |
| 789 if (!maybe_value->ToObject(&value)) return maybe_value; | |
| 790 } | |
| 791 elms->set(IS_ACCESSOR_INDEX, heap->false_value()); | |
| 792 elms->set(VALUE_INDEX, value); | |
| 793 elms->set(WRITABLE_INDEX, heap->ToBoolean(!result.IsReadOnly())); | |
| 794 } else if (structure->IsFixedArray()) { | |
| 795 // __defineGetter__/__defineSetter__ callback. | |
| 796 elms->set(IS_ACCESSOR_INDEX, heap->true_value()); | |
| 797 elms->set(GETTER_INDEX, FixedArray::cast(structure)->get(0)); | |
| 798 elms->set(SETTER_INDEX, FixedArray::cast(structure)->get(1)); | |
| 799 } else { | |
| 800 return heap->undefined_value(); | |
| 801 } | |
| 802 } else { | |
| 803 elms->set(IS_ACCESSOR_INDEX, heap->false_value()); | |
| 804 elms->set(VALUE_INDEX, result.GetLazyValue()); | |
| 805 elms->set(WRITABLE_INDEX, heap->ToBoolean(!result.IsReadOnly())); | |
| 806 } | 856 } |
| 807 | 857 |
| 808 elms->set(ENUMERABLE_INDEX, heap->ToBoolean(!result.IsDontEnum())); | 858 elms->set(ENUMERABLE_INDEX, heap->ToBoolean(!result.IsDontEnum())); |
| 809 elms->set(CONFIGURABLE_INDEX, heap->ToBoolean(!result.IsDontDelete())); | 859 elms->set(CONFIGURABLE_INDEX, heap->ToBoolean(!result.IsDontDelete())); |
| 860 |
| 861 bool is_js_accessor = (result.type() == CALLBACKS) && |
| 862 (result.GetCallbackObject()->IsFixedArray()); |
| 863 |
| 864 if (is_js_accessor) { |
| 865 // __defineGetter__/__defineSetter__ callback. |
| 866 elms->set(IS_ACCESSOR_INDEX, heap->true_value()); |
| 867 |
| 868 FixedArray* structure = FixedArray::cast(result.GetCallbackObject()); |
| 869 if (CheckAccess(isolate, *obj, *name, &result, v8::ACCESS_GET)) { |
| 870 elms->set(GETTER_INDEX, structure->get(0)); |
| 871 } |
| 872 if (CheckAccess(isolate, *obj, *name, &result, v8::ACCESS_SET)) { |
| 873 elms->set(SETTER_INDEX, structure->get(1)); |
| 874 } |
| 875 } else { |
| 876 elms->set(IS_ACCESSOR_INDEX, heap->false_value()); |
| 877 elms->set(WRITABLE_INDEX, heap->ToBoolean(!result.IsReadOnly())); |
| 878 |
| 879 PropertyAttributes attrs; |
| 880 Object* value; |
| 881 // GetProperty will check access and report any violations. |
| 882 { MaybeObject* maybe_value = obj->GetProperty(*obj, &result, *name, &attrs); |
| 883 if (!maybe_value->ToObject(&value)) return maybe_value; |
| 884 } |
| 885 elms->set(VALUE_INDEX, value); |
| 886 } |
| 887 |
| 810 return *desc; | 888 return *desc; |
| 811 } | 889 } |
| 812 | 890 |
| 813 | 891 |
| 814 static MaybeObject* Runtime_PreventExtensions(RUNTIME_CALLING_CONVENTION) { | 892 static MaybeObject* Runtime_PreventExtensions(RUNTIME_CALLING_CONVENTION) { |
| 815 RUNTIME_GET_ISOLATE; | 893 RUNTIME_GET_ISOLATE; |
| 816 ASSERT(args.length() == 1); | 894 ASSERT(args.length() == 1); |
| 817 CONVERT_CHECKED(JSObject, obj, args[0]); | 895 CONVERT_CHECKED(JSObject, obj, args[0]); |
| 818 return obj->PreventExtensions(); | 896 return obj->PreventExtensions(); |
| 819 } | 897 } |
| (...skipping 10406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11226 cache_handle->set(index + 1, *value); | 11304 cache_handle->set(index + 1, *value); |
| 11227 cache_handle->set_finger_index(index); | 11305 cache_handle->set_finger_index(index); |
| 11228 | 11306 |
| 11229 #ifdef DEBUG | 11307 #ifdef DEBUG |
| 11230 cache_handle->JSFunctionResultCacheVerify(); | 11308 cache_handle->JSFunctionResultCacheVerify(); |
| 11231 #endif | 11309 #endif |
| 11232 | 11310 |
| 11233 return *value; | 11311 return *value; |
| 11234 } | 11312 } |
| 11235 | 11313 |
| 11314 |
| 11315 static MaybeObject* Runtime_NewMessageObject(RUNTIME_CALLING_CONVENTION) { |
| 11316 RUNTIME_GET_ISOLATE; |
| 11317 HandleScope scope; |
| 11318 CONVERT_ARG_CHECKED(String, type, 0); |
| 11319 CONVERT_ARG_CHECKED(JSArray, arguments, 1); |
| 11320 Factory* factory = isolate->factory(); |
| 11321 Handle<Object> undefined = factory->undefined_value(); |
| 11322 return *factory->NewJSMessageObject(type, |
| 11323 arguments, |
| 11324 0, |
| 11325 0, |
| 11326 undefined, |
| 11327 undefined, |
| 11328 undefined); |
| 11329 } |
| 11330 |
| 11331 |
| 11332 static MaybeObject* Runtime_MessageGetType(RUNTIME_CALLING_CONVENTION) { |
| 11333 RUNTIME_GET_ISOLATE; |
| 11334 CONVERT_CHECKED(JSMessageObject, message, args[0]); |
| 11335 return message->type(); |
| 11336 } |
| 11337 |
| 11338 |
| 11339 static MaybeObject* Runtime_MessageGetArguments(RUNTIME_CALLING_CONVENTION) { |
| 11340 RUNTIME_GET_ISOLATE; |
| 11341 CONVERT_CHECKED(JSMessageObject, message, args[0]); |
| 11342 return message->arguments(); |
| 11343 } |
| 11344 |
| 11345 |
| 11346 static MaybeObject* Runtime_MessageGetStartPosition( |
| 11347 RUNTIME_CALLING_CONVENTION) { |
| 11348 RUNTIME_GET_ISOLATE; |
| 11349 CONVERT_CHECKED(JSMessageObject, message, args[0]); |
| 11350 return Smi::FromInt(message->start_position()); |
| 11351 } |
| 11352 |
| 11353 |
| 11354 static MaybeObject* Runtime_MessageGetScript(RUNTIME_CALLING_CONVENTION) { |
| 11355 RUNTIME_GET_ISOLATE; |
| 11356 CONVERT_CHECKED(JSMessageObject, message, args[0]); |
| 11357 return message->script(); |
| 11358 } |
| 11359 |
| 11360 |
| 11236 #ifdef DEBUG | 11361 #ifdef DEBUG |
| 11237 // ListNatives is ONLY used by the fuzz-natives.js in debug mode | 11362 // ListNatives is ONLY used by the fuzz-natives.js in debug mode |
| 11238 // Exclude the code in release mode. | 11363 // Exclude the code in release mode. |
| 11239 static MaybeObject* Runtime_ListNatives(RUNTIME_CALLING_CONVENTION) { | 11364 static MaybeObject* Runtime_ListNatives(RUNTIME_CALLING_CONVENTION) { |
| 11240 RUNTIME_GET_ISOLATE; | 11365 RUNTIME_GET_ISOLATE; |
| 11241 ASSERT(args.length() == 0); | 11366 ASSERT(args.length() == 0); |
| 11242 HandleScope scope(isolate); | 11367 HandleScope scope(isolate); |
| 11243 Handle<JSArray> result = isolate->factory()->NewJSArray(0); | 11368 Handle<JSArray> result = isolate->factory()->NewJSArray(0); |
| 11244 int index = 0; | 11369 int index = 0; |
| 11245 bool inline_runtime_functions = false; | 11370 bool inline_runtime_functions = false; |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11360 } else { | 11485 } else { |
| 11361 // Handle last resort GC and make sure to allow future allocations | 11486 // Handle last resort GC and make sure to allow future allocations |
| 11362 // to grow the heap without causing GCs (if possible). | 11487 // to grow the heap without causing GCs (if possible). |
| 11363 COUNTERS->gc_last_resort_from_js()->Increment(); | 11488 COUNTERS->gc_last_resort_from_js()->Increment(); |
| 11364 HEAP->CollectAllGarbage(false); | 11489 HEAP->CollectAllGarbage(false); |
| 11365 } | 11490 } |
| 11366 } | 11491 } |
| 11367 | 11492 |
| 11368 | 11493 |
| 11369 } } // namespace v8::internal | 11494 } } // namespace v8::internal |
| OLD | NEW |