Can invoke method with int params and return type classloader
authorJaroslav Tulach <jaroslav.tulach@apidesign.org>
Tue, 11 Jun 2013 09:13:33 +0200
branchclassloader
changeset 1172c04c43d5fdc6
parent 1171 9753524d698f
child 1174 f78cdceed17b
Can invoke method with int params and return type
launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/fximpl/JsClassLoader.java
launcher/fx/src/test/java/org/apidesign/bck2brwsr/launcher/fximpl/JsClassLoaderTest.java
launcher/fx/src/test/java/org/apidesign/bck2brwsr/launcher/fximpl/JsMethods.java
     1.1 --- a/launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/fximpl/JsClassLoader.java	Mon Jun 10 18:19:40 2013 +0200
     1.2 +++ b/launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/fximpl/JsClassLoader.java	Tue Jun 11 09:13:33 2013 +0200
     1.3 @@ -31,6 +31,8 @@
     1.4  import org.objectweb.asm.MethodVisitor;
     1.5  import org.objectweb.asm.Opcodes;
     1.6  import org.objectweb.asm.Type;
     1.7 +import org.objectweb.asm.signature.SignatureReader;
     1.8 +import org.objectweb.asm.signature.SignatureVisitor;
     1.9  
    1.10  /** 
    1.11   *
    1.12 @@ -91,19 +93,21 @@
    1.13  
    1.14          @Override
    1.15          public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
    1.16 -            return new FindInMethod(name,
    1.17 +            return new FindInMethod(name, desc,
    1.18                  super.visitMethod(access, name, desc, signature, exceptions)
    1.19              );
    1.20          }
    1.21          
    1.22          private final class FindInMethod extends MethodVisitor {
    1.23              private final String name;
    1.24 +            private final String desc;
    1.25              private List<String> args;
    1.26              private String body;
    1.27              
    1.28 -            public FindInMethod(String name, MethodVisitor mv) {
    1.29 +            public FindInMethod(String name, String desc, MethodVisitor mv) {
    1.30                  super(Opcodes.ASM4, mv);
    1.31                  this.name = name;
    1.32 +                this.desc = desc;
    1.33              }
    1.34  
    1.35              @Override
    1.36 @@ -156,10 +160,89 @@
    1.37                  super.visitLabel(ifNotNull);
    1.38                  super.visitIntInsn(Opcodes.SIPUSH, args.size());
    1.39                  super.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/Object");
    1.40 +                
    1.41 +                class SV extends SignatureVisitor {
    1.42 +                    private boolean nowReturn;
    1.43 +                    private Type returnType;
    1.44 +                    private int index;
    1.45 +                    
    1.46 +                    public SV() {
    1.47 +                        super(Opcodes.ASM4);
    1.48 +                    }
    1.49 +                    
    1.50 +                    @Override
    1.51 +                    public void visitBaseType(char descriptor) {
    1.52 +                        final Type t = Type.getType("" + descriptor);
    1.53 +                        if (nowReturn) {
    1.54 +                            returnType = t;
    1.55 +                            return;
    1.56 +                        }
    1.57 +                        FindInMethod.super.visitInsn(Opcodes.DUP);
    1.58 +                        FindInMethod.super.visitIntInsn(Opcodes.SIPUSH, index);
    1.59 +                        FindInMethod.super.visitVarInsn(t.getOpcode(Opcodes.ILOAD), index);
    1.60 +                        String factory;
    1.61 +                        switch (descriptor) {
    1.62 +                        case 'I': factory = "java/lang/Integer"; break;
    1.63 +                        case 'J': factory = "java/lang/Long"; break;
    1.64 +                        case 'S': factory = "java/lang/Short"; break;
    1.65 +                        case 'F': factory = "java/lang/Float"; break;
    1.66 +                        case 'D': factory = "java/lang/Double"; break;
    1.67 +                        case 'Z': factory = "java/lang/Boolean"; break;
    1.68 +                        case 'C': factory = "java/lang/Character"; break;
    1.69 +                        case 'B': factory = "java/lang/Byte"; break;
    1.70 +                        default: throw new IllegalStateException(t.toString());
    1.71 +                        }
    1.72 +                        FindInMethod.super.visitMethodInsn(Opcodes.INVOKESTATIC,
    1.73 +                            factory, "valueOf", "(" + descriptor + ")L" + factory + ";"
    1.74 +                        );
    1.75 +                        FindInMethod.super.visitInsn(Opcodes.AASTORE);
    1.76 +                        index++;
    1.77 +                    }
    1.78 +
    1.79 +                    @Override
    1.80 +                    public void visitClassType(String name) {
    1.81 +                        if (nowReturn) {
    1.82 +                            returnType = Type.getObjectType(name);
    1.83 +                            return;
    1.84 +                        }
    1.85 +                        FindInMethod.super.visitInsn(Opcodes.DUP);
    1.86 +                        FindInMethod.super.visitIntInsn(Opcodes.SIPUSH, index);
    1.87 +                        FindInMethod.super.visitVarInsn(Opcodes.ALOAD, index);
    1.88 +                        FindInMethod.super.visitInsn(Opcodes.AASTORE);
    1.89 +                        index++;
    1.90 +                    }
    1.91 +
    1.92 +                    @Override
    1.93 +                    public SignatureVisitor visitReturnType() {
    1.94 +                        nowReturn = true;
    1.95 +                        return this;
    1.96 +                    }
    1.97 +                    
    1.98 +                    
    1.99 +                }
   1.100 +                SV sv = new SV();
   1.101 +                SignatureReader sr = new SignatureReader(desc);
   1.102 +                sr.accept(sv);
   1.103 +                
   1.104                  super.visitMethodInsn(Opcodes.INVOKEVIRTUAL, 
   1.105                      "org/apidesign/bck2brwsr/launcher/fximpl/Fn", "invoke", "([Ljava/lang/Object;)Ljava/lang/Object;"
   1.106                  );
   1.107 -                super.visitInsn(Opcodes.ARETURN);
   1.108 +                switch (sv.returnType.getSort()) {
   1.109 +                case Type.VOID: 
   1.110 +                    super.visitInsn(Opcodes.RETURN);
   1.111 +                    return;
   1.112 +                case Type.ARRAY:
   1.113 +                case Type.OBJECT:
   1.114 +                    super.visitTypeInsn(Opcodes.CHECKCAST, sv.returnType.getInternalName());
   1.115 +                    super.visitInsn(Opcodes.ARETURN);
   1.116 +                    return;
   1.117 +                default:
   1.118 +                    super.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/Number");
   1.119 +                    super.visitMethodInsn(Opcodes.INVOKEVIRTUAL, 
   1.120 +                        "java/lang/Number", sv.returnType.getClassName() + "Value", "()" + sv.returnType.getDescriptor()
   1.121 +                    );
   1.122 +                    super.visitInsn(sv.returnType.getOpcode(Opcodes.IRETURN));
   1.123 +                }
   1.124              }
   1.125  
   1.126              @Override
     2.1 --- a/launcher/fx/src/test/java/org/apidesign/bck2brwsr/launcher/fximpl/JsClassLoaderTest.java	Mon Jun 10 18:19:40 2013 +0200
     2.2 +++ b/launcher/fx/src/test/java/org/apidesign/bck2brwsr/launcher/fximpl/JsClassLoaderTest.java	Tue Jun 11 09:13:33 2013 +0200
     2.3 @@ -24,6 +24,7 @@
     2.4  import javax.script.ScriptEngine;
     2.5  import javax.script.ScriptEngineManager;
     2.6  import javax.script.ScriptException;
     2.7 +import org.objectweb.asm.signature.SignatureReader;
     2.8  import static org.testng.Assert.*;
     2.9  import org.testng.annotations.BeforeClass;
    2.10  import org.testng.annotations.Test;
    2.11 @@ -92,7 +93,7 @@
    2.12              throw ex.getTargetException();
    2.13          }
    2.14      }
    2.15 -    /*
    2.16 +    
    2.17      @Test public void testExecuteScript() throws Throwable {
    2.18          Method plus = methodClass.getMethod("plus", int.class, int.class);
    2.19          try {
    2.20 @@ -101,6 +102,4 @@
    2.21              throw ex.getTargetException();
    2.22          }
    2.23      }
    2.24 -    */
    2.25 -
    2.26  }
    2.27 \ No newline at end of file
     3.1 --- a/launcher/fx/src/test/java/org/apidesign/bck2brwsr/launcher/fximpl/JsMethods.java	Mon Jun 10 18:19:40 2013 +0200
     3.2 +++ b/launcher/fx/src/test/java/org/apidesign/bck2brwsr/launcher/fximpl/JsMethods.java	Tue Jun 11 09:13:33 2013 +0200
     3.3 @@ -29,10 +29,8 @@
     3.4          return -42;
     3.5      }
     3.6      
     3.7 -/*
     3.8      @JavaScriptBody(args = {"x", "y" }, body = "return x + y;")
     3.9      public static int plus(int x, int y) {
    3.10          return 0;
    3.11      }
    3.12 - */   
    3.13  }