diff --git a/js/src/gc/Barrier.h b/js/src/gc/Barrier.h index 314d3c1fea76..bc551e9bde0e 100644 --- a/js/src/gc/Barrier.h +++ b/js/src/gc/Barrier.h @@ -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; } diff --git a/js/src/gc/Root.h b/js/src/gc/Root.h index c27ae3be3735..9bff766dcc88 100644 --- a/js/src/gc/Root.h +++ b/js/src/gc/Root.h @@ -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::result>::result _; ptr = reinterpret_cast(&NullPtr::constNullValue); } @@ -137,6 +136,10 @@ class Handle const T *ptr; }; +/* Defined in jsapi.h under Value definition */ +template <> +class Handle; + typedef Handle HandleObject; typedef Handle HandleFunction; typedef Handle HandleScript; diff --git a/js/src/jsapi.h b/js/src/jsapi.h index 7ee50f096f79..135acbd79223 100644 --- a/js/src/jsapi.h +++ b/js/src/jsapi.h @@ -614,6 +614,75 @@ IsPoisonedValue(const Value &v) /************************************************************************/ +/* This is a specialization of the general Handle template in gc/Root.h */ +template <> +class Handle +{ + 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 &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() { diff --git a/js/src/jsinterpinlines.h b/js/src/jsinterpinlines.h index 87618ac3bd80..39e427d60828 100644 --- a/js/src/jsinterpinlines.h +++ b/js/src/jsinterpinlines.h @@ -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;