Bug 739541. Add faster versions of JS_ValueToNumber and JS_ValueToECMAInt32. r=dmandelin

This commit is contained in:
Boris Zbarsky 2012-03-28 16:35:21 -07:00
parent 5506b28ad7
commit 102b2ce8c9
4 changed files with 78 additions and 28 deletions

View File

@ -571,7 +571,7 @@ JS_ValueToECMAInt32(JSContext *cx, jsval v, int32_t *ip)
assertSameCompartment(cx, v);
AutoValueRooter tvr(cx, v);
return ToInt32(cx, tvr.value(), (int32_t *)ip);
return ToInt32(cx, tvr.value(), ip);
}
JS_PUBLIC_API(JSBool)
@ -6625,6 +6625,16 @@ AutoEnumStateRooter::~AutoEnumStateRooter()
MOZ_ALWAYS_TRUE(obj->enumerate(context, JSENUMERATE_DESTROY, &stateValue, 0));
}
#ifdef DEBUG
JS_PUBLIC_API(void)
AssertArgumentsAreSane(JSContext *cx, const JS::Value &v)
{
AssertNoGC(cx);
CHECK_REQUEST(cx);
assertSameCompartment(cx, v);
}
#endif /* DEBUG */
} // namespace JS
JS_PUBLIC_API(void *)

View File

@ -809,7 +809,18 @@ class JS_PUBLIC_API(AutoCheckRequestDepth)
# define CHECK_REQUEST(cx) \
((void) 0)
#endif
#endif /* JS_THREADSAFE && DEBUG */
#ifdef DEBUG
/* Assert that we're not doing GC on cx, that we're in a request as
needed, and that the compartments for cx and v are correct. */
JS_PUBLIC_API(void)
AssertArgumentsAreSane(JSContext *cx, const Value &v);
#else
inline void AssertArgumentsAreSane(JSContext *cx, const Value &v) {
/* Do nothing */
}
#endif /* DEBUG */
class JS_PUBLIC_API(AutoGCRooter) {
public:
@ -2244,6 +2255,32 @@ JS_ValueToSource(JSContext *cx, jsval v);
extern JS_PUBLIC_API(JSBool)
JS_ValueToNumber(JSContext *cx, jsval v, double *dp);
#ifdef __cplusplus
namespace js {
/*
* DO NOT CALL THIS. Use JS::ToNumber
*/
extern JS_PUBLIC_API(bool)
ToNumberSlow(JSContext *cx, JS::Value v, double *dp);
} /* namespace js */
namespace JS {
/* ES5 9.3 ToNumber. */
JS_ALWAYS_INLINE bool
ToNumber(JSContext *cx, const Value &v, double *out)
{
AssertArgumentsAreSane(cx, v);
if (v.isNumber()) {
*out = v.toNumber();
return true;
}
return js::ToNumberSlow(cx, v, out);
}
} /* namespace JS */
#endif /* __cplusplus */
extern JS_PUBLIC_API(JSBool)
JS_DoubleIsInt32(double d, int32_t *ip);
@ -2260,6 +2297,31 @@ JS_DoubleToUint32(double d);
extern JS_PUBLIC_API(JSBool)
JS_ValueToECMAInt32(JSContext *cx, jsval v, int32_t *ip);
#ifdef __cplusplus
namespace js {
/*
* DO NOT CALL THIS. Use JS::ToInt32
*/
extern JS_PUBLIC_API(bool)
ToInt32Slow(JSContext *cx, const JS::Value &v, int32_t *out);
} /* namespace js */
namespace JS {
JS_ALWAYS_INLINE bool
ToInt32(JSContext *cx, const js::Value &v, int32_t *out)
{
AssertArgumentsAreSane(cx, v);
if (v.isInt32()) {
*out = v.toInt32();
return true;
}
return js::ToInt32Slow(cx, v, out);
}
} /* namespace JS */
#endif /* __cplusplus */
/*
* Convert a value to a number, then to a uint32_t, according to the ECMA rules
* for ToUint32.

View File

@ -1225,7 +1225,7 @@ NumberValueToStringBuffer(JSContext *cx, const Value &v, StringBuffer &sb)
return sb.appendInflated(cstr, cstrlen);
}
bool
JS_PUBLIC_API(bool)
ToNumberSlow(JSContext *cx, Value v, double *out)
{
JS_ASSERT(!v.isNumber());
@ -1264,7 +1264,7 @@ ToNumberSlow(JSContext *cx, Value v, double *out)
return true;
}
bool
JS_PUBLIC_API(bool)
ToInt32Slow(JSContext *cx, const Value &v, int32_t *out)
{
JS_ASSERT(!v.isInt32());

View File

@ -235,18 +235,6 @@ extern bool
GetPrefixInteger(JSContext *cx, const jschar *start, const jschar *end, int base,
const jschar **endp, double *dp);
/* ES5 9.3 ToNumber. */
JS_ALWAYS_INLINE bool
ToNumber(JSContext *cx, const Value &v, double *out)
{
if (v.isNumber()) {
*out = v.toNumber();
return true;
}
extern bool ToNumberSlow(JSContext *cx, js::Value v, double *dp);
return ToNumberSlow(cx, v, out);
}
/* ES5 9.3 ToNumber, overwriting *vp with the appropriate number value. */
JS_ALWAYS_INLINE bool
ToNumber(JSContext *cx, Value *vp)
@ -262,20 +250,10 @@ ToNumber(JSContext *cx, Value *vp)
}
/*
* Convert a value to an int32_t or uint32_t, according to the ECMA rules for
* ToInt32 and ToUint32. Return converted value in *out on success, !ok on
* Convert a value to a uint32_t, according to the ECMA rules for
* ToUint32. Return converted value in *out on success, !ok on
* failure.
*/
JS_ALWAYS_INLINE bool
ToInt32(JSContext *cx, const js::Value &v, int32_t *out)
{
if (v.isInt32()) {
*out = v.toInt32();
return true;
}
extern bool ToInt32Slow(JSContext *cx, const js::Value &v, int32_t *ip);
return ToInt32Slow(cx, v, out);
}
JS_ALWAYS_INLINE bool
ToUint32(JSContext *cx, const js::Value &v, uint32_t *out)