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 |