OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 513 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
524 return holder->GetPropertyWithInterceptor(recvr, name, attributes); | 524 return holder->GetPropertyWithInterceptor(recvr, name, attributes); |
525 } | 525 } |
526 default: | 526 default: |
527 UNREACHABLE(); | 527 UNREACHABLE(); |
528 return NULL; | 528 return NULL; |
529 } | 529 } |
530 } | 530 } |
531 | 531 |
532 | 532 |
533 MaybeObject* Object::GetElementWithReceiver(Object* receiver, uint32_t index) { | 533 MaybeObject* Object::GetElementWithReceiver(Object* receiver, uint32_t index) { |
534 // Non-JS objects do not have integer indexed properties. | 534 if (IsJSObject()) { |
535 if (!IsJSObject()) return Heap::undefined_value(); | 535 return JSObject::cast(this)->GetElementWithReceiver(receiver, index); |
536 return JSObject::cast(this)->GetElementWithReceiver(JSObject::cast(receiver), | 536 } |
537 index); | 537 |
| 538 Object* holder = NULL; |
| 539 Context* global_context = Top::context()->global_context(); |
| 540 if (IsString()) { |
| 541 holder = global_context->string_function()->instance_prototype(); |
| 542 } else if (IsNumber()) { |
| 543 holder = global_context->number_function()->instance_prototype(); |
| 544 } else if (IsBoolean()) { |
| 545 holder = global_context->boolean_function()->instance_prototype(); |
| 546 } else { |
| 547 // Undefined and null have no indexed properties. |
| 548 ASSERT(IsUndefined() || IsNull()); |
| 549 return Heap::undefined_value(); |
| 550 } |
| 551 |
| 552 return JSObject::cast(holder)->GetElementWithReceiver(receiver, index); |
538 } | 553 } |
539 | 554 |
540 | 555 |
541 Object* Object::GetPrototype() { | 556 Object* Object::GetPrototype() { |
542 // The object is either a number, a string, a boolean, or a real JS object. | 557 // The object is either a number, a string, a boolean, or a real JS object. |
543 if (IsJSObject()) return JSObject::cast(this)->map()->prototype(); | 558 if (IsJSObject()) return JSObject::cast(this)->map()->prototype(); |
544 Context* context = Top::context()->global_context(); | 559 Context* context = Top::context()->global_context(); |
545 | 560 |
546 if (IsNumber()) return context->number_function()->instance_prototype(); | 561 if (IsNumber()) return context->number_function()->instance_prototype(); |
547 if (IsString()) return context->string_function()->instance_prototype(); | 562 if (IsString()) return context->string_function()->instance_prototype(); |
(...skipping 6682 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7230 { MaybeObject* maybe_len = | 7245 { MaybeObject* maybe_len = |
7231 Heap::NumberFromDouble(static_cast<double>(index) + 1); | 7246 Heap::NumberFromDouble(static_cast<double>(index) + 1); |
7232 if (!maybe_len->ToObject(&len)) return maybe_len; | 7247 if (!maybe_len->ToObject(&len)) return maybe_len; |
7233 } | 7248 } |
7234 set_length(len); | 7249 set_length(len); |
7235 } | 7250 } |
7236 return value; | 7251 return value; |
7237 } | 7252 } |
7238 | 7253 |
7239 | 7254 |
7240 MaybeObject* JSObject::GetElementPostInterceptor(JSObject* receiver, | 7255 MaybeObject* JSObject::GetElementPostInterceptor(Object* receiver, |
7241 uint32_t index) { | 7256 uint32_t index) { |
7242 // Get element works for both JSObject and JSArray since | 7257 // Get element works for both JSObject and JSArray since |
7243 // JSArray::length cannot change. | 7258 // JSArray::length cannot change. |
7244 switch (GetElementsKind()) { | 7259 switch (GetElementsKind()) { |
7245 case FAST_ELEMENTS: { | 7260 case FAST_ELEMENTS: { |
7246 FixedArray* elms = FixedArray::cast(elements()); | 7261 FixedArray* elms = FixedArray::cast(elements()); |
7247 if (index < static_cast<uint32_t>(elms->length())) { | 7262 if (index < static_cast<uint32_t>(elms->length())) { |
7248 Object* value = elms->get(index); | 7263 Object* value = elms->get(index); |
7249 if (!value->IsTheHole()) return value; | 7264 if (!value->IsTheHole()) return value; |
7250 } | 7265 } |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7287 break; | 7302 break; |
7288 } | 7303 } |
7289 | 7304 |
7290 // Continue searching via the prototype chain. | 7305 // Continue searching via the prototype chain. |
7291 Object* pt = GetPrototype(); | 7306 Object* pt = GetPrototype(); |
7292 if (pt == Heap::null_value()) return Heap::undefined_value(); | 7307 if (pt == Heap::null_value()) return Heap::undefined_value(); |
7293 return pt->GetElementWithReceiver(receiver, index); | 7308 return pt->GetElementWithReceiver(receiver, index); |
7294 } | 7309 } |
7295 | 7310 |
7296 | 7311 |
7297 MaybeObject* JSObject::GetElementWithInterceptor(JSObject* receiver, | 7312 MaybeObject* JSObject::GetElementWithInterceptor(Object* receiver, |
7298 uint32_t index) { | 7313 uint32_t index) { |
7299 // Make sure that the top context does not change when doing | 7314 // Make sure that the top context does not change when doing |
7300 // callbacks or interceptor calls. | 7315 // callbacks or interceptor calls. |
7301 AssertNoContextChange ncc; | 7316 AssertNoContextChange ncc; |
7302 HandleScope scope; | 7317 HandleScope scope; |
7303 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor()); | 7318 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor()); |
7304 Handle<JSObject> this_handle(receiver); | 7319 Handle<Object> this_handle(receiver); |
7305 Handle<JSObject> holder_handle(this); | 7320 Handle<JSObject> holder_handle(this); |
7306 | 7321 |
7307 if (!interceptor->getter()->IsUndefined()) { | 7322 if (!interceptor->getter()->IsUndefined()) { |
7308 v8::IndexedPropertyGetter getter = | 7323 v8::IndexedPropertyGetter getter = |
7309 v8::ToCData<v8::IndexedPropertyGetter>(interceptor->getter()); | 7324 v8::ToCData<v8::IndexedPropertyGetter>(interceptor->getter()); |
7310 LOG(ApiIndexedPropertyAccess("interceptor-indexed-get", this, index)); | 7325 LOG(ApiIndexedPropertyAccess("interceptor-indexed-get", this, index)); |
7311 CustomArguments args(interceptor->data(), receiver, this); | 7326 CustomArguments args(interceptor->data(), receiver, this); |
7312 v8::AccessorInfo info(args.end()); | 7327 v8::AccessorInfo info(args.end()); |
7313 v8::Handle<v8::Value> result; | 7328 v8::Handle<v8::Value> result; |
7314 { | 7329 { |
7315 // Leaving JavaScript. | 7330 // Leaving JavaScript. |
7316 VMState state(EXTERNAL); | 7331 VMState state(EXTERNAL); |
7317 result = getter(index, info); | 7332 result = getter(index, info); |
7318 } | 7333 } |
7319 RETURN_IF_SCHEDULED_EXCEPTION(); | 7334 RETURN_IF_SCHEDULED_EXCEPTION(); |
7320 if (!result.IsEmpty()) return *v8::Utils::OpenHandle(*result); | 7335 if (!result.IsEmpty()) return *v8::Utils::OpenHandle(*result); |
7321 } | 7336 } |
7322 | 7337 |
7323 MaybeObject* raw_result = | 7338 MaybeObject* raw_result = |
7324 holder_handle->GetElementPostInterceptor(*this_handle, index); | 7339 holder_handle->GetElementPostInterceptor(*this_handle, index); |
7325 RETURN_IF_SCHEDULED_EXCEPTION(); | 7340 RETURN_IF_SCHEDULED_EXCEPTION(); |
7326 return raw_result; | 7341 return raw_result; |
7327 } | 7342 } |
7328 | 7343 |
7329 | 7344 |
7330 MaybeObject* JSObject::GetElementWithReceiver(JSObject* receiver, | 7345 MaybeObject* JSObject::GetElementWithReceiver(Object* receiver, |
7331 uint32_t index) { | 7346 uint32_t index) { |
7332 // Check access rights if needed. | 7347 // Check access rights if needed. |
7333 if (IsAccessCheckNeeded() && | 7348 if (IsAccessCheckNeeded() && |
7334 !Top::MayIndexedAccess(this, index, v8::ACCESS_GET)) { | 7349 !Top::MayIndexedAccess(this, index, v8::ACCESS_GET)) { |
7335 Top::ReportFailedAccessCheck(this, v8::ACCESS_GET); | 7350 Top::ReportFailedAccessCheck(this, v8::ACCESS_GET); |
7336 return Heap::undefined_value(); | 7351 return Heap::undefined_value(); |
7337 } | 7352 } |
7338 | 7353 |
7339 if (HasIndexedInterceptor()) { | 7354 if (HasIndexedInterceptor()) { |
7340 return GetElementWithInterceptor(receiver, index); | 7355 return GetElementWithInterceptor(receiver, index); |
(...skipping 2629 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9970 if (break_point_objects()->IsUndefined()) return 0; | 9985 if (break_point_objects()->IsUndefined()) return 0; |
9971 // Single beak point. | 9986 // Single beak point. |
9972 if (!break_point_objects()->IsFixedArray()) return 1; | 9987 if (!break_point_objects()->IsFixedArray()) return 1; |
9973 // Multiple break points. | 9988 // Multiple break points. |
9974 return FixedArray::cast(break_point_objects())->length(); | 9989 return FixedArray::cast(break_point_objects())->length(); |
9975 } | 9990 } |
9976 #endif | 9991 #endif |
9977 | 9992 |
9978 | 9993 |
9979 } } // namespace v8::internal | 9994 } } // namespace v8::internal |
OLD | NEW |