OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
142 return JSObject::cast(this)->Lookup(name, result); | 142 return JSObject::cast(this)->Lookup(name, result); |
143 } | 143 } |
144 Context* global_context = Isolate::Current()->context()->global_context(); | 144 Context* global_context = Isolate::Current()->context()->global_context(); |
145 if (heap_object->IsString()) { | 145 if (heap_object->IsString()) { |
146 holder = global_context->string_function()->instance_prototype(); | 146 holder = global_context->string_function()->instance_prototype(); |
147 } else if (heap_object->IsHeapNumber()) { | 147 } else if (heap_object->IsHeapNumber()) { |
148 holder = global_context->number_function()->instance_prototype(); | 148 holder = global_context->number_function()->instance_prototype(); |
149 } else if (heap_object->IsBoolean()) { | 149 } else if (heap_object->IsBoolean()) { |
150 holder = global_context->boolean_function()->instance_prototype(); | 150 holder = global_context->boolean_function()->instance_prototype(); |
151 } else if (heap_object->IsJSProxy()) { | 151 } else if (heap_object->IsJSProxy()) { |
152 return result->NotFound(); // For now... | 152 return result->HandlerResult(); |
153 } | 153 } |
154 } | 154 } |
155 ASSERT(holder != NULL); // Cannot handle null or undefined. | 155 ASSERT(holder != NULL); // Cannot handle null or undefined. |
156 JSObject::cast(holder)->Lookup(name, result); | 156 JSObject::cast(holder)->Lookup(name, result); |
157 } | 157 } |
158 | 158 |
159 | 159 |
160 MaybeObject* Object::GetPropertyWithReceiver(Object* receiver, | 160 MaybeObject* Object::GetPropertyWithReceiver(Object* receiver, |
161 String* name, | 161 String* name, |
162 PropertyAttributes* attributes) { | 162 PropertyAttributes* attributes) { |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
218 } | 218 } |
219 // Getter is not a function. | 219 // Getter is not a function. |
220 return isolate->heap()->undefined_value(); | 220 return isolate->heap()->undefined_value(); |
221 } | 221 } |
222 | 222 |
223 UNREACHABLE(); | 223 UNREACHABLE(); |
224 return NULL; | 224 return NULL; |
225 } | 225 } |
226 | 226 |
227 | 227 |
| 228 MaybeObject* Object::GetPropertyWithHandler(Object* receiver_raw, |
| 229 String* name_raw, |
| 230 Object* handler_raw) { |
| 231 Isolate* isolate = name_raw->GetIsolate(); |
| 232 HandleScope scope; |
| 233 Handle<Object> receiver(receiver_raw); |
| 234 Handle<Object> name(name_raw); |
| 235 Handle<Object> handler(handler_raw); |
| 236 |
| 237 // Extract trap function. |
| 238 LookupResult lookup; |
| 239 Handle<Object> trap(v8::internal::GetProperty(handler, "get", &lookup)); |
| 240 if (!lookup.IsFound()) { |
| 241 // Get the derived `get' property. |
| 242 Object* derived = isolate->global_context()->builtins()->javascript_builtin( |
| 243 Builtins::DERIVED_GET_TRAP); |
| 244 trap = Handle<JSFunction>(JSFunction::cast(derived)); |
| 245 } |
| 246 |
| 247 // Call trap function. |
| 248 Object** args[] = { receiver.location(), name.location() }; |
| 249 bool has_exception; |
| 250 Handle<Object> result = |
| 251 Execution::Call(trap, handler, ARRAY_SIZE(args), args, &has_exception); |
| 252 if (has_exception) return Failure::Exception(); |
| 253 |
| 254 return *result; |
| 255 } |
| 256 |
| 257 |
228 MaybeObject* Object::GetPropertyWithDefinedGetter(Object* receiver, | 258 MaybeObject* Object::GetPropertyWithDefinedGetter(Object* receiver, |
229 JSFunction* getter) { | 259 JSFunction* getter) { |
230 HandleScope scope; | 260 HandleScope scope; |
231 Handle<JSFunction> fun(JSFunction::cast(getter)); | 261 Handle<JSFunction> fun(JSFunction::cast(getter)); |
232 Handle<Object> self(receiver); | 262 Handle<Object> self(receiver); |
233 #ifdef ENABLE_DEBUGGER_SUPPORT | 263 #ifdef ENABLE_DEBUGGER_SUPPORT |
234 Debug* debug = fun->GetHeap()->isolate()->debug(); | 264 Debug* debug = fun->GetHeap()->isolate()->debug(); |
235 // Handle stepping into a getter if step into is active. | 265 // Handle stepping into a getter if step into is active. |
236 if (debug->StepInActive()) { | 266 if (debug->StepInActive()) { |
237 debug->HandleStepIn(fun, Handle<Object>::null(), 0, false); | 267 debug->HandleStepIn(fun, Handle<Object>::null(), 0, false); |
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
490 // callbacks or interceptor calls. | 520 // callbacks or interceptor calls. |
491 AssertNoContextChange ncc; | 521 AssertNoContextChange ncc; |
492 Heap* heap = name->GetHeap(); | 522 Heap* heap = name->GetHeap(); |
493 | 523 |
494 // Traverse the prototype chain from the current object (this) to | 524 // Traverse the prototype chain from the current object (this) to |
495 // the holder and check for access rights. This avoids traversing the | 525 // the holder and check for access rights. This avoids traversing the |
496 // objects more than once in case of interceptors, because the | 526 // objects more than once in case of interceptors, because the |
497 // holder will always be the interceptor holder and the search may | 527 // holder will always be the interceptor holder and the search may |
498 // only continue with a current object just after the interceptor | 528 // only continue with a current object just after the interceptor |
499 // holder in the prototype chain. | 529 // holder in the prototype chain. |
500 Object* last = result->IsProperty() ? result->holder() : heap->null_value(); | 530 // Proxy handlers do not use the proxy's prototype, so we can skip this. |
501 ASSERT(this != this->GetPrototype()); | 531 if (!result->IsHandler()) { |
502 for (Object* current = this; true; current = current->GetPrototype()) { | 532 Object* last = result->IsProperty() ? result->holder() : heap->null_value(); |
503 if (current->IsAccessCheckNeeded()) { | 533 ASSERT(this != this->GetPrototype()); |
504 // Check if we're allowed to read from the current object. Note | 534 for (Object* current = this; true; current = current->GetPrototype()) { |
505 // that even though we may not actually end up loading the named | 535 if (current->IsAccessCheckNeeded()) { |
506 // property from the current object, we still check that we have | 536 // Check if we're allowed to read from the current object. Note |
507 // access to it. | 537 // that even though we may not actually end up loading the named |
508 JSObject* checked = JSObject::cast(current); | 538 // property from the current object, we still check that we have |
509 if (!heap->isolate()->MayNamedAccess(checked, name, v8::ACCESS_GET)) { | 539 // access to it. |
510 return checked->GetPropertyWithFailedAccessCheck(receiver, | 540 JSObject* checked = JSObject::cast(current); |
511 result, | 541 if (!heap->isolate()->MayNamedAccess(checked, name, v8::ACCESS_GET)) { |
512 name, | 542 return checked->GetPropertyWithFailedAccessCheck(receiver, |
513 attributes); | 543 result, |
| 544 name, |
| 545 attributes); |
| 546 } |
514 } | 547 } |
| 548 // Stop traversing the chain once we reach the last object in the |
| 549 // chain; either the holder of the result or null in case of an |
| 550 // absent property. |
| 551 if (current == last) break; |
515 } | 552 } |
516 // Stop traversing the chain once we reach the last object in the | |
517 // chain; either the holder of the result or null in case of an | |
518 // absent property. | |
519 if (current == last) break; | |
520 } | 553 } |
521 | 554 |
522 if (!result->IsProperty()) { | 555 if (!result->IsProperty()) { |
523 *attributes = ABSENT; | 556 *attributes = ABSENT; |
524 return heap->undefined_value(); | 557 return heap->undefined_value(); |
525 } | 558 } |
526 *attributes = result->GetAttributes(); | 559 *attributes = result->GetAttributes(); |
527 Object* value; | 560 Object* value; |
528 JSObject* holder = result->holder(); | 561 JSObject* holder = result->holder(); |
529 switch (result->type()) { | 562 switch (result->type()) { |
530 case NORMAL: | 563 case NORMAL: |
531 value = holder->GetNormalizedProperty(result); | 564 value = holder->GetNormalizedProperty(result); |
532 ASSERT(!value->IsTheHole() || result->IsReadOnly()); | 565 ASSERT(!value->IsTheHole() || result->IsReadOnly()); |
533 return value->IsTheHole() ? heap->undefined_value() : value; | 566 return value->IsTheHole() ? heap->undefined_value() : value; |
534 case FIELD: | 567 case FIELD: |
535 value = holder->FastPropertyAt(result->GetFieldIndex()); | 568 value = holder->FastPropertyAt(result->GetFieldIndex()); |
536 ASSERT(!value->IsTheHole() || result->IsReadOnly()); | 569 ASSERT(!value->IsTheHole() || result->IsReadOnly()); |
537 return value->IsTheHole() ? heap->undefined_value() : value; | 570 return value->IsTheHole() ? heap->undefined_value() : value; |
538 case CONSTANT_FUNCTION: | 571 case CONSTANT_FUNCTION: |
539 return result->GetConstantFunction(); | 572 return result->GetConstantFunction(); |
540 case CALLBACKS: | 573 case CALLBACKS: |
541 return GetPropertyWithCallback(receiver, | 574 return GetPropertyWithCallback(receiver, |
542 result->GetCallbackObject(), | 575 result->GetCallbackObject(), |
543 name, | 576 name, |
544 holder); | 577 holder); |
| 578 case HANDLER: { |
| 579 JSProxy* proxy = JSProxy::cast(this); |
| 580 return GetPropertyWithHandler(receiver, name, proxy->handler()); |
| 581 } |
545 case INTERCEPTOR: { | 582 case INTERCEPTOR: { |
546 JSObject* recvr = JSObject::cast(receiver); | 583 JSObject* recvr = JSObject::cast(receiver); |
547 return holder->GetPropertyWithInterceptor(recvr, name, attributes); | 584 return holder->GetPropertyWithInterceptor(recvr, name, attributes); |
548 } | 585 } |
549 default: | 586 case MAP_TRANSITION: |
550 UNREACHABLE(); | 587 case EXTERNAL_ARRAY_TRANSITION: |
551 return NULL; | 588 case CONSTANT_TRANSITION: |
| 589 case NULL_DESCRIPTOR: |
| 590 break; |
552 } | 591 } |
| 592 UNREACHABLE(); |
| 593 return NULL; |
553 } | 594 } |
554 | 595 |
555 | 596 |
556 MaybeObject* Object::GetElementWithReceiver(Object* receiver, uint32_t index) { | 597 MaybeObject* Object::GetElementWithReceiver(Object* receiver, uint32_t index) { |
557 Object* holder = NULL; | 598 Object* holder = NULL; |
558 if (IsSmi()) { | 599 if (IsSmi()) { |
559 Context* global_context = Isolate::Current()->context()->global_context(); | 600 Context* global_context = Isolate::Current()->context()->global_context(); |
560 holder = global_context->number_function()->instance_prototype(); | 601 holder = global_context->number_function()->instance_prototype(); |
561 } else { | 602 } else { |
562 HeapObject* heap_object = HeapObject::cast(this); | 603 HeapObject* heap_object = HeapObject::cast(this); |
(...skipping 5980 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6543 return NULL; | 6584 return NULL; |
6544 } | 6585 } |
6545 | 6586 |
6546 | 6587 |
6547 const char* Code::PropertyType2String(PropertyType type) { | 6588 const char* Code::PropertyType2String(PropertyType type) { |
6548 switch (type) { | 6589 switch (type) { |
6549 case NORMAL: return "NORMAL"; | 6590 case NORMAL: return "NORMAL"; |
6550 case FIELD: return "FIELD"; | 6591 case FIELD: return "FIELD"; |
6551 case CONSTANT_FUNCTION: return "CONSTANT_FUNCTION"; | 6592 case CONSTANT_FUNCTION: return "CONSTANT_FUNCTION"; |
6552 case CALLBACKS: return "CALLBACKS"; | 6593 case CALLBACKS: return "CALLBACKS"; |
| 6594 case HANDLER: return "HANDLER"; |
6553 case INTERCEPTOR: return "INTERCEPTOR"; | 6595 case INTERCEPTOR: return "INTERCEPTOR"; |
6554 case MAP_TRANSITION: return "MAP_TRANSITION"; | 6596 case MAP_TRANSITION: return "MAP_TRANSITION"; |
6555 case EXTERNAL_ARRAY_TRANSITION: return "EXTERNAL_ARRAY_TRANSITION"; | 6597 case EXTERNAL_ARRAY_TRANSITION: return "EXTERNAL_ARRAY_TRANSITION"; |
6556 case CONSTANT_TRANSITION: return "CONSTANT_TRANSITION"; | 6598 case CONSTANT_TRANSITION: return "CONSTANT_TRANSITION"; |
6557 case NULL_DESCRIPTOR: return "NULL_DESCRIPTOR"; | 6599 case NULL_DESCRIPTOR: return "NULL_DESCRIPTOR"; |
6558 } | 6600 } |
6559 UNREACHABLE(); | 6601 UNREACHABLE(); |
6560 return NULL; | 6602 return NULL; |
6561 } | 6603 } |
6562 | 6604 |
(...skipping 3867 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10430 if (break_point_objects()->IsUndefined()) return 0; | 10472 if (break_point_objects()->IsUndefined()) return 0; |
10431 // Single beak point. | 10473 // Single beak point. |
10432 if (!break_point_objects()->IsFixedArray()) return 1; | 10474 if (!break_point_objects()->IsFixedArray()) return 1; |
10433 // Multiple break points. | 10475 // Multiple break points. |
10434 return FixedArray::cast(break_point_objects())->length(); | 10476 return FixedArray::cast(break_point_objects())->length(); |
10435 } | 10477 } |
10436 #endif | 10478 #endif |
10437 | 10479 |
10438 | 10480 |
10439 } } // namespace v8::internal | 10481 } } // namespace v8::internal |
OLD | NEW |