From e325bd50b87b2a5f3c5a7efe5e9e67dd30be79be Mon Sep 17 00:00:00 2001 From: Eric Faust Date: Fri, 13 Nov 2015 18:22:21 -0800 Subject: [PATCH] Bug 1055472 - Part 6: Make the Number constructor properly subclassable. (r=Waldo) --- js/src/jsnum.cpp | 6 +++++- js/src/tests/ecma_6/Class/extendBuiltinConstructors.js | 1 + js/src/vm/NumberObject-inl.h | 9 ++++----- js/src/vm/NumberObject.h | 7 ++++--- 4 files changed, 14 insertions(+), 9 deletions(-) diff --git a/js/src/jsnum.cpp b/js/src/jsnum.cpp index 1b90adb581f..68c70a028a5 100644 --- a/js/src/jsnum.cpp +++ b/js/src/jsnum.cpp @@ -488,7 +488,11 @@ Number(JSContext* cx, unsigned argc, Value* vp) if (!isConstructing) return true; - JSObject* obj = NumberObject::create(cx, args.rval().toNumber()); + RootedObject newTarget(cx, &args.newTarget().toObject()); + RootedObject proto(cx); + if (!GetPrototypeFromConstructor(cx, newTarget, &proto)) + return false; + JSObject* obj = NumberObject::create(cx, args.rval().toNumber(), proto); if (!obj) return false; args.rval().setObject(*obj); diff --git a/js/src/tests/ecma_6/Class/extendBuiltinConstructors.js b/js/src/tests/ecma_6/Class/extendBuiltinConstructors.js index cb5b1eef2d5..940fe8ff685 100644 --- a/js/src/tests/ecma_6/Class/extendBuiltinConstructors.js +++ b/js/src/tests/ecma_6/Class/extendBuiltinConstructors.js @@ -25,6 +25,7 @@ testBuiltin(ReferenceError); testBuiltin(SyntaxError); testBuiltin(TypeError); testBuiltin(URIError); +testBuiltin(Number); `; diff --git a/js/src/vm/NumberObject-inl.h b/js/src/vm/NumberObject-inl.h index 5d4ff021432..7e0237b1c86 100644 --- a/js/src/vm/NumberObject-inl.h +++ b/js/src/vm/NumberObject-inl.h @@ -14,14 +14,13 @@ namespace js { inline NumberObject* -NumberObject::create(JSContext* cx, double d) +NumberObject::create(JSContext* cx, double d, HandleObject proto /* = nullptr */) { - JSObject* obj = NewBuiltinClassInstance(cx, &class_); + NumberObject* obj = NewObjectWithClassProto(cx, proto); if (!obj) return nullptr; - NumberObject& numobj = obj->as(); - numobj.setPrimitiveValue(d); - return &numobj; + obj->setPrimitiveValue(d); + return obj; } } // namespace js diff --git a/js/src/vm/NumberObject.h b/js/src/vm/NumberObject.h index c3523b8465a..dd808309c78 100644 --- a/js/src/vm/NumberObject.h +++ b/js/src/vm/NumberObject.h @@ -22,10 +22,11 @@ class NumberObject : public NativeObject static const Class class_; /* - * Creates a new Number object boxing the given number. The object's - * [[Prototype]] is determined from context. + * Creates a new Number object boxing the given number. + * If proto is nullptr, then Number.prototype will be used instead. */ - static inline NumberObject* create(JSContext* cx, double d); + static inline NumberObject* create(JSContext* cx, double d, + HandleObject proto = nullptr); double unbox() const { return getFixedSlot(PRIMITIVE_VALUE_SLOT).toNumber();