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

Unified Diff: src/objects.cc

Issue 6992072: Implement set trap for proxies, and revamp class hierarchy in preparation (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Address review. 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/objects.cc
diff --git a/src/objects.cc b/src/objects.cc
index 292e75300633026409a114e52ddda7e0ceae7f48..bf881e99db955d6e88bc4d666e7f0df3f9d194e0 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -140,6 +140,8 @@ void Object::Lookup(String* name, LookupResult* result) {
HeapObject* heap_object = HeapObject::cast(this);
if (heap_object->IsJSObject()) {
return JSObject::cast(this)->Lookup(name, result);
+ } else if (heap_object->IsJSProxy()) {
+ return result->HandlerResult();
}
Context* global_context = Isolate::Current()->context()->global_context();
if (heap_object->IsString()) {
@@ -148,8 +150,6 @@ void Object::Lookup(String* name, LookupResult* result) {
holder = global_context->number_function()->instance_prototype();
} else if (heap_object->IsBoolean()) {
holder = global_context->boolean_function()->instance_prototype();
- } else if (heap_object->IsJSProxy()) {
- return result->HandlerResult();
}
}
ASSERT(holder != NULL); // Cannot handle null or undefined.
@@ -236,9 +236,9 @@ MaybeObject* Object::GetPropertyWithHandler(Object* receiver_raw,
Handle<Object> handler(handler_raw);
// Extract trap function.
- LookupResult lookup;
- Handle<Object> trap(v8::internal::GetProperty(handler, "get", &lookup));
- if (!lookup.IsFound()) {
+ Handle<String> trap_name = isolate->factory()->LookupAsciiSymbol("get");
+ Handle<Object> trap(v8::internal::GetProperty(handler, trap_name));
+ if (trap->IsUndefined()) {
// Get the derived `get' property.
trap = isolate->derived_get_trap();
}
@@ -1281,8 +1281,8 @@ void HeapNumber::HeapNumberPrint(StringStream* accumulator) {
}
-String* JSObject::class_name() {
- if (IsJSFunction()) {
+String* JSReceiver::class_name() {
+ if (IsJSFunction() && IsJSFunctionProxy()) {
return GetHeap()->function_class_symbol();
}
if (map()->constructor()->IsJSFunction()) {
@@ -1294,7 +1294,7 @@ String* JSObject::class_name() {
}
-String* JSObject::constructor_name() {
+String* JSReceiver::constructor_name() {
if (map()->constructor()->IsJSFunction()) {
JSFunction* constructor = JSFunction::cast(map()->constructor());
String* name = String::cast(constructor->shared()->name());
@@ -1304,6 +1304,7 @@ String* JSObject::constructor_name() {
Object* proto = GetPrototype();
if (proto->IsJSObject()) return JSObject::cast(proto)->constructor_name();
}
+ // TODO(rossberg): what about proxies?
// If the constructor is not present, return "Object".
return GetHeap()->Object_symbol();
}
@@ -1758,10 +1759,10 @@ MaybeObject* JSObject::SetPropertyWithInterceptor(
}
-MaybeObject* JSObject::SetProperty(String* name,
- Object* value,
- PropertyAttributes attributes,
- StrictModeFlag strict_mode) {
+MaybeObject* JSReceiver::SetProperty(String* name,
+ Object* value,
+ PropertyAttributes attributes,
+ StrictModeFlag strict_mode) {
LookupResult result;
LocalLookup(name, &result);
return SetProperty(&result, name, value, attributes, strict_mode);
@@ -2139,7 +2140,89 @@ MaybeObject* JSObject::SetPropertyWithFailedAccessCheck(
}
-MaybeObject* JSObject::SetProperty(LookupResult* result,
+MaybeObject* JSReceiver::SetProperty(LookupResult* result,
+ String* key,
+ Object* value,
+ PropertyAttributes attributes,
+ StrictModeFlag strict_mode) {
+ if (result->IsFound() && result->type() == HANDLER) {
+ return JSProxy::cast(this)->SetPropertyWithHandler(
+ key, value, attributes, strict_mode);
+ } else {
+ return JSObject::cast(this)->SetPropertyForResult(
+ result, key, value, attributes, strict_mode);
+ }
+}
+
+
+MUST_USE_RESULT MaybeObject* JSProxy::SetPropertyWithHandler(
+ String* name_raw,
+ Object* value_raw,
+ PropertyAttributes attributes,
+ StrictModeFlag strict_mode) {
+ Isolate* isolate = GetIsolate();
+ HandleScope scope;
+ Handle<Object> receiver(this);
+ Handle<Object> name(name_raw);
+ Handle<Object> value(value_raw);
+ Handle<Object> handler(this->handler());
+
+ // Extract trap function.
+ Handle<String> trap_name = isolate->factory()->LookupAsciiSymbol("set");
+ Handle<Object> trap(v8::internal::GetProperty(handler, trap_name));
+ if (trap->IsUndefined()) {
+ trap = isolate->derived_set_trap();
+ }
+
+ // Call trap function.
+ Object** args[] = {
+ receiver.location(), name.location(), value.location()
+ };
+ bool has_exception;
+ Handle<Object> result =
+ Execution::Call(trap, handler, ARRAY_SIZE(args), args, &has_exception);
+ if (has_exception) return Failure::Exception();
+
+ return value_raw;
+}
+
+
+MUST_USE_RESULT PropertyAttributes JSProxy::GetPropertyAttributeWithHandler(
+ JSReceiver* receiver_raw,
+ String* name_raw,
+ bool* has_exception) {
+ Isolate* isolate = GetIsolate();
+ HandleScope scope;
+ Handle<JSReceiver> receiver(receiver_raw);
+ Handle<Object> name(name_raw);
+ Handle<Object> handler(this->handler());
+
+ // Extract trap function.
+ Handle<String> trap_name =
+ isolate->factory()->LookupAsciiSymbol("getPropertyDescriptor");
+ Handle<Object> trap(v8::internal::GetProperty(handler, trap_name));
+ if (trap->IsUndefined()) {
+ Handle<Object> args[] = { handler, trap_name };
+ Handle<Object> error = isolate->factory()->NewTypeError(
+ "handler_trap_missing", HandleVector(args, ARRAY_SIZE(args)));
+ isolate->Throw(*error);
+ *has_exception = true;
+ return NONE;
+ }
+
+ // Call trap function.
+ Object** args[] = { name.location() };
+ Handle<Object> result =
+ Execution::Call(trap, handler, ARRAY_SIZE(args), args, has_exception);
+ if (has_exception) return NONE;
+
+ // TODO(rossberg): convert result to PropertyAttributes
+ USE(result);
+ return NONE;
+}
+
+
+MaybeObject* JSObject::SetPropertyForResult(LookupResult* result,
String* name,
Object* value,
PropertyAttributes attributes,
@@ -2424,12 +2507,13 @@ PropertyAttributes JSObject::GetPropertyAttributeWithInterceptor(
}
-PropertyAttributes JSObject::GetPropertyAttributeWithReceiver(
- JSObject* receiver,
+PropertyAttributes JSReceiver::GetPropertyAttributeWithReceiver(
+ JSReceiver* receiver,
String* key) {
uint32_t index = 0;
- if (key->AsArrayIndex(&index)) {
- if (HasElementWithReceiver(receiver, index)) return NONE;
+ if (IsJSObject() && key->AsArrayIndex(&index)) {
+ if (JSObject::cast(this)->HasElementWithReceiver(receiver, index))
+ return NONE;
return ABSENT;
}
// Named property.
@@ -2439,18 +2523,17 @@ PropertyAttributes JSObject::GetPropertyAttributeWithReceiver(
}
-PropertyAttributes JSObject::GetPropertyAttribute(JSObject* receiver,
- LookupResult* result,
- String* name,
- bool continue_search) {
+PropertyAttributes JSReceiver::GetPropertyAttribute(JSReceiver* receiver,
+ LookupResult* result,
+ String* name,
+ bool continue_search) {
// Check access rights if needed.
if (IsAccessCheckNeeded()) {
+ JSObject* this_obj = JSObject::cast(this);
Heap* heap = GetHeap();
- if (!heap->isolate()->MayNamedAccess(this, name, v8::ACCESS_HAS)) {
- return GetPropertyAttributeWithFailedAccessCheck(receiver,
- result,
- name,
- continue_search);
+ if (!heap->isolate()->MayNamedAccess(this_obj, name, v8::ACCESS_HAS)) {
+ return this_obj->GetPropertyAttributeWithFailedAccessCheck(
+ receiver, result, name, continue_search);
}
}
if (result->IsProperty()) {
@@ -2460,9 +2543,15 @@ PropertyAttributes JSObject::GetPropertyAttribute(JSObject* receiver,
case CONSTANT_FUNCTION:
case CALLBACKS:
return result->GetAttributes();
+ case HANDLER: {
+ // TODO(rossberg): propagate exceptions properly.
+ bool has_exception = false;
+ return JSProxy::cast(this)->GetPropertyAttributeWithHandler(
+ receiver, name, &has_exception);
+ }
case INTERCEPTOR:
- return result->holder()->
- GetPropertyAttributeWithInterceptor(receiver, name, continue_search);
+ return result->holder()->GetPropertyAttributeWithInterceptor(
+ JSObject::cast(receiver), name, continue_search);
default:
UNREACHABLE();
}
@@ -2471,11 +2560,11 @@ PropertyAttributes JSObject::GetPropertyAttribute(JSObject* receiver,
}
-PropertyAttributes JSObject::GetLocalPropertyAttribute(String* name) {
+PropertyAttributes JSReceiver::GetLocalPropertyAttribute(String* name) {
// Check whether the name is an array index.
uint32_t index = 0;
- if (name->AsArrayIndex(&index)) {
- if (HasLocalElement(index)) return NONE;
+ if (IsJSObject() && name->AsArrayIndex(&index)) {
+ if (JSObject::cast(this)->HasLocalElement(index)) return NONE;
return ABSENT;
}
// Named property.
@@ -3228,6 +3317,15 @@ AccessorDescriptor* Map::FindAccessor(String* name) {
}
+void JSReceiver::LocalLookup(String* name, LookupResult* result) {
+ if (IsJSProxy()) {
+ result->HandlerResult();
+ } else {
+ JSObject::cast(this)->LocalLookup(name, result);
+ }
+}
+
+
void JSObject::LocalLookup(String* name, LookupResult* result) {
ASSERT(name->IsString());
@@ -3263,7 +3361,7 @@ void JSObject::LocalLookup(String* name, LookupResult* result) {
}
-void JSObject::Lookup(String* name, LookupResult* result) {
+void JSReceiver::Lookup(String* name, LookupResult* result) {
// Ecma-262 3rd 8.6.2.4
Heap* heap = GetHeap();
for (Object* current = this;
@@ -7026,12 +7124,12 @@ MaybeObject* Map::PutPrototypeTransition(Object* prototype, Map* map) {
}
-MaybeObject* JSObject::SetPrototype(Object* value,
- bool skip_hidden_prototypes) {
+MaybeObject* JSReceiver::SetPrototype(Object* value,
+ bool skip_hidden_prototypes) {
Heap* heap = GetHeap();
// Silently ignore the change if value is not a JSObject or null.
// SpiderMonkey behaves this way.
- if (!value->IsJSObject() && !value->IsNull()) return value;
+ if (!value->IsJSReceiver() && !value->IsNull()) return value;
// From 8.6.2 Object Internal Methods
// ...
@@ -7062,7 +7160,7 @@ MaybeObject* JSObject::SetPrototype(Object* value,
}
}
- JSObject* real_receiver = this;
+ JSReceiver* real_receiver = this;
if (skip_hidden_prototypes) {
// Find the first object in the chain whose prototype object is not
@@ -7103,7 +7201,7 @@ MaybeObject* JSObject::SetPrototype(Object* value,
}
-bool JSObject::HasElementPostInterceptor(JSObject* receiver, uint32_t index) {
+bool JSObject::HasElementPostInterceptor(JSReceiver* receiver, uint32_t index) {
switch (GetElementsKind()) {
case FAST_ELEMENTS: {
uint32_t length = IsJSArray() ?
@@ -7158,14 +7256,14 @@ bool JSObject::HasElementPostInterceptor(JSObject* receiver, uint32_t index) {
}
-bool JSObject::HasElementWithInterceptor(JSObject* receiver, uint32_t index) {
+bool JSObject::HasElementWithInterceptor(JSReceiver* receiver, uint32_t index) {
Isolate* isolate = GetIsolate();
// Make sure that the top context does not change when doing
// callbacks or interceptor calls.
AssertNoContextChange ncc;
HandleScope scope(isolate);
Handle<InterceptorInfo> interceptor(GetIndexedInterceptor());
- Handle<JSObject> receiver_handle(receiver);
+ Handle<JSReceiver> receiver_handle(receiver);
Handle<JSObject> holder_handle(this);
CustomArguments args(isolate, interceptor->data(), receiver, this);
v8::AccessorInfo info(args.end());
@@ -7274,7 +7372,7 @@ JSObject::LocalElementType JSObject::HasLocalElement(uint32_t index) {
}
-bool JSObject::HasElementWithReceiver(JSObject* receiver, uint32_t index) {
+bool JSObject::HasElementWithReceiver(JSReceiver* receiver, uint32_t index) {
// Check access rights if needed.
if (IsAccessCheckNeeded()) {
Heap* heap = GetHeap();
@@ -8157,7 +8255,7 @@ InterceptorInfo* JSObject::GetIndexedInterceptor() {
MaybeObject* JSObject::GetPropertyPostInterceptor(
- JSObject* receiver,
+ JSReceiver* receiver,
String* name,
PropertyAttributes* attributes) {
// Check local property in holder, ignore interceptor.
@@ -8175,7 +8273,7 @@ MaybeObject* JSObject::GetPropertyPostInterceptor(
MaybeObject* JSObject::GetLocalPropertyPostInterceptor(
- JSObject* receiver,
+ JSReceiver* receiver,
String* name,
PropertyAttributes* attributes) {
// Check local property in holder, ignore interceptor.
@@ -8189,13 +8287,13 @@ MaybeObject* JSObject::GetLocalPropertyPostInterceptor(
MaybeObject* JSObject::GetPropertyWithInterceptor(
- JSObject* receiver,
+ JSReceiver* receiver,
String* name,
PropertyAttributes* attributes) {
Isolate* isolate = GetIsolate();
InterceptorInfo* interceptor = GetNamedInterceptor();
HandleScope scope(isolate);
- Handle<JSObject> receiver_handle(receiver);
+ Handle<JSReceiver> receiver_handle(receiver);
Handle<JSObject> holder_handle(this);
Handle<String> name_handle(name);
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698