Trace Math.max. r=brendan
Trace Math.max. r=brendan
--- a/js/src/builtins.tbl
+++ b/js/src/builtins.tbl
@@ -50,16 +50,17 @@ BUILTIN1(DoubleToInt32, F,
BUILTIN1(DoubleToUint32, F, LO, int32, jsdouble, 1, 1)
BUILTIN1(Math_sin, F, F, jsdouble, jsdouble, 1, 1)
BUILTIN1(Math_cos, F, F, jsdouble, jsdouble, 1, 1)
BUILTIN2(Math_pow, F, F, F, jsdouble, jsdouble, jsdouble, 1, 1)
BUILTIN1(Math_sqrt, F, F, jsdouble, jsdouble, 1, 1)
BUILTIN1(Math_floor, F, F, jsdouble, jsdouble, 1, 1)
BUILTIN1(Math_ceil, F, F, jsdouble, jsdouble, 1, 1)
BUILTIN1(Math_log, F, F, jsdouble, jsdouble, 1, 1)
+BUILTIN2(Math_max, F, F, F, jsdouble, jsdouble, jsdouble, 1, 1)
BUILTIN4(Array_dense_setelem, LO, LO, LO, LO, LO, bool, JSContext*, JSObject*, jsint, jsval, 0, 0)
BUILTIN3(Array_p_join, LO, LO, LO, P, JSString*, JSContext*, JSObject*, JSString*, 0, 0)
BUILTIN4(String_p_substring, LO, LO, LO, LO, P, JSString*, JSContext*, JSString*, jsint, jsint, 1, 1)
BUILTIN3(String_p_substring_1, LO, LO, LO, P, JSString*, JSContext*, JSString*, jsint, 1, 1)
BUILTIN3(ConcatStrings, LO, LO, LO, P, JSString*, JSContext*, JSString*, JSString*, 1, 1)
BUILTIN3(String_getelem, LO, LO, LO, P, JSString*, JSContext*, JSString*, jsint, 1, 1)
BUILTIN2(String_fromCharCode, LO, LO, P, JSString*, JSContext*, jsint, 1, 1)
BUILTIN2(String_p_charCodeAt, LO, LO, LO, jsint, JSString*, jsint, 1, 1)
--- a/js/src/jsbuiltins.cpp
+++ b/js/src/jsbuiltins.cpp
@@ -43,16 +43,17 @@
#include <math.h>
#include "jsapi.h"
#include "jsarray.h"
#include "jsbool.h"
#include "jscntxt.h"
#include "jsgc.h"
#include "jsiter.h"
+#include "jslibmath.h"
#include "jsmath.h"
#include "jsnum.h"
#include "jsscope.h"
#include "jsstr.h"
#include "jstracer.h"
#include "nanojit/avmplus.h"
#include "nanojit/nanojit.h"
@@ -190,16 +191,27 @@ js_Math_log(jsdouble d)
{
#if !JS_USE_FDLIBM_MATH && defined(SOLARIS) && defined(__GNUC__)
if (d < 0)
return js_NaN;
#endif
return log(d);
}
+jsdouble FASTCALL
+js_Math_max(jsdouble d, jsdouble p)
+{
+ if (JSDOUBLE_IS_NaN(d) || JSDOUBLE_IS_NaN(p))
+ return js_NaN;
+
+ if (p == 0 && p == d && fd_copysign(1.0, d) == -1)
+ return p;
+ return (d > p) ? d : p;
+}
+
JSBool FASTCALL
js_Array_dense_setelem(JSContext* cx, JSObject* obj, jsint i, jsval v)
{
JS_ASSERT(OBJ_IS_DENSE_ARRAY(cx, obj));
jsuint length = ARRAY_DENSE_LENGTH(obj);
if ((jsuint)i < length) {
if (obj->dslots[i] == JSVAL_HOLE) {
--- a/js/src/jsmath.cpp
+++ b/js/src/jsmath.cpp
@@ -316,18 +316,18 @@ js_math_log(JSContext *cx, uintN argc, j
*vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
return JS_TRUE;
}
#endif
z = fd_log(x);
return js_NewNumberInRootedValue(cx, z, vp);
}
-static JSBool
-math_max(JSContext *cx, uintN argc, jsval *vp)
+JSBool
+js_math_max(JSContext *cx, uintN argc, jsval *vp)
{
jsdouble x, z = *cx->runtime->jsNegativeInfinity;
jsval *argv;
uintN i;
if (argc == 0) {
*vp = DOUBLE_TO_JSVAL(cx->runtime->jsNegativeInfinity);
return JS_TRUE;
@@ -593,17 +593,17 @@ static JSFunctionSpec math_static_method
JS_FN("asin", math_asin, 1, 0),
JS_FN("atan", math_atan, 1, 0),
JS_FN("atan2", math_atan2, 2, 0),
JS_FN("ceil", js_math_ceil, 1, 0),
JS_FN("cos", js_math_cos, 1, 0),
JS_FN("exp", math_exp, 1, 0),
JS_FN("floor", js_math_floor, 1, 0),
JS_FN("log", js_math_log, 1, 0),
- JS_FN("max", math_max, 2, 0),
+ JS_FN("max", js_math_max, 2, 0),
JS_FN("min", math_min, 2, 0),
JS_FN("pow", js_math_pow, 2, 0),
JS_FN("random", js_math_random, 0, 0),
JS_FN("round", math_round, 1, 0),
JS_FN("sin", js_math_sin, 1, 0),
JS_FN("sqrt", js_math_sqrt, 1, 0),
JS_FN("tan", math_tan, 1, 0),
JS_FS_END
--- a/js/src/jstracer.cpp
+++ b/js/src/jstracer.cpp
@@ -4619,16 +4619,17 @@ TraceRecorder::interpretedFunctionCall(j
#define KNOWN_NATIVE_DECL(name) JSBool name(JSContext* cx, uintN argc, jsval* vp);
KNOWN_NATIVE_DECL(js_fun_apply)
KNOWN_NATIVE_DECL(js_math_ceil)
KNOWN_NATIVE_DECL(js_math_cos)
KNOWN_NATIVE_DECL(js_math_floor)
KNOWN_NATIVE_DECL(js_math_log)
+KNOWN_NATIVE_DECL(js_math_max)
KNOWN_NATIVE_DECL(js_math_pow)
KNOWN_NATIVE_DECL(js_math_random)
KNOWN_NATIVE_DECL(js_math_sin)
KNOWN_NATIVE_DECL(js_math_sqrt)
KNOWN_NATIVE_DECL(js_num_toString)
KNOWN_NATIVE_DECL(js_str_charAt)
KNOWN_NATIVE_DECL(js_str_charCodeAt)
KNOWN_NATIVE_DECL(js_str_concat)
@@ -4674,16 +4675,17 @@ TraceRecorder::record_JSOP_CALL()
{ js_math_sin, F_Math_sin, "", "d", INFALLIBLE },
{ js_math_cos, F_Math_cos, "", "d", INFALLIBLE },
{ js_math_pow, F_Math_pow, "", "dd", INFALLIBLE },
{ js_math_sqrt, F_Math_sqrt, "", "d", INFALLIBLE },
{ js_math_floor, F_Math_floor, "", "d", INFALLIBLE },
{ js_math_ceil, F_Math_ceil, "", "d", INFALLIBLE },
{ js_math_random, F_Math_random, "R", "", INFALLIBLE },
{ js_math_log, F_Math_log, "", "d", INFALLIBLE },
+ { js_math_max, F_Math_max, "", "dd", INFALLIBLE },
{ js_num_parseInt, F_ParseInt, "C", "s", INFALLIBLE },
{ js_num_parseInt, F_ParseIntDouble, "", "d", INFALLIBLE },
{ js_num_parseFloat, F_ParseFloat, "C", "s", INFALLIBLE },
{ js_num_toString, F_NumberToString, "TC", "", FAIL_NULL },
{ js_obj_hasOwnProperty, F_Object_p_hasOwnProperty,
"TC", "s", FAIL_VOID },
{ js_obj_propertyIsEnumerable, F_Object_p_propertyIsEnumerable,
"TC", "s", FAIL_VOID },
--- a/js/src/trace-test.js
+++ b/js/src/trace-test.js
@@ -1201,17 +1201,17 @@ function testConstIf() {
testConstIf.expected = 2;
test(testConstIf);
function testTypeofHole() {
var a = new Array(6);
a[5] = 3;
for (var i = 0; i < 6; ++i)
a[i] = typeof a[i];
- return a.toString();
+ return a.join(",");
}
testTypeofHole.expected = "undefined,undefined,undefined,undefined,undefined,number"
test(testTypeofHole);
function testNativeLog() {
var a = new Array(5);
for (var i = 0; i < 5; i++) {
a[i] = Math.log(Math.pow(Math.E, 10));
@@ -1274,11 +1274,33 @@ function test_JSOP_ARGCNT() {
a[8] = f8('a','b','c','d','e','f','g','h','i');
a[9] = f9('a','b','c','d','e','f','g','h','i','j');
}
return a.join(",");
}
test_JSOP_ARGCNT.expected = "1,2,3,4,5,6,7,8,9,10";
test(test_JSOP_ARGCNT);
+function testNativeMax() {
+ var out = [], k;
+ for (var i = 0; i < 5; ++i) {
+ k = Math.max(k, i);
+ }
+ out.push(k);
+
+ k = 0;
+ for (var i = 0; i < 5; ++i) {
+ k = Math.max(k, i);
+ }
+ out.push(k);
+
+ for (var i = 0; i < 5; ++i) {
+ k = Math.max(0, -0);
+ }
+ out.push((1 / k) < 0);
+ return out.join(",");
+}
+testNativeMax.expected = "NaN,4,false";
+test(testNativeMax);
+
/* Keep these at the end so that we can see the summary after the trace-debug spew. */
print("\npassed:", passes.length && passes.join(","));
print("\nFAILED:", fails.length && fails.join(","));