"I truly thought" you would not raise a question to which V8/Dart people already know the answer. Range prop is not the only solution.
Use JIT techniques to speculate profitably that most ints fit in JS doubles. This can be done in JS-hosted VMs, just as in machine-code-generating native VMs.
Again, this is extremely old hat to the Dart/V8 folks. See, e.g.
http://mraleph.tumblr.com/post/24351748336/explaining-js-vm-...
In SpiderMonkey, we augment JIT techniques with online type inference that distinguishes int from double. The same type inference could add bignum to the speculative tower. See
http://rfrn.org/~shu/drafts/ti.pdf
This avoids most of those checks that you assume are too expensive (and by assuming, so casually fork Dart semantics).
Here is a JS version of [Hackett&Shu, PLDI 2012], from @pcwalton:
https://github.com/pcwalton/doctorjsmm/
Can the full JIT+TI approach to bignum/double/int perform well enough for dart2js? Better find out, because forking semantics is just the wrong thing.
Another road not taken: we hear "can't wait for JS to get better", but Dart started at least by 2010, possibly earlier.
http://wiki.ecmascript.org/doku.php?id=strawman:bignums
could have been proposed and actually worked into ES6 by now, but the Dart team was in stealth mode (Dash) for too long. Still, better late than never. There's time for ES7. Who from Google will actually do the work in V8 and with Ecma TC39?
/be