Commit 23850c16 authored by rossberg@chromium.org's avatar rossberg@chromium.org

Object.observe: notify of __proto__ changes

BUG=v8:2409

Review URL: https://codereview.chromium.org/11299260

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@13141 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent f19959cd
......@@ -758,7 +758,7 @@ const AccessorDescriptor Accessors::FunctionCaller = {
//
MaybeObject* Accessors::ObjectGetPrototype(Object* receiver, void*) {
static inline Object* GetPrototypeSkipHiddenPrototypes(Object* receiver) {
Object* current = receiver->GetPrototype();
while (current->IsJSObject() &&
JSObject::cast(current)->map()->is_hidden_prototype()) {
......@@ -768,12 +768,36 @@ MaybeObject* Accessors::ObjectGetPrototype(Object* receiver, void*) {
}
MaybeObject* Accessors::ObjectSetPrototype(JSObject* receiver,
Object* value,
MaybeObject* Accessors::ObjectGetPrototype(Object* receiver, void*) {
return GetPrototypeSkipHiddenPrototypes(receiver);
}
MaybeObject* Accessors::ObjectSetPrototype(JSObject* receiver_raw,
Object* value_raw,
void*) {
const bool skip_hidden_prototypes = true;
const bool kSkipHiddenPrototypes = true;
// To be consistent with other Set functions, return the value.
return receiver->SetPrototype(value, skip_hidden_prototypes);
if (!(FLAG_harmony_observation && receiver_raw->map()->is_observed()))
return receiver_raw->SetPrototype(value_raw, kSkipHiddenPrototypes);
Isolate* isolate = receiver_raw->GetIsolate();
HandleScope scope(isolate);
Handle<JSObject> receiver(receiver_raw);
Handle<Object> value(value_raw);
Handle<Object> old_value(GetPrototypeSkipHiddenPrototypes(*receiver));
MaybeObject* result = receiver->SetPrototype(*value, kSkipHiddenPrototypes);
Handle<Object> hresult;
if (!result->ToHandle(&hresult, isolate)) return result;
Handle<Object> new_value(GetPrototypeSkipHiddenPrototypes(*receiver));
if (!new_value->SameValue(*old_value)) {
JSObject::EnqueueChangeRecord(receiver, "prototype",
isolate->factory()->Proto_symbol(),
old_value);
}
return *hresult;
}
......
......@@ -810,3 +810,23 @@ observer.assertCallbackRecords([
{ object: array, name: '0', type: 'deleted', oldValue: 0 },
{ object: array, name: 'length', type: 'updated', oldValue: 1},
]);
// __proto__
reset();
var obj = {};
Object.observe(obj, observer.callback);
var p = {foo: 'yes'};
var q = {bar: 'no'};
obj.__proto__ = p;
obj.__proto__ = p; // ignored
obj.__proto__ = null;
obj.__proto__ = q;
// TODO(adamk): Add tests for objects with hidden prototypes
// once we support observing the global object.
Object.deliverChangeRecords(observer.callback);
observer.assertCallbackRecords([
{ object: obj, name: '__proto__', type: 'prototype',
oldValue: Object.prototype },
{ object: obj, name: '__proto__', type: 'prototype', oldValue: p },
{ object: obj, name: '__proto__', type: 'prototype', oldValue: null },
]);
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