Commit ece7700d authored by ager@chromium.org's avatar ager@chromium.org

Revert "Make instanceof and Object.getPrototypeOf work for proxies, plus a few other tweaks."

This change caused errors in es5conform tests for getPrototypeOf.

TBR=rossberg@chromium.org
BUG=
TEST=

Review URL: http://codereview.chromium.org/7109004

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@8159 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent b4c15254
...@@ -192,11 +192,7 @@ function FormatMessage(message) { ...@@ -192,11 +192,7 @@ function FormatMessage(message) {
redefine_disallowed: ["Cannot redefine property: ", "%0"], redefine_disallowed: ["Cannot redefine property: ", "%0"],
define_disallowed: ["Cannot define property, object is not extensible: ", "%0"], define_disallowed: ["Cannot define property, object is not extensible: ", "%0"],
non_extensible_proto: ["%0", " is not extensible"], non_extensible_proto: ["%0", " is not extensible"],
handler_non_object: ["Proxy.", "%0", " called with non-object as handler"],
handler_trap_missing: ["Proxy handler ", "%0", " has no '", "%1", "' trap"], handler_trap_missing: ["Proxy handler ", "%0", " has no '", "%1", "' trap"],
proxy_prop_not_configurable: ["Trap ", "%1", " of proxy handler ", "%0", " returned non-configurable descriptor for property ", "%2"],
proxy_non_object_prop_names: ["Trap ", "%1", " returned non-object ", "%0"],
proxy_repeated_prop_name: ["Trap ", "%1", " returned repeated property name ", "%2"],
// RangeError // RangeError
invalid_array_length: ["Invalid array length"], invalid_array_length: ["Invalid array length"],
stack_overflow: ["Maximum call stack size exceeded"], stack_overflow: ["Maximum call stack size exceeded"],
......
...@@ -2961,7 +2961,7 @@ Object* Map::prototype() { ...@@ -2961,7 +2961,7 @@ Object* Map::prototype() {
void Map::set_prototype(Object* value, WriteBarrierMode mode) { void Map::set_prototype(Object* value, WriteBarrierMode mode) {
ASSERT(value->IsNull() || value->IsJSReceiver()); ASSERT(value->IsNull() || value->IsJSObject());
WRITE_FIELD(this, kPrototypeOffset, value); WRITE_FIELD(this, kPrototypeOffset, value);
CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, mode); CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, mode);
} }
......
...@@ -638,7 +638,7 @@ Object* Object::GetPrototype() { ...@@ -638,7 +638,7 @@ Object* Object::GetPrototype() {
// The object is either a number, a string, a boolean, // The object is either a number, a string, a boolean,
// a real JS object, or a Harmony proxy. // a real JS object, or a Harmony proxy.
if (heap_object->IsJSReceiver()) { if (heap_object->IsJSObject() || heap_object->IsJSProxy()) {
return heap_object->map()->prototype(); return heap_object->map()->prototype();
} }
Heap* heap = heap_object->GetHeap(); Heap* heap = heap_object->GetHeap();
...@@ -3345,7 +3345,8 @@ void JSObject::LocalLookup(String* name, LookupResult* result) { ...@@ -3345,7 +3345,8 @@ void JSObject::LocalLookup(String* name, LookupResult* result) {
} }
// Check __proto__ before interceptor. // Check __proto__ before interceptor.
if (name->Equals(heap->Proto_symbol()) && !IsJSContextExtensionObject()) { if (name->Equals(heap->Proto_symbol()) &&
!IsJSContextExtensionObject()) {
result->ConstantResult(this); result->ConstantResult(this);
return; return;
} }
......
...@@ -60,9 +60,8 @@ $Proxy.createFunction = function(handler, callTrap, constructTrap) { ...@@ -60,9 +60,8 @@ $Proxy.createFunction = function(handler, callTrap, constructTrap) {
} }
$Proxy.create = function(handler, proto) { $Proxy.create = function(handler, proto) {
if (!IS_SPEC_OBJECT(handler)) if (!IS_SPEC_OBJECT(handler)) throw TypeError
throw MakeTypeError("handler_non_object", ["create"]) if (!IS_SPEC_OBJECT(proto)) proto = $Object.prototype
if (!IS_SPEC_OBJECT(proto)) proto = null // Mozilla does this...
return %CreateJSProxy(handler, proto) return %CreateJSProxy(handler, proto)
} }
...@@ -131,7 +130,3 @@ function DerivedSetTrap(receiver, name, val) { ...@@ -131,7 +130,3 @@ function DerivedSetTrap(receiver, name, val) {
configurable: true}); configurable: true});
return true; return true;
} }
function DerivedHasTrap(name) {
return !!this.getPropertyDescriptor(name)
}
...@@ -594,26 +594,12 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateJSProxy) { ...@@ -594,26 +594,12 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateJSProxy) {
Object* handler = args[0]; Object* handler = args[0];
Object* prototype = args[1]; Object* prototype = args[1];
Object* used_prototype = Object* used_prototype =
prototype->IsJSReceiver() ? prototype : isolate->heap()->null_value(); (prototype->IsJSObject() || prototype->IsJSProxy()) ? prototype
: isolate->heap()->null_value();
return isolate->heap()->AllocateJSProxy(handler, used_prototype); return isolate->heap()->AllocateJSProxy(handler, used_prototype);
} }
RUNTIME_FUNCTION(MaybeObject*, Runtime_IsJSProxy) {
ASSERT(args.length() == 1);
Object* obj = args[0];
return obj->IsJSProxy()
? isolate->heap()->true_value() : isolate->heap()->false_value();
}
RUNTIME_FUNCTION(MaybeObject*, Runtime_GetHandler) {
ASSERT(args.length() == 1);
CONVERT_CHECKED(JSProxy, proxy, args[0]);
return proxy->handler();
}
RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateCatchExtensionObject) { RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateCatchExtensionObject) {
ASSERT(args.length() == 2); ASSERT(args.length() == 2);
CONVERT_CHECKED(String, key, args[0]); CONVERT_CHECKED(String, key, args[0]);
...@@ -648,15 +634,6 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_ClassOf) { ...@@ -648,15 +634,6 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_ClassOf) {
} }
RUNTIME_FUNCTION(MaybeObject*, Runtime_GetPrototype) {
NoHandleAllocation ha;
ASSERT(args.length() == 1);
Object* obj = args[0];
if (obj->IsJSGlobalProxy()) obj = obj->GetPrototype();
return obj->GetPrototype();
}
RUNTIME_FUNCTION(MaybeObject*, Runtime_IsInPrototypeChain) { RUNTIME_FUNCTION(MaybeObject*, Runtime_IsInPrototypeChain) {
NoHandleAllocation ha; NoHandleAllocation ha;
ASSERT(args.length() == 2); ASSERT(args.length() == 2);
......
...@@ -67,7 +67,6 @@ namespace internal { ...@@ -67,7 +67,6 @@ namespace internal {
F(SpecialArrayFunctions, 1, 1) \ F(SpecialArrayFunctions, 1, 1) \
F(GetGlobalReceiver, 0, 1) \ F(GetGlobalReceiver, 0, 1) \
\ \
F(GetPrototype, 1, 1) \
F(IsInPrototypeChain, 2, 1) \ F(IsInPrototypeChain, 2, 1) \
F(SetHiddenPrototype, 2, 1) \ F(SetHiddenPrototype, 2, 1) \
\ \
...@@ -279,8 +278,6 @@ namespace internal { ...@@ -279,8 +278,6 @@ namespace internal {
\ \
/* Harmony proxies */ \ /* Harmony proxies */ \
F(CreateJSProxy, 2, 1) \ F(CreateJSProxy, 2, 1) \
F(IsJSProxy, 1, 1) \
F(GetHandler, 1, 1) \
\ \
/* Catch context extension objects */ \ /* Catch context extension objects */ \
F(CreateCatchExtensionObject, 2, 1) \ F(CreateCatchExtensionObject, 2, 1) \
......
...@@ -336,7 +336,6 @@ function IsInconsistentDescriptor(desc) { ...@@ -336,7 +336,6 @@ function IsInconsistentDescriptor(desc) {
return IsAccessorDescriptor(desc) && IsDataDescriptor(desc); return IsAccessorDescriptor(desc) && IsDataDescriptor(desc);
} }
// ES5 8.10.4 // ES5 8.10.4
function FromPropertyDescriptor(desc) { function FromPropertyDescriptor(desc) {
if (IS_UNDEFINED(desc)) return desc; if (IS_UNDEFINED(desc)) return desc;
...@@ -400,23 +399,6 @@ function ToPropertyDescriptor(obj) { ...@@ -400,23 +399,6 @@ function ToPropertyDescriptor(obj) {
} }
// For Harmony proxies.
function ToCompletePropertyDescriptor(obj) {
var desc = ToPropertyDescriptor(obj)
if (IsGenericDescriptor(desc) || IsDataDescriptor(desc)) {
if (!("value" in desc)) desc.value = void 0;
if (!("writable" in desc)) desc.writable = false;
} else {
// Is accessor descriptor.
if (!("get" in desc)) desc.get = void 0;
if (!("set" in desc)) desc.set = void 0;
}
if (!("enumerable" in desc)) desc.enumerable = false;
if (!("configurable" in desc)) desc.configurable = false;
return desc;
}
function PropertyDescriptor() { function PropertyDescriptor() {
// Initialize here so they are all in-object and have the same map. // Initialize here so they are all in-object and have the same map.
// Default values from ES5 8.6.1. // Default values from ES5 8.6.1.
...@@ -565,25 +547,9 @@ function ConvertDescriptorArrayToDescriptor(desc_array) { ...@@ -565,25 +547,9 @@ function ConvertDescriptorArrayToDescriptor(desc_array) {
// ES5 section 8.12.2. // ES5 section 8.12.2.
function GetProperty(obj, p) { function GetProperty(obj, p) {
if (%IsJSProxy(obj)) {
var handler = %GetHandler(obj);
var getProperty = handler.getPropertyDescriptor;
if (IS_UNDEFINED(getProperty)) {
throw MakeTypeError("handler_trap_missing",
[handler, "getPropertyDescriptor"]);
}
var descriptor = getProperty.call(handler, p);
if (IS_UNDEFINED(descriptor)) return descriptor;
var desc = ToCompletePropertyDescriptor(descriptor);
if (!desc.configurable) {
throw MakeTypeError("proxy_prop_not_configurable",
[handler, "getPropertyDescriptor", p, descriptor]);
}
return desc;
}
var prop = GetOwnProperty(obj); var prop = GetOwnProperty(obj);
if (!IS_UNDEFINED(prop)) return prop; if (!IS_UNDEFINED(prop)) return prop;
var proto = %GetPrototype(obj); var proto = obj.__proto__;
if (IS_NULL(proto)) return void 0; if (IS_NULL(proto)) return void 0;
return GetProperty(proto, p); return GetProperty(proto, p);
} }
...@@ -591,12 +557,6 @@ function GetProperty(obj, p) { ...@@ -591,12 +557,6 @@ function GetProperty(obj, p) {
// ES5 section 8.12.6 // ES5 section 8.12.6
function HasProperty(obj, p) { function HasProperty(obj, p) {
if (%IsJSProxy(obj)) {
var handler = %GetHandler(obj)
var has = handler.has
if (IS_UNDEFINED(has)) has = DerivedHasTrap
return ToBoolean(has.call(handler, obj, p))
}
var desc = GetProperty(obj, p); var desc = GetProperty(obj, p);
return IS_UNDEFINED(desc) ? false : true; return IS_UNDEFINED(desc) ? false : true;
} }
...@@ -785,7 +745,7 @@ function DefineOwnProperty(obj, p, desc, should_throw) { ...@@ -785,7 +745,7 @@ function DefineOwnProperty(obj, p, desc, should_throw) {
function ObjectGetPrototypeOf(obj) { function ObjectGetPrototypeOf(obj) {
if (!IS_SPEC_OBJECT(obj)) if (!IS_SPEC_OBJECT(obj))
throw MakeTypeError("obj_ctor_property_non_object", ["getPrototypeOf"]); throw MakeTypeError("obj_ctor_property_non_object", ["getPrototypeOf"]);
return %GetPrototype(obj); return obj.__proto__;
} }
...@@ -798,43 +758,11 @@ function ObjectGetOwnPropertyDescriptor(obj, p) { ...@@ -798,43 +758,11 @@ function ObjectGetOwnPropertyDescriptor(obj, p) {
} }
// For Harmony proxies
function ToStringArray(obj, trap) {
if (!IS_SPEC_OBJECT(obj)) {
throw MakeTypeError("proxy_non_object_prop_names", [obj, trap]);
}
var n = ToUint32(obj.length);
var array = new $Array(n);
var names = {}
for (var index = 0; index < n; index++) {
var s = ToString(obj[index]);
if (s in names) {
throw MakeTypeError("proxy_repeated_prop_name", [obj, trap, s])
}
array[index] = s;
names.s = 0;
}
return array;
}
// ES5 section 15.2.3.4. // ES5 section 15.2.3.4.
function ObjectGetOwnPropertyNames(obj) { function ObjectGetOwnPropertyNames(obj) {
if (!IS_SPEC_OBJECT(obj)) if (!IS_SPEC_OBJECT(obj))
throw MakeTypeError("obj_ctor_property_non_object", ["getOwnPropertyNames"]); throw MakeTypeError("obj_ctor_property_non_object", ["getOwnPropertyNames"]);
// Special handling for proxies.
if (%IsJSProxy(obj)) {
var handler = %GetHandler(obj);
var getOwnPropertyNames = handler.getOwnPropertyNames;
if (IS_UNDEFINED(getOwnPropertyNames)) {
throw MakeTypeError("handler_trap_missing",
[handler, "getOwnPropertyNames"]);
}
var names = getOwnPropertyNames.call(handler);
return ToStringArray(names, "getOwnPropertyNames");
}
// Find all the indexed properties. // Find all the indexed properties.
// Get the local element names. // Get the local element names.
......
...@@ -363,7 +363,6 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm, ...@@ -363,7 +363,6 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
// If the type of the result (stored in its map) is less than // If the type of the result (stored in its map) is less than
// FIRST_SPEC_OBJECT_TYPE, it is not an object in the ECMA sense. // FIRST_SPEC_OBJECT_TYPE, it is not an object in the ECMA sense.
STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE);
__ CmpObjectType(rax, FIRST_SPEC_OBJECT_TYPE, rcx); __ CmpObjectType(rax, FIRST_SPEC_OBJECT_TYPE, rcx);
__ j(above_equal, &exit); __ j(above_equal, &exit);
......
...@@ -38,35 +38,12 @@ function TestGet(handler) { ...@@ -38,35 +38,12 @@ function TestGet(handler) {
// assertEquals(Object.getOwnPropertyDescriptor(o, "b").value, 42) // assertEquals(Object.getOwnPropertyDescriptor(o, "b").value, 42)
} }
TestGet({ TestGet({get: function(r, k) { return 42 }})
get: function(r, k) { return 42 } TestGet({getPropertyDescriptor: function(k) { return {value: 42} }})
}) TestGet({getPropertyDescriptor: function(k) { return {get value() { return 42 }} }})
TestGet({ TestGet({get: undefined, getPropertyDescriptor: function(k) { return {value: 42} }})
get: function(r, k) { return this.get2(r, k) },
get2: function(r, k) { return 42 }
})
TestGet({
getPropertyDescriptor: function(k) { return {value: 42} }
})
TestGet({
getPropertyDescriptor: function(k) { return this.getPropertyDescriptor2(k) },
getPropertyDescriptor2: function(k) { return {value: 42} }
})
TestGet({
getPropertyDescriptor: function(k) {
return {get value() { return 42 }}
}
})
TestGet({
get: undefined,
getPropertyDescriptor: function(k) { return {value: 42} }
})
TestGet(Proxy.create({ TestGet(Proxy.create({get: function(pr, pk) { return function(r, k) { return 42 } }}))
get: function(pr, pk) {
return function(r, k) { return 42 }
}
}))
...@@ -87,86 +64,46 @@ function TestSet(handler) { ...@@ -87,86 +64,46 @@ function TestSet(handler) {
// assertEquals(44, val) // assertEquals(44, val)
} }
TestSet({ TestSet({set: function(r, k, v) { key = k; val = v; return true }})
set: function(r, k, v) { key = k; val = v; return true } TestSet({getOwnPropertyDescriptor: function(k) { return {writable: true} },
}) defineProperty: function(k, desc) { key = k, val = desc.value }})
TestSet({ TestSet({getOwnPropertyDescriptor: function(k) { return {get writable() { return true }} },
set: function(r, k, v) { return this.set2(r, k, v) }, defineProperty: function(k, desc) { key = k, val = desc.value }})
set2: function(r, k, v) { key = k; val = v; return true } TestSet({getOwnPropertyDescriptor: function(k) { return {set: function(v) { key = k, val = v }} }})
}) TestSet({getOwnPropertyDescriptor: function(k) { return null },
TestSet({ getPropertyDescriptor: function(k) { return {writable: true} },
getOwnPropertyDescriptor: function(k) { return {writable: true} }, defineProperty: function(k, desc) { key = k, val = desc.value }})
defineProperty: function(k, desc) { key = k; val = desc.value } TestSet({getOwnPropertyDescriptor: function(k) { return null },
}) getPropertyDescriptor: function(k) { return {get writable() { return true }} },
TestSet({ defineProperty: function(k, desc) { key = k, val = desc.value }})
getOwnPropertyDescriptor: function(k) { TestSet({getOwnPropertyDescriptor: function(k) { return null },
return this.getOwnPropertyDescriptor2(k) getPropertyDescriptor: function(k) { return {set: function(v) { key = k, val = v }} }})
}, TestSet({getOwnPropertyDescriptor: function(k) { return null },
getOwnPropertyDescriptor2: function(k) { return {writable: true} }, getPropertyDescriptor: function(k) { return null },
defineProperty: function(k, desc) { this.defineProperty2(k, desc) }, defineProperty: function(k, desc) { key = k, val = desc.value }})
defineProperty2: function(k, desc) { key = k; val = desc.value }
})
TestSet({
getOwnPropertyDescriptor: function(k) {
return {get writable() { return true }}
},
defineProperty: function(k, desc) { key = k; val = desc.value }
})
TestSet({
getOwnPropertyDescriptor: function(k) {
return {set: function(v) { key = k; val = v }}
}
})
TestSet({
getOwnPropertyDescriptor: function(k) { return null },
getPropertyDescriptor: function(k) { return {writable: true} },
defineProperty: function(k, desc) { key = k; val = desc.value }
})
TestSet({
getOwnPropertyDescriptor: function(k) { return null },
getPropertyDescriptor: function(k) {
return {get writable() { return true }}
},
defineProperty: function(k, desc) { key = k; val = desc.value }
})
TestSet({
getOwnPropertyDescriptor: function(k) { return null },
getPropertyDescriptor: function(k) {
return {set: function(v) { key = k; val = v }}
}
})
TestSet({
getOwnPropertyDescriptor: function(k) { return null },
getPropertyDescriptor: function(k) { return null },
defineProperty: function(k, desc) { key = k, val = desc.value }
})
TestSet(Proxy.create({ TestSet(Proxy.create({get: function(pr, pk) { return function(r, k, v) { key = k; val = v; return true } }}))
get: function(pr, pk) {
return function(r, k, v) { key = k; val = v; return true }
}
}))
// Comparison. // Comparison.
function TestComparison(eq) { var o1 = Proxy.create({})
var o1 = Proxy.create({}) var o2 = Proxy.create({})
var o2 = Proxy.create({})
assertTrue(eq(o1, o1)) assertTrue(o1 == o1)
assertTrue(eq(o2, o2)) assertTrue(o2 == o2)
assertTrue(!eq(o1, o2)) assertTrue(!(o1 == o2))
assertTrue(!eq(o1, {})) assertTrue(!(o1 == {}))
assertTrue(!eq({}, o2)) assertTrue(!({} == o2))
assertTrue(!eq({}, {})) assertTrue(!({} == {}))
}
TestComparison(function(o1, o2) { return o1 == o2 }) assertTrue(o1 === o1)
TestComparison(function(o1, o2) { return o1 === o2 }) assertTrue(o2 === o2)
TestComparison(function(o1, o2) { return !(o1 != o2) }) assertTrue(!(o1 === o2))
TestComparison(function(o1, o2) { return !(o1 !== o2) }) assertTrue(!(o1 === {}))
assertTrue(!({} === o2))
assertTrue(!({} === {}))
...@@ -177,85 +114,3 @@ assertTrue(typeof Proxy.create({}) == "object") ...@@ -177,85 +114,3 @@ assertTrue(typeof Proxy.create({}) == "object")
assertTrue("object" == typeof Proxy.create({})) assertTrue("object" == typeof Proxy.create({}))
// No function proxies yet. // No function proxies yet.
// Instanceof (instanceof).
function TestInstanceof() {
var o = {}
var p1 = Proxy.create({})
var p2 = Proxy.create({}, o)
var p3 = Proxy.create({}, p2)
var f = function() {}
f.prototype = o
var f1 = function() {}
f1.prototype = p1
var f2 = function() {}
f2.prototype = p2
assertTrue(o instanceof Object)
assertFalse(o instanceof f)
assertFalse(o instanceof f1)
assertFalse(o instanceof f2)
assertFalse(p1 instanceof Object)
assertFalse(p1 instanceof f)
assertFalse(p1 instanceof f1)
assertFalse(p1 instanceof f2)
assertTrue(p2 instanceof Object)
assertTrue(p2 instanceof f)
assertFalse(p2 instanceof f1)
assertFalse(p2 instanceof f2)
assertTrue(p3 instanceof Object)
assertTrue(p3 instanceof f)
assertFalse(p3 instanceof f1)
assertTrue(p3 instanceof f2)
}
TestInstanceof()
// Prototype (Object.getPrototypeOf).
function TestPrototype() {
var o = {}
var p1 = Proxy.create({})
var p2 = Proxy.create({}, o)
var p3 = Proxy.create({}, p2)
var p4 = Proxy.create({}, 666)
assertSame(Object.getPrototypeOf(o), Object.prototype)
assertSame(Object.getPrototypeOf(p1), null)
assertSame(Object.getPrototypeOf(p2), o)
assertSame(Object.getPrototypeOf(p3), p2)
assertSame(Object.getPrototypeOf(p4), null)
}
TestPrototype()
// Property names (Object.getOwnPropertyNames).
function TestPropertyNames(names, handler) {
var p = Proxy.create(handler)
assertArrayEquals(names, Object.getOwnPropertyNames(p))
}
TestPropertyNames([], {
getOwnPropertyNames: function() { return [] }
})
TestPropertyNames(["a", "zz", " ", "0"], {
getOwnPropertyNames: function() { return ["a", "zz", " ", 0] }
})
TestPropertyNames(["throw", "function "], {
getOwnPropertyNames: function() { return this.getOwnPropertyNames2() },
getOwnPropertyNames2: function() { return ["throw", "function "] }
})
TestPropertyNames(["[object Object]"], {
get getOwnPropertyNames() {
return function() { return [{}] }
}
})
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