Bug 728095 - Eliminate all primitive-this machinery from JSObject and relegate it to subclasses. r=bhackett

This commit is contained in:
Jeff Walden 2012-02-16 19:10:45 -08:00
parent ed8c5375af
commit 850206480a
12 changed files with 47 additions and 60 deletions

View File

@ -157,7 +157,7 @@ js_InitBooleanClass(JSContext *cx, JSObject *obj)
JSObject *booleanProto = global->createBlankPrototype(cx, &BooleanClass);
if (!booleanProto)
return NULL;
booleanProto->setPrimitiveThis(BooleanValue(false));
booleanProto->setFixedSlot(BooleanObject::PRIMITIVE_VALUE_SLOT, BooleanValue(false));
JSFunction *ctor = global->createConstructor(cx, Boolean, &BooleanClass,
CLASS_ATOM(cx, Boolean), 1);

View File

@ -42,13 +42,15 @@
#include "jsobjinlines.h"
#include "vm/BooleanObject-inl.h"
namespace js {
inline bool
BooleanGetPrimitiveValue(JSContext *cx, JSObject &obj, Value *vp)
{
if (obj.isBoolean()) {
*vp = obj.getPrimitiveThis();
*vp = BooleanValue(obj.asBoolean().unbox());
return true;
}

View File

@ -42,7 +42,10 @@
#include "jstypedarrayinlines.h"
#include "vm/BooleanObject-inl.h"
#include "vm/NumberObject-inl.h"
#include "vm/RegExpObject-inl.h"
#include "vm/StringObject-inl.h"
using namespace js;
@ -536,12 +539,12 @@ JSStructuredCloneWriter::startWrite(const js::Value &v)
} else if (js_IsArrayBuffer(obj)) {
return writeArrayBuffer(obj);
} else if (obj->isBoolean()) {
return out.writePair(SCTAG_BOOLEAN_OBJECT, obj->getPrimitiveThis().toBoolean());
return out.writePair(SCTAG_BOOLEAN_OBJECT, obj->asBoolean().unbox());
} else if (obj->isNumber()) {
return out.writePair(SCTAG_NUMBER_OBJECT, 0) &&
out.writeDouble(obj->getPrimitiveThis().toNumber());
out.writeDouble(obj->asNumber().unbox());
} else if (obj->isString()) {
return writeString(SCTAG_STRING_OBJECT, obj->getPrimitiveThis().toString());
return writeString(SCTAG_STRING_OBJECT, obj->asString().unbox());
}
if (callbacks && callbacks->write)

View File

@ -490,10 +490,9 @@ Number(JSContext *cx, uintN argc, Value *vp)
if (!isConstructing)
return true;
JSObject *obj = NewBuiltinClassInstance(cx, &NumberClass);
JSObject *obj = NumberObject::create(cx, vp[0].toNumber());
if (!obj)
return false;
obj->setPrimitiveThis(vp[0]);
vp->setObject(*obj);
return true;
}

View File

@ -5862,7 +5862,7 @@ DefaultValue(JSContext *cx, JSObject *obj, JSType hint, Value *vp)
&StringClass,
ATOM_TO_JSID(cx->runtime->atomState.toStringAtom),
js_str_toString)) {
*vp = obj->getPrimitiveThis();
*vp = StringValue(obj->asString().unbox());
return true;
}
@ -5885,7 +5885,9 @@ DefaultValue(JSContext *cx, JSObject *obj, JSType hint, Value *vp)
ClassMethodIsNative(cx, obj, &NumberClass,
ATOM_TO_JSID(cx->runtime->atomState.valueOfAtom),
js_num_valueOf))) {
*vp = obj->getPrimitiveThis();
*vp = obj->isString()
? StringValue(obj->asString().unbox())
: NumberValue(obj->asNumber().unbox());
return true;
}

View File

