Some operations are faster when included in the generated code rather than dispatched to Number.prototype
1.1 --- a/benchmarks/sieve/src/test/java/org/apidesign/benchmark/sieve/SieveTest.java Mon Jan 25 05:53:21 2016 +0100
1.2 +++ b/benchmarks/sieve/src/test/java/org/apidesign/benchmark/sieve/SieveTest.java Mon Jan 25 06:40:40 2016 +0100
1.3 @@ -45,6 +45,16 @@
1.4 log("oneThousand in " + took + " ms");
1.5 return res;
1.6 }
1.7 +
1.8 + @Compare(scripting = false)
1.9 + public int fiveThousand() throws IOException {
1.10 + SieveTest sieve = new SieveTest();
1.11 + int now = time();
1.12 + int res = sieve.compute(5000);
1.13 + int took = time() - now;
1.14 + log("oneThousand in " + took + " ms");
1.15 + return res;
1.16 + }
1.17
1.18 @Factory
1.19 public static Object[] create() {
1.20 @@ -54,5 +64,6 @@
1.21 @JavaScriptBody(args = { "msg" }, body = "if (typeof console !== 'undefined') console.log(msg);")
1.22 @Override
1.23 protected void log(String msg) {
1.24 + System.err.println(msg);
1.25 }
1.26 }
2.1 --- a/rt/emul/mini/src/main/resources/org/apidesign/vm4brwsr/emul/lang/java_lang_Number.js Mon Jan 25 05:53:21 2016 +0100
2.2 +++ b/rt/emul/mini/src/main/resources/org/apidesign/vm4brwsr/emul/lang/java_lang_Number.js Mon Jan 25 06:40:40 2016 +0100
2.3 @@ -1,25 +1,27 @@
2.4 // empty line needed here
2.5
2.6 (function(numberPrototype) {
2.7 - numberPrototype.add32 = function(x) {
2.8 - return (this + x) | 0;
2.9 - };
2.10 - numberPrototype.sub32 = function(x) {
2.11 - return (this - x) | 0;
2.12 + function add32(x, y) {
2.13 + return (x + y) | 0;
2.14 };
2.15 numberPrototype.mul32 = function(x) {
2.16 return (((this * (x >> 16)) << 16) + this * (x & 0xFFFF)) | 0;
2.17 };
2.18 - numberPrototype.neg32 = function() {
2.19 - return (-this) | 0;
2.20 - };
2.21 + numberPrototype.div32 = function(x) {
2.22 + if (x === 0) {
2.23 + __handleDivByZero();
2.24 + }
2.25
2.26 - numberPrototype.toInt8 = function() {
2.27 - return (this << 24) >> 24;
2.28 - };
2.29 - numberPrototype.toInt16 = function() {
2.30 - return (this << 16) >> 16;
2.31 - };
2.32 + return (this / x) | 0;
2.33 + }
2.34 +
2.35 + numberPrototype.mod32 = function(x) {
2.36 + if (x === 0) {
2.37 + __handleDivByZero();
2.38 + }
2.39 +
2.40 + return (this % x);
2.41 + }
2.42
2.43 var __m32 = 0xFFFFFFFF;
2.44
2.45 @@ -35,9 +37,6 @@
2.46 numberPrototype.high32 = function() {
2.47 return this.hi ? this.hi : (Math.floor(this / (__m32 + 1))) | 0;
2.48 };
2.49 - numberPrototype.toInt32 = function() {
2.50 - return this | 0;
2.51 - };
2.52 numberPrototype.toFP = function() {
2.53 return this.hi ? this.hi * (__m32 + 1) + this : this;
2.54 };
2.55 @@ -137,7 +136,7 @@
2.56
2.57 var m1 = this.high32().mul32(x);
2.58 var m2 = this.mul32(x.high32());
2.59 - hi = hi.add32(m1).add32(m2);
2.60 + hi = add32(add32(hi, m1), m2);
2.61
2.62 return hi.next32(low);
2.63 };
2.64 @@ -225,16 +224,6 @@
2.65 }
2.66 };
2.67
2.68 - // keeping for compatibility with generated bck2brwsr.js library files
2.69 - // not used since 0.14
2.70 - numberPrototype.compare = function(x) {
2.71 - if (this == x) {
2.72 - return 0;
2.73 - } else {
2.74 - return (this < x) ? -1 : 1;
2.75 - }
2.76 - };
2.77 -
2.78 numberPrototype.compare64 = function(x) {
2.79 if (this.high32() === x.high32()) {
2.80 return (this < x) ? -1 : ((this > x) ? 1 : 0);
2.81 @@ -490,22 +479,6 @@
2.82 }
2.83 }
2.84
2.85 - numberPrototype.div32 = function(x) {
2.86 - if (x === 0) {
2.87 - __handleDivByZero();
2.88 - }
2.89 -
2.90 - return (this / x) | 0;
2.91 - }
2.92 -
2.93 - numberPrototype.mod32 = function(x) {
2.94 - if (x === 0) {
2.95 - __handleDivByZero();
2.96 - }
2.97 -
2.98 - return (this % x);
2.99 - }
2.100 -
2.101 numberPrototype.div64 = function(x) {
2.102 var negateResult = false;
2.103 var u, v;
3.1 --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Mon Jan 25 05:53:21 2016 +0100
3.2 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Mon Jan 25 06:40:40 2016 +0100
3.3 @@ -730,7 +730,7 @@
3.4 emit(smapper, this, "var @1 = @2;", lmapper.setD(3), smapper.popD());
3.5 break;
3.6 case opc_iadd:
3.7 - smapper.replace(this, VarType.INTEGER, "(@1).add32(@2)", smapper.getI(1), smapper.popI());
3.8 + smapper.replace(this, VarType.INTEGER, "(((@1) + (@2)) | 0)", smapper.getI(1), smapper.popI());
3.9 break;
3.10 case opc_ladd:
3.11 smapper.replace(this, VarType.LONG, "(@1).add64(@2)", smapper.getL(1), smapper.popL());
3.12 @@ -742,7 +742,7 @@
3.13 smapper.replace(this, VarType.DOUBLE, "(@1 + @2)", smapper.getD(1), smapper.popD());
3.14 break;
3.15 case opc_isub:
3.16 - smapper.replace(this, VarType.INTEGER, "(@1).sub32(@2)", smapper.getI(1), smapper.popI());
3.17 + smapper.replace(this, VarType.INTEGER, "(((@1) - (@2)) | 0)", smapper.getI(1), smapper.popI());
3.18 break;
3.19 case opc_lsub:
3.20 smapper.replace(this, VarType.LONG, "(@1).sub64(@2)", smapper.getL(1), smapper.popL());
3.21 @@ -812,7 +812,7 @@
3.22 smapper.replace(this, VarType.LONG, "(@1).xor64(@2)", smapper.getL(1), smapper.popL());
3.23 break;
3.24 case opc_ineg:
3.25 - smapper.replace(this, VarType.INTEGER, "(@1).neg32()", smapper.getI(0));
3.26 + smapper.replace(this, VarType.INTEGER, "(-(@1))", smapper.getI(0));
3.27 break;
3.28 case opc_lneg:
3.29 smapper.replace(this, VarType.LONG, "(@1).neg64()", smapper.getL(0));
3.30 @@ -886,7 +886,7 @@
3.31 smapper.replace(this, VarType.DOUBLE, "@1", smapper.getI(0));
3.32 break;
3.33 case opc_l2i:
3.34 - smapper.replace(this, VarType.INTEGER, "(@1).toInt32()", smapper.getL(0));
3.35 + smapper.replace(this, VarType.INTEGER, "((@1) | 0)", smapper.getL(0));
3.36 break;
3.37 // max int check?
3.38 case opc_l2f:
3.39 @@ -904,7 +904,7 @@
3.40 smapper.getD(0));
3.41 break;
3.42 case opc_f2i:
3.43 - smapper.replace(this, VarType.INTEGER, "(@1).toInt32()",
3.44 + smapper.replace(this, VarType.INTEGER, "((@1) | 0)",
3.45 smapper.getF(0));
3.46 break;
3.47 case opc_f2l:
3.48 @@ -912,18 +912,18 @@
3.49 smapper.getF(0));
3.50 break;
3.51 case opc_d2i:
3.52 - smapper.replace(this, VarType.INTEGER, "(@1).toInt32()",
3.53 + smapper.replace(this, VarType.INTEGER, "((@1)| 0)",
3.54 smapper.getD(0));
3.55 break;
3.56 case opc_d2l:
3.57 smapper.replace(this, VarType.LONG, "(@1).toLong()", smapper.getD(0));
3.58 break;
3.59 case opc_i2b:
3.60 - smapper.replace(this, VarType.INTEGER, "(@1).toInt8()", smapper.getI(0));
3.61 + smapper.replace(this, VarType.INTEGER, "(((@1) << 24) >> 24)", smapper.getI(0));
3.62 break;
3.63 case opc_i2c:
3.64 case opc_i2s:
3.65 - smapper.replace(this, VarType.INTEGER, "(@1).toInt16()", smapper.getI(0));
3.66 + smapper.replace(this, VarType.INTEGER, "(((@1) << 16) >> 16)", smapper.getI(0));
3.67 break;
3.68 case opc_aconst_null:
3.69 smapper.assign(this, VarType.REFERENCE, "null");