Bug 808148 -Implement experimental Math.imul. r=Waldo

This commit is contained in:
Tom Schuster 2012-12-14 19:28:14 +01:00
Родитель ef14f11685
Коммит 0b9039418f
3 изменённых файлов: 93 добавлений и 0 удалений

Просмотреть файл

@ -0,0 +1,71 @@
var table = [
[NaN, 0, 0],
[Infinity, Infinity, 0],
[NaN, 1000, 0],
[-1, -2, 2],
[1, 2, 2],
[-1, 2, -2],
[1, -2, -2],
[-0, 0, 0],
[0, -0, 0],
[-1, -0, 0],
[1, -0, 0],
[0xffffffff, 1, -1],
[0xffffffff, 0xffffffff, 1],
[0xffffffff, -0xffffffff, -1],
[0xffffffff, 0xfffffffe, 2],
[0xffffffff, -0xfffffffe, -2],
[0x10000, 0x10000, 0],
[{}, {}, 0],
[[], [], 0],
[{}, [], 0],
[[], {}, 0],
[{valueOf: function() { return -1; }}, 0x100000, -1048576],
["3", "-4", -12],
[3.4, 6, 18]
];
try {
Math.imul({ valueOf: function() { throw "ha ha ha"; } });
assertEq(true, false, "no error thrown");
} catch (e) {
assertEq(e, "ha ha ha");
}
var order = [];
assertEq(Math.imul({ valueOf: function() { order.push("first"); return 0; } },
{ valueOf: function() { order.push("second"); return 0; } }),
0);
assertEq(order[0], "first");
assertEq(order[1], "second");
var seen = [];
try
{
Math.imul({ valueOf: function() { seen.push("one"); return 17; } },
{ valueOf: function() { throw "abort!"; } });
assertEq(true, false, "no error thrown");
}
catch (e)
{
assertEq(e, "abort!", "should have thrown partway through, instead threw " + e);
}
assertEq(seen.length, 1);
assertEq(seen[0], "one");
assertEq(Math.imul(), 0);
assertEq(Math.imul(100), 0);
assertEq(Math.imul(NaN, 100), 0);
assertEq(Math.imul(NaN, NaN), 0);
assertEq(Math.imul(5, Infinity), 0);
for (var i = 0; i < table.length; i++) {
assertEq(Math.imul(table[i][0], table[i][1]), table[i][2]);
assertEq(Math.imul(table[i][1], table[i][0]), table[i][2]);
}

Просмотреть файл

@ -328,6 +328,24 @@ js_math_floor(JSContext *cx, unsigned argc, Value *vp)
return JS_TRUE;
}
JSBool
js::math_imul(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
uint32_t a = 0, b = 0;
if (args.hasDefined(0) && !ToUint32(cx, args[0], &a))
return false;
if (args.hasDefined(1) && !ToUint32(cx, args[1], &b))
return false;
uint32_t product = a * b;
args.rval().setInt32(product > INT32_MAX
? int32_t(INT32_MIN + (product - INT32_MAX - 1))
: int32_t(product));
return true;
}
double
js::math_log_impl(MathCache *cache, double x)
{
@ -702,6 +720,7 @@ static JSFunctionSpec math_static_methods[] = {
JS_FN("cos", math_cos, 1, 0),
JS_FN("exp", math_exp, 1, 0),
JS_FN("floor", js_math_floor, 1, 0),
JS_FN("imul", math_imul, 2, 0),
JS_FN("log", math_log, 1, 0),
JS_FN("max", js_math_max, 2, 0),
JS_FN("min", js_math_min, 2, 0),

Просмотреть файл

@ -95,6 +95,9 @@ js_math_floor_impl(double x);
namespace js {
extern JSBool
math_imul(JSContext *cx, unsigned argc, js::Value *vp);
extern JSBool
math_log(JSContext *cx, unsigned argc, js::Value *vp);