Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(211)

Side by Side Diff: src/objects.cc

Issue 7035007: Implement get trap for proxies. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Review feedback. Created 9 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/objects.h ('k') | src/property.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/property.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698