diff --git a/lib/coffee-script/nodes.js b/lib/coffee-script/nodes.js index 2c7959e1..bb13a493 100644 --- a/lib/coffee-script/nodes.js +++ b/lib/coffee-script/nodes.js @@ -3075,7 +3075,7 @@ return "[].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }"; }, modulo: function() { - return "function(a, b) { return (a % b + +b) % b; }"; + return "function(a, b) { b = +b; return (a % b + b) % b; }"; }, hasProp: function() { return '{}.hasOwnProperty'; diff --git a/src/nodes.coffee b/src/nodes.coffee index 15e77ff3..36bb063a 100644 --- a/src/nodes.coffee +++ b/src/nodes.coffee @@ -2194,7 +2194,7 @@ UTILITIES = " modulo: -> """ - function(a, b) { return (a % b + +b) % b; } + function(a, b) { b = +b; return (a % b + b) % b; } """ # Shortcuts to speed up the lookup time for native functions. diff --git a/test/operators.coffee b/test/operators.coffee index 6aa7c137..4bf30fa3 100644 --- a/test/operators.coffee +++ b/test/operators.coffee @@ -357,3 +357,9 @@ test "modulo operator converts arguments to numbers", -> eq 1, 1 %% '42' eq 1, '1' %% 42 eq 1, '1' %% '42' + +test "#3361: Modulo operator coerces right operand once", -> + count = 0 + res = 42 %% valueOf: -> count += 1 + eq 1, count + eq 0, res