vm/src/test/java/org/apidesign/vm4brwsr/NumberTest.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Mon, 11 Feb 2013 12:46:43 +0100
branchemul
changeset 708 59d5596a9c6c
parent 680 7ffb635a5c4f
child 747 ae352b763959
permissions -rw-r--r--
Encapsulation. Moving shared code into TestVM instance.
     1 /**
     2  * Back 2 Browser Bytecode Translator
     3  * Copyright (C) 2012 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 import static org.testng.Assert.*;
    21 import org.testng.annotations.BeforeClass;
    22 import org.testng.annotations.Test;
    23 
    24 /**
    25  *
    26  * @author Jaroslav Tulach <jtulach@netbeans.org>
    27  */
    28 public class NumberTest {
    29     @Test public void integerFromString() throws Exception {
    30         assertExec("Can convert string to integer", Integer.class, "parseInt__ILjava_lang_String_2",
    31             Double.valueOf(333), "333"
    32         );
    33     }
    34 
    35     @Test public void doubleFromString() throws Exception {
    36         assertExec("Can convert string to double", Double.class, "parseDouble__DLjava_lang_String_2",
    37             Double.valueOf(33.3), "33.3"
    38         );
    39     }
    40 
    41     @Test public void autoboxDouble() throws Exception {
    42         assertExec("Autoboxing of doubles is OK", Numbers.class, "autoboxDblToString__Ljava_lang_String_2",
    43             "3.3"
    44         );
    45     }
    46     
    47     @Test public void javalog1000() throws Exception {
    48         assertEquals(3.0, Math.log10(1000.0), 0.00003, "log_10(1000) == 3");
    49     }
    50 
    51     @Test public void jslog1000() throws Exception {
    52         assertExec("log_10(1000) == 3", Math.class, "log10__DD", 
    53             Double.valueOf(3.0), 1000.0
    54         );
    55     }
    56     
    57     @Test public void javaRem() {
    58         assertEquals(3, Numbers.rem(303, 10));
    59     }
    60     @Test public void jsRem() throws Exception {
    61         assertExec("Should be three", Numbers.class, "rem__III", 
    62             Double.valueOf(3.0), 303, 10
    63         );
    64     }
    65     
    66     @Test public void deserializeInt() throws Exception {
    67         int exp = Numbers.deserInt();
    68         assertExec("Should be the same", Numbers.class, "deserInt__I", 
    69             Double.valueOf(exp)
    70         );
    71     }
    72 
    73     @Test public void deserializeSimpleLong() throws Exception {
    74         assertExec("Should be 3454", Numbers.class, "deserLong__J_3B", 
    75             Double.valueOf(3454), 
    76             new byte[] { (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)13, (byte)126 }
    77         );
    78     }
    79     /* XXX: JavaScript cannot represent as big longs as Java. 
    80     @Test public void deserializeLargeLong() throws Exception {
    81         final byte[] arr = new byte[] {
    82             (byte)64, (byte)8, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0
    83         };
    84         long exp = Numbers.deserLong(arr);
    85         assertExec("Should be " + exp, "org_apidesign_vm4brwsr_Numbers_deserLong__JAB", 
    86             Double.valueOf(exp), arr);
    87     }
    88     */
    89     
    90     @Test public void deserializeFloatInJava() throws Exception {
    91         float f = 54324.32423f;
    92         float r = Numbers.deserFloat();
    93         assertEquals(r, f, "Floats are the same");
    94     }
    95     
    96     @Test public void deserializeFloatInJS() throws Exception {
    97         float f = 54324.32423f;
    98         assertExec("Should be the same", Numbers.class, "deserFloat__F", 
    99             Double.valueOf(f)
   100         );
   101     }
   102 
   103     @Test public void deserializeDoubleInJava() throws Exception {
   104         double f = 3.0;
   105         double r = Numbers.deserDouble();
   106         assertEquals(r, f, 0.001, "Doubles are the same");
   107     }
   108     
   109     @Test public void deserializeDoubleInJS() throws Exception {
   110         double f = 3.0;
   111         assertExec("Should be the same", Numbers.class, "deserDouble__D", f);
   112     }
   113     /*
   114     @Test public void serDouble() throws IOException {
   115         double f = 3.0;
   116         ByteArrayOutputStream os = new ByteArrayOutputStream();
   117         DataOutputStream d = new DataOutputStream(os);
   118         d.writeLong(3454);
   119         d.close();
   120         
   121         StringBuilder sb = new StringBuilder();
   122         byte[] arr = os.toByteArray();
   123         for (int i = 0; i < arr.length; i++) {
   124             sb.append("(byte)").append(arr[i]).append(", ");
   125         }
   126         fail("" + sb);
   127     }
   128 */    
   129     @Test public void fiveInStringJS() throws Exception {
   130         String s = Numbers.intToString();
   131         assertExec("Should be the same: " + s, 
   132             Numbers.class, "intToString__Ljava_lang_String_2", 
   133             s
   134         );
   135     }
   136 
   137     @Test public void sevenInStringJS() throws Exception {
   138         String s = Numbers.floatToString();
   139         assertExec("Should be the same: " + s, 
   140             Numbers.class, "floatToString__Ljava_lang_String_2", 
   141             s
   142         );
   143     }
   144     
   145     @Test public void longConversion() throws Exception {
   146         assertExec("Long from cPool",
   147             Numbers.class, "conversionL__J", 
   148             Double.valueOf(Long.MAX_VALUE)
   149         );
   150     }
   151     
   152     @Test public void longNegate1() throws Exception {
   153         final long res = -0x00fa37d7763e0ca1l;
   154         assertExec("Long negate",
   155             Numbers.class, "negL__J_3B", 
   156             Double.valueOf(res),
   157                 new byte[] { (byte)0x00, (byte)0xfa, (byte)0x37, (byte)0xd7, (byte)0x76, (byte)0x3e, (byte)0x0c, (byte)0xa1 }
   158         );
   159     }
   160     
   161     @Test public void longNegate2() throws Exception {
   162         final long res = -0x80fa37d7763e0ca1l;
   163         assertExec("Long negate",
   164             Numbers.class, "negL__J_3B", 
   165             Double.valueOf(res),
   166                 new byte[] { (byte)0x80, (byte)0xfa, (byte)0x37, (byte)0xd7, (byte)0x76, (byte)0x3e, (byte)0x0c, (byte)0xa1 }
   167         );
   168     }
   169 
   170     @Test public void longNegate3() throws Exception {
   171         final long res = -0xfffffffffffffeddl;
   172         assertExec("Long negate",
   173             Numbers.class, "negL__J_3B",
   174             Double.valueOf(res),
   175                 new byte[] { (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xfe, (byte)0xdd }
   176         );
   177     }
   178 
   179     @Test public void longAddOverflow() throws Exception {
   180         final long res = Long.MAX_VALUE + 1l;
   181         assertExec("Addition 1+MAX",
   182             Numbers.class, "addL__J_3B_3B", 
   183             Double.valueOf(res),
   184                 new byte[] { (byte)0x7f, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff },
   185                 new byte[] { (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)1 }
   186         );
   187     }
   188     
   189     @Test public void longAddMaxAndMax() throws Exception {
   190         final long res = Long.MAX_VALUE + Long.MAX_VALUE;
   191         assertExec("Addition MAX+MAX",
   192             Numbers.class, "addL__J_3B_3B", 
   193             Double.valueOf(res),
   194             new byte[] { (byte)0x7f, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff },
   195             new byte[] { (byte)0x7f, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff }
   196         );
   197     }
   198     
   199     @Test public void longSubUnderflow() throws Exception {
   200         final long res = Long.MIN_VALUE - 1l;
   201         assertExec("Subtraction MIN-1",
   202             Numbers.class, "subL__J_3B_3B", 
   203             Double.valueOf(res),
   204                 new byte[] { (byte)0x80, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 },
   205                 new byte[] { (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)1 }
   206         );
   207     }
   208     
   209     @Test public void longSubMinAndMin() throws Exception {
   210         final long res = Long.MIN_VALUE - Long.MIN_VALUE;
   211         assertExec("Subtraction MIN-MIN",
   212             Numbers.class, "subL__J_3B_3B", 
   213             Double.valueOf(res),
   214             new byte[] { (byte)0x80, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 },
   215             new byte[] { (byte)0x80, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 }
   216         );
   217     }
   218     
   219     @Test public void longSubMinAndMax() throws Exception {
   220         final long res = Long.MIN_VALUE - Long.MAX_VALUE;
   221         assertExec("Subtraction MIN-MAX",
   222             Numbers.class, "subL__J_3B_3B", 
   223             Double.valueOf(res),
   224             new byte[] { (byte)0x80, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 },
   225             new byte[] { (byte)0x7f, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff }
   226         );
   227     }
   228     
   229     @Test public void longMultiplyMax() throws Exception {
   230         final long res = Long.MAX_VALUE * 2l;
   231         assertExec("Multiplication MAX*2",
   232             Numbers.class, "mulL__J_3B_3B",
   233             Double.valueOf(res),
   234             new byte[] { (byte)0x7f, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff },
   235             new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x02 }
   236         );
   237     }
   238     
   239     @Test public void longMultiplyMaxAndMax() throws Exception {
   240         final long res = Long.MAX_VALUE * Long.MAX_VALUE;
   241         assertExec("Multiplication MAX*MAX",
   242             Numbers.class, "mulL__J_3B_3B",
   243             Double.valueOf(res),
   244             new byte[] { (byte)0x7f, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff },
   245             new byte[] { (byte)0x7f, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff }
   246         );
   247     }
   248     
   249     @Test public void longMultiplyMin() throws Exception {
   250         final long res = Long.MIN_VALUE * 2l;
   251         assertExec("Multiplication MIN*2",
   252             Numbers.class, "mulL__J_3B_3B",
   253             Double.valueOf(res),
   254             new byte[] { (byte)0x80, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 },
   255             new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x02 }
   256         );
   257     }
   258     
   259     @Test public void longMultiplyMinAndMin() throws Exception {
   260         final long res = Long.MIN_VALUE * Long.MIN_VALUE;
   261         assertExec("Multiplication MIN*2",
   262             Numbers.class, "mulL__J_3B_3B",
   263             Double.valueOf(res),
   264             new byte[] { (byte)0x80, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 },
   265             new byte[] { (byte)0x80, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 }
   266         );
   267     }
   268     
   269     @Test public void longMultiplyPrecision() throws Exception {
   270         final long res = 0x00fa37d7763e0ca1l * 0xa7b3432fff00123el;
   271         assertExec("Multiplication",
   272             Numbers.class, "mulL__J_3B_3B",
   273             Double.valueOf(res),
   274             new byte[] { (byte)0x00, (byte)0xfa, (byte)0x37, (byte)0xd7, (byte)0x76, (byte)0x3e, (byte)0x0c, (byte)0xa1 },
   275             new byte[] { (byte)0xa7, (byte)0xb3, (byte)0x43, (byte)0x2f, (byte)0xff, (byte)0x00, (byte)0x12, (byte)0x3e }
   276         );
   277     }
   278 
   279     @Test public void longDivideSmallPositiveNumbers() throws Exception {
   280         final long res = 0xabcdef / 0x123;
   281         assertExec("Division Small Positive Numbers",
   282             Numbers.class, "divL__J_3B_3B",
   283             Double.valueOf(res),
   284             new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0xab, (byte)0xcd, (byte)0xef },
   285             new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01, (byte)0x23 }
   286         );
   287     }
   288 
   289     @Test public void longDivideSmallNegativeNumbers() throws Exception {
   290         final long res = -0xabcdef / -0x123;
   291         assertExec("Division Small Negative Numbers",
   292             Numbers.class, "divL__J_3B_3B",
   293             Double.valueOf(res),
   294             new byte[] { (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x54, (byte)0x32, (byte)0x11 },
   295             new byte[] { (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xfe, (byte)0xdd }
   296         );
   297     }
   298 
   299     @Test public void longDivideSmallMixedNumbers() throws Exception {
   300         final long res = 0xabcdef / -0x123;
   301         assertExec("Division Small Mixed Numbers",
   302             Numbers.class, "divL__J_3B_3B",
   303             Double.valueOf(res),
   304             new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0xab, (byte)0xcd, (byte)0xef },
   305             new byte[] { (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xfe, (byte)0xdd }
   306         );
   307     }
   308 
   309     @Test public void longDividePositiveNumbersOneDigitDenom()
   310             throws Exception {
   311         final long res = 0xabcdef0102ffffL / 0x654;
   312         assertExec("Division Positive Numbers One Digit Denom",
   313             Numbers.class, "divL__J_3B_3B",
   314             Double.valueOf(res),
   315             new byte[] { (byte)0x00, (byte)0xab, (byte)0xcd, (byte)0xef, (byte)0x01, (byte)0x02, (byte)0xff, (byte)0xff },
   316             new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x54 }
   317         );
   318     }
   319 
   320     @Test public void longDivideNegativeNumbersOneDigitDenom()
   321             throws Exception {
   322         final long res = -0xabcdef0102ffffL / -0x654;
   323         assertExec("Division Negative Numbers One Digit Denom",
   324             Numbers.class, "divL__J_3B_3B",
   325             Double.valueOf(res),
   326             new byte[] { (byte)0xff, (byte)0x54, (byte)0x32, (byte)0x10, (byte)0xfe, (byte)0xfd, (byte)0x00, (byte)0x01 },
   327             new byte[] { (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xf9, (byte)0xac }
   328         );
   329     }
   330 
   331     @Test public void longDivideMixedNumbersOneDigitDenom()
   332             throws Exception {
   333         final long res = -0xabcdef0102ffffL / 0x654;
   334         assertExec("Division Mixed Numbers One Digit Denom",
   335             Numbers.class, "divL__J_3B_3B",
   336             Double.valueOf(res),
   337             new byte[] { (byte)0xff, (byte)0x54, (byte)0x32, (byte)0x10, (byte)0xfe, (byte)0xfd, (byte)0x00, (byte)0x01 },
   338             new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x54 }
   339         );
   340     }
   341 
   342     @Test public void longDividePositiveNumbersMultiDigitDenom()
   343             throws Exception {
   344         final long res = 0x7ffefc003322aabbL / 0x89ab1000L;
   345         assertExec("Division Positive Numbers Multi Digit Denom",
   346             Numbers.class, "divL__J_3B_3B",
   347             Double.valueOf(res),
   348             new byte[] { (byte)0x7f, (byte)0xfe, (byte)0xfc, (byte)0x00, (byte)0x33, (byte)0x22, (byte)0xaa, (byte)0xbb },
   349             new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x89, (byte)0xab, (byte)0x10, (byte)0x00 }
   350         );
   351     }
   352 
   353     @Test public void longDivideNegativeNumbersMultiDigitDenom()
   354             throws Exception {
   355         final long res = -0x7ffefc003322aabbL / -0x123489ab1001L;
   356         assertExec("Division Negative Numbers Multi Digit Denom",
   357             Numbers.class, "divL__J_3B_3B",
   358             Double.valueOf(res),
   359             new byte[] { (byte)0x80, (byte)0x01, (byte)0x03, (byte)0xff, (byte)0xcc, (byte)0xdd, (byte)0x55, (byte)0x45 },
   360             new byte[] { (byte)0xff, (byte)0xff, (byte)0xed, (byte)0xcb, (byte)0x76, (byte)0x54, (byte)0xef, (byte)0xff }
   361         );
   362     }
   363 
   364     @Test public void longDivideMixedNumbersMultiDigitDenom()
   365             throws Exception {
   366         final long res = 0x7ffefc003322aabbL / -0x38f49b0b7574e36L;
   367         assertExec("Division Mixed Numbers Multi Digit Denom",
   368             Numbers.class, "divL__J_3B_3B",
   369             Double.valueOf(res),
   370             new byte[] { (byte)0x7f, (byte)0xfe, (byte)0xfc, (byte)0x00, (byte)0x33, (byte)0x22, (byte)0xaa, (byte)0xbb },
   371             new byte[] { (byte)0xfc, (byte)0x70, (byte)0xb6, (byte)0x4f, (byte)0x48, (byte)0xa8, (byte)0xb1, (byte)0xca }
   372         );
   373     }
   374 
   375     @Test public void longDivideWithOverflow() throws Exception {
   376         final long res = 0x8000fffe0000L / 0x8000ffffL;
   377         assertExec("Division With Overflow",
   378             Numbers.class, "divL__J_3B_3B",
   379             Double.valueOf(res),
   380             new byte[] { (byte)0x00, (byte)0x00, (byte)0x80, (byte)0x00, (byte)0xff, (byte)0xfe, (byte)0x00, (byte)0x00 },
   381             new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x80, (byte)0x00, (byte)0xff, (byte)0xff }
   382         );
   383     }
   384 
   385     @Test public void longDivideWithCorrection() throws Exception {
   386         final long res = 0x7fff800000000000L / 0x800000000001L;
   387         assertExec("Division With Correction",
   388             Numbers.class, "divL__J_3B_3B",
   389             Double.valueOf(res),
   390             new byte[] { (byte)0x7f, (byte)0xff, (byte)0x80, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 },
   391             new byte[] { (byte)0x00, (byte)0x00, (byte)0x80, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01 }
   392         );
   393     }
   394 
   395     @Test public void longModuloSmallPositiveNumbers() throws Exception {
   396         final long res = 0xabcdef % 0x123;
   397         assertExec("Modulo Small Positive Numbers",
   398             Numbers.class, "modL__J_3B_3B",
   399             Double.valueOf(res),
   400             new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0xab, (byte)0xcd, (byte)0xef },
   401             new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01, (byte)0x23 }
   402         );
   403     }
   404 
   405     @Test public void longModuloSmallNegativeNumbers() throws Exception {
   406         final long res = -0xabcdef % -0x123;
   407         assertExec("Modulo Small Negative Numbers",
   408             Numbers.class, "modL__J_3B_3B",
   409             Double.valueOf(res),
   410             new byte[] { (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x54, (byte)0x32, (byte)0x11 },
   411             new byte[] { (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xfe, (byte)0xdd }
   412         );
   413     }
   414 
   415     @Test public void longModuloSmallMixedNumbers() throws Exception {
   416         final long res = 0xabcdef % -0x123;
   417         assertExec("Modulo Small Mixed Numbers",
   418             Numbers.class, "modL__J_3B_3B",
   419             Double.valueOf(res),
   420             new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0xab, (byte)0xcd, (byte)0xef },
   421             new byte[] { (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xfe, (byte)0xdd }
   422         );
   423     }
   424 
   425     @Test public void longModuloPositiveNumbersOneDigitDenom()
   426             throws Exception {
   427         final long res = 0xabcdef0102ffffL % 0x654;
   428         assertExec("Modulo Positive Numbers One Digit Denom",
   429             Numbers.class, "modL__J_3B_3B",
   430             Double.valueOf(res),
   431             new byte[] { (byte)0x00, (byte)0xab, (byte)0xcd, (byte)0xef, (byte)0x01, (byte)0x02, (byte)0xff, (byte)0xff },
   432             new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x54 }
   433         );
   434     }
   435 
   436     @Test public void longModuloNegativeNumbersOneDigitDenom()
   437             throws Exception {
   438         final long res = -0xabcdef0102ffffL % -0x654;
   439         assertExec("Modulo Negative Numbers One Digit Denom",
   440             Numbers.class, "modL__J_3B_3B",
   441             Double.valueOf(res),
   442             new byte[] { (byte)0xff, (byte)0x54, (byte)0x32, (byte)0x10, (byte)0xfe, (byte)0xfd, (byte)0x00, (byte)0x01 },
   443             new byte[] { (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xf9, (byte)0xac }
   444         );
   445     }
   446 
   447     @Test public void longModuloMixedNumbersOneDigitDenom()
   448             throws Exception {
   449         final long res = -0xabcdef0102ffffL % 0x654;
   450         assertExec("Modulo Mixed Numbers One Digit Denom",
   451             Numbers.class, "modL__J_3B_3B",
   452             Double.valueOf(res),
   453             new byte[] { (byte)0xff, (byte)0x54, (byte)0x32, (byte)0x10, (byte)0xfe, (byte)0xfd, (byte)0x00, (byte)0x01 },
   454             new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x54 }
   455         );
   456     }
   457 
   458     @Test public void longModuloPositiveNumbersMultiDigitDenom()
   459             throws Exception {
   460         final long res = 0x7ffefc003322aabbL % 0x89ab1000L;
   461         assertExec("Modulo Positive Numbers Multi Digit Denom",
   462             Numbers.class, "modL__J_3B_3B",
   463             Double.valueOf(res),
   464             new byte[] { (byte)0x7f, (byte)0xfe, (byte)0xfc, (byte)0x00, (byte)0x33, (byte)0x22, (byte)0xaa, (byte)0xbb },
   465             new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x89, (byte)0xab, (byte)0x10, (byte)0x00 }
   466         );
   467     }
   468 
   469     @Test public void longModuloNegativeNumbersMultiDigitDenom()
   470             throws Exception {
   471         final long res = -0x7ffefc003322aabbL % -0x123489ab1001L;
   472         assertExec("Modulo Negative Numbers Multi Digit Denom",
   473             Numbers.class, "modL__J_3B_3B",
   474             Double.valueOf(res),
   475             new byte[] { (byte)0x80, (byte)0x01, (byte)0x03, (byte)0xff, (byte)0xcc, (byte)0xdd, (byte)0x55, (byte)0x45 },
   476             new byte[] { (byte)0xff, (byte)0xff, (byte)0xed, (byte)0xcb, (byte)0x76, (byte)0x54, (byte)0xef, (byte)0xff }
   477         );
   478     }
   479 
   480     @Test public void longModuloMixedNumbersMultiDigitDenom()
   481             throws Exception {
   482         final long res = 0x7ffefc003322aabbL % -0x38f49b0b7574e36L;
   483         assertExec("Modulo Mixed Numbers Multi Digit Denom",
   484             Numbers.class, "modL__J_3B_3B",
   485             Double.valueOf(res),
   486             new byte[] { (byte)0x7f, (byte)0xfe, (byte)0xfc, (byte)0x00, (byte)0x33, (byte)0x22, (byte)0xaa, (byte)0xbb },
   487             new byte[] { (byte)0xfc, (byte)0x70, (byte)0xb6, (byte)0x4f, (byte)0x48, (byte)0xa8, (byte)0xb1, (byte)0xca }
   488         );
   489     }
   490 
   491     @Test public void longModuloWithOverflow() throws Exception {
   492         final long res = 0x8000fffe0000L % 0x8000ffffL;
   493         assertExec("Modulo With Overflow",
   494             Numbers.class, "modL__J_3B_3B",
   495             Double.valueOf(res),
   496             new byte[] { (byte)0x00, (byte)0x00, (byte)0x80, (byte)0x00, (byte)0xff, (byte)0xfe, (byte)0x00, (byte)0x00 },
   497             new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x80, (byte)0x00, (byte)0xff, (byte)0xff }
   498         );
   499     }
   500 
   501     @Test public void longModuloWithCorrection() throws Exception {
   502         final long res = 0x7fff800000000000L % 0x800000000001L;
   503         assertExec("Modulo With Correction",
   504             Numbers.class, "modL__J_3B_3B",
   505             Double.valueOf(res),
   506             new byte[] { (byte)0x7f, (byte)0xff, (byte)0x80, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 },
   507             new byte[] { (byte)0x00, (byte)0x00, (byte)0x80, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01 }
   508         );
   509     }
   510 
   511     @Test public void longShiftL1() throws Exception {
   512         final long res = 0x00fa37d7763e0ca1l << 5;
   513         assertExec("Long << 5",
   514             Numbers.class, "shlL__J_3BI", 
   515             Double.valueOf(res),
   516                 new byte[] { (byte)0x00, (byte)0xfa, (byte)0x37, (byte)0xd7, (byte)0x76, (byte)0x3e, (byte)0x0c, (byte)0xa1 },
   517                 5);
   518     }
   519     
   520     @Test public void longShiftL2() throws Exception {
   521         final long res = 0x00fa37d7763e0ca1l << 32;
   522         assertExec("Long << 32",
   523             Numbers.class, "shlL__J_3BI", 
   524             Double.valueOf(res),
   525                 new byte[] { (byte)0x00, (byte)0xfa, (byte)0x37, (byte)0xd7, (byte)0x76, (byte)0x3e, (byte)0x0c, (byte)0xa1 },
   526                 32);
   527     }
   528     
   529     @Test public void longShiftL3() throws Exception {
   530         final long res = 0x00fa37d7763e0ca1l << 45;
   531         assertExec("Long << 45",
   532             Numbers.class, "shlL__J_3BI", 
   533             Double.valueOf(res),
   534                 new byte[] { (byte)0x00, (byte)0xfa, (byte)0x37, (byte)0xd7, (byte)0x76, (byte)0x3e, (byte)0x0c, (byte)0xa1 },
   535                 45);
   536     }
   537     
   538     @Test public void longShiftR1() throws Exception {
   539         final long res = 0x00fa37d7763e0ca1l >> 5;
   540         assertExec("Long >> 5",
   541             Numbers.class, "shrL__J_3BI", 
   542             Double.valueOf(res),
   543                 new byte[] { (byte)0x00, (byte)0xfa, (byte)0x37, (byte)0xd7, (byte)0x76, (byte)0x3e, (byte)0x0c, (byte)0xa1 },
   544                 5);
   545     }
   546     
   547     @Test public void longShiftR2() throws Exception {
   548         final long res = 0x00fa37d7763e0ca1l >> 32;
   549         assertExec("Long >> 32",
   550             Numbers.class, "shrL__J_3BI", 
   551             Double.valueOf(res),
   552                 new byte[] { (byte)0x00, (byte)0xfa, (byte)0x37, (byte)0xd7, (byte)0x76, (byte)0x3e, (byte)0x0c, (byte)0xa1 },
   553                 32);
   554     }
   555     
   556     @Test public void longShiftR3() throws Exception {
   557         final long res = 0x00fa37d7763e0ca1l >> 45;
   558         assertExec("Long >> 45",
   559             Numbers.class, "shrL__J_3BI", 
   560             Double.valueOf(res),
   561                 new byte[] { (byte)0x00, (byte)0xfa, (byte)0x37, (byte)0xd7, (byte)0x76, (byte)0x3e, (byte)0x0c, (byte)0xa1 },
   562                 45);
   563     }
   564     
   565     @Test public void longUShiftR1() throws Exception {
   566         final long res = 0x00fa37d7763e0ca1l >>> 5;
   567         assertExec("Long >>> 5",
   568             Numbers.class, "ushrL__J_3BI", 
   569             Double.valueOf(res),
   570                 new byte[] { (byte)0x00, (byte)0xfa, (byte)0x37, (byte)0xd7, (byte)0x76, (byte)0x3e, (byte)0x0c, (byte)0xa1 },
   571                 5);
   572     }
   573     
   574     @Test public void longUShiftR2() throws Exception {
   575         final long res = 0x00fa37d7763e0ca1l >>> 45;
   576         assertExec("Long >>> 45",
   577             Numbers.class, "ushrL__J_3BI", 
   578             Double.valueOf(res),
   579                 new byte[] { (byte)0x00, (byte)0xfa, (byte)0x37, (byte)0xd7, (byte)0x76, (byte)0x3e, (byte)0x0c, (byte)0xa1 },
   580                 45);
   581     }
   582     
   583     @Test public void longUShiftR3() throws Exception {
   584         final long res = 0xf0fa37d7763e0ca1l >>> 5;
   585         assertExec("Long >>> 5",
   586             Numbers.class, "ushrL__J_3BI", 
   587             Double.valueOf(res),
   588                 new byte[] { (byte)0xf0, (byte)0xfa, (byte)0x37, (byte)0xd7, (byte)0x76, (byte)0x3e, (byte)0x0c, (byte)0xa1 },
   589                 5);
   590     }
   591     
   592     @Test public void longUShiftR4() throws Exception {
   593         final long res = 0xf0fa37d7763e0ca1l >>> 45;
   594         assertExec("Long >>> 45",
   595             Numbers.class, "ushrL__J_3BI", 
   596             Double.valueOf(res),
   597                 new byte[] { (byte)0xf0, (byte)0xfa, (byte)0x37, (byte)0xd7, (byte)0x76, (byte)0x3e, (byte)0x0c, (byte)0xa1 },
   598                 45);
   599     }
   600     
   601     @Test public void longAnd() throws Exception {
   602         final long res = 0x00fa37d7763e0ca1l & 0xa7b3432fff00123el;
   603         assertExec("LOng binary AND",
   604             Numbers.class, "andL__J_3B_3B", 
   605             Double.valueOf(res),
   606             new byte[] { (byte)0x00, (byte)0xfa, (byte)0x37, (byte)0xd7, (byte)0x76, (byte)0x3e, (byte)0x0c, (byte)0xa1 },
   607             new byte[] { (byte)0xa7, (byte)0xb3, (byte)0x43, (byte)0x2f, (byte)0xff, (byte)0x00, (byte)0x12, (byte)0x3e }
   608         );
   609     }
   610     
   611     @Test public void longOr() throws Exception {
   612         final long res = 0x00fa37d7763e0ca1l | 0xa7b3432fff00123el;
   613         assertExec("Long binary OR",
   614             Numbers.class, "orL__J_3B_3B", 
   615             Double.valueOf(res),
   616             new byte[] { (byte)0x00, (byte)0xfa, (byte)0x37, (byte)0xd7, (byte)0x76, (byte)0x3e, (byte)0x0c, (byte)0xa1 },
   617             new byte[] { (byte)0xa7, (byte)0xb3, (byte)0x43, (byte)0x2f, (byte)0xff, (byte)0x00, (byte)0x12, (byte)0x3e }
   618         );
   619     }
   620     
   621     @Test public void longXor1() throws Exception {
   622         final long res = 0x00fa37d7763e0ca1l ^ 0xa7b3432fff00123el;
   623         assertExec("Long binary XOR",
   624             Numbers.class, "xorL__J_3B_3B", 
   625             Double.valueOf(res),
   626             new byte[] { (byte)0x00, (byte)0xfa, (byte)0x37, (byte)0xd7, (byte)0x76, (byte)0x3e, (byte)0x0c, (byte)0xa1 },
   627             new byte[] { (byte)0xa7, (byte)0xb3, (byte)0x43, (byte)0x2f, (byte)0xff, (byte)0x00, (byte)0x12, (byte)0x3e }
   628         );
   629     }
   630     
   631     @Test public void longXor2() throws Exception {
   632         final long res = 0x00fa37d7763e0ca1l ^ 0x00000000ff00123el;
   633         assertExec("Long binary XOR",
   634             Numbers.class, "xorL__J_3B_3B", 
   635             Double.valueOf(res),
   636             new byte[] { (byte)0x00, (byte)0xfa, (byte)0x37, (byte)0xd7, (byte)0x76, (byte)0x3e, (byte)0x0c, (byte)0xa1 },
   637             new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0xff, (byte)0x00, (byte)0x12, (byte)0x3e }
   638         );
   639     }
   640     
   641     @Test public void longXor3() throws Exception {
   642         final long res = 0x00000000763e0ca1l ^ 0x00000000ff00123el;
   643         assertExec("Long binary XOR",
   644             Numbers.class, "xorL__J_3B_3B", 
   645             Double.valueOf(res),
   646             new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x76, (byte)0x3e, (byte)0x0c, (byte)0xa1 },
   647             new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0xff, (byte)0x00, (byte)0x12, (byte)0x3e }
   648         );
   649     }
   650 
   651     @Test public void longCompareSameNumbers() throws Exception {
   652         assertExec("Long compare same numbers",
   653             Numbers.class, "compareL__I_3B_3BI",
   654             0.0,
   655             new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 },
   656             new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 },
   657             0
   658         );
   659     }
   660 
   661     @Test public void longComparePositiveNumbers() throws Exception {
   662         assertExec("Long compare positive numbers",
   663             Numbers.class, "compareL__I_3B_3BI",
   664             -1.0,
   665             new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x20, (byte)0x00, (byte)0x00 },
   666             new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x10, (byte)0x00, (byte)0x00, (byte)0x00 },
   667             0
   668         );
   669     }
   670 
   671     @Test public void longCompareNegativeNumbers() throws Exception {
   672         assertExec("Long compare negative numbers",
   673             Numbers.class, "compareL__I_3B_3BI",
   674             1.0,
   675             new byte[] { (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff },
   676             new byte[] { (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 },
   677             0
   678         );
   679     }
   680 
   681     @Test public void longCompareMixedNumbers() throws Exception {
   682         assertExec("Long compare mixed numbers",
   683             Numbers.class, "compareL__I_3B_3BI",
   684             -1.0,
   685             new byte[] { (byte)0x80, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 },
   686             new byte[] { (byte)0x7f, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff },
   687             0
   688         );
   689     }
   690 
   691     private static TestVM code;
   692 
   693     @BeforeClass
   694     public void compileTheCode() throws Exception {
   695         code = TestVM.compileClass("org/apidesign/vm4brwsr/Numbers");
   696     }
   697 
   698     private static void assertExec(
   699         String msg, Class<?> clazz, String method, Object expRes, Object... args) throws Exception
   700     {
   701         Object ret = code.execCode(msg, clazz, method, expRes, args);
   702         if (ret == null) {
   703             return;
   704         }
   705         if (expRes instanceof Double && ret instanceof Double) {
   706             double expD = ((Double)expRes).doubleValue();
   707             double retD = ((Double)ret).doubleValue();
   708             assertEquals(retD, expD, 0.000004, msg + " "
   709                     + code.toString());
   710             return;
   711         }
   712         assertEquals(ret, expRes, msg + " " + code.toString());
   713     }
   714     
   715 }