diff --git a/js/src/jsnum.cpp b/js/src/jsnum.cpp index 6a9fabf16285..acc8c51342e6 100644 --- a/js/src/jsnum.cpp +++ b/js/src/jsnum.cpp @@ -84,6 +84,7 @@ #include "jsobjinlines.h" #include "jsstrinlines.h" +#include "vm/NumberObject-inl.h" #include "vm/String-inl.h" using namespace js; @@ -1111,7 +1112,7 @@ js_InitNumberClass(JSContext *cx, JSObject *obj) JSObject *numberProto = global->createBlankPrototype(cx, &NumberClass); if (!numberProto) return NULL; - numberProto->setPrimitiveThis(Int32Value(0)); + numberProto->asNumber()->setPrimitiveValue(0); JSFunction *ctor = global->createConstructor(cx, Number, &NumberClass, CLASS_ATOM(cx, Number), 1); diff --git a/js/src/jsobj.cpp b/js/src/jsobj.cpp index cfa9555dc302..0b7c1df0e572 100644 --- a/js/src/jsobj.cpp +++ b/js/src/jsobj.cpp @@ -89,6 +89,7 @@ #include "jsscriptinlines.h" #include "jsobjinlines.h" +#include "vm/NumberObject-inl.h" #include "vm/StringObject-inl.h" #if JS_HAS_GENERATORS @@ -6763,10 +6764,11 @@ PrimitiveToObject(JSContext *cx, const Value &v) { if (v.isString()) return StringObject::create(cx, v.toString()); + if (v.isNumber()) + return NumberObject::create(cx, v.toNumber()); - JS_ASSERT(v.isNumber() || v.isBoolean()); - Class *clasp = v.isNumber() ? &NumberClass : &BooleanClass; - JSObject *obj = NewBuiltinClassInstance(cx, clasp); + JS_ASSERT(v.isBoolean()); + JSObject *obj = NewBuiltinClassInstance(cx, &BooleanClass); if (!obj) return NULL; diff --git a/js/src/jsobj.h b/js/src/jsobj.h index 210641c2e869..2ffeaee3b106 100644 --- a/js/src/jsobj.h +++ b/js/src/jsobj.h @@ -380,6 +380,7 @@ extern Class XMLFilterClass; class ArgumentsObject; class GlobalObject; class NormalArgumentsObject; +class NumberObject; class StrictArgumentsObject; class StringObject; @@ -1052,6 +1053,7 @@ struct JSObject : js::gc::Cell { } public: + inline js::NumberObject *asNumber(); inline js::StringObject *asString(); /* diff --git a/js/src/vm/NumberObject-inl.h b/js/src/vm/NumberObject-inl.h new file mode 100644 index 000000000000..2b7c1549e2f6 --- /dev/null +++ b/js/src/vm/NumberObject-inl.h @@ -0,0 +1,80 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * vim: set ts=8 sw=4 et tw=78: + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is SpiderMonkey string object code. + * + * The Initial Developer of the Original Code is + * the Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2011 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Jeff Walden (original author) + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef NumberObject_inl_h___ +#define NumberObject_inl_h___ + +#include "NumberObject.h" + +inline js::NumberObject * +JSObject::asNumber() +{ + JS_ASSERT(isNumber()); + return static_cast(const_cast(this)); +} + +namespace js { + +inline NumberObject * +NumberObject::create(JSContext *cx, jsdouble d) +{ + JSObject *obj = NewBuiltinClassInstance(cx, &NumberClass); + if (!obj) + return NULL; + NumberObject *numobj = obj->asNumber(); + numobj->setPrimitiveValue(d); + return numobj; +} + +inline NumberObject * +NumberObject::createWithProto(JSContext *cx, jsdouble d, JSObject &proto) +{ + JSObject *obj = NewObjectWithClassProto(cx, &NumberClass, &proto, + gc::GetGCObjectKind(RESERVED_SLOTS)); + if (!obj) + return NULL; + NumberObject *numobj = obj->asNumber(); + numobj->setPrimitiveValue(d); + return numobj; +} + +} // namespace js + +#endif /* NumberObject_inl_h__ */ diff --git a/js/src/vm/NumberObject.h b/js/src/vm/NumberObject.h new file mode 100644 index 000000000000..d52efcf016eb --- /dev/null +++ b/js/src/vm/NumberObject.h @@ -0,0 +1,89 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * vim: set ts=8 sw=4 et tw=78: + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is SpiderMonkey string object code. + * + * The Initial Developer of the Original Code is + * the Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2011 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Jeff Walden (original author) + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef NumberObject_h___ +#define NumberObject_h___ + +#include "jsnum.h" + +namespace js { + +class NumberObject : public ::JSObject +{ + /* Stores this Number object's [[PrimitiveValue]]. */ + static const uintN PRIMITIVE_VALUE_SLOT = 0; + + public: + static const uintN RESERVED_SLOTS = 1; + + /* + * Creates a new Number object boxing the given number. The object's + * [[Prototype]] is determined from context. + */ + static inline NumberObject *create(JSContext *cx, jsdouble d); + + /* + * Identical to create(), but uses |proto| as [[Prototype]]. This method + * must not be used to create |Number.prototype|. + */ + static inline NumberObject *createWithProto(JSContext *cx, jsdouble d, JSObject &proto); + + Value unbox() const { + JS_ASSERT(getSlot(PRIMITIVE_VALUE_SLOT).isNumber()); + return getSlot(PRIMITIVE_VALUE_SLOT); + } + + private: + inline void setPrimitiveValue(jsdouble d) { + setSlot(PRIMITIVE_VALUE_SLOT, NumberValue(d)); + } + + /* For access to init, as Number.prototype is special. */ + friend JSObject * + ::js_InitNumberClass(JSContext *cx, JSObject *global); + + private: + NumberObject(); + NumberObject &operator=(const NumberObject &so); +}; + +} // namespace js + +#endif /* NumberObject_h__ */