| 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(JSObject* obj, |
| 698 String* name, |
| 699 LookupResult* result, |
| 700 v8::AccessType access_type) { |
| 701 ASSERT(result->IsProperty()); |
| 702 |
| 703 JSObject* holder = result->holder(); |
| 704 JSObject* current = obj; |
| 705 Isolate* isolate = obj->GetIsolate(); |
| 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 |
| 750 // TODO(1095): we should traverse hidden prototype hierachy as well. |
| 751 static bool CheckElementAccess(JSObject* obj, |
| 752 uint32_t index, |
| 753 v8::AccessType access_type) { |
| 754 if (obj->IsAccessCheckNeeded() && |
| 755 !obj->GetIsolate()->MayIndexedAccess(obj, index, access_type)) { |
| 756 return false; |
| 757 } |
| 758 |
| 759 return true; |
| 760 } |
| 761 |
| 762 |
| 678 // Enumerator used as indices into the array returned from GetOwnProperty | 763 // Enumerator used as indices into the array returned from GetOwnProperty |
| 679 enum PropertyDescriptorIndices { | 764 enum PropertyDescriptorIndices { |
| 680 IS_ACCESSOR_INDEX, | 765 IS_ACCESSOR_INDEX, |
| 681 VALUE_INDEX, | 766 VALUE_INDEX, |
| 682 GETTER_INDEX, | 767 GETTER_INDEX, |
| 683 SETTER_INDEX, | 768 SETTER_INDEX, |
| 684 WRITABLE_INDEX, | 769 WRITABLE_INDEX, |
| 685 ENUMERABLE_INDEX, | 770 ENUMERABLE_INDEX, |
| 686 CONFIGURABLE_INDEX, | 771 CONFIGURABLE_INDEX, |
| 687 DESCRIPTOR_SIZE | 772 DESCRIPTOR_SIZE |
| (...skipping 24 matching lines...) Expand all Loading... |
| 712 case JSObject::UNDEFINED_ELEMENT: | 797 case JSObject::UNDEFINED_ELEMENT: |
| 713 return heap->undefined_value(); | 798 return heap->undefined_value(); |
| 714 | 799 |
| 715 case JSObject::STRING_CHARACTER_ELEMENT: { | 800 case JSObject::STRING_CHARACTER_ELEMENT: { |
| 716 // Special handling of string objects according to ECMAScript 5 | 801 // Special handling of string objects according to ECMAScript 5 |
| 717 // 15.5.5.2. Note that this might be a string object with elements | 802 // 15.5.5.2. Note that this might be a string object with elements |
| 718 // other than the actual string value. This is covered by the | 803 // other than the actual string value. This is covered by the |
| 719 // subsequent cases. | 804 // subsequent cases. |
| 720 Handle<JSValue> js_value = Handle<JSValue>::cast(obj); | 805 Handle<JSValue> js_value = Handle<JSValue>::cast(obj); |
| 721 Handle<String> str(String::cast(js_value->value())); | 806 Handle<String> str(String::cast(js_value->value())); |
| 722 Handle<String> substr = SubString(str, index, index+1, NOT_TENURED); | 807 Handle<String> substr = SubString(str, index, index + 1, NOT_TENURED); |
| 723 | 808 |
| 724 elms->set(IS_ACCESSOR_INDEX, heap->false_value()); | 809 elms->set(IS_ACCESSOR_INDEX, heap->false_value()); |
| 725 elms->set(VALUE_INDEX, *substr); | 810 elms->set(VALUE_INDEX, *substr); |
| 726 elms->set(WRITABLE_INDEX, heap->false_value()); | 811 elms->set(WRITABLE_INDEX, heap->false_value()); |
| 727 elms->set(ENUMERABLE_INDEX, heap->false_value()); | 812 elms->set(ENUMERABLE_INDEX, heap->false_value()); |
| 728 elms->set(CONFIGURABLE_INDEX, heap->false_value()); | 813 elms->set(CONFIGURABLE_INDEX, heap->false_value()); |
| 729 return *desc; | 814 return *desc; |
| 730 } | 815 } |
| 731 | 816 |
| 732 case JSObject::INTERCEPTED_ELEMENT: | 817 case JSObject::INTERCEPTED_ELEMENT: |
| 733 case JSObject::FAST_ELEMENT: { | 818 case JSObject::FAST_ELEMENT: { |
| 734 elms->set(IS_ACCESSOR_INDEX, heap->false_value()); | 819 elms->set(IS_ACCESSOR_INDEX, heap->false_value()); |
| 735 Handle<Object> element = GetElement(Handle<Object>(obj), index); | 820 elms->set(VALUE_INDEX, *GetElement(obj, index)); |
| 736 elms->set(VALUE_INDEX, *element); | |
| 737 elms->set(WRITABLE_INDEX, heap->true_value()); | 821 elms->set(WRITABLE_INDEX, heap->true_value()); |
| 738 elms->set(ENUMERABLE_INDEX, heap->true_value()); | 822 elms->set(ENUMERABLE_INDEX, heap->true_value()); |
| 739 elms->set(CONFIGURABLE_INDEX, heap->true_value()); | 823 elms->set(CONFIGURABLE_INDEX, heap->true_value()); |
| 740 return *desc; | 824 return *desc; |
| 741 } | 825 } |
| 742 | 826 |
| 743 case JSObject::DICTIONARY_ELEMENT: { | 827 case JSObject::DICTIONARY_ELEMENT: { |
| 744 NumberDictionary* dictionary = obj->element_dictionary(); | 828 Handle<JSObject> holder = obj; |
| 829 if (obj->IsJSGlobalProxy()) { |
| 830 Object* proto = obj->GetPrototype(); |
| 831 if (proto->IsNull()) return heap->undefined_value(); |
| 832 ASSERT(proto->IsJSGlobalObject()); |
| 833 holder = Handle<JSObject>(JSObject::cast(proto)); |
| 834 } |
| 835 NumberDictionary* dictionary = holder->element_dictionary(); |
| 745 int entry = dictionary->FindEntry(index); | 836 int entry = dictionary->FindEntry(index); |
| 746 ASSERT(entry != NumberDictionary::kNotFound); | 837 ASSERT(entry != NumberDictionary::kNotFound); |
| 747 PropertyDetails details = dictionary->DetailsAt(entry); | 838 PropertyDetails details = dictionary->DetailsAt(entry); |
| 748 switch (details.type()) { | 839 switch (details.type()) { |
| 749 case CALLBACKS: { | 840 case CALLBACKS: { |
| 750 // This is an accessor property with getter and/or setter. | 841 // This is an accessor property with getter and/or setter. |
| 751 FixedArray* callbacks = | 842 FixedArray* callbacks = |
| 752 FixedArray::cast(dictionary->ValueAt(entry)); | 843 FixedArray::cast(dictionary->ValueAt(entry)); |
| 753 elms->set(IS_ACCESSOR_INDEX, heap->true_value()); | 844 elms->set(IS_ACCESSOR_INDEX, heap->true_value()); |
| 754 elms->set(GETTER_INDEX, callbacks->get(0)); | 845 if (CheckElementAccess(*obj, index, v8::ACCESS_GET)) { |
| 755 elms->set(SETTER_INDEX, callbacks->get(1)); | 846 elms->set(GETTER_INDEX, callbacks->get(0)); |
| 847 } |
| 848 if (CheckElementAccess(*obj, index, v8::ACCESS_SET)) { |
| 849 elms->set(SETTER_INDEX, callbacks->get(1)); |
| 850 } |
| 756 break; | 851 break; |
| 757 } | 852 } |
| 758 case NORMAL: | 853 case NORMAL: |
| 759 // This is a data property. | 854 // This is a data property. |
| 760 elms->set(IS_ACCESSOR_INDEX, heap->false_value()); | 855 elms->set(IS_ACCESSOR_INDEX, heap->false_value()); |
| 761 elms->set(VALUE_INDEX, dictionary->ValueAt(entry)); | 856 elms->set(VALUE_INDEX, *GetElement(obj, index)); |
| 762 elms->set(WRITABLE_INDEX, heap->ToBoolean(!details.IsReadOnly())); | 857 elms->set(WRITABLE_INDEX, heap->ToBoolean(!details.IsReadOnly())); |
| 763 break; | 858 break; |
| 764 default: | 859 default: |
| 765 UNREACHABLE(); | 860 UNREACHABLE(); |
| 766 break; | 861 break; |
| 767 } | 862 } |
| 768 elms->set(ENUMERABLE_INDEX, heap->ToBoolean(!details.IsDontEnum())); | 863 elms->set(ENUMERABLE_INDEX, heap->ToBoolean(!details.IsDontEnum())); |
| 769 elms->set(CONFIGURABLE_INDEX, heap->ToBoolean(!details.IsDontDelete())); | 864 elms->set(CONFIGURABLE_INDEX, heap->ToBoolean(!details.IsDontDelete())); |
| 770 return *desc; | 865 return *desc; |
| 771 } | 866 } |
| 772 } | 867 } |
| 773 } | 868 } |
| 774 | 869 |
| 775 // Use recursive implementation to also traverse hidden prototypes | 870 // Use recursive implementation to also traverse hidden prototypes |
| 776 GetOwnPropertyImplementation(*obj, *name, &result); | 871 GetOwnPropertyImplementation(*obj, *name, &result); |
| 777 | 872 |
| 778 if (!result.IsProperty()) { | 873 if (!result.IsProperty()) { |
| 779 return heap->undefined_value(); | 874 return heap->undefined_value(); |
| 780 } | 875 } |
| 781 if (result.type() == CALLBACKS) { | 876 |
| 782 Object* structure = result.GetCallbackObject(); | 877 if (!CheckAccess(*obj, *name, &result, v8::ACCESS_HAS)) { |
| 783 if (structure->IsProxy() || structure->IsAccessorInfo()) { | 878 return heap->false_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 } | 879 } |
| 807 | 880 |
| 808 elms->set(ENUMERABLE_INDEX, heap->ToBoolean(!result.IsDontEnum())); | 881 elms->set(ENUMERABLE_INDEX, heap->ToBoolean(!result.IsDontEnum())); |
| 809 elms->set(CONFIGURABLE_INDEX, heap->ToBoolean(!result.IsDontDelete())); | 882 elms->set(CONFIGURABLE_INDEX, heap->ToBoolean(!result.IsDontDelete())); |
| 883 |
| 884 bool is_js_accessor = (result.type() == CALLBACKS) && |
| 885 (result.GetCallbackObject()->IsFixedArray()); |
| 886 |
| 887 if (is_js_accessor) { |
| 888 // __defineGetter__/__defineSetter__ callback. |
| 889 elms->set(IS_ACCESSOR_INDEX, heap->true_value()); |
| 890 |
| 891 FixedArray* structure = FixedArray::cast(result.GetCallbackObject()); |
| 892 if (CheckAccess(*obj, *name, &result, v8::ACCESS_GET)) { |
| 893 elms->set(GETTER_INDEX, structure->get(0)); |
| 894 } |
| 895 if (CheckAccess(*obj, *name, &result, v8::ACCESS_SET)) { |
| 896 elms->set(SETTER_INDEX, structure->get(1)); |
| 897 } |
| 898 } else { |
| 899 elms->set(IS_ACCESSOR_INDEX, heap->false_value()); |
| 900 elms->set(WRITABLE_INDEX, heap->ToBoolean(!result.IsReadOnly())); |
| 901 |
| 902 PropertyAttributes attrs; |
| 903 Object* value; |
| 904 // GetProperty will check access and report any violations. |
| 905 { MaybeObject* maybe_value = obj->GetProperty(*obj, &result, *name, &attrs); |
| 906 if (!maybe_value->ToObject(&value)) return maybe_value; |
| 907 } |
| 908 elms->set(VALUE_INDEX, value); |
| 909 } |
| 910 |
| 810 return *desc; | 911 return *desc; |
| 811 } | 912 } |
| 812 | 913 |
| 813 | 914 |
| 814 static MaybeObject* Runtime_PreventExtensions(RUNTIME_CALLING_CONVENTION) { | 915 static MaybeObject* Runtime_PreventExtensions(RUNTIME_CALLING_CONVENTION) { |
| 815 RUNTIME_GET_ISOLATE; | 916 RUNTIME_GET_ISOLATE; |
| 816 ASSERT(args.length() == 1); | 917 ASSERT(args.length() == 1); |
| 817 CONVERT_CHECKED(JSObject, obj, args[0]); | 918 CONVERT_CHECKED(JSObject, obj, args[0]); |
| 818 return obj->PreventExtensions(); | 919 return obj->PreventExtensions(); |
| 819 } | 920 } |
| 820 | 921 |
| 922 |
| 821 static MaybeObject* Runtime_IsExtensible(RUNTIME_CALLING_CONVENTION) { | 923 static MaybeObject* Runtime_IsExtensible(RUNTIME_CALLING_CONVENTION) { |
| 822 RUNTIME_GET_ISOLATE; | 924 RUNTIME_GET_ISOLATE; |
| 823 ASSERT(args.length() == 1); | 925 ASSERT(args.length() == 1); |
| 824 CONVERT_CHECKED(JSObject, obj, args[0]); | 926 CONVERT_CHECKED(JSObject, obj, args[0]); |
| 927 if (obj->IsJSGlobalProxy()) { |
| 928 Object* proto = obj->GetPrototype(); |
| 929 if (proto->IsNull()) return isolate->heap()->false_value(); |
| 930 ASSERT(proto->IsJSGlobalObject()); |
| 931 obj = JSObject::cast(proto); |
| 932 } |
| 825 return obj->map()->is_extensible() ? isolate->heap()->true_value() | 933 return obj->map()->is_extensible() ? isolate->heap()->true_value() |
| 826 : isolate->heap()->false_value(); | 934 : isolate->heap()->false_value(); |
| 827 } | 935 } |
| 828 | 936 |
| 829 | 937 |
| 830 static MaybeObject* Runtime_RegExpCompile(RUNTIME_CALLING_CONVENTION) { | 938 static MaybeObject* Runtime_RegExpCompile(RUNTIME_CALLING_CONVENTION) { |
| 831 RUNTIME_GET_ISOLATE; | 939 RUNTIME_GET_ISOLATE; |
| 832 HandleScope scope(isolate); | 940 HandleScope scope(isolate); |
| 833 ASSERT(args.length() == 3); | 941 ASSERT(args.length() == 3); |
| 834 CONVERT_ARG_CHECKED(JSRegExp, re, 0); | 942 CONVERT_ARG_CHECKED(JSRegExp, re, 0); |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1024 // that claims the property is absent. | 1132 // that claims the property is absent. |
| 1025 | 1133 |
| 1026 // Check for conflicting re-declarations. We cannot have | 1134 // Check for conflicting re-declarations. We cannot have |
| 1027 // conflicting types in case of intercepted properties because | 1135 // conflicting types in case of intercepted properties because |
| 1028 // they are absent. | 1136 // they are absent. |
| 1029 if (lookup.type() != INTERCEPTOR && | 1137 if (lookup.type() != INTERCEPTOR && |
| 1030 (lookup.IsReadOnly() || is_const_property)) { | 1138 (lookup.IsReadOnly() || is_const_property)) { |
| 1031 const char* type = (lookup.IsReadOnly()) ? "const" : "var"; | 1139 const char* type = (lookup.IsReadOnly()) ? "const" : "var"; |
| 1032 return ThrowRedeclarationError(isolate, type, name); | 1140 return ThrowRedeclarationError(isolate, type, name); |
| 1033 } | 1141 } |
| 1034 SetProperty(global, name, value, attributes); | 1142 Handle<Object> result = SetProperty(global, name, value, attributes); |
| 1143 if (result.is_null()) { |
| 1144 ASSERT(isolate->has_pending_exception()); |
| 1145 return Failure::Exception(); |
| 1146 } |
| 1035 } else { | 1147 } else { |
| 1036 // If a property with this name does not already exist on the | 1148 // If a property with this name does not already exist on the |
| 1037 // global object add the property locally. We take special | 1149 // global object add the property locally. We take special |
| 1038 // precautions to always add it as a local property even in case | 1150 // precautions to always add it as a local property even in case |
| 1039 // of callbacks in the prototype chain (this rules out using | 1151 // of callbacks in the prototype chain (this rules out using |
| 1040 // SetProperty). Also, we must use the handle-based version to | 1152 // SetProperty). Also, we must use the handle-based version to |
| 1041 // avoid GC issues. | 1153 // avoid GC issues. |
| 1042 SetLocalPropertyIgnoreAttributes(global, name, value, attributes); | 1154 Handle<Object> result = |
| 1155 SetLocalPropertyIgnoreAttributes(global, name, value, attributes); |
| 1156 if (result.is_null()) { |
| 1157 ASSERT(isolate->has_pending_exception()); |
| 1158 return Failure::Exception(); |
| 1159 } |
| 1043 } | 1160 } |
| 1044 } | 1161 } |
| 1045 | 1162 |
| 1163 ASSERT(!isolate->has_pending_exception()); |
| 1046 return isolate->heap()->undefined_value(); | 1164 return isolate->heap()->undefined_value(); |
| 1047 } | 1165 } |
| 1048 | 1166 |
| 1049 | 1167 |
| 1050 static MaybeObject* Runtime_DeclareContextSlot(RUNTIME_CALLING_CONVENTION) { | 1168 static MaybeObject* Runtime_DeclareContextSlot(RUNTIME_CALLING_CONVENTION) { |
| 1051 RUNTIME_GET_ISOLATE; | 1169 RUNTIME_GET_ISOLATE; |
| 1052 HandleScope scope(isolate); | 1170 HandleScope scope(isolate); |
| 1053 ASSERT(args.length() == 4); | 1171 ASSERT(args.length() == 4); |
| 1054 | 1172 |
| 1055 CONVERT_ARG_CHECKED(Context, context, 0); | 1173 CONVERT_ARG_CHECKED(Context, context, 0); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 1086 // the function context or the arguments object. | 1204 // the function context or the arguments object. |
| 1087 if (holder->IsContext()) { | 1205 if (holder->IsContext()) { |
| 1088 ASSERT(holder.is_identical_to(context)); | 1206 ASSERT(holder.is_identical_to(context)); |
| 1089 if (((attributes & READ_ONLY) == 0) || | 1207 if (((attributes & READ_ONLY) == 0) || |
| 1090 context->get(index)->IsTheHole()) { | 1208 context->get(index)->IsTheHole()) { |
| 1091 context->set(index, *initial_value); | 1209 context->set(index, *initial_value); |
| 1092 } | 1210 } |
| 1093 } else { | 1211 } else { |
| 1094 // The holder is an arguments object. | 1212 // The holder is an arguments object. |
| 1095 Handle<JSObject> arguments(Handle<JSObject>::cast(holder)); | 1213 Handle<JSObject> arguments(Handle<JSObject>::cast(holder)); |
| 1096 SetElement(arguments, index, initial_value); | 1214 Handle<Object> result = SetElement(arguments, index, initial_value); |
| 1215 if (result.is_null()) return Failure::Exception(); |
| 1097 } | 1216 } |
| 1098 } else { | 1217 } else { |
| 1099 // Slow case: The property is not in the FixedArray part of the context. | 1218 // Slow case: The property is not in the FixedArray part of the context. |
| 1100 Handle<JSObject> context_ext = Handle<JSObject>::cast(holder); | 1219 Handle<JSObject> context_ext = Handle<JSObject>::cast(holder); |
| 1101 SetProperty(context_ext, name, initial_value, mode); | 1220 Handle<Object> result = |
| 1221 SetProperty(context_ext, name, initial_value, mode); |
| 1222 if (result.is_null()) return Failure::Exception(); |
| 1102 } | 1223 } |
| 1103 } | 1224 } |
| 1104 | 1225 |
| 1105 } else { | 1226 } else { |
| 1106 // The property is not in the function context. It needs to be | 1227 // The property is not in the function context. It needs to be |
| 1107 // "declared" in the function context's extension context, or in the | 1228 // "declared" in the function context's extension context, or in the |
| 1108 // global context. | 1229 // global context. |
| 1109 Handle<JSObject> context_ext; | 1230 Handle<JSObject> context_ext; |
| 1110 if (context->has_extension()) { | 1231 if (context->has_extension()) { |
| 1111 // The function context's extension context exists - use it. | 1232 // The function context's extension context exists - use it. |
| 1112 context_ext = Handle<JSObject>(context->extension()); | 1233 context_ext = Handle<JSObject>(context->extension()); |
| 1113 } else { | 1234 } else { |
| 1114 // The function context's extension context does not exists - allocate | 1235 // The function context's extension context does not exists - allocate |
| 1115 // it. | 1236 // it. |
| 1116 context_ext = isolate->factory()->NewJSObject( | 1237 context_ext = isolate->factory()->NewJSObject( |
| 1117 isolate->context_extension_function()); | 1238 isolate->context_extension_function()); |
| 1118 // And store it in the extension slot. | 1239 // And store it in the extension slot. |
| 1119 context->set_extension(*context_ext); | 1240 context->set_extension(*context_ext); |
| 1120 } | 1241 } |
| 1121 ASSERT(*context_ext != NULL); | 1242 ASSERT(*context_ext != NULL); |
| 1122 | 1243 |
| 1123 // Declare the property by setting it to the initial value if provided, | 1244 // Declare the property by setting it to the initial value if provided, |
| 1124 // or undefined, and use the correct mode (e.g. READ_ONLY attribute for | 1245 // or undefined, and use the correct mode (e.g. READ_ONLY attribute for |
| 1125 // constant declarations). | 1246 // constant declarations). |
| 1126 ASSERT(!context_ext->HasLocalProperty(*name)); | 1247 ASSERT(!context_ext->HasLocalProperty(*name)); |
| 1127 Handle<Object> value(isolate->heap()->undefined_value(), isolate); | 1248 Handle<Object> value(isolate->heap()->undefined_value(), isolate); |
| 1128 if (*initial_value != NULL) value = initial_value; | 1249 if (*initial_value != NULL) value = initial_value; |
| 1129 SetProperty(context_ext, name, value, mode); | 1250 Handle<Object> result = SetProperty(context_ext, name, value, mode); |
| 1130 ASSERT(context_ext->GetLocalPropertyAttribute(*name) == mode); | 1251 if (result.is_null()) return Failure::Exception(); |
| 1131 } | 1252 } |
| 1132 | 1253 |
| 1133 return isolate->heap()->undefined_value(); | 1254 return isolate->heap()->undefined_value(); |
| 1134 } | 1255 } |
| 1135 | 1256 |
| 1136 | 1257 |
| 1137 static MaybeObject* Runtime_InitializeVarGlobal(RUNTIME_CALLING_CONVENTION) { | 1258 static MaybeObject* Runtime_InitializeVarGlobal(RUNTIME_CALLING_CONVENTION) { |
| 1138 RUNTIME_GET_ISOLATE; | 1259 RUNTIME_GET_ISOLATE; |
| 1139 NoHandleAllocation nha; | 1260 NoHandleAllocation nha; |
| 1140 | 1261 |
| (...skipping 2498 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3639 value = JSGlobalPropertyCell::cast(value)->value(); | 3760 value = JSGlobalPropertyCell::cast(value)->value(); |
| 3640 if (!value->IsTheHole()) return value; | 3761 if (!value->IsTheHole()) return value; |
| 3641 // If value is the hole do the general lookup. | 3762 // If value is the hole do the general lookup. |
| 3642 } | 3763 } |
| 3643 } | 3764 } |
| 3644 } else if (args[0]->IsString() && args[1]->IsSmi()) { | 3765 } else if (args[0]->IsString() && args[1]->IsSmi()) { |
| 3645 // Fast case for string indexing using [] with a smi index. | 3766 // Fast case for string indexing using [] with a smi index. |
| 3646 HandleScope scope(isolate); | 3767 HandleScope scope(isolate); |
| 3647 Handle<String> str = args.at<String>(0); | 3768 Handle<String> str = args.at<String>(0); |
| 3648 int index = Smi::cast(args[1])->value(); | 3769 int index = Smi::cast(args[1])->value(); |
| 3649 Handle<Object> result = GetCharAt(str, index); | 3770 if (index >= 0 && index < str->length()) { |
| 3650 return *result; | 3771 Handle<Object> result = GetCharAt(str, index); |
| 3772 return *result; |
| 3773 } |
| 3651 } | 3774 } |
| 3652 | 3775 |
| 3653 // Fall back to GetObjectProperty. | 3776 // Fall back to GetObjectProperty. |
| 3654 return Runtime::GetObjectProperty(isolate, | 3777 return Runtime::GetObjectProperty(isolate, |
| 3655 args.at<Object>(0), | 3778 args.at<Object>(0), |
| 3656 args.at<Object>(1)); | 3779 args.at<Object>(1)); |
| 3657 } | 3780 } |
| 3658 | 3781 |
| 3659 | 3782 // Implements part of 8.12.9 DefineOwnProperty. |
| 3783 // There are 3 cases that lead here: |
| 3784 // Step 4b - define a new accessor property. |
| 3785 // Steps 9c & 12 - replace an existing data property with an accessor property. |
| 3786 // Step 12 - update an existing accessor property with an accessor or generic |
| 3787 // descriptor. |
| 3660 static MaybeObject* Runtime_DefineOrRedefineAccessorProperty( | 3788 static MaybeObject* Runtime_DefineOrRedefineAccessorProperty( |
| 3661 RUNTIME_CALLING_CONVENTION) { | 3789 RUNTIME_CALLING_CONVENTION) { |
| 3662 RUNTIME_GET_ISOLATE; | 3790 RUNTIME_GET_ISOLATE; |
| 3663 ASSERT(args.length() == 5); | 3791 ASSERT(args.length() == 5); |
| 3664 HandleScope scope(isolate); | 3792 HandleScope scope(isolate); |
| 3665 CONVERT_ARG_CHECKED(JSObject, obj, 0); | 3793 CONVERT_ARG_CHECKED(JSObject, obj, 0); |
| 3666 CONVERT_CHECKED(String, name, args[1]); | 3794 CONVERT_CHECKED(String, name, args[1]); |
| 3667 CONVERT_CHECKED(Smi, flag_setter, args[2]); | 3795 CONVERT_CHECKED(Smi, flag_setter, args[2]); |
| 3668 Object* fun = args[3]; | 3796 Object* fun = args[3]; |
| 3669 RUNTIME_ASSERT(fun->IsJSFunction() || fun->IsUndefined()); | 3797 RUNTIME_ASSERT(fun->IsJSFunction() || fun->IsUndefined()); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 3683 || result.type() == CONSTANT_FUNCTION)) { | 3811 || result.type() == CONSTANT_FUNCTION)) { |
| 3684 Object* ok; | 3812 Object* ok; |
| 3685 { MaybeObject* maybe_ok = | 3813 { MaybeObject* maybe_ok = |
| 3686 obj->DeleteProperty(name, JSObject::NORMAL_DELETION); | 3814 obj->DeleteProperty(name, JSObject::NORMAL_DELETION); |
| 3687 if (!maybe_ok->ToObject(&ok)) return maybe_ok; | 3815 if (!maybe_ok->ToObject(&ok)) return maybe_ok; |
| 3688 } | 3816 } |
| 3689 } | 3817 } |
| 3690 return obj->DefineAccessor(name, flag_setter->value() == 0, fun, attr); | 3818 return obj->DefineAccessor(name, flag_setter->value() == 0, fun, attr); |
| 3691 } | 3819 } |
| 3692 | 3820 |
| 3821 // Implements part of 8.12.9 DefineOwnProperty. |
| 3822 // There are 3 cases that lead here: |
| 3823 // Step 4a - define a new data property. |
| 3824 // Steps 9b & 12 - replace an existing accessor property with a data property. |
| 3825 // Step 12 - update an existing data property with a data or generic |
| 3826 // descriptor. |
| 3693 static MaybeObject* Runtime_DefineOrRedefineDataProperty( | 3827 static MaybeObject* Runtime_DefineOrRedefineDataProperty( |
| 3694 RUNTIME_CALLING_CONVENTION) { | 3828 RUNTIME_CALLING_CONVENTION) { |
| 3695 RUNTIME_GET_ISOLATE; | 3829 RUNTIME_GET_ISOLATE; |
| 3696 ASSERT(args.length() == 4); | 3830 ASSERT(args.length() == 4); |
| 3697 HandleScope scope(isolate); | 3831 HandleScope scope(isolate); |
| 3698 CONVERT_ARG_CHECKED(JSObject, js_object, 0); | 3832 CONVERT_ARG_CHECKED(JSObject, js_object, 0); |
| 3699 CONVERT_ARG_CHECKED(String, name, 1); | 3833 CONVERT_ARG_CHECKED(String, name, 1); |
| 3700 Handle<Object> obj_value = args.at<Object>(2); | 3834 Handle<Object> obj_value = args.at<Object>(2); |
| 3701 | 3835 |
| 3702 CONVERT_CHECKED(Smi, flag, args[3]); | 3836 CONVERT_CHECKED(Smi, flag, args[3]); |
| 3703 int unchecked = flag->value(); | 3837 int unchecked = flag->value(); |
| 3704 RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); | 3838 RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); |
| 3705 | 3839 |
| 3706 PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked); | 3840 PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked); |
| 3707 | 3841 |
| 3708 // Check if this is an element. | 3842 // Check if this is an element. |
| 3709 uint32_t index; | 3843 uint32_t index; |
| 3710 bool is_element = name->AsArrayIndex(&index); | 3844 bool is_element = name->AsArrayIndex(&index); |
| 3711 | 3845 |
| 3712 // Special case for elements if any of the flags are true. | 3846 // Special case for elements if any of the flags are true. |
| 3713 // If elements are in fast case we always implicitly assume that: | 3847 // If elements are in fast case we always implicitly assume that: |
| 3714 // DONT_DELETE: false, DONT_ENUM: false, READ_ONLY: false. | 3848 // DONT_DELETE: false, DONT_ENUM: false, READ_ONLY: false. |
| 3715 if (((unchecked & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0) && | 3849 if (((unchecked & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0) && |
| 3716 is_element) { | 3850 is_element) { |
| 3717 // Normalize the elements to enable attributes on the property. | 3851 // Normalize the elements to enable attributes on the property. |
| 3852 if (js_object->IsJSGlobalProxy()) { |
| 3853 Handle<Object> proto(js_object->GetPrototype()); |
| 3854 // If proxy is detached, ignore the assignment. Alternatively, |
| 3855 // we could throw an exception. |
| 3856 if (proto->IsNull()) return *obj_value; |
| 3857 js_object = Handle<JSObject>::cast(proto); |
| 3858 } |
| 3718 NormalizeElements(js_object); | 3859 NormalizeElements(js_object); |
| 3719 Handle<NumberDictionary> dictionary(js_object->element_dictionary()); | 3860 Handle<NumberDictionary> dictionary(js_object->element_dictionary()); |
| 3720 // Make sure that we never go back to fast case. | 3861 // Make sure that we never go back to fast case. |
| 3721 dictionary->set_requires_slow_elements(); | 3862 dictionary->set_requires_slow_elements(); |
| 3722 PropertyDetails details = PropertyDetails(attr, NORMAL); | 3863 PropertyDetails details = PropertyDetails(attr, NORMAL); |
| 3723 NumberDictionarySet(dictionary, index, obj_value, details); | 3864 NumberDictionarySet(dictionary, index, obj_value, details); |
| 3865 return *obj_value; |
| 3724 } | 3866 } |
| 3725 | 3867 |
| 3726 LookupResult result; | 3868 LookupResult result; |
| 3727 js_object->LookupRealNamedProperty(*name, &result); | 3869 js_object->LookupRealNamedProperty(*name, &result); |
| 3728 | 3870 |
| 3729 // Take special care when attributes are different and there is already | 3871 // Take special care when attributes are different and there is already |
| 3730 // a property. For simplicity we normalize the property which enables us | 3872 // a property. For simplicity we normalize the property which enables us |
| 3731 // to not worry about changing the instance_descriptor and creating a new | 3873 // to not worry about changing the instance_descriptor and creating a new |
| 3732 // map. The current version of SetObjectProperty does not handle attributes | 3874 // map. The current version of SetObjectProperty does not handle attributes |
| 3733 // correctly in the case where a property is a field and is reset with | 3875 // correctly in the case where a property is a field and is reset with |
| 3734 // new attributes. | 3876 // new attributes. |
| 3735 if (result.IsProperty() && | 3877 if (result.IsProperty() && |
| 3736 (attr != result.GetAttributes() || result.type() == CALLBACKS)) { | 3878 (attr != result.GetAttributes() || result.type() == CALLBACKS)) { |
| 3737 // New attributes - normalize to avoid writing to instance descriptor | 3879 // New attributes - normalize to avoid writing to instance descriptor |
| 3880 if (js_object->IsJSGlobalProxy()) { |
| 3881 // Since the result is a property, the prototype will exist so |
| 3882 // we don't have to check for null. |
| 3883 js_object = Handle<JSObject>(JSObject::cast(js_object->GetPrototype())); |
| 3884 } |
| 3738 NormalizeProperties(js_object, CLEAR_INOBJECT_PROPERTIES, 0); | 3885 NormalizeProperties(js_object, CLEAR_INOBJECT_PROPERTIES, 0); |
| 3739 // Use IgnoreAttributes version since a readonly property may be | 3886 // Use IgnoreAttributes version since a readonly property may be |
| 3740 // overridden and SetProperty does not allow this. | 3887 // overridden and SetProperty does not allow this. |
| 3741 return js_object->SetLocalPropertyIgnoreAttributes(*name, | 3888 return js_object->SetLocalPropertyIgnoreAttributes(*name, |
| 3742 *obj_value, | 3889 *obj_value, |
| 3743 attr); | 3890 attr); |
| 3744 } | 3891 } |
| 3745 | 3892 |
| 3746 return Runtime::SetObjectProperty(isolate, js_object, name, obj_value, attr); | 3893 return Runtime::SetObjectProperty(isolate, js_object, name, obj_value, attr); |
| 3747 } | 3894 } |
| (...skipping 608 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4356 return *object; | 4503 return *object; |
| 4357 } | 4504 } |
| 4358 | 4505 |
| 4359 | 4506 |
| 4360 static MaybeObject* Runtime_ToSlowProperties(RUNTIME_CALLING_CONVENTION) { | 4507 static MaybeObject* Runtime_ToSlowProperties(RUNTIME_CALLING_CONVENTION) { |
| 4361 RUNTIME_GET_ISOLATE; | 4508 RUNTIME_GET_ISOLATE; |
| 4362 HandleScope scope(isolate); | 4509 HandleScope scope(isolate); |
| 4363 | 4510 |
| 4364 ASSERT(args.length() == 1); | 4511 ASSERT(args.length() == 1); |
| 4365 Handle<Object> object = args.at<Object>(0); | 4512 Handle<Object> object = args.at<Object>(0); |
| 4366 if (object->IsJSObject()) { | 4513 if (object->IsJSObject() && !object->IsJSGlobalProxy()) { |
| 4367 Handle<JSObject> js_object = Handle<JSObject>::cast(object); | 4514 Handle<JSObject> js_object = Handle<JSObject>::cast(object); |
| 4368 NormalizeProperties(js_object, CLEAR_INOBJECT_PROPERTIES, 0); | 4515 NormalizeProperties(js_object, CLEAR_INOBJECT_PROPERTIES, 0); |
| 4369 } | 4516 } |
| 4370 return *object; | 4517 return *object; |
| 4371 } | 4518 } |
| 4372 | 4519 |
| 4373 | 4520 |
| 4374 static MaybeObject* Runtime_ToBool(RUNTIME_CALLING_CONVENTION) { | 4521 static MaybeObject* Runtime_ToBool(RUNTIME_CALLING_CONVENTION) { |
| 4375 RUNTIME_GET_ISOLATE; | 4522 RUNTIME_GET_ISOLATE; |
| 4376 NoHandleAllocation ha; | 4523 NoHandleAllocation ha; |
| (...skipping 2471 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6848 isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, | 6995 isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, |
| 6849 context, | 6996 context, |
| 6850 pretenure_flag); | 6997 pretenure_flag); |
| 6851 return *result; | 6998 return *result; |
| 6852 } | 6999 } |
| 6853 | 7000 |
| 6854 static MaybeObject* Runtime_NewObjectFromBound(RUNTIME_CALLING_CONVENTION) { | 7001 static MaybeObject* Runtime_NewObjectFromBound(RUNTIME_CALLING_CONVENTION) { |
| 6855 RUNTIME_GET_ISOLATE; | 7002 RUNTIME_GET_ISOLATE; |
| 6856 HandleScope scope(isolate); | 7003 HandleScope scope(isolate); |
| 6857 ASSERT(args.length() == 2); | 7004 ASSERT(args.length() == 2); |
| 7005 // First argument is a function to use as a constructor. |
| 6858 CONVERT_ARG_CHECKED(JSFunction, function, 0); | 7006 CONVERT_ARG_CHECKED(JSFunction, function, 0); |
| 6859 CONVERT_ARG_CHECKED(JSArray, params, 1); | |
| 6860 | 7007 |
| 6861 RUNTIME_ASSERT(params->HasFastElements()); | 7008 // Second argument is either null or an array of bound arguments. |
| 6862 FixedArray* fixed = FixedArray::cast(params->elements()); | 7009 FixedArray* bound_args = NULL; |
| 7010 int bound_argc = 0; |
| 7011 if (!args[1]->IsNull()) { |
| 7012 CONVERT_ARG_CHECKED(JSArray, params, 1); |
| 7013 RUNTIME_ASSERT(params->HasFastElements()); |
| 7014 bound_args = FixedArray::cast(params->elements()); |
| 7015 bound_argc = Smi::cast(params->length())->value(); |
| 7016 } |
| 6863 | 7017 |
| 6864 int fixed_length = Smi::cast(params->length())->value(); | 7018 // Find frame containing arguments passed to the caller. |
| 6865 SmartPointer<Object**> param_data(NewArray<Object**>(fixed_length)); | 7019 JavaScriptFrameIterator it; |
| 6866 for (int i = 0; i < fixed_length; i++) { | 7020 JavaScriptFrame* frame = it.frame(); |
| 6867 Handle<Object> val(fixed->get(i), isolate); | 7021 ASSERT(!frame->is_optimized()); |
| 7022 it.AdvanceToArgumentsFrame(); |
| 7023 frame = it.frame(); |
| 7024 int argc = frame->GetProvidedParametersCount(); |
| 7025 |
| 7026 // Prepend bound arguments to caller's arguments. |
| 7027 int total_argc = bound_argc + argc; |
| 7028 SmartPointer<Object**> param_data(NewArray<Object**>(total_argc)); |
| 7029 for (int i = 0; i < bound_argc; i++) { |
| 7030 Handle<Object> val = Handle<Object>(bound_args->get(i)); |
| 6868 param_data[i] = val.location(); | 7031 param_data[i] = val.location(); |
| 6869 } | 7032 } |
| 7033 for (int i = 0; i < argc; i++) { |
| 7034 Handle<Object> val = Handle<Object>(frame->GetParameter(i)); |
| 7035 param_data[bound_argc + i] = val.location(); |
| 7036 } |
| 6870 | 7037 |
| 6871 bool exception = false; | 7038 bool exception = false; |
| 6872 Handle<Object> result = Execution::New( | 7039 Handle<Object> result = |
| 6873 function, fixed_length, *param_data, &exception); | 7040 Execution::New(function, total_argc, *param_data, &exception); |
| 6874 if (exception) { | 7041 if (exception) { |
| 6875 return Failure::Exception(); | 7042 return Failure::Exception(); |
| 6876 } | 7043 } |
| 7044 |
| 6877 ASSERT(!result.is_null()); | 7045 ASSERT(!result.is_null()); |
| 6878 return *result; | 7046 return *result; |
| 6879 } | 7047 } |
| 6880 | 7048 |
| 6881 | 7049 |
| 6882 static void TrySettingInlineConstructStub(Isolate* isolate, | 7050 static void TrySettingInlineConstructStub(Isolate* isolate, |
| 6883 Handle<JSFunction> function) { | 7051 Handle<JSFunction> function) { |
| 6884 Handle<Object> prototype = isolate->factory()->null_value(); | 7052 Handle<Object> prototype = isolate->factory()->null_value(); |
| 6885 if (function->has_instance_prototype()) { | 7053 if (function->has_instance_prototype()) { |
| 6886 prototype = Handle<Object>(function->instance_prototype(), isolate); | 7054 prototype = Handle<Object>(function->instance_prototype(), isolate); |
| (...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7185 JavaScriptFrameIterator it; | 7353 JavaScriptFrameIterator it; |
| 7186 JavaScriptFrame* frame = it.frame(); | 7354 JavaScriptFrame* frame = it.frame(); |
| 7187 ASSERT(frame->function() == *function); | 7355 ASSERT(frame->function() == *function); |
| 7188 ASSERT(frame->LookupCode(isolate) == *unoptimized); | 7356 ASSERT(frame->LookupCode(isolate) == *unoptimized); |
| 7189 ASSERT(unoptimized->contains(frame->pc())); | 7357 ASSERT(unoptimized->contains(frame->pc())); |
| 7190 | 7358 |
| 7191 // Use linear search of the unoptimized code's stack check table to find | 7359 // Use linear search of the unoptimized code's stack check table to find |
| 7192 // the AST id matching the PC. | 7360 // the AST id matching the PC. |
| 7193 Address start = unoptimized->instruction_start(); | 7361 Address start = unoptimized->instruction_start(); |
| 7194 unsigned target_pc_offset = static_cast<unsigned>(frame->pc() - start); | 7362 unsigned target_pc_offset = static_cast<unsigned>(frame->pc() - start); |
| 7195 Address table_cursor = start + unoptimized->stack_check_table_start(); | 7363 Address table_cursor = start + unoptimized->stack_check_table_offset(); |
| 7196 uint32_t table_length = Memory::uint32_at(table_cursor); | 7364 uint32_t table_length = Memory::uint32_at(table_cursor); |
| 7197 table_cursor += kIntSize; | 7365 table_cursor += kIntSize; |
| 7198 for (unsigned i = 0; i < table_length; ++i) { | 7366 for (unsigned i = 0; i < table_length; ++i) { |
| 7199 // Table entries are (AST id, pc offset) pairs. | 7367 // Table entries are (AST id, pc offset) pairs. |
| 7200 uint32_t pc_offset = Memory::uint32_at(table_cursor + kIntSize); | 7368 uint32_t pc_offset = Memory::uint32_at(table_cursor + kIntSize); |
| 7201 if (pc_offset == target_pc_offset) { | 7369 if (pc_offset == target_pc_offset) { |
| 7202 ast_id = static_cast<int>(Memory::uint32_at(table_cursor)); | 7370 ast_id = static_cast<int>(Memory::uint32_at(table_cursor)); |
| 7203 break; | 7371 break; |
| 7204 } | 7372 } |
| 7205 table_cursor += 2 * kIntSize; | 7373 table_cursor += 2 * kIntSize; |
| (...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7533 | 7701 |
| 7534 int index; | 7702 int index; |
| 7535 PropertyAttributes attributes; | 7703 PropertyAttributes attributes; |
| 7536 ContextLookupFlags flags = FOLLOW_CHAINS; | 7704 ContextLookupFlags flags = FOLLOW_CHAINS; |
| 7537 Handle<Object> holder = context->Lookup(name, flags, &index, &attributes); | 7705 Handle<Object> holder = context->Lookup(name, flags, &index, &attributes); |
| 7538 | 7706 |
| 7539 if (index >= 0) { | 7707 if (index >= 0) { |
| 7540 if (holder->IsContext()) { | 7708 if (holder->IsContext()) { |
| 7541 // Ignore if read_only variable. | 7709 // Ignore if read_only variable. |
| 7542 if ((attributes & READ_ONLY) == 0) { | 7710 if ((attributes & READ_ONLY) == 0) { |
| 7543 Handle<Context>::cast(holder)->set(index, *value); | 7711 // Context is a fixed array and set cannot fail. |
| 7712 Context::cast(*holder)->set(index, *value); |
| 7544 } | 7713 } |
| 7545 } else { | 7714 } else { |
| 7546 ASSERT((attributes & READ_ONLY) == 0); | 7715 ASSERT((attributes & READ_ONLY) == 0); |
| 7547 Handle<JSObject>::cast(holder)->SetElement(index, *value)-> | 7716 Handle<Object> result = |
| 7548 ToObjectUnchecked(); | 7717 SetElement(Handle<JSObject>::cast(holder), index, value); |
| 7718 if (result.is_null()) { |
| 7719 ASSERT(isolate->has_pending_exception()); |
| 7720 return Failure::Exception(); |
| 7721 } |
| 7549 } | 7722 } |
| 7550 return *value; | 7723 return *value; |
| 7551 } | 7724 } |
| 7552 | 7725 |
| 7553 // Slow case: The property is not in a FixedArray context. | 7726 // Slow case: The property is not in a FixedArray context. |
| 7554 // It is either in an JSObject extension context or it was not found. | 7727 // It is either in an JSObject extension context or it was not found. |
| 7555 Handle<JSObject> context_ext; | 7728 Handle<JSObject> context_ext; |
| 7556 | 7729 |
| 7557 if (!holder.is_null()) { | 7730 if (!holder.is_null()) { |
| 7558 // The property exists in the extension context. | 7731 // The property exists in the extension context. |
| 7559 context_ext = Handle<JSObject>::cast(holder); | 7732 context_ext = Handle<JSObject>::cast(holder); |
| 7560 } else { | 7733 } else { |
| 7561 // The property was not found. It needs to be stored in the global context. | 7734 // The property was not found. It needs to be stored in the global context. |
| 7562 ASSERT(attributes == ABSENT); | 7735 ASSERT(attributes == ABSENT); |
| 7563 attributes = NONE; | 7736 attributes = NONE; |
| 7564 context_ext = Handle<JSObject>(isolate->context()->global()); | 7737 context_ext = Handle<JSObject>(isolate->context()->global()); |
| 7565 } | 7738 } |
| 7566 | 7739 |
| 7567 // Set the property, but ignore if read_only variable on the context | 7740 // Set the property, but ignore if read_only variable on the context |
| 7568 // extension object itself. | 7741 // extension object itself. |
| 7569 if ((attributes & READ_ONLY) == 0 || | 7742 if ((attributes & READ_ONLY) == 0 || |
| 7570 (context_ext->GetLocalPropertyAttribute(*name) == ABSENT)) { | 7743 (context_ext->GetLocalPropertyAttribute(*name) == ABSENT)) { |
| 7571 Handle<Object> set = SetProperty(context_ext, name, value, NONE); | 7744 Handle<Object> result = SetProperty(context_ext, name, value, NONE); |
| 7572 if (set.is_null()) { | 7745 if (result.is_null()) { |
| 7573 // Failure::Exception is converted to a null handle in the | 7746 // Failure::Exception is converted to a null handle in the |
| 7574 // handle-based methods such as SetProperty. We therefore need | 7747 // handle-based methods such as SetProperty. We therefore need |
| 7575 // to convert null handles back to exceptions. | 7748 // to convert null handles back to exceptions. |
| 7576 ASSERT(isolate->has_pending_exception()); | 7749 ASSERT(isolate->has_pending_exception()); |
| 7577 return Failure::Exception(); | 7750 return Failure::Exception(); |
| 7578 } | 7751 } |
| 7579 } | 7752 } |
| 7580 return *value; | 7753 return *value; |
| 7581 } | 7754 } |
| 7582 | 7755 |
| (...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7881 static MaybeObject* Runtime_CompileString(RUNTIME_CALLING_CONVENTION) { | 8054 static MaybeObject* Runtime_CompileString(RUNTIME_CALLING_CONVENTION) { |
| 7882 RUNTIME_GET_ISOLATE; | 8055 RUNTIME_GET_ISOLATE; |
| 7883 HandleScope scope(isolate); | 8056 HandleScope scope(isolate); |
| 7884 ASSERT_EQ(1, args.length()); | 8057 ASSERT_EQ(1, args.length()); |
| 7885 CONVERT_ARG_CHECKED(String, source, 0); | 8058 CONVERT_ARG_CHECKED(String, source, 0); |
| 7886 | 8059 |
| 7887 // Compile source string in the global context. | 8060 // Compile source string in the global context. |
| 7888 Handle<Context> context(isolate->context()->global_context()); | 8061 Handle<Context> context(isolate->context()->global_context()); |
| 7889 Handle<SharedFunctionInfo> shared = Compiler::CompileEval(source, | 8062 Handle<SharedFunctionInfo> shared = Compiler::CompileEval(source, |
| 7890 context, | 8063 context, |
| 7891 true); | 8064 true, |
| 8065 kNonStrictMode); |
| 7892 if (shared.is_null()) return Failure::Exception(); | 8066 if (shared.is_null()) return Failure::Exception(); |
| 7893 Handle<JSFunction> fun = | 8067 Handle<JSFunction> fun = |
| 7894 isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, | 8068 isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, |
| 7895 context, | 8069 context, |
| 7896 NOT_TENURED); | 8070 NOT_TENURED); |
| 7897 return *fun; | 8071 return *fun; |
| 7898 } | 8072 } |
| 7899 | 8073 |
| 7900 | 8074 |
| 7901 static ObjectPair CompileGlobalEval(Isolate* isolate, | 8075 static ObjectPair CompileGlobalEval(Isolate* isolate, |
| 7902 Handle<String> source, | 8076 Handle<String> source, |
| 7903 Handle<Object> receiver) { | 8077 Handle<Object> receiver, |
| 8078 StrictModeFlag mode) { |
| 7904 // Deal with a normal eval call with a string argument. Compile it | 8079 // Deal with a normal eval call with a string argument. Compile it |
| 7905 // and return the compiled function bound in the local context. | 8080 // and return the compiled function bound in the local context. |
| 7906 Handle<SharedFunctionInfo> shared = Compiler::CompileEval( | 8081 Handle<SharedFunctionInfo> shared = Compiler::CompileEval( |
| 7907 source, | 8082 source, |
| 7908 Handle<Context>(isolate->context()), | 8083 Handle<Context>(isolate->context()), |
| 7909 isolate->context()->IsGlobalContext()); | 8084 isolate->context()->IsGlobalContext(), |
| 8085 mode); |
| 7910 if (shared.is_null()) return MakePair(Failure::Exception(), NULL); | 8086 if (shared.is_null()) return MakePair(Failure::Exception(), NULL); |
| 7911 Handle<JSFunction> compiled = | 8087 Handle<JSFunction> compiled = |
| 7912 isolate->factory()->NewFunctionFromSharedFunctionInfo( | 8088 isolate->factory()->NewFunctionFromSharedFunctionInfo( |
| 7913 shared, Handle<Context>(isolate->context()), NOT_TENURED); | 8089 shared, Handle<Context>(isolate->context()), NOT_TENURED); |
| 7914 return MakePair(*compiled, *receiver); | 8090 return MakePair(*compiled, *receiver); |
| 7915 } | 8091 } |
| 7916 | 8092 |
| 7917 | 8093 |
| 7918 static ObjectPair Runtime_ResolvePossiblyDirectEval( | 8094 static ObjectPair Runtime_ResolvePossiblyDirectEval( |
| 7919 RUNTIME_CALLING_CONVENTION) { | 8095 RUNTIME_CALLING_CONVENTION) { |
| 7920 RUNTIME_GET_ISOLATE; | 8096 RUNTIME_GET_ISOLATE; |
| 7921 ASSERT(args.length() == 3); | 8097 ASSERT(args.length() == 4); |
| 7922 if (!args[0]->IsJSFunction()) { | 8098 if (!args[0]->IsJSFunction()) { |
| 7923 return MakePair(isolate->ThrowIllegalOperation(), NULL); | 8099 return MakePair(isolate->ThrowIllegalOperation(), NULL); |
| 7924 } | 8100 } |
| 7925 | 8101 |
| 7926 HandleScope scope(isolate); | 8102 HandleScope scope(isolate); |
| 7927 Handle<JSFunction> callee = args.at<JSFunction>(0); | 8103 Handle<JSFunction> callee = args.at<JSFunction>(0); |
| 7928 Handle<Object> receiver; // Will be overwritten. | 8104 Handle<Object> receiver; // Will be overwritten. |
| 7929 | 8105 |
| 7930 // Compute the calling context. | 8106 // Compute the calling context. |
| 7931 Handle<Context> context = Handle<Context>(isolate->context(), isolate); | 8107 Handle<Context> context = Handle<Context>(isolate->context(), isolate); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7980 } | 8156 } |
| 7981 | 8157 |
| 7982 // 'eval' is bound in the global context, but it may have been overwritten. | 8158 // 'eval' is bound in the global context, but it may have been overwritten. |
| 7983 // Compare it to the builtin 'GlobalEval' function to make sure. | 8159 // Compare it to the builtin 'GlobalEval' function to make sure. |
| 7984 if (*callee != isolate->global_context()->global_eval_fun() || | 8160 if (*callee != isolate->global_context()->global_eval_fun() || |
| 7985 !args[1]->IsString()) { | 8161 !args[1]->IsString()) { |
| 7986 return MakePair(*callee, | 8162 return MakePair(*callee, |
| 7987 isolate->context()->global()->global_receiver()); | 8163 isolate->context()->global()->global_receiver()); |
| 7988 } | 8164 } |
| 7989 | 8165 |
| 7990 return CompileGlobalEval(isolate, args.at<String>(1), args.at<Object>(2)); | 8166 ASSERT(args[3]->IsSmi()); |
| 8167 return CompileGlobalEval(isolate, |
| 8168 args.at<String>(1), |
| 8169 args.at<Object>(2), |
| 8170 static_cast<StrictModeFlag>( |
| 8171 Smi::cast(args[3])->value())); |
| 7991 } | 8172 } |
| 7992 | 8173 |
| 7993 | 8174 |
| 7994 static ObjectPair Runtime_ResolvePossiblyDirectEvalNoLookup( | 8175 static ObjectPair Runtime_ResolvePossiblyDirectEvalNoLookup( |
| 7995 RUNTIME_CALLING_CONVENTION) { | 8176 RUNTIME_CALLING_CONVENTION) { |
| 7996 RUNTIME_GET_ISOLATE; | 8177 RUNTIME_GET_ISOLATE; |
| 7997 ASSERT(args.length() == 3); | 8178 ASSERT(args.length() == 4); |
| 7998 if (!args[0]->IsJSFunction()) { | 8179 if (!args[0]->IsJSFunction()) { |
| 7999 return MakePair(isolate->ThrowIllegalOperation(), NULL); | 8180 return MakePair(isolate->ThrowIllegalOperation(), NULL); |
| 8000 } | 8181 } |
| 8001 | 8182 |
| 8002 HandleScope scope(isolate); | 8183 HandleScope scope(isolate); |
| 8003 Handle<JSFunction> callee = args.at<JSFunction>(0); | 8184 Handle<JSFunction> callee = args.at<JSFunction>(0); |
| 8004 | 8185 |
| 8005 // 'eval' is bound in the global context, but it may have been overwritten. | 8186 // 'eval' is bound in the global context, but it may have been overwritten. |
| 8006 // Compare it to the builtin 'GlobalEval' function to make sure. | 8187 // Compare it to the builtin 'GlobalEval' function to make sure. |
| 8007 if (*callee != isolate->global_context()->global_eval_fun() || | 8188 if (*callee != isolate->global_context()->global_eval_fun() || |
| 8008 !args[1]->IsString()) { | 8189 !args[1]->IsString()) { |
| 8009 return MakePair(*callee, | 8190 return MakePair(*callee, |
| 8010 isolate->context()->global()->global_receiver()); | 8191 isolate->context()->global()->global_receiver()); |
| 8011 } | 8192 } |
| 8012 | 8193 |
| 8013 return CompileGlobalEval(isolate, args.at<String>(1), args.at<Object>(2)); | 8194 ASSERT(args[3]->IsSmi()); |
| 8195 return CompileGlobalEval(isolate, |
| 8196 args.at<String>(1), |
| 8197 args.at<Object>(2), |
| 8198 static_cast<StrictModeFlag>( |
| 8199 Smi::cast(args[3])->value())); |
| 8014 } | 8200 } |
| 8015 | 8201 |
| 8016 | 8202 |
| 8017 static MaybeObject* Runtime_SetNewFunctionAttributes( | 8203 static MaybeObject* Runtime_SetNewFunctionAttributes( |
| 8018 RUNTIME_CALLING_CONVENTION) { | 8204 RUNTIME_CALLING_CONVENTION) { |
| 8019 RUNTIME_GET_ISOLATE; | 8205 RUNTIME_GET_ISOLATE; |
| 8020 // This utility adjusts the property attributes for newly created Function | 8206 // This utility adjusts the property attributes for newly created Function |
| 8021 // object ("new Function(...)") by changing the map. | 8207 // object ("new Function(...)") by changing the map. |
| 8022 // All it does is changing the prototype property to enumerable | 8208 // All it does is changing the prototype property to enumerable |
| 8023 // as specified in ECMA262, 15.3.5.2. | 8209 // as specified in ECMA262, 15.3.5.2. |
| (...skipping 2206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10230 | 10416 |
| 10231 // Wrap the evaluation statement in a new function compiled in the newly | 10417 // Wrap the evaluation statement in a new function compiled in the newly |
| 10232 // created context. The function has one parameter which has to be called | 10418 // created context. The function has one parameter which has to be called |
| 10233 // 'arguments'. This it to have access to what would have been 'arguments' in | 10419 // 'arguments'. This it to have access to what would have been 'arguments' in |
| 10234 // the function being debugged. | 10420 // the function being debugged. |
| 10235 // function(arguments,__source__) {return eval(__source__);} | 10421 // function(arguments,__source__) {return eval(__source__);} |
| 10236 | 10422 |
| 10237 Handle<String> function_source = | 10423 Handle<String> function_source = |
| 10238 isolate->factory()->NewStringFromAscii( | 10424 isolate->factory()->NewStringFromAscii( |
| 10239 Vector<const char>(kSourceStr, sizeof(kSourceStr) - 1)); | 10425 Vector<const char>(kSourceStr, sizeof(kSourceStr) - 1)); |
| 10426 |
| 10427 // Currently, the eval code will be executed in non-strict mode, |
| 10428 // even in the strict code context. |
| 10240 Handle<SharedFunctionInfo> shared = | 10429 Handle<SharedFunctionInfo> shared = |
| 10241 Compiler::CompileEval(function_source, | 10430 Compiler::CompileEval(function_source, |
| 10242 context, | 10431 context, |
| 10243 context->IsGlobalContext()); | 10432 context->IsGlobalContext(), |
| 10433 kNonStrictMode); |
| 10244 if (shared.is_null()) return Failure::Exception(); | 10434 if (shared.is_null()) return Failure::Exception(); |
| 10245 Handle<JSFunction> compiled_function = | 10435 Handle<JSFunction> compiled_function = |
| 10246 isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, context); | 10436 isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, context); |
| 10247 | 10437 |
| 10248 // Invoke the result of the compilation to get the evaluation function. | 10438 // Invoke the result of the compilation to get the evaluation function. |
| 10249 bool has_pending_exception; | 10439 bool has_pending_exception; |
| 10250 Handle<Object> receiver(frame->receiver(), isolate); | 10440 Handle<Object> receiver(frame->receiver(), isolate); |
| 10251 Handle<Object> evaluation_function = | 10441 Handle<Object> evaluation_function = |
| 10252 Execution::Call(compiled_function, receiver, 0, NULL, | 10442 Execution::Call(compiled_function, receiver, 0, NULL, |
| 10253 &has_pending_exception); | 10443 &has_pending_exception); |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10320 isolate->factory()->undefined_value()); | 10510 isolate->factory()->undefined_value()); |
| 10321 go_between->set_context(*context); | 10511 go_between->set_context(*context); |
| 10322 context = | 10512 context = |
| 10323 isolate->factory()->NewFunctionContext( | 10513 isolate->factory()->NewFunctionContext( |
| 10324 Context::MIN_CONTEXT_SLOTS, go_between); | 10514 Context::MIN_CONTEXT_SLOTS, go_between); |
| 10325 context->set_extension(JSObject::cast(*additional_context)); | 10515 context->set_extension(JSObject::cast(*additional_context)); |
| 10326 is_global = false; | 10516 is_global = false; |
| 10327 } | 10517 } |
| 10328 | 10518 |
| 10329 // Compile the source to be evaluated. | 10519 // Compile the source to be evaluated. |
| 10520 // Currently, the eval code will be executed in non-strict mode, |
| 10521 // even in the strict code context. |
| 10330 Handle<SharedFunctionInfo> shared = | 10522 Handle<SharedFunctionInfo> shared = |
| 10331 Compiler::CompileEval(source, | 10523 Compiler::CompileEval(source, context, is_global, kNonStrictMode); |
| 10332 context, | |
| 10333 is_global); | |
| 10334 if (shared.is_null()) return Failure::Exception(); | 10524 if (shared.is_null()) return Failure::Exception(); |
| 10335 Handle<JSFunction> compiled_function = | 10525 Handle<JSFunction> compiled_function = |
| 10336 Handle<JSFunction>( | 10526 Handle<JSFunction>( |
| 10337 isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, | 10527 isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, |
| 10338 context)); | 10528 context)); |
| 10339 | 10529 |
| 10340 // Invoke the result of the compilation to get the evaluation function. | 10530 // Invoke the result of the compilation to get the evaluation function. |
| 10341 bool has_pending_exception; | 10531 bool has_pending_exception; |
| 10342 Handle<Object> receiver = isolate->global(); | 10532 Handle<Object> receiver = isolate->global(); |
| 10343 Handle<Object> result = | 10533 Handle<Object> result = |
| (...skipping 882 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11226 cache_handle->set(index + 1, *value); | 11416 cache_handle->set(index + 1, *value); |
| 11227 cache_handle->set_finger_index(index); | 11417 cache_handle->set_finger_index(index); |
| 11228 | 11418 |
| 11229 #ifdef DEBUG | 11419 #ifdef DEBUG |
| 11230 cache_handle->JSFunctionResultCacheVerify(); | 11420 cache_handle->JSFunctionResultCacheVerify(); |
| 11231 #endif | 11421 #endif |
| 11232 | 11422 |
| 11233 return *value; | 11423 return *value; |
| 11234 } | 11424 } |
| 11235 | 11425 |
| 11426 |
| 11427 static MaybeObject* Runtime_NewMessageObject(RUNTIME_CALLING_CONVENTION) { |
| 11428 RUNTIME_GET_ISOLATE; |
| 11429 HandleScope scope(isolate); |
| 11430 CONVERT_ARG_CHECKED(String, type, 0); |
| 11431 CONVERT_ARG_CHECKED(JSArray, arguments, 1); |
| 11432 return *isolate->factory()->NewJSMessageObject( |
| 11433 type, |
| 11434 arguments, |
| 11435 0, |
| 11436 0, |
| 11437 isolate->factory()->undefined_value(), |
| 11438 isolate->factory()->undefined_value(), |
| 11439 isolate->factory()->undefined_value()); |
| 11440 } |
| 11441 |
| 11442 |
| 11443 static MaybeObject* Runtime_MessageGetType(RUNTIME_CALLING_CONVENTION) { |
| 11444 RUNTIME_GET_ISOLATE; |
| 11445 CONVERT_CHECKED(JSMessageObject, message, args[0]); |
| 11446 return message->type(); |
| 11447 } |
| 11448 |
| 11449 |
| 11450 static MaybeObject* Runtime_MessageGetArguments(RUNTIME_CALLING_CONVENTION) { |
| 11451 RUNTIME_GET_ISOLATE; |
| 11452 CONVERT_CHECKED(JSMessageObject, message, args[0]); |
| 11453 return message->arguments(); |
| 11454 } |
| 11455 |
| 11456 |
| 11457 static MaybeObject* Runtime_MessageGetStartPosition( |
| 11458 RUNTIME_CALLING_CONVENTION) { |
| 11459 RUNTIME_GET_ISOLATE; |
| 11460 CONVERT_CHECKED(JSMessageObject, message, args[0]); |
| 11461 return Smi::FromInt(message->start_position()); |
| 11462 } |
| 11463 |
| 11464 |
| 11465 static MaybeObject* Runtime_MessageGetScript(RUNTIME_CALLING_CONVENTION) { |
| 11466 RUNTIME_GET_ISOLATE; |
| 11467 CONVERT_CHECKED(JSMessageObject, message, args[0]); |
| 11468 return message->script(); |
| 11469 } |
| 11470 |
| 11471 |
| 11236 #ifdef DEBUG | 11472 #ifdef DEBUG |
| 11237 // ListNatives is ONLY used by the fuzz-natives.js in debug mode | 11473 // ListNatives is ONLY used by the fuzz-natives.js in debug mode |
| 11238 // Exclude the code in release mode. | 11474 // Exclude the code in release mode. |
| 11239 static MaybeObject* Runtime_ListNatives(RUNTIME_CALLING_CONVENTION) { | 11475 static MaybeObject* Runtime_ListNatives(RUNTIME_CALLING_CONVENTION) { |
| 11240 RUNTIME_GET_ISOLATE; | 11476 RUNTIME_GET_ISOLATE; |
| 11241 ASSERT(args.length() == 0); | 11477 ASSERT(args.length() == 0); |
| 11242 HandleScope scope(isolate); | 11478 HandleScope scope(isolate); |
| 11243 Handle<JSArray> result = isolate->factory()->NewJSArray(0); | 11479 Handle<JSArray> result = isolate->factory()->NewJSArray(0); |
| 11244 int index = 0; | 11480 int index = 0; |
| 11245 bool inline_runtime_functions = false; | 11481 bool inline_runtime_functions = false; |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11360 } else { | 11596 } else { |
| 11361 // Handle last resort GC and make sure to allow future allocations | 11597 // Handle last resort GC and make sure to allow future allocations |
| 11362 // to grow the heap without causing GCs (if possible). | 11598 // to grow the heap without causing GCs (if possible). |
| 11363 COUNTERS->gc_last_resort_from_js()->Increment(); | 11599 COUNTERS->gc_last_resort_from_js()->Increment(); |
| 11364 HEAP->CollectAllGarbage(false); | 11600 HEAP->CollectAllGarbage(false); |
| 11365 } | 11601 } |
| 11366 } | 11602 } |
| 11367 | 11603 |
| 11368 | 11604 |
| 11369 } } // namespace v8::internal | 11605 } } // namespace v8::internal |
| OLD | NEW |