1.1 --- a/rt/emul/mini/src/main/resources/org/apidesign/vm4brwsr/emul/lang/java_lang_Number.js Mon Jan 25 06:40:40 2016 +0100
1.2 +++ b/rt/emul/mini/src/main/resources/org/apidesign/vm4brwsr/emul/lang/java_lang_Number.js Mon Jan 25 08:14:42 2016 +0100
1.3 @@ -4,25 +4,9 @@
1.4 function add32(x, y) {
1.5 return (x + y) | 0;
1.6 };
1.7 - numberPrototype.mul32 = function(x) {
1.8 - return (((this * (x >> 16)) << 16) + this * (x & 0xFFFF)) | 0;
1.9 + function mul32(x, y) {
1.10 + return (((x * (y >> 16)) << 16) + x * (y & 0xFFFF)) | 0;
1.11 };
1.12 - numberPrototype.div32 = function(x) {
1.13 - if (x === 0) {
1.14 - __handleDivByZero();
1.15 - }
1.16 -
1.17 - return (this / x) | 0;
1.18 - }
1.19 -
1.20 - numberPrototype.mod32 = function(x) {
1.21 - if (x === 0) {
1.22 - __handleDivByZero();
1.23 - }
1.24 -
1.25 - return (this % x);
1.26 - }
1.27 -
1.28 var __m32 = 0xFFFFFFFF;
1.29
1.30 numberPrototype.next32 = function(low) {
1.31 @@ -116,7 +100,7 @@
1.32 };
1.33
1.34 numberPrototype.mul64 = function(x) {
1.35 - var low = this.mul32(x);
1.36 + var low = mul32(this, x);
1.37 low += (low < 0) ? (__m32 + 1) : 0;
1.38 // first count upper 32 bits of (this.low * x.low)
1.39 var hi_hi = 0;
1.40 @@ -134,8 +118,8 @@
1.41 }
1.42 var hi = (hi_hi << 16) + hi_low;
1.43
1.44 - var m1 = this.high32().mul32(x);
1.45 - var m2 = this.mul32(x.high32());
1.46 + var m1 = mul32(this.high32(), x);
1.47 + var m2 = mul32(this, x.high32());
1.48 hi = add32(add32(hi, m1), m2);
1.49
1.50 return hi.next32(low);
2.1 --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Mon Jan 25 06:40:40 2016 +0100
2.2 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Mon Jan 25 08:14:42 2016 +0100
2.3 @@ -41,6 +41,7 @@
2.4 private final StringArray classRefs = new StringArray();
2.5 private boolean outChanged;
2.6 private boolean callbacks;
2.7 + private final NumberOperations numbers = new NumberOperations();
2.8
2.9 protected ByteCodeToJavaScript(Appendable out) {
2.10 this.out = out;
2.11 @@ -293,6 +294,7 @@
2.12 append("\n m.access = " + m.getAccess()).append(";");
2.13 append("\n m.cls = CLS;");
2.14 }
2.15 + append(numbers.generate());
2.16 append("\n c.constructor = CLS;");
2.17 append("\n function ").append(className).append("fillInstOf(x) {");
2.18 String instOfName = "$instOf_" + className;
2.19 @@ -754,7 +756,7 @@
2.20 smapper.replace(this, VarType.DOUBLE, "(@1 - @2)", smapper.getD(1), smapper.popD());
2.21 break;
2.22 case opc_imul:
2.23 - smapper.replace(this, VarType.INTEGER, "(@1).mul32(@2)", smapper.getI(1), smapper.popI());
2.24 + smapper.replace(this, VarType.INTEGER, numbers.mul32(), smapper.getI(1), smapper.popI());
2.25 break;
2.26 case opc_lmul:
2.27 smapper.replace(this, VarType.LONG, "(@1).mul64(@2)", smapper.getL(1), smapper.popL());
2.28 @@ -766,7 +768,7 @@
2.29 smapper.replace(this, VarType.DOUBLE, "(@1 * @2)", smapper.getD(1), smapper.popD());
2.30 break;
2.31 case opc_idiv:
2.32 - smapper.replace(this, VarType.INTEGER, "(@1).div32(@2)",
2.33 + smapper.replace(this, VarType.INTEGER, numbers.div32(),
2.34 smapper.getI(1), smapper.popI());
2.35 break;
2.36 case opc_ldiv:
2.37 @@ -780,7 +782,7 @@
2.38 smapper.replace(this, VarType.DOUBLE, "(@1 / @2)", smapper.getD(1), smapper.popD());
2.39 break;
2.40 case opc_irem:
2.41 - smapper.replace(this, VarType.INTEGER, "(@1).mod32(@2)",
2.42 + smapper.replace(this, VarType.INTEGER, numbers.mod32(),
2.43 smapper.getI(1), smapper.popI());
2.44 break;
2.45 case opc_lrem:
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/NumberOperations.java Mon Jan 25 08:14:42 2016 +0100
3.3 @@ -0,0 +1,86 @@
3.4 +/**
3.5 + * Back 2 Browser Bytecode Translator
3.6 + * Copyright (C) 2012-2015 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
3.7 + *
3.8 + * This program is free software: you can redistribute it and/or modify
3.9 + * it under the terms of the GNU General Public License as published by
3.10 + * the Free Software Foundation, version 2 of the License.
3.11 + *
3.12 + * This program is distributed in the hope that it will be useful,
3.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
3.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3.15 + * GNU General Public License for more details.
3.16 + *
3.17 + * You should have received a copy of the GNU General Public License
3.18 + * along with this program. Look for COPYING file in the top folder.
3.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
3.20 + */
3.21 +package org.apidesign.vm4brwsr;
3.22 +
3.23 +final class NumberOperations {
3.24 + private static final int DIV32 = 1;
3.25 + private static final int MOD32 = 2;
3.26 + private static final int MUL32 = 4;
3.27 +
3.28 + private int used;
3.29 +
3.30 + public String mul32() {
3.31 + used |= MUL32;
3.32 + return "__mul32(@1,@2)";
3.33 + }
3.34 + public String div32() {
3.35 + used |= DIV32;
3.36 + return "__div32(@1,@2)";
3.37 + }
3.38 +
3.39 + public String mod32() {
3.40 + used |= MOD32;
3.41 + return "__mod32(@1,@2)";
3.42 + }
3.43 +
3.44 + public String generate() {
3.45 + if (used == 0) {
3.46 + return "";
3.47 + }
3.48 + StringBuilder sb = new StringBuilder();
3.49 + if ((used & MUL32) != 0) {
3.50 + sb.append(
3.51 + " __mul32 = function(x, y) {\n" +
3.52 + " return (((x * (y >> 16)) << 16) + x * (y & 0xFFFF)) | 0;\n" +
3.53 + " };\n" +
3.54 + ""
3.55 + );
3.56 + }
3.57 + if ((used & (MOD32 | DIV32)) != 0) {
3.58 + sb.append(
3.59 + " function __handleDivByZero() {\n" +
3.60 + " var exception = new vm.java_lang_ArithmeticException;\n" +
3.61 + " vm.java_lang_ArithmeticException(false).constructor\n" +
3.62 + " .cons__VLjava_lang_String_2.call(exception, \"/ by zero\");\n" +
3.63 + "\n" +
3.64 + " throw exception;\n" +
3.65 + " }\n" +
3.66 + ""
3.67 + );
3.68 + }
3.69 + if ((used & MOD32) != 0) {
3.70 + sb.append(
3.71 + " function __mod32(x, y) {\n" +
3.72 + " if (y === 0) __handleDivByZero();\n" +
3.73 + " return (x % y) | 0;\n" +
3.74 + " }\n" +
3.75 + ""
3.76 + );
3.77 + }
3.78 + if ((used & DIV32) != 0) {
3.79 + sb.append(
3.80 + " function __div32(x, y) {\n" +
3.81 + " if (y === 0) __handleDivByZero();\n" +
3.82 + " return (x / y) | 0;\n" +
3.83 + " }\n" +
3.84 + ""
3.85 + );
3.86 + }
3.87 + return sb.toString();
3.88 + }
3.89 +}