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