@ -998,22 +998,6 @@ struct JSObject : js::gc::Cell
bool isSealed(JSContext *cx, bool *resultp) { return isSealedOrFrozen(cx, SEAL, resultp); }
bool isFrozen(JSContext *cx, bool *resultp) { return isSealedOrFrozen(cx, FREEZE, resultp); }
/*
* Primitive-specific getters and setters.
*/
private:
static const uint32_t JSSLOT_PRIMITIVE_THIS = 0;
public:
inline const js::Value &getPrimitiveThis() const;
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);
}
/* Accessors for elements. */
js::ObjectElements *getElementsHeader() const {

View File

@ -65,8 +65,12 @@
#include "gc/Barrier.h"
#include "js/TemplateLib.h"
#include "vm/BooleanObject.h"
#include "vm/GlobalObject.h"
#include "vm/NumberObject.h"
#include "vm/RegExpStatics.h"
#include "vm/StringObject.h"
#include "jsatominlines.h"
#include "jsfuninlines.h"
@ -436,20 +440,6 @@ JSObject::setReservedSlot(uintN index, const js::Value &v)
setSlot(index, v);
}
inline const js::Value &
JSObject::getPrimitiveThis() const
{
JS_ASSERT(isPrimitive());
return getFixedSlot(JSSLOT_PRIMITIVE_THIS);
}
inline void
JSObject::setPrimitiveThis(const js::Value &pthis)
{
JS_ASSERT(isPrimitive());
setFixedSlot(JSSLOT_PRIMITIVE_THIS, pthis);
}
inline bool
JSObject::hasContiguousSlots(size_t start, size_t count) const
{
@ -1916,6 +1906,7 @@ class PrimitiveBehavior<JSString *> {
public:
static inline bool isType(const Value &v) { return v.isString(); }
static inline JSString *extract(const Value &v) { return v.toString(); }
static inline JSString *extract(JSObject &obj) { return obj.asString().unbox(); }
static inline Class *getClass() { return &StringClass; }
};
@ -1924,6 +1915,7 @@ class PrimitiveBehavior<bool> {
public:
static inline bool isType(const Value &v) { return v.isBoolean(); }
static inline bool extract(const Value &v) { return v.toBoolean(); }
static inline bool extract(JSObject &obj) { return obj.asBoolean().unbox(); }
static inline Class *getClass() { return &BooleanClass; }
};
@ -1932,6 +1924,7 @@ class PrimitiveBehavior<double> {
public:
static inline bool isType(const Value &v) { return v.isNumber(); }
static inline double extract(const Value &v) { return v.toNumber(); }
static inline double extract(JSObject &obj) { return obj.asNumber().unbox(); }
static inline Class *getClass() { return &NumberClass; }
};
@ -1968,7 +1961,7 @@ BoxedPrimitiveMethodGuard(JSContext *cx, CallArgs args, Native native, T *v, boo
if (!NonGenericMethodGuard(cx, args, native, Behavior::getClass(), ok))
return false;
*v = Behavior::extract(thisv.toObject().getPrimitiveThis());
*v = Behavior::extract(thisv.toObject());
return true;
}

View File

@ -399,7 +399,7 @@ static const uintN STRING_ELEMENT_ATTRS = JSPROP_ENUMERATE | JSPROP_READONLY | J
static JSBool
str_enumerate(JSContext *cx, JSObject *obj)
{
JSString *str = obj->getPrimitiveThis().toString();
JSString *str = obj->asString().unbox();
for (size_t i = 0, length = str->length(); i < length; i++) {
JSString *str1 = js_NewDependentString(cx, str, i, 1);
if (!str1)
@ -421,7 +421,7 @@ str_resolve(JSContext *cx, JSObject *obj, jsid id, uintN flags,
if (!JSID_IS_INT(id))
return JS_TRUE;
JSString *str = obj->getPrimitiveThis().toString();
JSString *str = obj->asString().unbox();
jsint slot = JSID_TO_INT(id);
if ((size_t)slot < str->length()) {
@ -472,8 +472,9 @@ ThisToStringForStringProto(JSContext *cx, CallReceiver call)
ATOM_TO_JSID(cx->runtime->atomState.toStringAtom),
js_str_toString))
{
call.thisv() = obj->getPrimitiveThis();
return call.thisv().toString();
JSString *str = obj->asString().unbox();
call.thisv().setString(str);
return str;
}
} else if (call.thisv().isNullOrUndefined()) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_CONVERT_TO,

View File

@ -53,6 +53,7 @@
#include "jsautooplen.h"
#include "vm/ScopeObject-inl.h"
#include "vm/StringObject-inl.h"
#if defined JS_POLYIC
@ -944,7 +945,7 @@ class GetPropCompiler : public PICStubCompiler
Jump notStringObj = masm.guardShape(pic.objReg, obj);
masm.loadPayload(Address(pic.objReg, JSObject::getPrimitiveThisOffset()), pic.objReg);
masm.loadPayload(Address(pic.objReg, StringObject::getPrimitiveValueOffset()), pic.objReg);
masm.loadPtr(Address(pic.objReg, JSString::offsetOfLengthAndFlags()), pic.objReg);
masm.urshift32(Imm32(JSString::LENGTH_SHIFT), pic.objReg);
masm.move(ImmType(JSVAL_TYPE_INT32), pic.shapeReg);
@ -1885,7 +1886,7 @@ GetPropMaybeCached(VMFrame &f, ic::PICInfo *pic, bool cached)
LookupStatus status = cc.generateStringObjLengthStub();
if (status == Lookup_Error)
THROW();
JSString *str = obj->getPrimitiveThis().toString();
JSString *str = obj->asString().unbox();
f.regs.sp[-1].setInt32(str->length());
}
return;

View File

@ -67,14 +67,13 @@ class BooleanObject : public JSObject
*/
static inline BooleanObject *createWithProto(JSContext *cx, bool b, JSObject &proto);
Value unbox() const {
JS_ASSERT(getSlot(PRIMITIVE_VALUE_SLOT).isBoolean());
return getSlot(PRIMITIVE_VALUE_SLOT);
bool unbox() const {
return getFixedSlot(PRIMITIVE_VALUE_SLOT).toBoolean();
}
private:
inline void setPrimitiveValue(bool b) {
setSlot(PRIMITIVE_VALUE_SLOT, BooleanValue(b));
setFixedSlot(PRIMITIVE_VALUE_SLOT, BooleanValue(b));
}
/* For access to init, as Boolean.prototype is special. */

View File

@ -67,14 +67,13 @@ class NumberObject : public JSObject
*/
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);
double unbox() const {
return getFixedSlot(PRIMITIVE_VALUE_SLOT).toNumber();
}
private:
inline void setPrimitiveValue(jsdouble d) {
setSlot(PRIMITIVE_VALUE_SLOT, NumberValue(d));
setFixedSlot(PRIMITIVE_VALUE_SLOT, NumberValue(d));
}
/* For access to init, as Number.prototype is special. */

View File

@ -50,7 +50,7 @@ namespace js {
class StringObject : public JSObject
{
static const uintN PRIMITIVE_THIS_SLOT = 0;
static const uintN PRIMITIVE_VALUE_SLOT = 0;
static const uintN LENGTH_SLOT = 1;
public:
@ -69,20 +69,24 @@ class StringObject : public JSObject
static inline StringObject *createWithProto(JSContext *cx, JSString *str, JSObject &proto);
JSString *unbox() const {
return getSlot(PRIMITIVE_THIS_SLOT).toString();
return getFixedSlot(PRIMITIVE_VALUE_SLOT).toString();
}
inline size_t length() const {
return size_t(getSlot(LENGTH_SLOT).toInt32());
return size_t(getFixedSlot(LENGTH_SLOT).toInt32());
}
static size_t getPrimitiveValueOffset() {
return getFixedSlotOffset(PRIMITIVE_VALUE_SLOT);
}
private:
inline bool init(JSContext *cx, JSString *str);
void setStringThis(JSString *str) {
JS_ASSERT(getSlot(PRIMITIVE_THIS_SLOT).isUndefined());
setSlot(PRIMITIVE_THIS_SLOT, StringValue(str));
setSlot(LENGTH_SLOT, Int32Value(int32_t(str->length())));
JS_ASSERT(getReservedSlot(PRIMITIVE_VALUE_SLOT).isUndefined());
setFixedSlot(PRIMITIVE_VALUE_SLOT, StringValue(str));
setFixedSlot(LENGTH_SLOT, Int32Value(int32_t(str->length())));
}
/* For access to init, as String.prototype is special. */