Commit 50fdcca1 authored by rossberg@chromium.org's avatar rossberg@chromium.org

Proxies: Fix receiver for setters inherited from proxies.

R=mstarzinger@chromium.org
BUG=v8:1543
TEST=

Review URL: https://chromiumcodereview.appspot.com/10451064

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@11677 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 7a7ea0b5
...@@ -248,13 +248,14 @@ MaybeObject* JSProxy::GetElementWithHandler(Object* receiver, ...@@ -248,13 +248,14 @@ MaybeObject* JSProxy::GetElementWithHandler(Object* receiver,
} }
MaybeObject* JSProxy::SetElementWithHandler(uint32_t index, MaybeObject* JSProxy::SetElementWithHandler(JSReceiver* receiver,
uint32_t index,
Object* value, Object* value,
StrictModeFlag strict_mode) { StrictModeFlag strict_mode) {
String* name; String* name;
MaybeObject* maybe = GetHeap()->Uint32ToString(index); MaybeObject* maybe = GetHeap()->Uint32ToString(index);
if (!maybe->To<String>(&name)) return maybe; if (!maybe->To<String>(&name)) return maybe;
return SetPropertyWithHandler(name, value, NONE, strict_mode); return SetPropertyWithHandler(receiver, name, value, NONE, strict_mode);
} }
...@@ -2085,7 +2086,7 @@ MaybeObject* JSObject::SetElementWithCallbackSetterInPrototypes( ...@@ -2085,7 +2086,7 @@ MaybeObject* JSObject::SetElementWithCallbackSetterInPrototypes(
return maybe; return maybe;
} }
return JSProxy::cast(pt)->SetPropertyWithHandlerIfDefiningSetter( return JSProxy::cast(pt)->SetPropertyWithHandlerIfDefiningSetter(
name, value, NONE, strict_mode, found); this, name, value, NONE, strict_mode, found);
} }
if (!JSObject::cast(pt)->HasDictionaryElements()) { if (!JSObject::cast(pt)->HasDictionaryElements()) {
continue; continue;
...@@ -2140,7 +2141,7 @@ MaybeObject* JSObject::SetPropertyWithCallbackSetterInPrototypes( ...@@ -2140,7 +2141,7 @@ MaybeObject* JSObject::SetPropertyWithCallbackSetterInPrototypes(
Handle<Object> hvalue(value); Handle<Object> hvalue(value);
MaybeObject* result = MaybeObject* result =
accessor_result.proxy()->SetPropertyWithHandlerIfDefiningSetter( accessor_result.proxy()->SetPropertyWithHandlerIfDefiningSetter(
name, value, attributes, strict_mode, &found); this, name, value, attributes, strict_mode, &found);
if (found) return result; if (found) return result;
// The proxy does not define the property as an accessor. // The proxy does not define the property as an accessor.
// Consequently, it has no effect on setting the receiver. // Consequently, it has no effect on setting the receiver.
...@@ -2624,7 +2625,7 @@ MaybeObject* JSReceiver::SetProperty(LookupResult* result, ...@@ -2624,7 +2625,7 @@ MaybeObject* JSReceiver::SetProperty(LookupResult* result,
StrictModeFlag strict_mode) { StrictModeFlag strict_mode) {
if (result->IsFound() && result->type() == HANDLER) { if (result->IsFound() && result->type() == HANDLER) {
return result->proxy()->SetPropertyWithHandler( return result->proxy()->SetPropertyWithHandler(
key, value, attributes, strict_mode); this, key, value, attributes, strict_mode);
} else { } else {
return JSObject::cast(this)->SetPropertyForResult( return JSObject::cast(this)->SetPropertyForResult(
result, key, value, attributes, strict_mode); result, key, value, attributes, strict_mode);
...@@ -2648,13 +2649,14 @@ bool JSProxy::HasPropertyWithHandler(String* name_raw) { ...@@ -2648,13 +2649,14 @@ bool JSProxy::HasPropertyWithHandler(String* name_raw) {
MUST_USE_RESULT MaybeObject* JSProxy::SetPropertyWithHandler( MUST_USE_RESULT MaybeObject* JSProxy::SetPropertyWithHandler(
JSReceiver* receiver_raw,
String* name_raw, String* name_raw,
Object* value_raw, Object* value_raw,
PropertyAttributes attributes, PropertyAttributes attributes,
StrictModeFlag strict_mode) { StrictModeFlag strict_mode) {
Isolate* isolate = GetIsolate(); Isolate* isolate = GetIsolate();
HandleScope scope(isolate); HandleScope scope(isolate);
Handle<Object> receiver(this); Handle<JSReceiver> receiver(receiver_raw);
Handle<Object> name(name_raw); Handle<Object> name(name_raw);
Handle<Object> value(value_raw); Handle<Object> value(value_raw);
...@@ -2667,6 +2669,7 @@ MUST_USE_RESULT MaybeObject* JSProxy::SetPropertyWithHandler( ...@@ -2667,6 +2669,7 @@ MUST_USE_RESULT MaybeObject* JSProxy::SetPropertyWithHandler(
MUST_USE_RESULT MaybeObject* JSProxy::SetPropertyWithHandlerIfDefiningSetter( MUST_USE_RESULT MaybeObject* JSProxy::SetPropertyWithHandlerIfDefiningSetter(
JSReceiver* receiver_raw,
String* name_raw, String* name_raw,
Object* value_raw, Object* value_raw,
PropertyAttributes attributes, PropertyAttributes attributes,
...@@ -2674,6 +2677,7 @@ MUST_USE_RESULT MaybeObject* JSProxy::SetPropertyWithHandlerIfDefiningSetter( ...@@ -2674,6 +2677,7 @@ MUST_USE_RESULT MaybeObject* JSProxy::SetPropertyWithHandlerIfDefiningSetter(
bool* found) { bool* found) {
*found = true; // except where defined otherwise... *found = true; // except where defined otherwise...
Isolate* isolate = GetHeap()->isolate(); Isolate* isolate = GetHeap()->isolate();
Handle<JSReceiver> receiver(receiver_raw);
Handle<JSProxy> proxy(this); Handle<JSProxy> proxy(this);
Handle<Object> handler(this->handler()); // Trap might morph proxy. Handle<Object> handler(this->handler()); // Trap might morph proxy.
Handle<String> name(name_raw); Handle<String> name(name_raw);
...@@ -2715,7 +2719,7 @@ MUST_USE_RESULT MaybeObject* JSProxy::SetPropertyWithHandlerIfDefiningSetter( ...@@ -2715,7 +2719,7 @@ MUST_USE_RESULT MaybeObject* JSProxy::SetPropertyWithHandlerIfDefiningSetter(
if (!setter->IsUndefined()) { if (!setter->IsUndefined()) {
// We have a setter -- invoke it. // We have a setter -- invoke it.
// TODO(rossberg): nicer would be to cast to some JSCallable here... // TODO(rossberg): nicer would be to cast to some JSCallable here...
return proxy->SetPropertyWithDefinedSetter( return receiver->SetPropertyWithDefinedSetter(
JSReceiver::cast(*setter), *value); JSReceiver::cast(*setter), *value);
} else { } else {
Handle<String> get_name = isolate->factory()->LookupAsciiSymbol("get_"); Handle<String> get_name = isolate->factory()->LookupAsciiSymbol("get_");
...@@ -9657,7 +9661,7 @@ MaybeObject* JSReceiver::SetElement(uint32_t index, ...@@ -9657,7 +9661,7 @@ MaybeObject* JSReceiver::SetElement(uint32_t index,
bool check_proto) { bool check_proto) {
if (IsJSProxy()) { if (IsJSProxy()) {
return JSProxy::cast(this)->SetElementWithHandler( return JSProxy::cast(this)->SetElementWithHandler(
index, value, strict_mode); this, index, value, strict_mode);
} else { } else {
return JSObject::cast(this)->SetElement( return JSObject::cast(this)->SetElement(
index, value, attributes, strict_mode, check_proto); index, value, attributes, strict_mode, check_proto);
......
...@@ -7708,11 +7708,13 @@ class JSProxy: public JSReceiver { ...@@ -7708,11 +7708,13 @@ class JSProxy: public JSReceiver {
uint32_t index); uint32_t index);
MUST_USE_RESULT MaybeObject* SetPropertyWithHandler( MUST_USE_RESULT MaybeObject* SetPropertyWithHandler(
JSReceiver* receiver,
String* name, String* name,
Object* value, Object* value,
PropertyAttributes attributes, PropertyAttributes attributes,
StrictModeFlag strict_mode); StrictModeFlag strict_mode);
MUST_USE_RESULT MaybeObject* SetElementWithHandler( MUST_USE_RESULT MaybeObject* SetElementWithHandler(
JSReceiver* receiver,
uint32_t index, uint32_t index,
Object* value, Object* value,
StrictModeFlag strict_mode); StrictModeFlag strict_mode);
...@@ -7720,6 +7722,7 @@ class JSProxy: public JSReceiver { ...@@ -7720,6 +7722,7 @@ class JSProxy: public JSReceiver {
// If the handler defines an accessor property, invoke its setter // If the handler defines an accessor property, invoke its setter
// (or throw if only a getter exists) and set *found to true. Otherwise false. // (or throw if only a getter exists) and set *found to true. Otherwise false.
MUST_USE_RESULT MaybeObject* SetPropertyWithHandlerIfDefiningSetter( MUST_USE_RESULT MaybeObject* SetPropertyWithHandlerIfDefiningSetter(
JSReceiver* receiver,
String* name, String* name,
Object* value, Object* value,
PropertyAttributes attributes, PropertyAttributes attributes,
......
...@@ -572,6 +572,7 @@ TestSetThrow(Proxy.create({ ...@@ -572,6 +572,7 @@ TestSetThrow(Proxy.create({
})) }))
var rec
var key var key
var val var val
...@@ -611,6 +612,7 @@ function TestSetForDerived2(create, handler) { ...@@ -611,6 +612,7 @@ function TestSetForDerived2(create, handler) {
assertEquals(46, o.p_setter = 46) assertEquals(46, o.p_setter = 46)
assertEquals("p_setter", key) assertEquals("p_setter", key)
assertSame(o, rec)
assertEquals(46, val) // written to parent assertEquals(46, val) // written to parent
assertFalse(Object.prototype.hasOwnProperty.call(o, "p_setter")) assertFalse(Object.prototype.hasOwnProperty.call(o, "p_setter"))
...@@ -641,8 +643,14 @@ TestSetForDerived({ ...@@ -641,8 +643,14 @@ TestSetForDerived({
switch (k) { switch (k) {
case "p_writable": return {writable: true, configurable: true} case "p_writable": return {writable: true, configurable: true}
case "p_nonwritable": return {writable: false, configurable: true} case "p_nonwritable": return {writable: false, configurable: true}
case "p_setter":return {set: function(x) { val = x }, configurable: true} case "p_setter":return {
case "p_nosetter": return {get: function() { return 1 }, configurable: true} set: function(x) { rec = this; val = x },
configurable: true
}
case "p_nosetter": return {
get: function() { return 1 },
configurable: true
}
case "p_nonconf":return {} case "p_nonconf":return {}
case "p_throw": throw "myexn" case "p_throw": throw "myexn"
case "p_setterthrow": return {set: function(x) { throw "myexn" }} case "p_setterthrow": return {set: function(x) { throw "myexn" }}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment