rt/vm/src/main/java/org/apidesign/vm4brwsr/NumberOperations.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Tue, 22 Mar 2016 02:51:04 +0100
changeset 1906 48053538940a
parent 1871 bcbc4c03d35d
permissions -rw-r--r--
Don't generate 64-bit arithmetic into every class
     1 /**
     2  * Back 2 Browser Bytecode Translator
     3  * Copyright (C) 2012-2015 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
     4  *
     5  * This program is free software: you can redistribute it and/or modify
     6  * it under the terms of the GNU General Public License as published by
     7  * the Free Software Foundation, version 2 of the License.
     8  *
     9  * This program is distributed in the hope that it will be useful,
    10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12  * GNU General Public License for more details.
    13  *
    14  * You should have received a copy of the GNU General Public License
    15  * along with this program. Look for COPYING file in the top folder.
    16  * If not, see http://opensource.org/licenses/GPL-2.0.
    17  */
    18 package org.apidesign.vm4brwsr;
    19 
    20 final class NumberOperations {
    21     private static final int DIV32 = 1;
    22     private static final int MOD32 = 2;
    23     private static final int MUL32 = 4;
    24     private static final int BIT64 = 8;
    25 
    26     private int used;
    27 
    28     public void reset() {
    29         used = 0;
    30     }
    31 
    32     public String mul32() {
    33         used |= MUL32;
    34         return "__mul32(@1,@2)";
    35     }
    36     public String div32() {
    37         used |= DIV32;
    38         return "__div32(@1,@2)";
    39     }
    40 
    41     public String mod32() {
    42         used |= MOD32;
    43         return "__mod32(@1,@2)";
    44     }
    45 
    46     public String add64() {
    47         used |= BIT64;
    48         return "__add64(@1,@2)";
    49     }
    50 
    51     public String sub64() {
    52         used |= BIT64;
    53         return "__sub64(@1,@2)";
    54     }
    55 
    56     public String mul64() {
    57         used |= BIT64;
    58         return "__mul64(@1,@2)";
    59     }
    60 
    61     public String div64() {
    62         used |= BIT64;
    63         return "__div64(@1,@2)";
    64     }
    65 
    66     public String mod64() {
    67         used |= BIT64;
    68         return "__mod64(@1,@2)";
    69     }
    70 
    71     public String and64() {
    72         used |= BIT64;
    73         return "__and64(@1,@2)";
    74     }
    75 
    76     public String or64() {
    77         used |= BIT64;
    78         return "__or64(@1,@2)";
    79     }
    80 
    81     public String xor64() {
    82         used |= BIT64;
    83         return "__xor64(@1,@2)";
    84     }
    85 
    86     public String neg64() {
    87         used |= BIT64;
    88         return "__neg64(@1)";
    89     }
    90 
    91     public String shl64() {
    92         used |= BIT64;
    93         return "__shl64(@1,@2)";
    94     }
    95 
    96     public String shr64() {
    97         used |= BIT64;
    98         return "__shr64(@1,@2)";
    99     }
   100 
   101     public String ushr64() {
   102         used |= BIT64;
   103         return "__ushr64(@1,@2)";
   104     }
   105 
   106     public String compare64() {
   107         used |= BIT64;
   108         return "__compare64(@2,@1)";
   109     }
   110 
   111     public String generate() {
   112         if (used == 0) {
   113             return "";
   114         }
   115         StringBuilder sb = new StringBuilder();
   116         if ((used & MUL32) != 0) {
   117             sb.append(
   118                 "    __mul32 = function(x, y) {\n" +
   119                 "        return (((x * (y >> 16)) << 16) + x * (y & 0xFFFF)) | 0;\n" +
   120                 "    };\n" +
   121                 ""
   122             );
   123         }
   124         if ((used & (MOD32 | DIV32)) != 0) {
   125             sb.append(
   126                 "    function __handleDivByZero() {\n" +
   127                 "        var exception = new vm.java_lang_ArithmeticException;\n" +
   128                 "        vm.java_lang_ArithmeticException(false).constructor\n" +
   129                 "          .cons__VLjava_lang_String_2.call(exception, \"/ by zero\");\n" +
   130                 "\n" +
   131                 "        throw exception;\n" +
   132                 "    }\n" +
   133                 ""
   134             );
   135         }
   136         if ((used & MOD32) != 0) {
   137             sb.append(
   138                 "    function __mod32(x, y) {\n" +
   139                 "        if (y === 0) __handleDivByZero();\n" +
   140                 "        return (x % y) | 0;\n" +
   141                 "    }\n" +
   142                 ""
   143             );
   144         }
   145         if ((used & DIV32) != 0) {
   146             sb.append(
   147                 "    function __div32(x, y) {\n" +
   148                 "        if (y === 0) __handleDivByZero();\n" +
   149                 "        return (x / y) | 0;\n" +
   150                 "    }\n" +
   151                 ""
   152             );
   153         }
   154         if ((used & BIT64) != 0) {
   155             sb.append(
   156                 "    var __add64 = Number.prototype['__bit64']['add64'];\n" +
   157                 "    var __sub64 = Number.prototype['__bit64']['sub64'];\n" +
   158                 "    var __mul64 = Number.prototype['__bit64']['mul64'];\n" +
   159                 "    var __div64 = Number.prototype['__bit64']['div64'];\n" +
   160                 "    var __mod64 = Number.prototype['__bit64']['mod64'];\n" +
   161                 "    var __and64 = Number.prototype['__bit64']['and64'];\n" +
   162                 "    var __or64 = Number.prototype['__bit64']['or64'];\n" +
   163                 "    var __xor64 = Number.prototype['__bit64']['xor64'];\n" +
   164                 "    var __neg64 = Number.prototype['__bit64']['neg64'];\n" +
   165                 "    var __shl64 = Number.prototype['__bit64']['shl64'];\n" +
   166                 "    var __shr64 = Number.prototype['__bit64']['shr64'];\n" +
   167                 "    var __ushr64 = Number.prototype['__bit64']['ushr64'];\n" +
   168                 "    var __compare64 = Number.prototype['__bit64']['compare64'];\n" +
   169                 ""
   170             );
   171         }
   172         return sb.toString();
   173     }
   174 }