Can call method with two integer arguments from JavaScript classloader
authorJaroslav Tulach <jaroslav.tulach@apidesign.org>
Tue, 25 Jun 2013 21:09:48 +0200
branchclassloader
changeset 161ea5ca9cc685d
parent 160 b5a06e2b3b92
child 162 50b9aff26ad9
Can call method with two integer arguments from JavaScript
boot/src/main/java/org/apidesign/html/boot/impl/FnUtils.java
boot/src/main/java/org/apidesign/html/boot/impl/JsClassLoader.java
boot/src/test/java/org/apidesign/html/boot/impl/FnTest.java
boot/src/test/java/org/apidesign/html/boot/impl/JsClassLoaderBase.java
boot/src/test/java/org/apidesign/html/boot/impl/JsClassLoaderTest.java
boot/src/test/java/org/apidesign/html/boot/impl/JsMethods.java
     1.1 --- a/boot/src/main/java/org/apidesign/html/boot/impl/FnUtils.java	Tue Jun 25 15:34:37 2013 +0200
     1.2 +++ b/boot/src/main/java/org/apidesign/html/boot/impl/FnUtils.java	Tue Jun 25 21:09:48 2013 +0200
     1.3 @@ -26,17 +26,14 @@
     1.4  import java.util.Collections;
     1.5  import java.util.Enumeration;
     1.6  import java.util.List;
     1.7 -import java.util.logging.Level;
     1.8 -import java.util.logging.Logger;
     1.9 -import java.util.regex.Pattern;
    1.10  import org.apidesign.html.boot.spi.Fn;
    1.11 +import org.objectweb.asm.Type;
    1.12  
    1.13  /**
    1.14   *
    1.15   * @author Jaroslav Tulach <jtulach@netbeans.org>
    1.16   */
    1.17  public final class FnUtils {
    1.18 -
    1.19      private FnUtils() {
    1.20      }
    1.21  
    1.22 @@ -104,10 +101,15 @@
    1.23              
    1.24              String fqn = body.substring(next + 2, colon4);
    1.25              String method = body.substring(colon4 + 2, sigBeg);
    1.26 -            String params = body.substring(sigBeg + 1, sigEnd);
    1.27 +            String params = body.substring(sigBeg, sigEnd + 1);
    1.28              
    1.29              Class<?> clazz = Class.forName(fqn, false, loader);
    1.30 -            Method m = clazz.getMethod(method);
    1.31 +            final Type[] argTps = Type.getArgumentTypes(params);
    1.32 +            Class<?>[] argCls = new Class<?>[argTps.length];
    1.33 +            for (int i = 0; i < argCls.length; i++) {
    1.34 +                argCls[i] = toClass(argTps[i], loader);
    1.35 +            }
    1.36 +            Method m = clazz.getMethod(method, argCls);
    1.37              
    1.38              sb.append("['").append(m.getName()).append("(");
    1.39              String sep = "";
    1.40 @@ -121,5 +123,27 @@
    1.41          }
    1.42      }
    1.43  
    1.44 +    private static Class<?> toClass(final Type t, ClassLoader loader) throws ClassNotFoundException {
    1.45 +        if (t == Type.INT_TYPE) {
    1.46 +            return Integer.TYPE;
    1.47 +        } else if (t == Type.VOID_TYPE) {
    1.48 +            return Void.TYPE;
    1.49 +        } else if (t == Type.BOOLEAN_TYPE) {
    1.50 +            return Boolean.TYPE;
    1.51 +        } else if (t == Type.BYTE_TYPE) {
    1.52 +            return Byte.TYPE;
    1.53 +        } else if (t == Type.CHAR_TYPE) {
    1.54 +            return Character.TYPE;
    1.55 +        } else if (t == Type.SHORT_TYPE) {
    1.56 +            return Short.TYPE;
    1.57 +        } else if (t == Type.DOUBLE_TYPE) {
    1.58 +            return Double.TYPE;
    1.59 +        } else if (t == Type.FLOAT_TYPE) {
    1.60 +            return Float.TYPE;
    1.61 +        } else if (t == Type.LONG_TYPE) {
    1.62 +            return Long.TYPE;
    1.63 +        }
    1.64 +        return Class.forName(t.getClassName(), false, loader);
    1.65 +    }
    1.66      
    1.67  }
     2.1 --- a/boot/src/main/java/org/apidesign/html/boot/impl/JsClassLoader.java	Tue Jun 25 15:34:37 2013 +0200
     2.2 +++ b/boot/src/main/java/org/apidesign/html/boot/impl/JsClassLoader.java	Tue Jun 25 21:09:48 2013 +0200
     2.3 @@ -39,6 +39,7 @@
     2.4  import org.objectweb.asm.Type;
     2.5  import org.objectweb.asm.signature.SignatureReader;
     2.6  import org.objectweb.asm.signature.SignatureVisitor;
     2.7 +import org.objectweb.asm.signature.SignatureWriter;
     2.8  
     2.9  /** 
    2.10   *
    2.11 @@ -277,16 +278,21 @@
    2.12                      }
    2.13  
    2.14                      @Override
    2.15 +                    public SignatureVisitor visitArrayType() {
    2.16 +                        if (nowReturn) {
    2.17 +                            throw new IllegalStateException("Not supported yet");
    2.18 +                        }
    2.19 +                        loadObject();
    2.20 +                        return new SignatureWriter();
    2.21 +                    }
    2.22 +
    2.23 +                    @Override
    2.24                      public void visitClassType(String name) {
    2.25                          if (nowReturn) {
    2.26                              returnType = Type.getObjectType(name);
    2.27                              return;
    2.28                          }
    2.29 -                        FindInMethod.super.visitInsn(Opcodes.DUP);
    2.30 -                        FindInMethod.super.visitIntInsn(Opcodes.SIPUSH, index);
    2.31 -                        FindInMethod.super.visitVarInsn(Opcodes.ALOAD, index + offset);
    2.32 -                        FindInMethod.super.visitInsn(Opcodes.AASTORE);
    2.33 -                        index++;
    2.34 +                        loadObject();
    2.35                      }
    2.36  
    2.37                      @Override
    2.38 @@ -294,7 +300,14 @@
    2.39                          nowReturn = true;
    2.40                          return this;
    2.41                      }
    2.42 -                    
    2.43 +
    2.44 +                    private void loadObject() {
    2.45 +                        FindInMethod.super.visitInsn(Opcodes.DUP);
    2.46 +                        FindInMethod.super.visitIntInsn(Opcodes.SIPUSH, index);
    2.47 +                        FindInMethod.super.visitVarInsn(Opcodes.ALOAD, index + offset);
    2.48 +                        FindInMethod.super.visitInsn(Opcodes.AASTORE);
    2.49 +                        index++;
    2.50 +                    }
    2.51                      
    2.52                  }
    2.53                  SV sv = new SV();
     3.1 --- a/boot/src/test/java/org/apidesign/html/boot/impl/FnTest.java	Tue Jun 25 15:34:37 2013 +0200
     3.2 +++ b/boot/src/test/java/org/apidesign/html/boot/impl/FnTest.java	Tue Jun 25 21:09:48 2013 +0200
     3.3 @@ -85,8 +85,12 @@
     3.4                              all.add(thiz == null ? val : thiz);
     3.5                              all.addAll(Arrays.asList(args));
     3.6                              Invocable inv = (Invocable)eng;
     3.7 -                            Object ret = inv.invokeMethod(val, "call", all.toArray());
     3.8 -                            return ret == val ? null : ret;
     3.9 +                            try {
    3.10 +                                Object ret = inv.invokeMethod(val, "call", all.toArray());
    3.11 +                                return ret == val ? null : ret;
    3.12 +                            } catch (ScriptException ex) {
    3.13 +                                throw ex;
    3.14 +                            }
    3.15                          }
    3.16                      };
    3.17                  } catch (ScriptException ex) {
     4.1 --- a/boot/src/test/java/org/apidesign/html/boot/impl/JsClassLoaderBase.java	Tue Jun 25 15:34:37 2013 +0200
     4.2 +++ b/boot/src/test/java/org/apidesign/html/boot/impl/JsClassLoaderBase.java	Tue Jun 25 21:09:48 2013 +0200
     4.3 @@ -123,4 +123,8 @@
     4.4          assertEquals(r.cnt, 1, "Callback happened");
     4.5      }
     4.6      
     4.7 +    @Test public void sumArray() throws Throwable {
     4.8 +        Method st = methodClass.getMethod("sumArr", int[].class);
     4.9 +        assertEquals(st.invoke(null, new int[] { 1, 2, 3 }), 6, "1+2+3 is six");
    4.10 +    }
    4.11  }
    4.12 \ No newline at end of file
     5.1 --- a/boot/src/test/java/org/apidesign/html/boot/impl/JsClassLoaderTest.java	Tue Jun 25 15:34:37 2013 +0200
     5.2 +++ b/boot/src/test/java/org/apidesign/html/boot/impl/JsClassLoaderTest.java	Tue Jun 25 21:09:48 2013 +0200
     5.3 @@ -77,8 +77,12 @@
     5.4                              all.add(thiz == null ? val : thiz);
     5.5                              all.addAll(Arrays.asList(args));
     5.6                              Invocable inv = (Invocable)eng;
     5.7 -                            Object ret = inv.invokeMethod(val, "call", all.toArray());
     5.8 -                            return ret == val ? null : ret;
     5.9 +                            try {
    5.10 +                                Object ret = inv.invokeMethod(val, "call", all.toArray());
    5.11 +                                return ret == val ? null : ret;
    5.12 +                            } catch (Exception ex) {
    5.13 +                                throw ex;
    5.14 +                            }
    5.15                          }
    5.16                      };
    5.17                  } catch (ScriptException ex) {
     6.1 --- a/boot/src/test/java/org/apidesign/html/boot/impl/JsMethods.java	Tue Jun 25 15:34:37 2013 +0200
     6.2 +++ b/boot/src/test/java/org/apidesign/html/boot/impl/JsMethods.java	Tue Jun 25 21:09:48 2013 +0200
     6.3 @@ -54,4 +54,17 @@
     6.4      
     6.5      @JavaScriptBody(args = { "r" }, javacall=true, body = "r.@java.lang.Runnable::run()()")
     6.6      public static native void callback(Runnable r);
     6.7 +    
     6.8 +    @JavaScriptBody(args = { "at", "arr" }, javacall = true, body =
     6.9 +          "var a = 0;\n"
    6.10 +        + "for (var i = 0; i < arr.length; i++) {\n"
    6.11 +        + "  a = at.@org.apidesign.html.boot.impl.Arithm::sumTwo(II)(a, arr[i]);\n"
    6.12 +        + "}\n"
    6.13 +        + "return a;"
    6.14 +    )
    6.15 +    private static native int sumArr(Arithm at, int... arr);
    6.16 +    
    6.17 +    public static int sumArr(int... arr) {
    6.18 +        return sumArr(new Arithm(), arr);
    6.19 +    }
    6.20  }