зеркало из https://github.com/mozilla/pjs.git
Bug 600016 - TM: Recognize that the result of Math.floor is an integer (r=nnethercote)
This commit is contained in:
Родитель
be97a4f096
Коммит
d588393631
|
@ -248,8 +248,8 @@ math_atan2(JSContext *cx, uintN argc, Value *vp)
|
|||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static inline jsdouble JS_FASTCALL
|
||||
math_ceil_kernel(jsdouble x)
|
||||
jsdouble
|
||||
js_math_ceil_impl(jsdouble x)
|
||||
{
|
||||
#ifdef __APPLE__
|
||||
if (x < 0 && x > -1.0)
|
||||
|
@ -269,7 +269,7 @@ js_math_ceil(JSContext *cx, uintN argc, Value *vp)
|
|||
}
|
||||
if (!ValueToNumber(cx, vp[2], &x))
|
||||
return JS_FALSE;
|
||||
z = math_ceil_kernel(x);
|
||||
z = js_math_ceil_impl(x);
|
||||
vp->setNumber(z);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
@ -326,6 +326,12 @@ math_exp(JSContext *cx, uintN argc, Value *vp)
|
|||
return JS_TRUE;
|
||||
}
|
||||
|
||||
jsdouble
|
||||
js_math_floor_impl(jsdouble x)
|
||||
{
|
||||
return floor(x);
|
||||
}
|
||||
|
||||
JSBool
|
||||
js_math_floor(JSContext *cx, uintN argc, Value *vp)
|
||||
{
|
||||
|
@ -337,7 +343,7 @@ js_math_floor(JSContext *cx, uintN argc, Value *vp)
|
|||
}
|
||||
if (!ValueToNumber(cx, vp[2], &x))
|
||||
return JS_FALSE;
|
||||
z = floor(x);
|
||||
z = js_math_floor_impl(x);
|
||||
vp->setNumber(z);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
@ -573,6 +579,12 @@ js_copysign(double x, double y)
|
|||
}
|
||||
#endif
|
||||
|
||||
jsdouble
|
||||
js_math_round_impl(jsdouble x)
|
||||
{
|
||||
return js_copysign(floor(x + 0.5), x);
|
||||
}
|
||||
|
||||
JSBool
|
||||
js_math_round(JSContext *cx, uintN argc, Value *vp)
|
||||
{
|
||||
|
@ -777,19 +789,19 @@ math_random_tn(JSContext *cx)
|
|||
static jsdouble FASTCALL
|
||||
math_round_tn(jsdouble x)
|
||||
{
|
||||
return js_copysign(floor(x + 0.5), x);
|
||||
return js_math_round_impl(x);
|
||||
}
|
||||
|
||||
static jsdouble FASTCALL
|
||||
math_ceil_tn(jsdouble x)
|
||||
{
|
||||
return math_ceil_kernel(x);
|
||||
return js_math_ceil_impl(x);
|
||||
}
|
||||
|
||||
static jsdouble FASTCALL
|
||||
math_floor_tn(jsdouble x)
|
||||
{
|
||||
return floor(x);
|
||||
return js_math_floor_impl(x);
|
||||
}
|
||||
|
||||
JS_DEFINE_TRCINFO_1(math_acos,
|
||||
|
|
|
@ -105,4 +105,13 @@ js_math_min(JSContext *cx, uintN argc, js::Value *vp);
|
|||
extern JSBool
|
||||
js_math_round(JSContext *cx, uintN argc, js::Value *vp);
|
||||
|
||||
extern jsdouble
|
||||
js_math_ceil_impl(jsdouble x);
|
||||
|
||||
extern jsdouble
|
||||
js_math_floor_impl(jsdouble x);
|
||||
|
||||
extern jsdouble
|
||||
js_math_round_impl(jsdouble x);
|
||||
|
||||
#endif /* jsmath_h___ */
|
||||
|
|
|
@ -11337,6 +11337,50 @@ next_specialization:;
|
|||
return RECORD_STOP;
|
||||
}
|
||||
|
||||
static JSBool FASTCALL
|
||||
ceilReturningInt(jsdouble x, int32 *out)
|
||||
{
|
||||
jsdouble r = js_math_ceil_impl(x);
|
||||
return JSDOUBLE_IS_INT32(r, out);
|
||||
}
|
||||
|
||||
static JSBool FASTCALL
|
||||
floorReturningInt(jsdouble x, int32 *out)
|
||||
{
|
||||
jsdouble r = js_math_floor_impl(x);
|
||||
return JSDOUBLE_IS_INT32(r, out);
|
||||
}
|
||||
|
||||
static JSBool FASTCALL
|
||||
roundReturningInt(jsdouble x, int32 *out)
|
||||
{
|
||||
jsdouble r = js_math_round_impl(x);
|
||||
return JSDOUBLE_IS_INT32(r, out);
|
||||
}
|
||||
|
||||
JS_DEFINE_CALLINFO_2(static, BOOL, ceilReturningInt, DOUBLE, INT32PTR, 1, ACCSET_NONE)
|
||||
JS_DEFINE_CALLINFO_2(static, BOOL, floorReturningInt, DOUBLE, INT32PTR, 1, ACCSET_NONE)
|
||||
JS_DEFINE_CALLINFO_2(static, BOOL, roundReturningInt, DOUBLE, INT32PTR, 1, ACCSET_NONE)
|
||||
|
||||
JS_REQUIRES_STACK RecordingStatus
|
||||
TraceRecorder::callFloatReturningInt(uintN argc, const nanojit::CallInfo *ci)
|
||||
{
|
||||
Value& arg = stackval(-1);
|
||||
LIns* resptr_ins = lir->insAlloc(sizeof(int32));
|
||||
LIns* args[] = { resptr_ins, get(&arg) };
|
||||
LIns* fits_ins = lir->insCall(ci, args);
|
||||
|
||||
guard(false, lir->insEqI_0(fits_ins), OVERFLOW_EXIT);
|
||||
|
||||
LIns* res_ins = lir->insLoad(LIR_ldi, resptr_ins, 0, ACCSET_ALLOC);
|
||||
|
||||
set(&stackval(0 - (2 + argc)), lir->ins1(LIR_i2d, res_ins));
|
||||
|
||||
pendingSpecializedNative = IGNORE_NATIVE_CALL_COMPLETE_CALLBACK;
|
||||
|
||||
return RECORD_CONTINUE;
|
||||
}
|
||||
|
||||
JS_REQUIRES_STACK RecordingStatus
|
||||
TraceRecorder::callNative(uintN argc, JSOp mode)
|
||||
{
|
||||
|
@ -11354,11 +11398,22 @@ TraceRecorder::callNative(uintN argc, JSOp mode)
|
|||
if (vp[2].isNumber() && mode == JSOP_CALL) {
|
||||
if (native == js_math_ceil || native == js_math_floor || native == js_math_round) {
|
||||
LIns* a = get(&vp[2]);
|
||||
int32 result;
|
||||
if (isPromote(a)) {
|
||||
set(&vp[0], a);
|
||||
pendingSpecializedNative = IGNORE_NATIVE_CALL_COMPLETE_CALLBACK;
|
||||
return RECORD_CONTINUE;
|
||||
}
|
||||
if (native == js_math_floor) {
|
||||
if (floorReturningInt(vp[2].toNumber(), &result))
|
||||
return callFloatReturningInt(argc, &floorReturningInt_ci);
|
||||
} else if (native == js_math_ceil) {
|
||||
if (ceilReturningInt(vp[2].toNumber(), &result))
|
||||
return callFloatReturningInt(argc, &ceilReturningInt_ci);
|
||||
} else if (native == js_math_round) {
|
||||
if (roundReturningInt(vp[2].toNumber(), &result))
|
||||
return callFloatReturningInt(argc, &roundReturningInt_ci);
|
||||
}
|
||||
}
|
||||
if (vp[1].isString()) {
|
||||
JSString *str = vp[1].toString();
|
||||
|
|
|
@ -1356,6 +1356,8 @@ class TraceRecorder
|
|||
JS_REQUIRES_STACK RecordingStatus callSpecializedNative(JSNativeTraceInfo* trcinfo, uintN argc,
|
||||
bool constructing);
|
||||
JS_REQUIRES_STACK RecordingStatus callNative(uintN argc, JSOp mode);
|
||||
JS_REQUIRES_STACK RecordingStatus callFloatReturningInt(uintN argc,
|
||||
const nanojit::CallInfo *ci);
|
||||
JS_REQUIRES_STACK RecordingStatus functionCall(uintN argc, JSOp mode);
|
||||
|
||||
JS_REQUIRES_STACK void trackCfgMerges(jsbytecode* pc);
|
||||
|
|
Загрузка…
Ссылка в новой задаче