OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 1027 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1038 return ACCESS_ALLOWED; | 1038 return ACCESS_ALLOWED; |
1039 } | 1039 } |
1040 | 1040 |
1041 obj->GetIsolate()->ReportFailedAccessCheck(obj, access_type); | 1041 obj->GetIsolate()->ReportFailedAccessCheck(obj, access_type); |
1042 return ACCESS_FORBIDDEN; | 1042 return ACCESS_FORBIDDEN; |
1043 } | 1043 } |
1044 | 1044 |
1045 | 1045 |
1046 static AccessCheckResult CheckPropertyAccess( | 1046 static AccessCheckResult CheckPropertyAccess( |
1047 JSObject* obj, | 1047 JSObject* obj, |
1048 String* name, | 1048 Name* name, |
1049 v8::AccessType access_type) { | 1049 v8::AccessType access_type) { |
1050 uint32_t index; | 1050 uint32_t index; |
1051 if (name->AsArrayIndex(&index)) { | 1051 if (name->AsArrayIndex(&index)) { |
1052 return CheckElementAccess(obj, index, access_type); | 1052 return CheckElementAccess(obj, index, access_type); |
1053 } | 1053 } |
1054 | 1054 |
1055 LookupResult lookup(obj->GetIsolate()); | 1055 LookupResult lookup(obj->GetIsolate()); |
1056 obj->LocalLookup(name, &lookup, true); | 1056 obj->LocalLookup(name, &lookup, true); |
1057 | 1057 |
1058 if (!lookup.IsProperty()) return ACCESS_ABSENT; | 1058 if (!lookup.IsProperty()) return ACCESS_ABSENT; |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1098 SETTER_INDEX, | 1098 SETTER_INDEX, |
1099 WRITABLE_INDEX, | 1099 WRITABLE_INDEX, |
1100 ENUMERABLE_INDEX, | 1100 ENUMERABLE_INDEX, |
1101 CONFIGURABLE_INDEX, | 1101 CONFIGURABLE_INDEX, |
1102 DESCRIPTOR_SIZE | 1102 DESCRIPTOR_SIZE |
1103 }; | 1103 }; |
1104 | 1104 |
1105 | 1105 |
1106 static MaybeObject* GetOwnProperty(Isolate* isolate, | 1106 static MaybeObject* GetOwnProperty(Isolate* isolate, |
1107 Handle<JSObject> obj, | 1107 Handle<JSObject> obj, |
1108 Handle<String> name) { | 1108 Handle<Name> name) { |
1109 Heap* heap = isolate->heap(); | 1109 Heap* heap = isolate->heap(); |
1110 // Due to some WebKit tests, we want to make sure that we do not log | 1110 // Due to some WebKit tests, we want to make sure that we do not log |
1111 // more than one access failure here. | 1111 // more than one access failure here. |
1112 switch (CheckPropertyAccess(*obj, *name, v8::ACCESS_HAS)) { | 1112 switch (CheckPropertyAccess(*obj, *name, v8::ACCESS_HAS)) { |
1113 case ACCESS_FORBIDDEN: return heap->false_value(); | 1113 case ACCESS_FORBIDDEN: return heap->false_value(); |
1114 case ACCESS_ALLOWED: break; | 1114 case ACCESS_ALLOWED: break; |
1115 case ACCESS_ABSENT: return heap->undefined_value(); | 1115 case ACCESS_ABSENT: return heap->undefined_value(); |
1116 } | 1116 } |
1117 | 1117 |
1118 PropertyAttributes attrs = obj->GetLocalPropertyAttribute(*name); | 1118 PropertyAttributes attrs = obj->GetLocalPropertyAttribute(*name); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1152 // if args[1] is not a property on args[0] | 1152 // if args[1] is not a property on args[0] |
1153 // returns undefined | 1153 // returns undefined |
1154 // if args[1] is a data property on args[0] | 1154 // if args[1] is a data property on args[0] |
1155 // [false, value, Writeable, Enumerable, Configurable] | 1155 // [false, value, Writeable, Enumerable, Configurable] |
1156 // if args[1] is an accessor on args[0] | 1156 // if args[1] is an accessor on args[0] |
1157 // [true, GetFunction, SetFunction, Enumerable, Configurable] | 1157 // [true, GetFunction, SetFunction, Enumerable, Configurable] |
1158 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOwnProperty) { | 1158 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOwnProperty) { |
1159 ASSERT(args.length() == 2); | 1159 ASSERT(args.length() == 2); |
1160 HandleScope scope(isolate); | 1160 HandleScope scope(isolate); |
1161 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); | 1161 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); |
1162 CONVERT_ARG_HANDLE_CHECKED(String, name, 1); | 1162 CONVERT_ARG_HANDLE_CHECKED(Name, name, 1); |
1163 return GetOwnProperty(isolate, obj, name); | 1163 return GetOwnProperty(isolate, obj, name); |
1164 } | 1164 } |
1165 | 1165 |
1166 | 1166 |
1167 RUNTIME_FUNCTION(MaybeObject*, Runtime_PreventExtensions) { | 1167 RUNTIME_FUNCTION(MaybeObject*, Runtime_PreventExtensions) { |
1168 ASSERT(args.length() == 1); | 1168 ASSERT(args.length() == 1); |
1169 CONVERT_ARG_CHECKED(JSObject, obj, 0); | 1169 CONVERT_ARG_CHECKED(JSObject, obj, 0); |
1170 return obj->PreventExtensions(); | 1170 return obj->PreventExtensions(); |
1171 } | 1171 } |
1172 | 1172 |
(...skipping 936 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2109 Map* new_map; | 2109 Map* new_map; |
2110 MaybeObject* maybe_map = | 2110 MaybeObject* maybe_map = |
2111 function->map()->CopyReplaceDescriptor( | 2111 function->map()->CopyReplaceDescriptor( |
2112 instance_desc, &new_desc, index, OMIT_TRANSITION); | 2112 instance_desc, &new_desc, index, OMIT_TRANSITION); |
2113 if (!maybe_map->To(&new_map)) return maybe_map; | 2113 if (!maybe_map->To(&new_map)) return maybe_map; |
2114 | 2114 |
2115 function->set_map(new_map); | 2115 function->set_map(new_map); |
2116 } else { // Dictionary properties. | 2116 } else { // Dictionary properties. |
2117 // Directly manipulate the property details. | 2117 // Directly manipulate the property details. |
2118 int entry = function->property_dictionary()->FindEntry(name); | 2118 int entry = function->property_dictionary()->FindEntry(name); |
2119 ASSERT(entry != StringDictionary::kNotFound); | 2119 ASSERT(entry != NameDictionary::kNotFound); |
2120 PropertyDetails details = function->property_dictionary()->DetailsAt(entry); | 2120 PropertyDetails details = function->property_dictionary()->DetailsAt(entry); |
2121 PropertyDetails new_details( | 2121 PropertyDetails new_details( |
2122 static_cast<PropertyAttributes>(details.attributes() | READ_ONLY), | 2122 static_cast<PropertyAttributes>(details.attributes() | READ_ONLY), |
2123 details.type(), | 2123 details.type(), |
2124 details.dictionary_index()); | 2124 details.dictionary_index()); |
2125 function->property_dictionary()->DetailsAtPut(entry, new_details); | 2125 function->property_dictionary()->DetailsAtPut(entry, new_details); |
2126 } | 2126 } |
2127 return function; | 2127 return function; |
2128 } | 2128 } |
2129 | 2129 |
(...skipping 1792 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3922 HandleVector(args, 2)); | 3922 HandleVector(args, 2)); |
3923 return isolate->Throw(*error); | 3923 return isolate->Throw(*error); |
3924 } | 3924 } |
3925 | 3925 |
3926 // Check if the given key is an array index. | 3926 // Check if the given key is an array index. |
3927 uint32_t index; | 3927 uint32_t index; |
3928 if (key->ToArrayIndex(&index)) { | 3928 if (key->ToArrayIndex(&index)) { |
3929 return GetElementOrCharAt(isolate, object, index); | 3929 return GetElementOrCharAt(isolate, object, index); |
3930 } | 3930 } |
3931 | 3931 |
3932 // Convert the key to a string - possibly by calling back into JavaScript. | 3932 // Convert the key to a name - possibly by calling back into JavaScript. |
3933 Handle<String> name; | 3933 Handle<Name> name; |
3934 if (key->IsString()) { | 3934 if (key->IsName()) { |
3935 name = Handle<String>::cast(key); | 3935 name = Handle<Name>::cast(key); |
3936 } else { | 3936 } else { |
3937 bool has_pending_exception = false; | 3937 bool has_pending_exception = false; |
3938 Handle<Object> converted = | 3938 Handle<Object> converted = |
3939 Execution::ToString(key, &has_pending_exception); | 3939 Execution::ToString(key, &has_pending_exception); |
3940 if (has_pending_exception) return Failure::Exception(); | 3940 if (has_pending_exception) return Failure::Exception(); |
3941 name = Handle<String>::cast(converted); | 3941 name = Handle<Name>::cast(converted); |
3942 } | 3942 } |
3943 | 3943 |
3944 // Check if the name is trivially convertible to an index and get | 3944 // Check if the name is trivially convertible to an index and get |
3945 // the element if so. | 3945 // the element if so. |
3946 if (name->AsArrayIndex(&index)) { | 3946 if (name->AsArrayIndex(&index)) { |
3947 return GetElementOrCharAt(isolate, object, index); | 3947 return GetElementOrCharAt(isolate, object, index); |
3948 } else { | 3948 } else { |
3949 return object->GetProperty(*name); | 3949 return object->GetProperty(*name); |
3950 } | 3950 } |
3951 } | 3951 } |
3952 | 3952 |
3953 | 3953 |
3954 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetProperty) { | 3954 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetProperty) { |
3955 NoHandleAllocation ha; | 3955 NoHandleAllocation ha; |
3956 ASSERT(args.length() == 2); | 3956 ASSERT(args.length() == 2); |
3957 | 3957 |
3958 Handle<Object> object = args.at<Object>(0); | 3958 Handle<Object> object = args.at<Object>(0); |
3959 Handle<Object> key = args.at<Object>(1); | 3959 Handle<Object> key = args.at<Object>(1); |
3960 | 3960 |
3961 return Runtime::GetObjectProperty(isolate, object, key); | 3961 return Runtime::GetObjectProperty(isolate, object, key); |
3962 } | 3962 } |
3963 | 3963 |
3964 | 3964 |
3965 // KeyedStringGetProperty is called from KeyedLoadIC::GenerateGeneric. | 3965 // KeyedGetProperty is called from KeyedLoadIC::GenerateGeneric. |
3966 RUNTIME_FUNCTION(MaybeObject*, Runtime_KeyedGetProperty) { | 3966 RUNTIME_FUNCTION(MaybeObject*, Runtime_KeyedGetProperty) { |
3967 NoHandleAllocation ha; | 3967 NoHandleAllocation ha; |
3968 ASSERT(args.length() == 2); | 3968 ASSERT(args.length() == 2); |
3969 | 3969 |
3970 // Fast cases for getting named properties of the receiver JSObject | 3970 // Fast cases for getting named properties of the receiver JSObject |
3971 // itself. | 3971 // itself. |
3972 // | 3972 // |
3973 // The global proxy objects has to be excluded since LocalLookup on | 3973 // The global proxy objects has to be excluded since LocalLookup on |
3974 // the global proxy object can return a valid result even though the | 3974 // the global proxy object can return a valid result even though the |
3975 // global proxy object never has properties. This is the case | 3975 // global proxy object never has properties. This is the case |
3976 // because the global proxy object forwards everything to its hidden | 3976 // because the global proxy object forwards everything to its hidden |
3977 // prototype including local lookups. | 3977 // prototype including local lookups. |
3978 // | 3978 // |
3979 // Additionally, we need to make sure that we do not cache results | 3979 // Additionally, we need to make sure that we do not cache results |
3980 // for objects that require access checks. | 3980 // for objects that require access checks. |
3981 if (args[0]->IsJSObject()) { | 3981 if (args[0]->IsJSObject()) { |
3982 if (!args[0]->IsJSGlobalProxy() && | 3982 if (!args[0]->IsJSGlobalProxy() && |
3983 !args[0]->IsAccessCheckNeeded() && | 3983 !args[0]->IsAccessCheckNeeded() && |
3984 args[1]->IsString()) { | 3984 args[1]->IsName()) { |
3985 JSObject* receiver = JSObject::cast(args[0]); | 3985 JSObject* receiver = JSObject::cast(args[0]); |
3986 String* key = String::cast(args[1]); | 3986 Name* key = Name::cast(args[1]); |
3987 if (receiver->HasFastProperties()) { | 3987 if (receiver->HasFastProperties()) { |
3988 // Attempt to use lookup cache. | 3988 // Attempt to use lookup cache. |
3989 Map* receiver_map = receiver->map(); | 3989 Map* receiver_map = receiver->map(); |
3990 KeyedLookupCache* keyed_lookup_cache = isolate->keyed_lookup_cache(); | 3990 KeyedLookupCache* keyed_lookup_cache = isolate->keyed_lookup_cache(); |
3991 int offset = keyed_lookup_cache->Lookup(receiver_map, key); | 3991 int offset = keyed_lookup_cache->Lookup(receiver_map, key); |
3992 if (offset != -1) { | 3992 if (offset != -1) { |
3993 Object* value = receiver->FastPropertyAt(offset); | 3993 Object* value = receiver->FastPropertyAt(offset); |
3994 return value->IsTheHole() | 3994 return value->IsTheHole() |
3995 ? isolate->heap()->undefined_value() | 3995 ? isolate->heap()->undefined_value() |
3996 : value; | 3996 : value; |
3997 } | 3997 } |
3998 // Lookup cache miss. Perform lookup and update the cache if | 3998 // Lookup cache miss. Perform lookup and update the cache if |
3999 // appropriate. | 3999 // appropriate. |
4000 LookupResult result(isolate); | 4000 LookupResult result(isolate); |
4001 receiver->LocalLookup(key, &result); | 4001 receiver->LocalLookup(key, &result); |
4002 if (result.IsField()) { | 4002 if (result.IsField()) { |
4003 int offset = result.GetFieldIndex().field_index(); | 4003 int offset = result.GetFieldIndex().field_index(); |
4004 keyed_lookup_cache->Update(receiver_map, key, offset); | 4004 keyed_lookup_cache->Update(receiver_map, key, offset); |
4005 return receiver->FastPropertyAt(offset); | 4005 return receiver->FastPropertyAt(offset); |
4006 } | 4006 } |
4007 } else { | 4007 } else { |
4008 // Attempt dictionary lookup. | 4008 // Attempt dictionary lookup. |
4009 StringDictionary* dictionary = receiver->property_dictionary(); | 4009 NameDictionary* dictionary = receiver->property_dictionary(); |
4010 int entry = dictionary->FindEntry(key); | 4010 int entry = dictionary->FindEntry(key); |
4011 if ((entry != StringDictionary::kNotFound) && | 4011 if ((entry != NameDictionary::kNotFound) && |
4012 (dictionary->DetailsAt(entry).type() == NORMAL)) { | 4012 (dictionary->DetailsAt(entry).type() == NORMAL)) { |
4013 Object* value = dictionary->ValueAt(entry); | 4013 Object* value = dictionary->ValueAt(entry); |
4014 if (!receiver->IsGlobalObject()) return value; | 4014 if (!receiver->IsGlobalObject()) return value; |
4015 value = JSGlobalPropertyCell::cast(value)->value(); | 4015 value = JSGlobalPropertyCell::cast(value)->value(); |
4016 if (!value->IsTheHole()) return value; | 4016 if (!value->IsTheHole()) return value; |
4017 // If value is the hole do the general lookup. | 4017 // If value is the hole do the general lookup. |
4018 } | 4018 } |
4019 } | 4019 } |
4020 } else if (FLAG_smi_only_arrays && args.at<Object>(1)->IsSmi()) { | 4020 } else if (FLAG_smi_only_arrays && args.at<Object>(1)->IsSmi()) { |
4021 // JSObject without a string key. If the key is a Smi, check for a | 4021 // JSObject without a name key. If the key is a Smi, check for a |
4022 // definite out-of-bounds access to elements, which is a strong indicator | 4022 // definite out-of-bounds access to elements, which is a strong indicator |
4023 // that subsequent accesses will also call the runtime. Proactively | 4023 // that subsequent accesses will also call the runtime. Proactively |
4024 // transition elements to FAST_*_ELEMENTS to avoid excessive boxing of | 4024 // transition elements to FAST_*_ELEMENTS to avoid excessive boxing of |
4025 // doubles for those future calls in the case that the elements would | 4025 // doubles for those future calls in the case that the elements would |
4026 // become FAST_DOUBLE_ELEMENTS. | 4026 // become FAST_DOUBLE_ELEMENTS. |
4027 Handle<JSObject> js_object(args.at<JSObject>(0)); | 4027 Handle<JSObject> js_object(args.at<JSObject>(0)); |
4028 ElementsKind elements_kind = js_object->GetElementsKind(); | 4028 ElementsKind elements_kind = js_object->GetElementsKind(); |
4029 if (IsFastDoubleElementsKind(elements_kind)) { | 4029 if (IsFastDoubleElementsKind(elements_kind)) { |
4030 FixedArrayBase* elements = js_object->elements(); | 4030 FixedArrayBase* elements = js_object->elements(); |
4031 if (args.at<Smi>(1)->value() >= elements->length()) { | 4031 if (args.at<Smi>(1)->value() >= elements->length()) { |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4071 // There are 3 cases that lead here: | 4071 // There are 3 cases that lead here: |
4072 // Step 4b - define a new accessor property. | 4072 // Step 4b - define a new accessor property. |
4073 // Steps 9c & 12 - replace an existing data property with an accessor property. | 4073 // Steps 9c & 12 - replace an existing data property with an accessor property. |
4074 // Step 12 - update an existing accessor property with an accessor or generic | 4074 // Step 12 - update an existing accessor property with an accessor or generic |
4075 // descriptor. | 4075 // descriptor. |
4076 RUNTIME_FUNCTION(MaybeObject*, Runtime_DefineOrRedefineAccessorProperty) { | 4076 RUNTIME_FUNCTION(MaybeObject*, Runtime_DefineOrRedefineAccessorProperty) { |
4077 ASSERT(args.length() == 5); | 4077 ASSERT(args.length() == 5); |
4078 HandleScope scope(isolate); | 4078 HandleScope scope(isolate); |
4079 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); | 4079 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); |
4080 RUNTIME_ASSERT(!obj->IsNull()); | 4080 RUNTIME_ASSERT(!obj->IsNull()); |
4081 CONVERT_ARG_HANDLE_CHECKED(String, name, 1); | 4081 CONVERT_ARG_HANDLE_CHECKED(Name, name, 1); |
4082 CONVERT_ARG_HANDLE_CHECKED(Object, getter, 2); | 4082 CONVERT_ARG_HANDLE_CHECKED(Object, getter, 2); |
4083 RUNTIME_ASSERT(IsValidAccessor(getter)); | 4083 RUNTIME_ASSERT(IsValidAccessor(getter)); |
4084 CONVERT_ARG_HANDLE_CHECKED(Object, setter, 3); | 4084 CONVERT_ARG_HANDLE_CHECKED(Object, setter, 3); |
4085 RUNTIME_ASSERT(IsValidAccessor(setter)); | 4085 RUNTIME_ASSERT(IsValidAccessor(setter)); |
4086 CONVERT_SMI_ARG_CHECKED(unchecked, 4); | 4086 CONVERT_SMI_ARG_CHECKED(unchecked, 4); |
4087 RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); | 4087 RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); |
4088 PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked); | 4088 PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked); |
4089 | 4089 |
4090 bool fast = obj->HasFastProperties(); | 4090 bool fast = obj->HasFastProperties(); |
4091 JSObject::DefineAccessor(obj, name, getter, setter, attr); | 4091 JSObject::DefineAccessor(obj, name, getter, setter, attr); |
4092 if (fast) JSObject::TransformToFastProperties(obj, 0); | 4092 if (fast) JSObject::TransformToFastProperties(obj, 0); |
4093 return isolate->heap()->undefined_value(); | 4093 return isolate->heap()->undefined_value(); |
4094 } | 4094 } |
4095 | 4095 |
4096 // Implements part of 8.12.9 DefineOwnProperty. | 4096 // Implements part of 8.12.9 DefineOwnProperty. |
4097 // There are 3 cases that lead here: | 4097 // There are 3 cases that lead here: |
4098 // Step 4a - define a new data property. | 4098 // Step 4a - define a new data property. |
4099 // Steps 9b & 12 - replace an existing accessor property with a data property. | 4099 // Steps 9b & 12 - replace an existing accessor property with a data property. |
4100 // Step 12 - update an existing data property with a data or generic | 4100 // Step 12 - update an existing data property with a data or generic |
4101 // descriptor. | 4101 // descriptor. |
4102 RUNTIME_FUNCTION(MaybeObject*, Runtime_DefineOrRedefineDataProperty) { | 4102 RUNTIME_FUNCTION(MaybeObject*, Runtime_DefineOrRedefineDataProperty) { |
4103 ASSERT(args.length() == 4); | 4103 ASSERT(args.length() == 4); |
4104 HandleScope scope(isolate); | 4104 HandleScope scope(isolate); |
4105 CONVERT_ARG_HANDLE_CHECKED(JSObject, js_object, 0); | 4105 CONVERT_ARG_HANDLE_CHECKED(JSObject, js_object, 0); |
4106 CONVERT_ARG_HANDLE_CHECKED(String, name, 1); | 4106 CONVERT_ARG_HANDLE_CHECKED(Name, name, 1); |
4107 CONVERT_ARG_HANDLE_CHECKED(Object, obj_value, 2); | 4107 CONVERT_ARG_HANDLE_CHECKED(Object, obj_value, 2); |
4108 CONVERT_SMI_ARG_CHECKED(unchecked, 3); | 4108 CONVERT_SMI_ARG_CHECKED(unchecked, 3); |
4109 RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); | 4109 RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); |
4110 PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked); | 4110 PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked); |
4111 | 4111 |
4112 LookupResult result(isolate); | 4112 LookupResult result(isolate); |
4113 js_object->LocalLookupRealNamedProperty(*name, &result); | 4113 js_object->LocalLookupRealNamedProperty(*name, &result); |
4114 | 4114 |
4115 // Special case for callback properties. | 4115 // Special case for callback properties. |
4116 if (result.IsPropertyCallbacks()) { | 4116 if (result.IsPropertyCallbacks()) { |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4161 name, | 4161 name, |
4162 obj_value, | 4162 obj_value, |
4163 attr); | 4163 attr); |
4164 } | 4164 } |
4165 | 4165 |
4166 | 4166 |
4167 // Return property without being observable by accessors or interceptors. | 4167 // Return property without being observable by accessors or interceptors. |
4168 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetDataProperty) { | 4168 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetDataProperty) { |
4169 ASSERT(args.length() == 2); | 4169 ASSERT(args.length() == 2); |
4170 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); | 4170 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); |
4171 CONVERT_ARG_HANDLE_CHECKED(String, key, 1); | 4171 CONVERT_ARG_HANDLE_CHECKED(Name, key, 1); |
4172 LookupResult lookup(isolate); | 4172 LookupResult lookup(isolate); |
4173 object->LookupRealNamedProperty(*key, &lookup); | 4173 object->LookupRealNamedProperty(*key, &lookup); |
4174 if (!lookup.IsFound()) return isolate->heap()->undefined_value(); | 4174 if (!lookup.IsFound()) return isolate->heap()->undefined_value(); |
4175 switch (lookup.type()) { | 4175 switch (lookup.type()) { |
4176 case NORMAL: | 4176 case NORMAL: |
4177 return lookup.holder()->GetNormalizedProperty(&lookup); | 4177 return lookup.holder()->GetNormalizedProperty(&lookup); |
4178 case FIELD: | 4178 case FIELD: |
4179 return lookup.holder()->FastPropertyAt( | 4179 return lookup.holder()->FastPropertyAt( |
4180 lookup.GetFieldIndex().field_index()); | 4180 lookup.GetFieldIndex().field_index()); |
4181 case CONSTANT_FUNCTION: | 4181 case CONSTANT_FUNCTION: |
(...skipping 22 matching lines...) Expand all Loading... |
4204 if (object->IsUndefined() || object->IsNull()) { | 4204 if (object->IsUndefined() || object->IsNull()) { |
4205 Handle<Object> args[2] = { key, object }; | 4205 Handle<Object> args[2] = { key, object }; |
4206 Handle<Object> error = | 4206 Handle<Object> error = |
4207 isolate->factory()->NewTypeError("non_object_property_store", | 4207 isolate->factory()->NewTypeError("non_object_property_store", |
4208 HandleVector(args, 2)); | 4208 HandleVector(args, 2)); |
4209 return isolate->Throw(*error); | 4209 return isolate->Throw(*error); |
4210 } | 4210 } |
4211 | 4211 |
4212 if (object->IsJSProxy()) { | 4212 if (object->IsJSProxy()) { |
4213 bool has_pending_exception = false; | 4213 bool has_pending_exception = false; |
4214 Handle<Object> name = Execution::ToString(key, &has_pending_exception); | 4214 Handle<Object> name = key->IsSymbol() |
| 4215 ? key : Execution::ToString(key, &has_pending_exception); |
4215 if (has_pending_exception) return Failure::Exception(); | 4216 if (has_pending_exception) return Failure::Exception(); |
4216 return JSProxy::cast(*object)->SetProperty( | 4217 return JSProxy::cast(*object)->SetProperty( |
4217 String::cast(*name), *value, attr, strict_mode); | 4218 Name::cast(*name), *value, attr, strict_mode); |
4218 } | 4219 } |
4219 | 4220 |
4220 // If the object isn't a JavaScript object, we ignore the store. | 4221 // If the object isn't a JavaScript object, we ignore the store. |
4221 if (!object->IsJSObject()) return *value; | 4222 if (!object->IsJSObject()) return *value; |
4222 | 4223 |
4223 Handle<JSObject> js_object = Handle<JSObject>::cast(object); | 4224 Handle<JSObject> js_object = Handle<JSObject>::cast(object); |
4224 | 4225 |
4225 // Check if the given key is an array index. | 4226 // Check if the given key is an array index. |
4226 uint32_t index; | 4227 uint32_t index; |
4227 if (key->ToArrayIndex(&index)) { | 4228 if (key->ToArrayIndex(&index)) { |
4228 // In Firefox/SpiderMonkey, Safari and Opera you can access the characters | 4229 // In Firefox/SpiderMonkey, Safari and Opera you can access the characters |
4229 // of a string using [] notation. We need to support this too in | 4230 // of a string using [] notation. We need to support this too in |
4230 // JavaScript. | 4231 // JavaScript. |
4231 // In the case of a String object we just need to redirect the assignment to | 4232 // In the case of a String object we just need to redirect the assignment to |
4232 // the underlying string if the index is in range. Since the underlying | 4233 // the underlying string if the index is in range. Since the underlying |
4233 // string does nothing with the assignment then we can ignore such | 4234 // string does nothing with the assignment then we can ignore such |
4234 // assignments. | 4235 // assignments. |
4235 if (js_object->IsStringObjectWithCharacterAt(index)) { | 4236 if (js_object->IsStringObjectWithCharacterAt(index)) { |
4236 return *value; | 4237 return *value; |
4237 } | 4238 } |
4238 | 4239 |
4239 js_object->ValidateElements(); | 4240 js_object->ValidateElements(); |
4240 Handle<Object> result = JSObject::SetElement( | 4241 Handle<Object> result = JSObject::SetElement( |
4241 js_object, index, value, attr, strict_mode, set_mode); | 4242 js_object, index, value, attr, strict_mode, set_mode); |
4242 js_object->ValidateElements(); | 4243 js_object->ValidateElements(); |
4243 if (result.is_null()) return Failure::Exception(); | 4244 if (result.is_null()) return Failure::Exception(); |
4244 return *value; | 4245 return *value; |
4245 } | 4246 } |
4246 | 4247 |
4247 if (key->IsString()) { | 4248 if (key->IsName()) { |
4248 Handle<Object> result; | 4249 Handle<Object> result; |
4249 if (Handle<String>::cast(key)->AsArrayIndex(&index)) { | 4250 Handle<Name> name = Handle<Name>::cast(key); |
| 4251 if (name->AsArrayIndex(&index)) { |
4250 result = JSObject::SetElement( | 4252 result = JSObject::SetElement( |
4251 js_object, index, value, attr, strict_mode, set_mode); | 4253 js_object, index, value, attr, strict_mode, set_mode); |
4252 } else { | 4254 } else { |
4253 Handle<String> key_string = Handle<String>::cast(key); | 4255 if (name->IsString()) Handle<String>::cast(name)->TryFlatten(); |
4254 key_string->TryFlatten(); | |
4255 result = JSReceiver::SetProperty( | 4256 result = JSReceiver::SetProperty( |
4256 js_object, key_string, value, attr, strict_mode); | 4257 js_object, name, value, attr, strict_mode); |
4257 } | 4258 } |
4258 if (result.is_null()) return Failure::Exception(); | 4259 if (result.is_null()) return Failure::Exception(); |
4259 return *value; | 4260 return *value; |
4260 } | 4261 } |
4261 | 4262 |
4262 // Call-back into JavaScript to convert the key to a string. | 4263 // Call-back into JavaScript to convert the key to a string. |
4263 bool has_pending_exception = false; | 4264 bool has_pending_exception = false; |
4264 Handle<Object> converted = Execution::ToString(key, &has_pending_exception); | 4265 Handle<Object> converted = Execution::ToString(key, &has_pending_exception); |
4265 if (has_pending_exception) return Failure::Exception(); | 4266 if (has_pending_exception) return Failure::Exception(); |
4266 Handle<String> name = Handle<String>::cast(converted); | 4267 Handle<String> name = Handle<String>::cast(converted); |
(...skipping 25 matching lines...) Expand all Loading... |
4292 // string does nothing with the assignment then we can ignore such | 4293 // string does nothing with the assignment then we can ignore such |
4293 // assignments. | 4294 // assignments. |
4294 if (js_object->IsStringObjectWithCharacterAt(index)) { | 4295 if (js_object->IsStringObjectWithCharacterAt(index)) { |
4295 return *value; | 4296 return *value; |
4296 } | 4297 } |
4297 | 4298 |
4298 return js_object->SetElement( | 4299 return js_object->SetElement( |
4299 index, *value, attr, kNonStrictMode, false, DEFINE_PROPERTY); | 4300 index, *value, attr, kNonStrictMode, false, DEFINE_PROPERTY); |
4300 } | 4301 } |
4301 | 4302 |
4302 if (key->IsString()) { | 4303 if (key->IsName()) { |
4303 if (Handle<String>::cast(key)->AsArrayIndex(&index)) { | 4304 Handle<Name> name = Handle<Name>::cast(key); |
| 4305 if (name->AsArrayIndex(&index)) { |
4304 return js_object->SetElement( | 4306 return js_object->SetElement( |
4305 index, *value, attr, kNonStrictMode, false, DEFINE_PROPERTY); | 4307 index, *value, attr, kNonStrictMode, false, DEFINE_PROPERTY); |
4306 } else { | 4308 } else { |
4307 Handle<String> key_string = Handle<String>::cast(key); | 4309 if (name->IsString()) Handle<String>::cast(name)->TryFlatten(); |
4308 key_string->TryFlatten(); | 4310 return js_object->SetLocalPropertyIgnoreAttributes(*name, *value, attr); |
4309 return js_object->SetLocalPropertyIgnoreAttributes(*key_string, | |
4310 *value, | |
4311 attr); | |
4312 } | 4311 } |
4313 } | 4312 } |
4314 | 4313 |
4315 // Call-back into JavaScript to convert the key to a string. | 4314 // Call-back into JavaScript to convert the key to a string. |
4316 bool has_pending_exception = false; | 4315 bool has_pending_exception = false; |
4317 Handle<Object> converted = Execution::ToString(key, &has_pending_exception); | 4316 Handle<Object> converted = Execution::ToString(key, &has_pending_exception); |
4318 if (has_pending_exception) return Failure::Exception(); | 4317 if (has_pending_exception) return Failure::Exception(); |
4319 Handle<String> name = Handle<String>::cast(converted); | 4318 Handle<String> name = Handle<String>::cast(converted); |
4320 | 4319 |
4321 if (name->AsArrayIndex(&index)) { | 4320 if (name->AsArrayIndex(&index)) { |
(...skipping 19 matching lines...) Expand all Loading... |
4341 // underlying string if the index is in range. Since the | 4340 // underlying string if the index is in range. Since the |
4342 // underlying string does nothing with the deletion, we can ignore | 4341 // underlying string does nothing with the deletion, we can ignore |
4343 // such deletions. | 4342 // such deletions. |
4344 if (receiver->IsStringObjectWithCharacterAt(index)) { | 4343 if (receiver->IsStringObjectWithCharacterAt(index)) { |
4345 return isolate->heap()->true_value(); | 4344 return isolate->heap()->true_value(); |
4346 } | 4345 } |
4347 | 4346 |
4348 return receiver->DeleteElement(index, JSReceiver::FORCE_DELETION); | 4347 return receiver->DeleteElement(index, JSReceiver::FORCE_DELETION); |
4349 } | 4348 } |
4350 | 4349 |
4351 Handle<String> key_string; | 4350 Handle<Name> name; |
4352 if (key->IsString()) { | 4351 if (key->IsName()) { |
4353 key_string = Handle<String>::cast(key); | 4352 name = Handle<Name>::cast(key); |
4354 } else { | 4353 } else { |
4355 // Call-back into JavaScript to convert the key to a string. | 4354 // Call-back into JavaScript to convert the key to a string. |
4356 bool has_pending_exception = false; | 4355 bool has_pending_exception = false; |
4357 Handle<Object> converted = Execution::ToString(key, &has_pending_exception); | 4356 Handle<Object> converted = Execution::ToString(key, &has_pending_exception); |
4358 if (has_pending_exception) return Failure::Exception(); | 4357 if (has_pending_exception) return Failure::Exception(); |
4359 key_string = Handle<String>::cast(converted); | 4358 name = Handle<String>::cast(converted); |
4360 } | 4359 } |
4361 | 4360 |
4362 key_string->TryFlatten(); | 4361 if (name->IsString()) Handle<String>::cast(name)->TryFlatten(); |
4363 return receiver->DeleteProperty(*key_string, JSReceiver::FORCE_DELETION); | 4362 return receiver->DeleteProperty(*name, JSReceiver::FORCE_DELETION); |
4364 } | 4363 } |
4365 | 4364 |
4366 | 4365 |
4367 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetProperty) { | 4366 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetProperty) { |
4368 NoHandleAllocation ha; | 4367 NoHandleAllocation ha; |
4369 RUNTIME_ASSERT(args.length() == 4 || args.length() == 5); | 4368 RUNTIME_ASSERT(args.length() == 4 || args.length() == 5); |
4370 | 4369 |
4371 Handle<Object> object = args.at<Object>(0); | 4370 Handle<Object> object = args.at<Object>(0); |
4372 Handle<Object> key = args.at<Object>(1); | 4371 Handle<Object> key = args.at<Object>(1); |
4373 Handle<Object> value = args.at<Object>(2); | 4372 Handle<Object> value = args.at<Object>(2); |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4540 return isolate->heap()->undefined_value(); | 4539 return isolate->heap()->undefined_value(); |
4541 } | 4540 } |
4542 | 4541 |
4543 | 4542 |
4544 // Set a local property, even if it is READ_ONLY. If the property does not | 4543 // Set a local property, even if it is READ_ONLY. If the property does not |
4545 // exist, it will be added with attributes NONE. | 4544 // exist, it will be added with attributes NONE. |
4546 RUNTIME_FUNCTION(MaybeObject*, Runtime_IgnoreAttributesAndSetProperty) { | 4545 RUNTIME_FUNCTION(MaybeObject*, Runtime_IgnoreAttributesAndSetProperty) { |
4547 NoHandleAllocation ha; | 4546 NoHandleAllocation ha; |
4548 RUNTIME_ASSERT(args.length() == 3 || args.length() == 4); | 4547 RUNTIME_ASSERT(args.length() == 3 || args.length() == 4); |
4549 CONVERT_ARG_CHECKED(JSObject, object, 0); | 4548 CONVERT_ARG_CHECKED(JSObject, object, 0); |
4550 CONVERT_ARG_CHECKED(String, name, 1); | 4549 CONVERT_ARG_CHECKED(Name, name, 1); |
4551 // Compute attributes. | 4550 // Compute attributes. |
4552 PropertyAttributes attributes = NONE; | 4551 PropertyAttributes attributes = NONE; |
4553 if (args.length() == 4) { | 4552 if (args.length() == 4) { |
4554 CONVERT_SMI_ARG_CHECKED(unchecked_value, 3); | 4553 CONVERT_SMI_ARG_CHECKED(unchecked_value, 3); |
4555 // Only attribute bits should be set. | 4554 // Only attribute bits should be set. |
4556 RUNTIME_ASSERT( | 4555 RUNTIME_ASSERT( |
4557 (unchecked_value & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); | 4556 (unchecked_value & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); |
4558 attributes = static_cast<PropertyAttributes>(unchecked_value); | 4557 attributes = static_cast<PropertyAttributes>(unchecked_value); |
4559 } | 4558 } |
4560 | 4559 |
4561 return object-> | 4560 return object-> |
4562 SetLocalPropertyIgnoreAttributes(name, args[2], attributes); | 4561 SetLocalPropertyIgnoreAttributes(name, args[2], attributes); |
4563 } | 4562 } |
4564 | 4563 |
4565 | 4564 |
4566 RUNTIME_FUNCTION(MaybeObject*, Runtime_DeleteProperty) { | 4565 RUNTIME_FUNCTION(MaybeObject*, Runtime_DeleteProperty) { |
4567 NoHandleAllocation ha; | 4566 NoHandleAllocation ha; |
4568 ASSERT(args.length() == 3); | 4567 ASSERT(args.length() == 3); |
4569 | 4568 |
4570 CONVERT_ARG_CHECKED(JSReceiver, object, 0); | 4569 CONVERT_ARG_CHECKED(JSReceiver, object, 0); |
4571 CONVERT_ARG_CHECKED(String, key, 1); | 4570 CONVERT_ARG_CHECKED(Name, key, 1); |
4572 CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode, 2); | 4571 CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode, 2); |
4573 return object->DeleteProperty(key, (strict_mode == kStrictMode) | 4572 return object->DeleteProperty(key, (strict_mode == kStrictMode) |
4574 ? JSReceiver::STRICT_DELETION | 4573 ? JSReceiver::STRICT_DELETION |
4575 : JSReceiver::NORMAL_DELETION); | 4574 : JSReceiver::NORMAL_DELETION); |
4576 } | 4575 } |
4577 | 4576 |
4578 | 4577 |
4579 static Object* HasLocalPropertyImplementation(Isolate* isolate, | 4578 static Object* HasLocalPropertyImplementation(Isolate* isolate, |
4580 Handle<JSObject> object, | 4579 Handle<JSObject> object, |
4581 Handle<String> key) { | 4580 Handle<Name> key) { |
4582 if (object->HasLocalProperty(*key)) return isolate->heap()->true_value(); | 4581 if (object->HasLocalProperty(*key)) return isolate->heap()->true_value(); |
4583 // Handle hidden prototypes. If there's a hidden prototype above this thing | 4582 // Handle hidden prototypes. If there's a hidden prototype above this thing |
4584 // then we have to check it for properties, because they are supposed to | 4583 // then we have to check it for properties, because they are supposed to |
4585 // look like they are on this object. | 4584 // look like they are on this object. |
4586 Handle<Object> proto(object->GetPrototype()); | 4585 Handle<Object> proto(object->GetPrototype()); |
4587 if (proto->IsJSObject() && | 4586 if (proto->IsJSObject() && |
4588 Handle<JSObject>::cast(proto)->map()->is_hidden_prototype()) { | 4587 Handle<JSObject>::cast(proto)->map()->is_hidden_prototype()) { |
4589 return HasLocalPropertyImplementation(isolate, | 4588 return HasLocalPropertyImplementation(isolate, |
4590 Handle<JSObject>::cast(proto), | 4589 Handle<JSObject>::cast(proto), |
4591 key); | 4590 key); |
4592 } | 4591 } |
4593 return isolate->heap()->false_value(); | 4592 return isolate->heap()->false_value(); |
4594 } | 4593 } |
4595 | 4594 |
4596 | 4595 |
4597 RUNTIME_FUNCTION(MaybeObject*, Runtime_HasLocalProperty) { | 4596 RUNTIME_FUNCTION(MaybeObject*, Runtime_HasLocalProperty) { |
4598 NoHandleAllocation ha; | 4597 NoHandleAllocation ha; |
4599 ASSERT(args.length() == 2); | 4598 ASSERT(args.length() == 2); |
4600 CONVERT_ARG_CHECKED(String, key, 1); | 4599 CONVERT_ARG_CHECKED(Name, key, 1); |
4601 | 4600 |
4602 uint32_t index; | 4601 uint32_t index; |
4603 const bool key_is_array_index = key->AsArrayIndex(&index); | 4602 const bool key_is_array_index = key->AsArrayIndex(&index); |
4604 | 4603 |
4605 Object* obj = args[0]; | 4604 Object* obj = args[0]; |
4606 // Only JS objects can have properties. | 4605 // Only JS objects can have properties. |
4607 if (obj->IsJSObject()) { | 4606 if (obj->IsJSObject()) { |
4608 JSObject* object = JSObject::cast(obj); | 4607 JSObject* object = JSObject::cast(obj); |
4609 // Fast case: either the key is a real named property or it is not | 4608 // Fast case: either the key is a real named property or it is not |
4610 // an array index and there are no interceptors or hidden | 4609 // an array index and there are no interceptors or hidden |
4611 // prototypes. | 4610 // prototypes. |
4612 if (object->HasRealNamedProperty(key)) return isolate->heap()->true_value(); | 4611 if (object->HasRealNamedProperty(key)) return isolate->heap()->true_value(); |
4613 Map* map = object->map(); | 4612 Map* map = object->map(); |
4614 if (!key_is_array_index && | 4613 if (!key_is_array_index && |
4615 !map->has_named_interceptor() && | 4614 !map->has_named_interceptor() && |
4616 !HeapObject::cast(map->prototype())->map()->is_hidden_prototype()) { | 4615 !HeapObject::cast(map->prototype())->map()->is_hidden_prototype()) { |
4617 return isolate->heap()->false_value(); | 4616 return isolate->heap()->false_value(); |
4618 } | 4617 } |
4619 // Slow case. | 4618 // Slow case. |
4620 HandleScope scope(isolate); | 4619 HandleScope scope(isolate); |
4621 return HasLocalPropertyImplementation(isolate, | 4620 return HasLocalPropertyImplementation(isolate, |
4622 Handle<JSObject>(object), | 4621 Handle<JSObject>(object), |
4623 Handle<String>(key)); | 4622 Handle<Name>(key)); |
4624 } else if (obj->IsString() && key_is_array_index) { | 4623 } else if (obj->IsString() && key_is_array_index) { |
4625 // Well, there is one exception: Handle [] on strings. | 4624 // Well, there is one exception: Handle [] on strings. |
4626 String* string = String::cast(obj); | 4625 String* string = String::cast(obj); |
4627 if (index < static_cast<uint32_t>(string->length())) { | 4626 if (index < static_cast<uint32_t>(string->length())) { |
4628 return isolate->heap()->true_value(); | 4627 return isolate->heap()->true_value(); |
4629 } | 4628 } |
4630 } | 4629 } |
4631 return isolate->heap()->false_value(); | 4630 return isolate->heap()->false_value(); |
4632 } | 4631 } |
4633 | 4632 |
4634 | 4633 |
4635 RUNTIME_FUNCTION(MaybeObject*, Runtime_HasProperty) { | 4634 RUNTIME_FUNCTION(MaybeObject*, Runtime_HasProperty) { |
4636 NoHandleAllocation na; | 4635 NoHandleAllocation na; |
4637 ASSERT(args.length() == 2); | 4636 ASSERT(args.length() == 2); |
4638 CONVERT_ARG_CHECKED(JSReceiver, receiver, 0); | 4637 CONVERT_ARG_CHECKED(JSReceiver, receiver, 0); |
4639 CONVERT_ARG_CHECKED(String, key, 1); | 4638 CONVERT_ARG_CHECKED(Name, key, 1); |
4640 | 4639 |
4641 bool result = receiver->HasProperty(key); | 4640 bool result = receiver->HasProperty(key); |
4642 if (isolate->has_pending_exception()) return Failure::Exception(); | 4641 if (isolate->has_pending_exception()) return Failure::Exception(); |
4643 return isolate->heap()->ToBoolean(result); | 4642 return isolate->heap()->ToBoolean(result); |
4644 } | 4643 } |
4645 | 4644 |
4646 | 4645 |
4647 RUNTIME_FUNCTION(MaybeObject*, Runtime_HasElement) { | 4646 RUNTIME_FUNCTION(MaybeObject*, Runtime_HasElement) { |
4648 NoHandleAllocation na; | 4647 NoHandleAllocation na; |
4649 ASSERT(args.length() == 2); | 4648 ASSERT(args.length() == 2); |
4650 CONVERT_ARG_CHECKED(JSReceiver, receiver, 0); | 4649 CONVERT_ARG_CHECKED(JSReceiver, receiver, 0); |
4651 CONVERT_SMI_ARG_CHECKED(index, 1); | 4650 CONVERT_SMI_ARG_CHECKED(index, 1); |
4652 | 4651 |
4653 bool result = receiver->HasElement(index); | 4652 bool result = receiver->HasElement(index); |
4654 if (isolate->has_pending_exception()) return Failure::Exception(); | 4653 if (isolate->has_pending_exception()) return Failure::Exception(); |
4655 return isolate->heap()->ToBoolean(result); | 4654 return isolate->heap()->ToBoolean(result); |
4656 } | 4655 } |
4657 | 4656 |
4658 | 4657 |
4659 RUNTIME_FUNCTION(MaybeObject*, Runtime_IsPropertyEnumerable) { | 4658 RUNTIME_FUNCTION(MaybeObject*, Runtime_IsPropertyEnumerable) { |
4660 NoHandleAllocation ha; | 4659 NoHandleAllocation ha; |
4661 ASSERT(args.length() == 2); | 4660 ASSERT(args.length() == 2); |
4662 | 4661 |
4663 CONVERT_ARG_CHECKED(JSObject, object, 0); | 4662 CONVERT_ARG_CHECKED(JSObject, object, 0); |
4664 CONVERT_ARG_CHECKED(String, key, 1); | 4663 CONVERT_ARG_CHECKED(Name, key, 1); |
4665 | 4664 |
4666 PropertyAttributes att = object->GetLocalPropertyAttribute(key); | 4665 PropertyAttributes att = object->GetLocalPropertyAttribute(key); |
4667 return isolate->heap()->ToBoolean(att != ABSENT && (att & DONT_ENUM) == 0); | 4666 return isolate->heap()->ToBoolean(att != ABSENT && (att & DONT_ENUM) == 0); |
4668 } | 4667 } |
4669 | 4668 |
4670 | 4669 |
4671 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetPropertyNames) { | 4670 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetPropertyNames) { |
4672 HandleScope scope(isolate); | 4671 HandleScope scope(isolate); |
4673 ASSERT(args.length() == 1); | 4672 ASSERT(args.length() == 1); |
4674 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0); | 4673 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0); |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4898 GetKeysInFixedArrayFor(object, LOCAL_ONLY, &threw); | 4897 GetKeysInFixedArrayFor(object, LOCAL_ONLY, &threw); |
4899 if (threw) return Failure::Exception(); | 4898 if (threw) return Failure::Exception(); |
4900 | 4899 |
4901 // Some fast paths through GetKeysInFixedArrayFor reuse a cached | 4900 // Some fast paths through GetKeysInFixedArrayFor reuse a cached |
4902 // property array and since the result is mutable we have to create | 4901 // property array and since the result is mutable we have to create |
4903 // a fresh clone on each invocation. | 4902 // a fresh clone on each invocation. |
4904 int length = contents->length(); | 4903 int length = contents->length(); |
4905 Handle<FixedArray> copy = isolate->factory()->NewFixedArray(length); | 4904 Handle<FixedArray> copy = isolate->factory()->NewFixedArray(length); |
4906 for (int i = 0; i < length; i++) { | 4905 for (int i = 0; i < length; i++) { |
4907 Object* entry = contents->get(i); | 4906 Object* entry = contents->get(i); |
4908 if (entry->IsString()) { | 4907 if (entry->IsName()) { |
4909 copy->set(i, entry); | 4908 copy->set(i, entry); |
4910 } else { | 4909 } else { |
4911 ASSERT(entry->IsNumber()); | 4910 ASSERT(entry->IsNumber()); |
4912 HandleScope scope(isolate); | 4911 HandleScope scope(isolate); |
4913 Handle<Object> entry_handle(entry, isolate); | 4912 Handle<Object> entry_handle(entry, isolate); |
4914 Handle<Object> entry_str = | 4913 Handle<Object> entry_str = |
4915 isolate->factory()->NumberToString(entry_handle); | 4914 isolate->factory()->NumberToString(entry_handle); |
4916 copy->set(i, *entry_str); | 4915 copy->set(i, *entry_str); |
4917 } | 4916 } |
4918 } | 4917 } |
(...skipping 13 matching lines...) Expand all Loading... |
4932 // Get the actual number of provided arguments. | 4931 // Get the actual number of provided arguments. |
4933 const uint32_t n = frame->ComputeParametersCount(); | 4932 const uint32_t n = frame->ComputeParametersCount(); |
4934 | 4933 |
4935 // Try to convert the key to an index. If successful and within | 4934 // Try to convert the key to an index. If successful and within |
4936 // index return the the argument from the frame. | 4935 // index return the the argument from the frame. |
4937 uint32_t index; | 4936 uint32_t index; |
4938 if (args[0]->ToArrayIndex(&index) && index < n) { | 4937 if (args[0]->ToArrayIndex(&index) && index < n) { |
4939 return frame->GetParameter(index); | 4938 return frame->GetParameter(index); |
4940 } | 4939 } |
4941 | 4940 |
| 4941 if (args[0]->IsSymbol()) { |
| 4942 // Lookup in the initial Object.prototype object. |
| 4943 return isolate->initial_object_prototype()->GetProperty( |
| 4944 Symbol::cast(args[0])); |
| 4945 } |
| 4946 |
4942 // Convert the key to a string. | 4947 // Convert the key to a string. |
4943 HandleScope scope(isolate); | 4948 HandleScope scope(isolate); |
4944 bool exception = false; | 4949 bool exception = false; |
4945 Handle<Object> converted = | 4950 Handle<Object> converted = |
4946 Execution::ToString(args.at<Object>(0), &exception); | 4951 Execution::ToString(args.at<Object>(0), &exception); |
4947 if (exception) return Failure::Exception(); | 4952 if (exception) return Failure::Exception(); |
4948 Handle<String> key = Handle<String>::cast(converted); | 4953 Handle<String> key = Handle<String>::cast(converted); |
4949 | 4954 |
4950 // Try to convert the string key into an array index. | 4955 // Try to convert the string key into an array index. |
4951 if (key->AsArrayIndex(&index)) { | 4956 if (key->AsArrayIndex(&index)) { |
(...skipping 5120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10072 isolate->factory()->NewNumber(static_cast<double>(min_length)); | 10077 isolate->factory()->NewNumber(static_cast<double>(min_length)); |
10073 single_interval->set(1, *length_object); | 10078 single_interval->set(1, *length_object); |
10074 return *isolate->factory()->NewJSArrayWithElements(single_interval); | 10079 return *isolate->factory()->NewJSArrayWithElements(single_interval); |
10075 } | 10080 } |
10076 } | 10081 } |
10077 | 10082 |
10078 | 10083 |
10079 RUNTIME_FUNCTION(MaybeObject*, Runtime_LookupAccessor) { | 10084 RUNTIME_FUNCTION(MaybeObject*, Runtime_LookupAccessor) { |
10080 ASSERT(args.length() == 3); | 10085 ASSERT(args.length() == 3); |
10081 CONVERT_ARG_CHECKED(JSReceiver, receiver, 0); | 10086 CONVERT_ARG_CHECKED(JSReceiver, receiver, 0); |
10082 CONVERT_ARG_CHECKED(String, name, 1); | 10087 CONVERT_ARG_CHECKED(Name, name, 1); |
10083 CONVERT_SMI_ARG_CHECKED(flag, 2); | 10088 CONVERT_SMI_ARG_CHECKED(flag, 2); |
10084 AccessorComponent component = flag == 0 ? ACCESSOR_GETTER : ACCESSOR_SETTER; | 10089 AccessorComponent component = flag == 0 ? ACCESSOR_GETTER : ACCESSOR_SETTER; |
10085 if (!receiver->IsJSObject()) return isolate->heap()->undefined_value(); | 10090 if (!receiver->IsJSObject()) return isolate->heap()->undefined_value(); |
10086 return JSObject::cast(receiver)->LookupAccessor(name, component); | 10091 return JSObject::cast(receiver)->LookupAccessor(name, component); |
10087 } | 10092 } |
10088 | 10093 |
10089 | 10094 |
10090 #ifdef ENABLE_DEBUGGER_SUPPORT | 10095 #ifdef ENABLE_DEBUGGER_SUPPORT |
10091 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugBreak) { | 10096 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugBreak) { |
10092 ASSERT(args.length() == 0); | 10097 ASSERT(args.length() == 0); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10125 | 10130 |
10126 RUNTIME_FUNCTION(MaybeObject*, Runtime_Break) { | 10131 RUNTIME_FUNCTION(MaybeObject*, Runtime_Break) { |
10127 ASSERT(args.length() == 0); | 10132 ASSERT(args.length() == 0); |
10128 isolate->stack_guard()->DebugBreak(); | 10133 isolate->stack_guard()->DebugBreak(); |
10129 return isolate->heap()->undefined_value(); | 10134 return isolate->heap()->undefined_value(); |
10130 } | 10135 } |
10131 | 10136 |
10132 | 10137 |
10133 static MaybeObject* DebugLookupResultValue(Heap* heap, | 10138 static MaybeObject* DebugLookupResultValue(Heap* heap, |
10134 Object* receiver, | 10139 Object* receiver, |
10135 String* name, | 10140 Name* name, |
10136 LookupResult* result, | 10141 LookupResult* result, |
10137 bool* caught_exception) { | 10142 bool* caught_exception) { |
10138 Object* value; | 10143 Object* value; |
10139 switch (result->type()) { | 10144 switch (result->type()) { |
10140 case NORMAL: | 10145 case NORMAL: |
10141 value = result->holder()->GetNormalizedProperty(result); | 10146 value = result->holder()->GetNormalizedProperty(result); |
10142 if (value->IsTheHole()) { | 10147 if (value->IsTheHole()) { |
10143 return heap->undefined_value(); | 10148 return heap->undefined_value(); |
10144 } | 10149 } |
10145 return value; | 10150 return value; |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10197 // 3: Getter function if defined | 10202 // 3: Getter function if defined |
10198 // 4: Setter function if defined | 10203 // 4: Setter function if defined |
10199 // Items 2-4 are only filled if the property has either a getter or a setter | 10204 // Items 2-4 are only filled if the property has either a getter or a setter |
10200 // defined through __defineGetter__ and/or __defineSetter__. | 10205 // defined through __defineGetter__ and/or __defineSetter__. |
10201 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugGetPropertyDetails) { | 10206 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugGetPropertyDetails) { |
10202 HandleScope scope(isolate); | 10207 HandleScope scope(isolate); |
10203 | 10208 |
10204 ASSERT(args.length() == 2); | 10209 ASSERT(args.length() == 2); |
10205 | 10210 |
10206 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); | 10211 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); |
10207 CONVERT_ARG_HANDLE_CHECKED(String, name, 1); | 10212 CONVERT_ARG_HANDLE_CHECKED(Name, name, 1); |
10208 | 10213 |
10209 // Make sure to set the current context to the context before the debugger was | 10214 // Make sure to set the current context to the context before the debugger was |
10210 // entered (if the debugger is entered). The reason for switching context here | 10215 // entered (if the debugger is entered). The reason for switching context here |
10211 // is that for some property lookups (accessors and interceptors) callbacks | 10216 // is that for some property lookups (accessors and interceptors) callbacks |
10212 // into the embedding application can occour, and the embedding application | 10217 // into the embedding application can occour, and the embedding application |
10213 // could have the assumption that its own native context is the current | 10218 // could have the assumption that its own native context is the current |
10214 // context and not some internal debugger context. | 10219 // context and not some internal debugger context. |
10215 SaveContext save(isolate); | 10220 SaveContext save(isolate); |
10216 if (isolate->debug()->InDebugger()) { | 10221 if (isolate->debug()->InDebugger()) { |
10217 isolate->set_context(*isolate->debug()->debugger_entry()->GetContext()); | 10222 isolate->set_context(*isolate->debug()->debugger_entry()->GetContext()); |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10295 return isolate->heap()->undefined_value(); | 10300 return isolate->heap()->undefined_value(); |
10296 } | 10301 } |
10297 | 10302 |
10298 | 10303 |
10299 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugGetProperty) { | 10304 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugGetProperty) { |
10300 HandleScope scope(isolate); | 10305 HandleScope scope(isolate); |
10301 | 10306 |
10302 ASSERT(args.length() == 2); | 10307 ASSERT(args.length() == 2); |
10303 | 10308 |
10304 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); | 10309 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); |
10305 CONVERT_ARG_HANDLE_CHECKED(String, name, 1); | 10310 CONVERT_ARG_HANDLE_CHECKED(Name, name, 1); |
10306 | 10311 |
10307 LookupResult result(isolate); | 10312 LookupResult result(isolate); |
10308 obj->Lookup(*name, &result); | 10313 obj->Lookup(*name, &result); |
10309 if (result.IsFound()) { | 10314 if (result.IsFound()) { |
10310 return DebugLookupResultValue(isolate->heap(), *obj, *name, &result, NULL); | 10315 return DebugLookupResultValue(isolate->heap(), *obj, *name, &result, NULL); |
10311 } | 10316 } |
10312 return isolate->heap()->undefined_value(); | 10317 return isolate->heap()->undefined_value(); |
10313 } | 10318 } |
10314 | 10319 |
10315 | 10320 |
(...skipping 26 matching lines...) Expand all Loading... |
10342 | 10347 |
10343 | 10348 |
10344 // Return property value from named interceptor. | 10349 // Return property value from named interceptor. |
10345 // args[0]: object | 10350 // args[0]: object |
10346 // args[1]: property name | 10351 // args[1]: property name |
10347 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugNamedInterceptorPropertyValue) { | 10352 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugNamedInterceptorPropertyValue) { |
10348 HandleScope scope(isolate); | 10353 HandleScope scope(isolate); |
10349 ASSERT(args.length() == 2); | 10354 ASSERT(args.length() == 2); |
10350 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); | 10355 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); |
10351 RUNTIME_ASSERT(obj->HasNamedInterceptor()); | 10356 RUNTIME_ASSERT(obj->HasNamedInterceptor()); |
10352 CONVERT_ARG_HANDLE_CHECKED(String, name, 1); | 10357 CONVERT_ARG_HANDLE_CHECKED(Name, name, 1); |
10353 | 10358 |
10354 PropertyAttributes attributes; | 10359 PropertyAttributes attributes; |
10355 return obj->GetPropertyWithInterceptor(*obj, *name, &attributes); | 10360 return obj->GetPropertyWithInterceptor(*obj, *name, &attributes); |
10356 } | 10361 } |
10357 | 10362 |
10358 | 10363 |
10359 // Return element value from indexed interceptor. | 10364 // Return element value from indexed interceptor. |
10360 // args[0]: object | 10365 // args[0]: object |
10361 // args[1]: index | 10366 // args[1]: index |
10362 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugIndexedInterceptorElementValue) { | 10367 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugIndexedInterceptorElementValue) { |
(...skipping 3108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13471 RUNTIME_FUNCTION_LIST(F) | 13476 RUNTIME_FUNCTION_LIST(F) |
13472 INLINE_FUNCTION_LIST(I) | 13477 INLINE_FUNCTION_LIST(I) |
13473 INLINE_RUNTIME_FUNCTION_LIST(I) | 13478 INLINE_RUNTIME_FUNCTION_LIST(I) |
13474 }; | 13479 }; |
13475 | 13480 |
13476 | 13481 |
13477 MaybeObject* Runtime::InitializeIntrinsicFunctionNames(Heap* heap, | 13482 MaybeObject* Runtime::InitializeIntrinsicFunctionNames(Heap* heap, |
13478 Object* dictionary) { | 13483 Object* dictionary) { |
13479 ASSERT(Isolate::Current()->heap() == heap); | 13484 ASSERT(Isolate::Current()->heap() == heap); |
13480 ASSERT(dictionary != NULL); | 13485 ASSERT(dictionary != NULL); |
13481 ASSERT(StringDictionary::cast(dictionary)->NumberOfElements() == 0); | 13486 ASSERT(NameDictionary::cast(dictionary)->NumberOfElements() == 0); |
13482 for (int i = 0; i < kNumFunctions; ++i) { | 13487 for (int i = 0; i < kNumFunctions; ++i) { |
13483 Object* name_string; | 13488 Object* name_string; |
13484 { MaybeObject* maybe_name_string = | 13489 { MaybeObject* maybe_name_string = |
13485 heap->InternalizeUtf8String(kIntrinsicFunctions[i].name); | 13490 heap->InternalizeUtf8String(kIntrinsicFunctions[i].name); |
13486 if (!maybe_name_string->ToObject(&name_string)) return maybe_name_string; | 13491 if (!maybe_name_string->ToObject(&name_string)) return maybe_name_string; |
13487 } | 13492 } |
13488 StringDictionary* string_dictionary = StringDictionary::cast(dictionary); | 13493 NameDictionary* name_dictionary = NameDictionary::cast(dictionary); |
13489 { MaybeObject* maybe_dictionary = string_dictionary->Add( | 13494 { MaybeObject* maybe_dictionary = name_dictionary->Add( |
13490 String::cast(name_string), | 13495 String::cast(name_string), |
13491 Smi::FromInt(i), | 13496 Smi::FromInt(i), |
13492 PropertyDetails(NONE, NORMAL)); | 13497 PropertyDetails(NONE, NORMAL)); |
13493 if (!maybe_dictionary->ToObject(&dictionary)) { | 13498 if (!maybe_dictionary->ToObject(&dictionary)) { |
13494 // Non-recoverable failure. Calling code must restart heap | 13499 // Non-recoverable failure. Calling code must restart heap |
13495 // initialization. | 13500 // initialization. |
13496 return maybe_dictionary; | 13501 return maybe_dictionary; |
13497 } | 13502 } |
13498 } | 13503 } |
13499 } | 13504 } |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13534 // Handle last resort GC and make sure to allow future allocations | 13539 // Handle last resort GC and make sure to allow future allocations |
13535 // to grow the heap without causing GCs (if possible). | 13540 // to grow the heap without causing GCs (if possible). |
13536 isolate->counters()->gc_last_resort_from_js()->Increment(); | 13541 isolate->counters()->gc_last_resort_from_js()->Increment(); |
13537 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, | 13542 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, |
13538 "Runtime::PerformGC"); | 13543 "Runtime::PerformGC"); |
13539 } | 13544 } |
13540 } | 13545 } |
13541 | 13546 |
13542 | 13547 |
13543 } } // namespace v8::internal | 13548 } } // namespace v8::internal |
OLD | NEW |