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,
}
MaybeObject* JSProxy::SetElementWithHandler(uint32_t index,
MaybeObject* JSProxy::SetElementWithHandler(JSReceiver* receiver,
uint32_t index,
Object* value,
StrictModeFlag strict_mode) {
String* name;
MaybeObject* maybe = GetHeap()->Uint32ToString(index);
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(
return maybe;
}
return JSProxy::cast(pt)->SetPropertyWithHandlerIfDefiningSetter(
name, value, NONE, strict_mode, found);
this, name, value, NONE, strict_mode, found);
}
if (!JSObject::cast(pt)->HasDictionaryElements()) {
continue;
......@@ -2140,7 +2141,7 @@ MaybeObject* JSObject::SetPropertyWithCallbackSetterInPrototypes(
Handle<Object> hvalue(value);
MaybeObject* result =
accessor_result.proxy()->SetPropertyWithHandlerIfDefiningSetter(
name, value, attributes, strict_mode, &found);
this, name, value, attributes, strict_mode, &found);
if (found) return result;
// The proxy does not define the property as an accessor.
// Consequently, it has no effect on setting the receiver.
......@@ -2624,7 +2625,7 @@ MaybeObject* JSReceiver::SetProperty(LookupResult* result,
StrictModeFlag strict_mode) {
if (result->IsFound() && result->type() == HANDLER) {
return result->proxy()->SetPropertyWithHandler(
key, value, attributes, strict_mode);
this, key, value, attributes, strict_mode);
} else {
return JSObject::cast(this)->SetPropertyForResult(
result, key, value, attributes, strict_mode);
......@@ -2648,13 +2649,14 @@ bool JSProxy::HasPropertyWithHandler(String* name_raw) {
MUST_USE_RESULT MaybeObject* JSProxy::SetPropertyWithHandler(
JSReceiver* receiver_raw,
String* name_raw,
Object* value_raw,
PropertyAttributes attributes,
StrictModeFlag strict_mode) {
Isolate* isolate = GetIsolate();
HandleScope scope(isolate);
Handle<Object> receiver(this);
Handle<JSReceiver> receiver(receiver_raw);
Handle<Object> name(name_raw);
Handle<Object> value(value_raw);
......@@ -2667,6 +2669,7 @@ MUST_USE_RESULT MaybeObject* JSProxy::SetPropertyWithHandler(
MUST_USE_RESULT MaybeObject* JSProxy::SetPropertyWithHandlerIfDefiningSetter(
JSReceiver* receiver_raw,
String* name_raw,
Object* value_raw,
PropertyAttributes attributes,
......@@ -2674,6 +2677,7 @@ MUST_USE_RESULT MaybeObject* JSProxy::SetPropertyWithHandlerIfDefiningSetter(
bool* found) {
*found = true; // except where defined otherwise...
Isolate* isolate = GetHeap()->isolate();
Handle<JSReceiver> receiver(receiver_raw);
Handle<JSProxy> proxy(this);
Handle<Object> handler(this->handler()); // Trap might morph proxy.
Handle<String> name(name_raw);
......@@ -2715,7 +2719,7 @@ MUST_USE_RESULT MaybeObject* JSProxy::SetPropertyWithHandlerIfDefiningSetter(
if (!setter->IsUndefined()) {
// We have a setter -- invoke it.
// TODO(rossberg): nicer would be to cast to some JSCallable here...
return proxy->SetPropertyWithDefinedSetter(
return receiver->SetPropertyWithDefinedSetter(
JSReceiver::cast(*setter), *value);
} else {
Handle<String> get_name = isolate->factory()->LookupAsciiSymbol("get_");
......@@ -9657,7 +9661,7 @@ MaybeObject* JSReceiver::SetElement(uint32_t index,
bool check_proto) {
if (IsJSProxy()) {
return JSProxy::cast(this)->SetElementWithHandler(
index, value, strict_mode);
this, index, value, strict_mode);
} else {
return JSObject::cast(this)->SetElement(
index, value, attributes, strict_mode, check_proto);
......
......@@ -7708,11 +7708,13 @@ class JSProxy: public JSReceiver {
uint32_t index);
MUST_USE_RESULT MaybeObject* SetPropertyWithHandler(
JSReceiver* receiver,
String* name,
Object* value,
PropertyAttributes attributes,
StrictModeFlag strict_mode);
MUST_USE_RESULT MaybeObject* SetElementWithHandler(
JSReceiver* receiver,
uint32_t index,
Object* value,
StrictModeFlag strict_mode);
......@@ -7720,6 +7722,7 @@ class JSProxy: public JSReceiver {
// If the handler defines an accessor property, invoke its setter
// (or throw if only a getter exists) and set *found to true. Otherwise false.
MUST_USE_RESULT MaybeObject* SetPropertyWithHandlerIfDefiningSetter(
JSReceiver* receiver,
String* name,
Object* value,
PropertyAttributes attributes,
......
......@@ -572,6 +572,7 @@ TestSetThrow(Proxy.create({
}))
var rec
var key
var val
......@@ -611,6 +612,7 @@ function TestSetForDerived2(create, handler) {
assertEquals(46, o.p_setter = 46)
assertEquals("p_setter", key)
assertSame(o, rec)
assertEquals(46, val) // written to parent
assertFalse(Object.prototype.hasOwnProperty.call(o, "p_setter"))
......@@ -641,8 +643,14 @@ TestSetForDerived({
switch (k) {
case "p_writable": return {writable: true, configurable: true}
case "p_nonwritable": return {writable: false, configurable: true}
case "p_setter":return {set: function(x) { val = x }, configurable: true}
case "p_nosetter": return {get: function() { return 1 }, configurable: true}
case "p_setter":return {
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_throw": 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