Chromium Code Reviews| 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 8903 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8914 EnsureElementsMode mode) { | 8914 EnsureElementsMode mode) { |
| 8915 // Elements in |Arguments| are ordered backwards (because they're on the | 8915 // Elements in |Arguments| are ordered backwards (because they're on the |
| 8916 // stack), but the method that's called here iterates over them in forward | 8916 // stack), but the method that's called here iterates over them in forward |
| 8917 // direction. | 8917 // direction. |
| 8918 return EnsureCanContainElements( | 8918 return EnsureCanContainElements( |
| 8919 args->arguments() - first_arg - (arg_count - 1), | 8919 args->arguments() - first_arg - (arg_count - 1), |
| 8920 arg_count, mode); | 8920 arg_count, mode); |
| 8921 } | 8921 } |
| 8922 | 8922 |
| 8923 | 8923 |
| 8924 bool JSObject::HasElementPostInterceptor(JSReceiver* receiver, uint32_t index) { | |
| 8925 switch (GetElementsKind()) { | |
| 8926 case FAST_SMI_ONLY_ELEMENTS: | |
| 8927 case FAST_ELEMENTS: { | |
| 8928 uint32_t length = IsJSArray() ? | |
| 8929 static_cast<uint32_t> | |
| 8930 (Smi::cast(JSArray::cast(this)->length())->value()) : | |
| 8931 static_cast<uint32_t>(FixedArray::cast(elements())->length()); | |
| 8932 if ((index < length) && | |
| 8933 !FixedArray::cast(elements())->get(index)->IsTheHole()) { | |
| 8934 return true; | |
| 8935 } | |
| 8936 break; | |
| 8937 } | |
| 8938 case FAST_DOUBLE_ELEMENTS: { | |
| 8939 uint32_t length = IsJSArray() ? | |
| 8940 static_cast<uint32_t> | |
| 8941 (Smi::cast(JSArray::cast(this)->length())->value()) : | |
| 8942 static_cast<uint32_t>(FixedDoubleArray::cast(elements())->length()); | |
| 8943 if ((index < length) && | |
| 8944 !FixedDoubleArray::cast(elements())->is_the_hole(index)) { | |
| 8945 return true; | |
| 8946 } | |
| 8947 break; | |
| 8948 } | |
| 8949 case EXTERNAL_PIXEL_ELEMENTS: { | |
| 8950 ExternalPixelArray* pixels = ExternalPixelArray::cast(elements()); | |
| 8951 if (index < static_cast<uint32_t>(pixels->length())) { | |
| 8952 return true; | |
| 8953 } | |
| 8954 break; | |
| 8955 } | |
| 8956 case EXTERNAL_BYTE_ELEMENTS: | |
| 8957 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | |
| 8958 case EXTERNAL_SHORT_ELEMENTS: | |
| 8959 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | |
| 8960 case EXTERNAL_INT_ELEMENTS: | |
| 8961 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | |
| 8962 case EXTERNAL_FLOAT_ELEMENTS: | |
| 8963 case EXTERNAL_DOUBLE_ELEMENTS: { | |
| 8964 ExternalArray* array = ExternalArray::cast(elements()); | |
| 8965 if (index < static_cast<uint32_t>(array->length())) { | |
| 8966 return true; | |
| 8967 } | |
| 8968 break; | |
| 8969 } | |
| 8970 case DICTIONARY_ELEMENTS: { | |
| 8971 if (element_dictionary()->FindEntry(index) | |
| 8972 != SeededNumberDictionary::kNotFound) { | |
| 8973 return true; | |
| 8974 } | |
| 8975 break; | |
| 8976 } | |
| 8977 case NON_STRICT_ARGUMENTS_ELEMENTS: | |
| 8978 UNREACHABLE(); | |
| 8979 break; | |
| 8980 } | |
| 8981 | |
| 8982 // Handle [] on String objects. | |
| 8983 if (this->IsStringObjectWithCharacterAt(index)) return true; | |
| 8984 | |
| 8985 Object* pt = GetPrototype(); | |
| 8986 if (pt->IsNull()) return false; | |
| 8987 if (pt->IsJSProxy()) { | |
|
Jakob Kummerow
2012/03/05 10:54:11
where did this case go?
danno
2012/03/06 11:02:05
Done.
| |
| 8988 // We need to follow the spec and simulate a call to [[GetOwnProperty]]. | |
| 8989 return JSProxy::cast(pt)->GetElementAttributeWithHandler( | |
| 8990 receiver, index) != ABSENT; | |
| 8991 } | |
| 8992 return JSObject::cast(pt)->HasElementWithReceiver(receiver, index); | |
| 8993 } | |
| 8994 | |
| 8995 | |
| 8996 bool JSObject::HasElementWithInterceptor(JSReceiver* receiver, uint32_t index) { | 8924 bool JSObject::HasElementWithInterceptor(JSReceiver* receiver, uint32_t index) { |
| 8997 Isolate* isolate = GetIsolate(); | 8925 Isolate* isolate = GetIsolate(); |
| 8998 // Make sure that the top context does not change when doing | 8926 // Make sure that the top context does not change when doing |
| 8999 // callbacks or interceptor calls. | 8927 // callbacks or interceptor calls. |
| 9000 AssertNoContextChange ncc; | 8928 AssertNoContextChange ncc; |
| 9001 HandleScope scope(isolate); | 8929 HandleScope scope(isolate); |
| 9002 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor()); | 8930 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor()); |
| 9003 Handle<JSReceiver> receiver_handle(receiver); | 8931 Handle<JSReceiver> receiver_handle(receiver); |
| 9004 Handle<JSObject> holder_handle(this); | 8932 Handle<JSObject> holder_handle(this); |
| 9005 CustomArguments args(isolate, interceptor->data(), receiver, this); | 8933 CustomArguments args(isolate, interceptor->data(), receiver, this); |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 9025 LOG(isolate, | 8953 LOG(isolate, |
| 9026 ApiIndexedPropertyAccess("interceptor-indexed-has-get", this, index)); | 8954 ApiIndexedPropertyAccess("interceptor-indexed-has-get", this, index)); |
| 9027 v8::Handle<v8::Value> result; | 8955 v8::Handle<v8::Value> result; |
| 9028 { | 8956 { |
| 9029 // Leaving JavaScript. | 8957 // Leaving JavaScript. |
| 9030 VMState state(isolate, EXTERNAL); | 8958 VMState state(isolate, EXTERNAL); |
| 9031 result = getter(index, info); | 8959 result = getter(index, info); |
| 9032 } | 8960 } |
| 9033 if (!result.IsEmpty()) return true; | 8961 if (!result.IsEmpty()) return true; |
| 9034 } | 8962 } |
| 9035 return holder_handle->HasElementPostInterceptor(*receiver_handle, index); | 8963 |
| 8964 if (holder_handle->GetElementsAccessor()->HasElement( | |
| 8965 holder_handle->elements(), index, *holder_handle, *receiver_handle)) { | |
| 8966 return true; | |
| 8967 } | |
| 8968 | |
| 8969 if (holder_handle->IsStringObjectWithCharacterAt(index)) return true; | |
| 8970 Object* pt = holder_handle->GetPrototype(); | |
| 8971 if (pt->IsNull()) return false; | |
| 8972 return JSObject::cast(pt)->HasElementWithReceiver(*receiver_handle, index); | |
| 9036 } | 8973 } |
| 9037 | 8974 |
| 9038 | 8975 |
| 9039 JSObject::LocalElementType JSObject::HasLocalElement(uint32_t index) { | 8976 JSObject::LocalElementType JSObject::HasLocalElement(uint32_t index) { |
| 9040 // Check access rights if needed. | 8977 // Check access rights if needed. |
| 9041 if (IsAccessCheckNeeded()) { | 8978 if (IsAccessCheckNeeded()) { |
| 9042 Heap* heap = GetHeap(); | 8979 Heap* heap = GetHeap(); |
| 9043 if (!heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_HAS)) { | 8980 if (!heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_HAS)) { |
| 9044 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS); | 8981 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS); |
| 9045 return UNDEFINED_ELEMENT; | 8982 return UNDEFINED_ELEMENT; |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 9135 if (probe != NULL && !probe->IsTheHole()) return FAST_ELEMENT; | 9072 if (probe != NULL && !probe->IsTheHole()) return FAST_ELEMENT; |
| 9136 } | 9073 } |
| 9137 break; | 9074 break; |
| 9138 } | 9075 } |
| 9139 } | 9076 } |
| 9140 | 9077 |
| 9141 return UNDEFINED_ELEMENT; | 9078 return UNDEFINED_ELEMENT; |
| 9142 } | 9079 } |
| 9143 | 9080 |
| 9144 | 9081 |
| 9145 bool JSObject::HasElementInElements(FixedArray* elements, | |
| 9146 ElementsKind kind, | |
| 9147 uint32_t index) { | |
| 9148 ASSERT(kind == FAST_ELEMENTS || kind == DICTIONARY_ELEMENTS); | |
| 9149 if (kind == FAST_ELEMENTS) { | |
| 9150 int length = IsJSArray() | |
| 9151 ? Smi::cast(JSArray::cast(this)->length())->value() | |
| 9152 : elements->length(); | |
| 9153 if (index < static_cast<uint32_t>(length) && | |
| 9154 !elements->get(index)->IsTheHole()) { | |
| 9155 return true; | |
| 9156 } | |
| 9157 } else { | |
| 9158 if (SeededNumberDictionary::cast(elements)->FindEntry(index) != | |
| 9159 SeededNumberDictionary::kNotFound) { | |
| 9160 return true; | |
| 9161 } | |
| 9162 } | |
| 9163 return false; | |
| 9164 } | |
| 9165 | |
| 9166 | |
| 9167 bool JSObject::HasElementWithReceiver(JSReceiver* receiver, uint32_t index) { | 9082 bool JSObject::HasElementWithReceiver(JSReceiver* receiver, uint32_t index) { |
| 9168 // Check access rights if needed. | 9083 // Check access rights if needed. |
| 9169 if (IsAccessCheckNeeded()) { | 9084 if (IsAccessCheckNeeded()) { |
| 9170 Heap* heap = GetHeap(); | 9085 Heap* heap = GetHeap(); |
| 9171 if (!heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_HAS)) { | 9086 if (!heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_HAS)) { |
| 9172 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS); | 9087 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS); |
| 9173 return false; | 9088 return false; |
| 9174 } | 9089 } |
| 9175 } | 9090 } |
| 9176 | 9091 |
| 9177 // Check for lookup interceptor | 9092 // Check for lookup interceptor |
| 9178 if (HasIndexedInterceptor()) { | 9093 if (HasIndexedInterceptor()) { |
| 9179 return HasElementWithInterceptor(receiver, index); | 9094 return HasElementWithInterceptor(receiver, index); |
| 9180 } | 9095 } |
| 9181 | 9096 |
| 9182 ElementsKind kind = GetElementsKind(); | 9097 ElementsAccessor* accessor = GetElementsAccessor(); |
| 9183 switch (kind) { | 9098 if (accessor->HasElement(elements(), index, this, receiver)) { |
| 9184 case FAST_SMI_ONLY_ELEMENTS: | 9099 return true; |
| 9185 case FAST_ELEMENTS: { | |
| 9186 uint32_t length = IsJSArray() ? | |
| 9187 static_cast<uint32_t> | |
| 9188 (Smi::cast(JSArray::cast(this)->length())->value()) : | |
| 9189 static_cast<uint32_t>(FixedArray::cast(elements())->length()); | |
| 9190 if ((index < length) && | |
| 9191 !FixedArray::cast(elements())->get(index)->IsTheHole()) return true; | |
| 9192 break; | |
| 9193 } | |
| 9194 case FAST_DOUBLE_ELEMENTS: { | |
| 9195 uint32_t length = IsJSArray() ? | |
| 9196 static_cast<uint32_t> | |
| 9197 (Smi::cast(JSArray::cast(this)->length())->value()) : | |
| 9198 static_cast<uint32_t>(FixedDoubleArray::cast(elements())->length()); | |
| 9199 if ((index < length) && | |
| 9200 !FixedDoubleArray::cast(elements())->is_the_hole(index)) return true; | |
| 9201 break; | |
| 9202 } | |
| 9203 case EXTERNAL_PIXEL_ELEMENTS: { | |
| 9204 ExternalPixelArray* pixels = ExternalPixelArray::cast(elements()); | |
| 9205 if (index < static_cast<uint32_t>(pixels->length())) { | |
| 9206 return true; | |
| 9207 } | |
| 9208 break; | |
| 9209 } | |
| 9210 case EXTERNAL_BYTE_ELEMENTS: | |
| 9211 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | |
| 9212 case EXTERNAL_SHORT_ELEMENTS: | |
| 9213 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | |
| 9214 case EXTERNAL_INT_ELEMENTS: | |
| 9215 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | |
| 9216 case EXTERNAL_FLOAT_ELEMENTS: | |
| 9217 case EXTERNAL_DOUBLE_ELEMENTS: { | |
| 9218 ExternalArray* array = ExternalArray::cast(elements()); | |
| 9219 if (index < static_cast<uint32_t>(array->length())) { | |
| 9220 return true; | |
| 9221 } | |
| 9222 break; | |
| 9223 } | |
| 9224 case DICTIONARY_ELEMENTS: { | |
| 9225 if (element_dictionary()->FindEntry(index) | |
| 9226 != SeededNumberDictionary::kNotFound) { | |
| 9227 return true; | |
| 9228 } | |
| 9229 break; | |
| 9230 } | |
| 9231 case NON_STRICT_ARGUMENTS_ELEMENTS: { | |
| 9232 FixedArray* parameter_map = FixedArray::cast(elements()); | |
| 9233 uint32_t length = parameter_map->length(); | |
| 9234 Object* probe = | |
| 9235 (index < length - 2) ? parameter_map->get(index + 2) : NULL; | |
| 9236 if (probe != NULL && !probe->IsTheHole()) return true; | |
| 9237 | |
| 9238 // Not a mapped parameter, check the arguments. | |
| 9239 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); | |
| 9240 kind = arguments->IsDictionary() ? DICTIONARY_ELEMENTS : FAST_ELEMENTS; | |
| 9241 if (HasElementInElements(arguments, kind, index)) return true; | |
| 9242 break; | |
| 9243 } | |
| 9244 } | 9100 } |
| 9245 | 9101 |
| 9246 // Handle [] on String objects. | 9102 // Handle [] on String objects. |
| 9247 if (this->IsStringObjectWithCharacterAt(index)) return true; | 9103 if (this->IsStringObjectWithCharacterAt(index)) return true; |
| 9248 | 9104 |
| 9249 Object* pt = GetPrototype(); | 9105 Object* pt = GetPrototype(); |
| 9250 if (pt->IsNull()) return false; | 9106 if (pt->IsNull()) return false; |
| 9251 if (pt->IsJSProxy()) { | 9107 if (pt->IsJSProxy()) { |
| 9252 // We need to follow the spec and simulate a call to [[GetOwnProperty]]. | 9108 // We need to follow the spec and simulate a call to [[GetOwnProperty]]. |
| 9253 return JSProxy::cast(pt)->GetElementAttributeWithHandler( | 9109 return JSProxy::cast(pt)->GetElementAttributeWithHandler( |
| (...skipping 3913 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 13167 if (break_point_objects()->IsUndefined()) return 0; | 13023 if (break_point_objects()->IsUndefined()) return 0; |
| 13168 // Single break point. | 13024 // Single break point. |
| 13169 if (!break_point_objects()->IsFixedArray()) return 1; | 13025 if (!break_point_objects()->IsFixedArray()) return 1; |
| 13170 // Multiple break points. | 13026 // Multiple break points. |
| 13171 return FixedArray::cast(break_point_objects())->length(); | 13027 return FixedArray::cast(break_point_objects())->length(); |
| 13172 } | 13028 } |
| 13173 #endif // ENABLE_DEBUGGER_SUPPORT | 13029 #endif // ENABLE_DEBUGGER_SUPPORT |
| 13174 | 13030 |
| 13175 | 13031 |
| 13176 } } // namespace v8::internal | 13032 } } // namespace v8::internal |
| OLD | NEW |