Bug 656810 - Implement js::NumberObject. r=njn
authorJeff Walden <jwalden@mit.edu>
Fri, 13 May 2011 14:12:15 -0700
changeset 78915 66736ca9c8c381f7bf9e2a8b67bb492c1b55398e
parent 78914 81329dc0ac9123654406d375d96605117438ce80
child 78916 f0630e6aac18421115a21bc1f64edbdded012b96
push id78
push userclegnitto@mozilla.com
push dateFri, 16 Dec 2011 17:32:24 +0000
treeherdermozilla-release@79d24e644fdd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnjn
bugs656810
milestone9.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 656810 - Implement js::NumberObject. r=njn
js/src/jsnum.cpp
js/src/jsobj.cpp
js/src/jsobj.h
js/src/vm/NumberObject-inl.h
js/src/vm/NumberObject.h
--- a/js/src/jsnum.cpp
+++ b/js/src/jsnum.cpp
@@ -79,16 +79,17 @@
 
 #include "jsatominlines.h"
 #include "jsinferinlines.h"
 #include "jsinterpinlines.h"
 #include "jsnuminlines.h"
 #include "jsobjinlines.h"
 #include "jsstrinlines.h"
 
+#include "vm/NumberObject-inl.h"
 #include "vm/String-inl.h"
 
 using namespace js;
 using namespace js::types;
 
 #ifndef JS_HAVE_STDINT_H /* Native support is innocent until proven guilty. */
 
 JS_STATIC_ASSERT(uint8_t(-1) == UINT8_MAX);
@@ -1106,17 +1107,17 @@ js_InitNumberClass(JSContext *cx, JSObje
     /* XXX must do at least once per new thread, so do it per JSContext... */
     FIX_FPU();
 
     GlobalObject *global = obj->asGlobal();
 
     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);
     if (!ctor)
         return NULL;
 
     if (!LinkConstructorAndPrototype(cx, ctor, numberProto))
         return NULL;
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -84,16 +84,17 @@
 #include "jswrapper.h"
 
 #include "jsarrayinlines.h"
 #include "jsinterpinlines.h"
 #include "jsscopeinlines.h"
 #include "jsscriptinlines.h"
 #include "jsobjinlines.h"
 
+#include "vm/NumberObject-inl.h"
 #include "vm/StringObject-inl.h"
 
 #if JS_HAS_GENERATORS
 #include "jsiter.h"
 #endif
 
 #if JS_HAS_XML_SUPPORT
 #include "jsxml.h"
@@ -6758,20 +6759,21 @@ js_GetClassPrototype(JSContext *cx, JSOb
     return FindClassPrototype(cx, scopeobj, protoKey, protop, clasp);
 }
 
 JSObject *
 PrimitiveToObject(JSContext *cx, const Value &v)
 {
     if (v.isString())
         return StringObject::create(cx, v.toString());
-
-    JS_ASSERT(v.isNumber() || v.isBoolean());
-    Class *clasp = v.isNumber() ? &NumberClass : &BooleanClass;
-    JSObject *obj = NewBuiltinClassInstance(cx, clasp);
+    if (v.isNumber())
+        return NumberObject::create(cx, v.toNumber());
+
+    JS_ASSERT(v.isBoolean());
+    JSObject *obj = NewBuiltinClassInstance(cx, &BooleanClass);
     if (!obj)
         return NULL;
 
     obj->setPrimitiveThis(v);
     return obj;
 }
 
 JSBool
--- a/js/src/jsobj.h
+++ b/js/src/jsobj.h
@@ -375,16 +375,17 @@ extern Class StringClass;
 extern Class StrictArgumentsObjectClass;
 extern Class WeakMapClass;
 extern Class WithClass;
 extern Class XMLFilterClass;
 
 class ArgumentsObject;
 class GlobalObject;
 class NormalArgumentsObject;
+class NumberObject;
 class StrictArgumentsObject;
 class StringObject;
 
 }  /* namespace js */
 
 /*
  * JSObject struct, with members sized to fit in 32 bytes on 32-bit targets,
  * 64 bytes on 64-bit systems. The JSFunction struct is an extension of this
@@ -1047,16 +1048,17 @@ struct JSObject : js::gc::Cell {
     inline void setPrimitiveThis(const js::Value &pthis);
 
     static size_t getPrimitiveThisOffset() {
         /* All primitive objects have their value in a fixed slot. */
         return getFixedSlotOffset(JSSLOT_PRIMITIVE_THIS);
     }
 
   public:
+    inline js::NumberObject *asNumber();
     inline js::StringObject *asString();
 
     /*
      * Array-specific getters and setters (for both dense and slow arrays).
      */
 
     inline uint32 getArrayLength() const;
     inline void setArrayLength(JSContext *cx, uint32 length);
new file mode 100644
--- /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 <jwalden+code@mit.edu> (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<js::NumberObject *>(const_cast<JSObject *>(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__ */
new file mode 100644
--- /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 <jwalden+code@mit.edu> (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__ */