Bug 1055472 - Part 4: Make the Boolean constructor properly subclassable. (r=Waldo)

This commit is contained in:
Eric Faust 2015-11-13 18:22:21 -08:00
parent 01e448f020
commit 2c77d4d966
5 changed files with 25 additions and 9 deletions

View File

@ -116,7 +116,13 @@ Boolean(JSContext* cx, unsigned argc, Value* vp)
bool b = args.length() != 0 ? JS::ToBoolean(args[0]) : false;
if (args.isConstructing()) {
JSObject* obj = BooleanObject::create(cx, b);
RootedObject newTarget (cx, &args.newTarget().toObject());
RootedObject proto(cx);
if (!GetPrototypeFromConstructor(cx, newTarget, &proto))
return false;
JSObject* obj = BooleanObject::create(cx, b, proto);
if (!obj)
return false;
args.rval().setObject(*obj);

View File

@ -687,6 +687,15 @@ NewObjectWithClassProto(ExclusiveContext* cx, const Class* clasp, HandleObject p
return NewObjectWithClassProto(cx, clasp, proto, allocKind, newKind);
}
template<class T>
inline T*
NewObjectWithClassProto(ExclusiveContext* cx, HandleObject proto,
NewObjectKind newKind = GenericObject)
{
JSObject* obj = NewObjectWithClassProto(cx, &T::class_, proto, newKind);
return obj ? &obj->as<T>() : nullptr;
}
/*
* Create a native instance of the given class with parent and proto set
* according to the context's active global.

View File

@ -17,6 +17,7 @@ function testBuiltin(builtin) {
testBuiltin(Function);
testBuiltin(Object);
testBuiltin(Boolean);
`;

View File

@ -14,14 +14,13 @@
namespace js {
inline BooleanObject*
BooleanObject::create(JSContext* cx, bool b)
BooleanObject::create(JSContext* cx, bool b, HandleObject proto /* = nullptr */)
{
JSObject* obj = NewBuiltinClassInstance(cx, &class_);
BooleanObject* obj = NewObjectWithClassProto<BooleanObject>(cx, proto);
if (!obj)
return nullptr;
BooleanObject& boolobj = obj->as<BooleanObject>();
boolobj.setPrimitiveValue(b);
return &boolobj;
obj->setPrimitiveValue(b);
return obj;
}
} // namespace js

View File

@ -24,10 +24,11 @@ class BooleanObject : public NativeObject
static const Class class_;
/*
* Creates a new Boolean object boxing the given primitive bool. The
* object's [[Prototype]] is determined from context.
* Creates a new Boolean object boxing the given primitive bool.
* If proto is nullptr, the [[Prototype]] will default to Boolean.prototype.
*/
static inline BooleanObject* create(JSContext* cx, bool b);
static inline BooleanObject* create(JSContext* cx, bool b,
HandleObject proto = nullptr);
bool unbox() const {
return getFixedSlot(PRIMITIVE_VALUE_SLOT).toBoolean();