Bug 771998 - add Handle<Value> specialization that is better suited for Value (r=billm)

--HG--
extra : rebase_source : b52fd5f8f6dda2343d1e4266dee6385ae9ef7a7a
This commit is contained in:
Luke Wagner 2012-07-10 15:48:07 -07:00
parent c06e3b9b0b
commit eb291f3ab2
4 changed files with 82 additions and 10 deletions

View File

@ -321,8 +321,8 @@ class EncapsulatedValue
~EncapsulatedValue() {}
public:
inline bool operator==(const EncapsulatedValue &v) const { return value == v.value; }
inline bool operator!=(const EncapsulatedValue &v) const { return value != v.value; }
bool operator==(const EncapsulatedValue &v) const { return value == v.value; }
bool operator!=(const EncapsulatedValue &v) const { return value != v.value; }
const Value &get() const { return value; }
Value *unsafeGet() { return &value; }

View File

@ -12,7 +12,7 @@
#include "mozilla/TypeTraits.h"
#include "jspubtd.h"
#include "jsapi.h"
#include "js/TemplateLib.h"
#include "js/Utility.h"
@ -97,8 +97,7 @@ class Handle
}
/* Create a handle for a NULL pointer. */
Handle(NullPtr)
{
Handle(NullPtr) {
typedef typename js::tl::StaticAssert<js::tl::IsPointerType<T>::result>::result _;
ptr = reinterpret_cast<const T *>(&NullPtr::constNullValue);
}
@ -137,6 +136,10 @@ class Handle
const T *ptr;
};
/* Defined in jsapi.h under Value definition */
template <>
class Handle<Value>;
typedef Handle<JSObject*> HandleObject;
typedef Handle<JSFunction*> HandleFunction;
typedef Handle<JSScript*> HandleScript;

View File

@ -614,6 +614,75 @@ IsPoisonedValue(const Value &v)
/************************************************************************/
/* This is a specialization of the general Handle template in gc/Root.h */
template <>
class Handle<Value>
{
public:
/*
* Construct a handle from an explicitly rooted location. This is the
* normal way to create a handle, and normally happens implicitly.
*/
inline Handle(Rooted<Value> &root) {
ptr = root.address();
}
/*
* This may be called only if the location of the T is guaranteed
* to be marked (for some reason other than being a Rooted),
* e.g., if it is guaranteed to be reachable from an implicit root.
*
* Create a Handle from a raw location of a T.
*/
static Handle fromMarkedLocation(const Value *p) {
Handle h;
h.ptr = p;
return h;
}
const Value *address() const { return ptr; }
const Value &get() const { return *ptr; }
operator const Value &() const { return *ptr; }
bool operator==(const Handle &h) const { return *ptr == *h.ptr; }
bool operator!=(const Handle &h) const { return *ptr != *h.ptr; }
bool isUndefined() const { return ptr->isUndefined(); }
bool isNull() const { return ptr->isNull(); }
bool isBoolean() const { return ptr->isBoolean(); }
bool isTrue() const { return ptr->isTrue(); }
bool isFalse() const { return ptr->isFalse(); }
bool isNumber() const { return ptr->isNumber(); }
bool isInt32() const { return ptr->isInt32(); }
bool isDouble() const { return ptr->isDouble(); }
bool isString() const { return ptr->isString(); }
bool isObject() const { return ptr->isObject(); }
bool isMagic() const { return ptr->isMagic(); }
bool isMagic(JSWhyMagic why) const { return ptr->isMagic(why); }
bool isGCThing() const { return ptr->isGCThing(); }
bool isMarkable() const { return ptr->isMarkable(); }
bool toBoolean() const { return ptr->toBoolean(); }
double toNumber() const { return ptr->toNumber(); }
int32_t toInt32() const { return ptr->toInt32(); }
double toDouble() const { return ptr->toDouble(); }
JSString *toString() const { return ptr->toString(); }
JSObject &toObject() const { return ptr->toObject(); }
JSObject *toObjectOrNull() const { return ptr->toObjectOrNull(); }
void *toGCThing() const { return ptr->toGCThing(); }
#ifdef DEBUG
JSWhyMagic whyMagic() const { return ptr->whyMagic(); }
#endif
private:
Handle() {}
const Value *ptr;
};
/************************************************************************/
static JS_ALWAYS_INLINE Value
NullValue()
{

View File

@ -547,7 +547,7 @@ SubOperation(JSContext *cx, HandleValue lhs, HandleValue rhs, Value *res)
if (!ToNumber(cx, lhs, &d1) || !ToNumber(cx, rhs, &d2))
return false;
double d = d1 - d2;
if (!res->setNumber(d) && !(lhs.get().isDouble() || rhs.get().isDouble()))
if (!res->setNumber(d) && !(lhs.isDouble() || rhs.isDouble()))
types::TypeScript::MonitorOverflow(cx);
return true;
}
@ -559,7 +559,7 @@ MulOperation(JSContext *cx, HandleValue lhs, HandleValue rhs, Value *res)
if (!ToNumber(cx, lhs, &d1) || !ToNumber(cx, rhs, &d2))
return false;
double d = d1 * d2;
if (!res->setNumber(d) && !(lhs.get().isDouble() || rhs.get().isDouble()))
if (!res->setNumber(d) && !(lhs.isDouble() || rhs.isDouble()))
types::TypeScript::MonitorOverflow(cx);
return true;
}
@ -572,7 +572,7 @@ DivOperation(JSContext *cx, HandleValue lhs, HandleValue rhs, Value *res)
return false;
res->setNumber(NumberDiv(d1, d2));
if (d2 == 0 || (res->isDouble() && !(lhs.get().isDouble() || rhs.get().isDouble())))
if (d2 == 0 || (res->isDouble() && !(lhs.isDouble() || rhs.isDouble())))
types::TypeScript::MonitorOverflow(cx);
return true;
}
@ -581,8 +581,8 @@ static JS_ALWAYS_INLINE bool
ModOperation(JSContext *cx, HandleValue lhs, HandleValue rhs, Value *res)
{
int32_t l, r;
if (lhs.get().isInt32() && rhs.get().isInt32() &&
(l = lhs.get().toInt32()) >= 0 && (r = rhs.get().toInt32()) > 0) {
if (lhs.isInt32() && rhs.isInt32() &&
(l = lhs.toInt32()) >= 0 && (r = rhs.toInt32()) > 0) {
int32_t mod = l % r;
res->setInt32(mod);
return true;