function f(){}
Object.defineProperty(f, 'length', { value: Infinity });
console.log(f.bind(0, 1, 2).length);
gives
#### ch
0
#### jsc
0
#### sm
Infinity
#### v8
Infinity
#### xs
9007199254740989
Presumably this is the fault of the following bit of the definition of F.p.bind:
1. Let _targetHasLength_ be ? HasOwnProperty(_Target_, *"length"*).
1. If _targetHasLength_ is *true*, then
1. Let _targetLen_ be ? Get(_Target_, *"length"*).
1. If Type(_targetLen_) is Number, then
1. Set _targetLen_ to ! ToInteger(_targetLen_).
1. Let _argCount_ be the number of elements in _args_.
1. Set _L_ to max(_targetLen_ - _argCount_, 0).
Note that ToInteger can return Infinity (for some reason), and hence this does arithmetic on a potentially infinite value, which isn't a thing we've said how to do. So it's unsurprising that engines have different behavior.
We should resolve this. I propose we say that binding a function whose length is Infinity produces a function whose length is Infinity, regardless of how many arguments are provided to bind.
Hmm, I thought I'd filed an issue for this when it came up on irc a month or two ago, but apparently not - thanks for filing!
I agree that if it's 卤Infinity (or perhaps also NaN? what do engines do there?) the value should be left alone (ie, when targetLen is not finite).
As of r266013, JSC also returns Infinity.
Implementation-wise, I have a slight preference for length being clamped to Number.MAX_SAFE_INTEGER by using ToLength instead of ToInteger.
also NaN? what do engines do there?) the value should be left alone (ie, when targetLen is not finite).
ToInteger returns +0 for NaN (step 2).
test262 coverage was recently updated for NaN, Infinity, and other edge-cases: https://github.com/tc39/test262/pull/2730.
Note that implementation divergence occurs well before Infinity:
$ eshost -se 'Object.defineProperties(function(){}, {length:{value:0x8000000000000480}}).bind().length'
#### ChakraCore
2048
#### engine262, JavaScriptCore, QuickJS, SpiderMonkey, V8
9223372036854778000
#### GraalJS
9223372036854776000
#### Moddable XS
9007199254740991
I think there's a reasonable case to be made for limiting length to 2 ** 32 - 1, aligning with arrays and template literals and regular expression captures.
Via @patrick-soquet:
XS uses
ToLengthso it returns 9007199254740991 which isNumber.MAX_SAFE_INTEGER - 2, because bind is called with two arguments.
That is almost what @shvaikalesh suggests. However, his preference matches @gibson042:
I would support the latest comment in the thread: limiting
lengthto 2 ** 32 - 1
Most helpful comment
Note that implementation divergence occurs well before
Infinity:I think there's a reasonable case to be made for limiting
lengthto 2 ** 32 - 1, aligning with arrays and template literals and regular expression captures.