Bug 1079090 - Coerce the argument passed to Object.getPrototypeOf using ToObject. r=till

This commit is contained in:
ziyunfei 2014-10-06 23:39:00 +02:00
parent 97f16397f6
commit 6c7ddd6c98
5 changed files with 28 additions and 48 deletions

View File

@ -531,33 +531,20 @@ obj_lookupSetter(JSContext *cx, unsigned argc, Value *vp)
}
#endif /* JS_OLD_GETTER_SETTER_METHODS */
/* ES5 15.2.3.2. */
// ES6 draft rev27 (2014/08/24) 19.1.2.9 Object.getPrototypeOf(O)
bool
js::obj_getPrototypeOf(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
/* Step 1. */
if (args.length() == 0) {
js_ReportMissingArg(cx, args.calleev(), 0);
/* Steps 1-2. */
RootedObject obj(cx, ToObject(cx, args.get(0)));
if (!obj)
return false;
}
if (args[0].isPrimitive()) {
RootedValue val(cx, args[0]);
char *bytes = DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, val, NullPtr());
if (!bytes)
return false;
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr,
JSMSG_UNEXPECTED_TYPE, bytes, "not an object");
js_free(bytes);
return false;
}
/* Step 2. */
RootedObject thisObj(cx, &args[0].toObject());
/* Step 3. */
RootedObject proto(cx);
if (!JSObject::getProto(cx, thisObj, &proto))
if (!JSObject::getProto(cx, obj, &proto))
return false;
args.rval().setObjectOrNull(proto);
return true;

View File

@ -31,9 +31,6 @@ function TestSetPrototypeOf(object, proto) {
// check if Object.setPrototypeOf works with coercible values
for(var value of coercibleValues) {
assertEq(Object.setPrototypeOf(value, {}), value);
assertThrowsInstanceOf(() => Object.getPrototypeOf(value),
TypeError, "Coercible values should not have a prototype");
}
// check if Object.setPrototypeOf fails on non-coercible values

View File

@ -1,9 +0,0 @@
actual = "";
expect = "TypeError: \"kittens\" is not an object";
try {
Object.getPrototypeOf.apply(null, ["kittens",4,3])
} catch (e) {
actual = "" + e;
}
assertEq(actual, expect);

View File

@ -101,22 +101,5 @@ function test()
reportCompare(expect, actual, summary + ' instance: ' + instance + ', type: ' + type.name);
}
var non_objects = [ true, false, 1.0, Infinity, NaN, Math.PI, "bar" ];
for (i = 0; i < non_objects.length; i++)
{
instance = non_objects[i];
expect = 'TypeError: instance is not an object';
try
{
actual = Object.getPrototypeOf(instance);
}
catch(ex)
{
actual = ex + '';
}
reportCompare(expect, actual, summary + ' non-object: ' + actual);
}
exitFunc ('test');
}

View File

@ -0,0 +1,22 @@
/*
* Any copyright is dedicated to the Public Domain.
* https://creativecommons.org/publicdomain/zero/1.0/
*/
var BUGNUMBER = 1079090;
var summary = "Coerce the argument passed to Object.getPrototypeOf using ToObject";
print(BUGNUMBER + ": " + summary);
assertThrowsInstanceOf(() => Object.getPrototypeOf(), TypeError);
assertThrowsInstanceOf(() => Object.getPrototypeOf(undefined), TypeError);
assertThrowsInstanceOf(() => Object.getPrototypeOf(null), TypeError);
assertEq(Object.getPrototypeOf(1), Number.prototype);
assertEq(Object.getPrototypeOf(true), Boolean.prototype);
assertEq(Object.getPrototypeOf("foo"), String.prototype);
if (typeof Symbol === "function") {
assertEq(Object.getPrototypeOf(Symbol("foo")), Symbol.prototype);
}
if (typeof reportCompare === "function")
reportCompare(true, true);