1 /*******************************************************************************
\r
2 * Copyright (c) 2010 Association for Decentralized Information Management in
\r
4 * All rights reserved. This program and the accompanying materials
\r
5 * are made available under the terms of the Eclipse Public License v1.0
\r
6 * which accompanies this distribution, and is available at
\r
7 * http://www.eclipse.org/legal/epl-v10.html
\r
10 * VTT Technical Research Centre of Finland - initial API and implementation
\r
11 *******************************************************************************/
\r
12 package org.simantics.databoard.tests;
14 import static org.objectweb.asm.Opcodes.AALOAD;
\r
15 import static org.objectweb.asm.Opcodes.AASTORE;
\r
16 import static org.objectweb.asm.Opcodes.ACC_ABSTRACT;
\r
17 import static org.objectweb.asm.Opcodes.ACC_FINAL;
\r
18 import static org.objectweb.asm.Opcodes.ACC_INTERFACE;
\r
19 import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
\r
20 import static org.objectweb.asm.Opcodes.ACC_STATIC;
\r
21 import static org.objectweb.asm.Opcodes.ACC_SUPER;
\r
22 import static org.objectweb.asm.Opcodes.ALOAD;
\r
23 import static org.objectweb.asm.Opcodes.ANEWARRAY;
\r
24 import static org.objectweb.asm.Opcodes.ARETURN;
\r
25 import static org.objectweb.asm.Opcodes.ARRAYLENGTH;
\r
26 import static org.objectweb.asm.Opcodes.ASTORE;
\r
27 import static org.objectweb.asm.Opcodes.ATHROW;
\r
28 import static org.objectweb.asm.Opcodes.CHECKCAST;
\r
29 import static org.objectweb.asm.Opcodes.DLOAD;
\r
30 import static org.objectweb.asm.Opcodes.DRETURN;
\r
31 import static org.objectweb.asm.Opcodes.DUP;
\r
32 import static org.objectweb.asm.Opcodes.FLOAD;
\r
33 import static org.objectweb.asm.Opcodes.FRETURN;
\r
34 import static org.objectweb.asm.Opcodes.GETFIELD;
\r
35 import static org.objectweb.asm.Opcodes.GETSTATIC;
\r
36 import static org.objectweb.asm.Opcodes.GOTO;
\r
37 import static org.objectweb.asm.Opcodes.ICONST_0;
\r
38 import static org.objectweb.asm.Opcodes.IFEQ;
\r
39 import static org.objectweb.asm.Opcodes.IF_ICMPLT;
\r
40 import static org.objectweb.asm.Opcodes.ILOAD;
\r
41 import static org.objectweb.asm.Opcodes.INSTANCEOF;
\r
42 import static org.objectweb.asm.Opcodes.INVOKEINTERFACE;
\r
43 import static org.objectweb.asm.Opcodes.INVOKESPECIAL;
\r
44 import static org.objectweb.asm.Opcodes.INVOKESTATIC;
\r
45 import static org.objectweb.asm.Opcodes.INVOKEVIRTUAL;
\r
46 import static org.objectweb.asm.Opcodes.IRETURN;
\r
47 import static org.objectweb.asm.Opcodes.ISTORE;
\r
48 import static org.objectweb.asm.Opcodes.LLOAD;
\r
49 import static org.objectweb.asm.Opcodes.LRETURN;
\r
50 import static org.objectweb.asm.Opcodes.NEW;
\r
51 import static org.objectweb.asm.Opcodes.POP;
\r
52 import static org.objectweb.asm.Opcodes.PUTFIELD;
\r
53 import static org.objectweb.asm.Opcodes.PUTSTATIC;
\r
54 import static org.objectweb.asm.Opcodes.RETURN;
\r
55 import static org.objectweb.asm.Opcodes.V1_6;
\r
57 import java.lang.reflect.Constructor;
\r
58 import java.util.Arrays;
\r
59 import java.util.HashSet;
\r
60 import java.util.Set;
\r
62 import org.objectweb.asm.AnnotationVisitor;
\r
63 import org.objectweb.asm.ClassWriter;
\r
64 import org.objectweb.asm.FieldVisitor;
\r
65 import org.objectweb.asm.Label;
\r
66 import org.objectweb.asm.MethodVisitor;
\r
67 import org.objectweb.asm.Opcodes;
\r
68 import org.objectweb.asm.Type;
\r
69 import org.simantics.databoard.Methods;
\r
70 import org.simantics.databoard.binding.error.BindingConstructionException;
\r
71 import org.simantics.databoard.method.InvokeException;
\r
72 import org.simantics.databoard.method.MethodInterface;
\r
73 import org.simantics.databoard.method.MethodInterface.AsyncResult;
\r
74 import org.simantics.databoard.method.MethodInterface.ExecutionError;
\r
75 import org.simantics.databoard.method.MethodInterface.Method;
\r
76 import org.simantics.databoard.method.MethodInterfaceUtil;
\r
77 import org.simantics.databoard.method.MethodNotSupportedException;
\r
78 import org.simantics.databoard.method.MethodTypeBinding;
\r
79 import org.simantics.databoard.method.RuntimeInvokeException;
\r
81 public class testASM {
83 public interface Abu {
85 Integer x(Integer i) throws testASM.MyException, testASM.RandomException, InvokeException;
87 String hello(int[] args) throws testASM.MyException, InvokeException;
91 public interface Rajapinta {
96 int m3(int arg0, int arg1);
97 Integer m10(int color, String name) throws InvokeException, ExecutionError;
98 int m11(int color, String name) throws InvokeException, ExecutionError;
101 static class Toteutus implements Rajapinta {
104 public Integer m10(int color, String name)
105 throws InvokeException, ExecutionError
107 AsyncResult result = _10.invoke(new Object[] {color, name});
109 return (Integer) result.waitForResponse();
110 } catch (InterruptedException e) {
111 throw new RuntimeException(e);
115 public int m11(int color, String name)
116 throws InvokeException, ExecutionError
118 AsyncResult result = _11.invoke(new Object[] {color, name});
120 return (Integer) result.waitForResponse();
121 } catch (InterruptedException e) {
122 throw new RuntimeException(e);
128 // TODO Auto-generated method stub
134 // TODO Auto-generated method stub
139 public int m2(int arg0) {
140 // TODO Auto-generated method stub
145 public int m3(int arg0, int arg1) {
146 // TODO Auto-generated method stub
154 public static byte[] dump () throws Exception {
155 ClassWriter cw = new ClassWriter(0);
158 AnnotationVisitor av0;
160 cw.visit(V1_6, ACC_SUPER, "org/simantics/data/Virhe", null, "java/lang/Object", null);
162 cw.visitSource("testASM.java", null);
165 mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
167 Label l0 = new Label();
169 mv.visitLineNumber(157, l0);
170 mv.visitVarInsn(ALOAD, 0);
171 mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
172 mv.visitInsn(RETURN);
173 Label l1 = new Label();
175 mv.visitLocalVariable("this", "Lorg/simantics/data/Virhe;", null, l0, l1, 0);
181 return cw.toByteArray();
184 public static class MyException extends Exception {
186 public MyException(String msg) {
190 public static class RandomException extends Exception {
192 public RandomException(String msg) {
197 public static void main(String[] args) throws Exception {
198 System.out.println(Object[][].class.getName());
200 System.out.println(Abu.class.getName());
201 System.out.println(void.class.getName());
202 System.out.println(int.class.getName());
205 Toteutus t = new Toteutus();
207 Virhe3 server = new Virhe3();
208 MethodInterface serverMi = MethodInterfaceUtil.bindInterface(Abu.class, server);
210 StubClassLoader cl = new StubClassLoader();
211 Class<?> virhe = cl.loadClass("org.simantics.data.testASM$Abu_Stub");
212 // Class<?> virhe = cl.loadClass("org.simantics.data.Virhe2");
214 Constructor<?> c = virhe.getConstructor(MethodInterface.class);
215 Abu client = (Abu) c.newInstance(serverMi);
216 // client = new Virhe2(serverMi);
218 System.out.println(client);
219 System.out.println(client.hello(new int[] {0,5,0}));
220 System.out.println(client.y());
221 System.out.println(client.x(5));
222 } catch (testASM.MyException e) {
223 System.err.printf("MyException = %s", e.msg);
231 class Virhe3 implements testASM.Abu {
233 public Integer x(Integer i) throws testASM.MyException, testASM.RandomException, InvokeException {
234 // throw new testASM.MyException("XYZ");
235 throw new testASM.RandomException("XYZ");
243 public String hello(int[] args) throws testASM.MyException, InvokeException {
244 return "World "+ Arrays.toString(args);
249 class Virhe2 implements testASM.Abu {
250 // static final MethodBinding x = new MethodBinding("x", DataTypes.getBinding(int.class), DataTypes.getBinding(void.class), DataTypes.getErrorBinding());
251 static final Class<?> interfaze = testASM.Abu.class;
252 static final MethodTypeBinding[] bindings;
255 java.lang.reflect.Method[] methods = interfaze.getMethods();
256 Arrays.sort(methods, MethodInterfaceUtil.methodComparator);
258 bindings = new MethodTypeBinding[methods.length];
259 for (int i=0; i<bindings.length; i++) {
261 bindings[i] = Methods.getMethodTypeBinding(methods[i]);
262 } catch (BindingConstructionException e) {
263 throw new RuntimeException(e);
270 public Virhe2(MethodInterface mi)
271 throws MethodNotSupportedException
274 methods = new Method[bindings.length];
275 for (int i=0; i<bindings.length; i++) {
276 methods[i] = mi.getMethod(bindings[i]);
280 public Integer x(Integer arg1) throws InvokeException, testASM.MyException {
281 Method m = methods[1];
283 Object args[] = new Object[] {arg1};
285 AsyncResult result = m.invoke(args);
287 return (Integer) result.waitForResponse();
288 } catch (ExecutionError e) {
289 Object cause = e.getError();
290 if (cause instanceof testASM.MyException)
291 throw (testASM.MyException) cause;
292 throw new RuntimeException(e);
293 } catch (InterruptedException e) {
294 throw new RuntimeException(e);
298 Method m = methods[2];
300 Object args[] = new Object[] {};
302 AsyncResult result = m.invoke(args);
304 return (Double) result.waitForResponse();
305 } catch (InvokeException e) {
306 throw new RuntimeInvokeException(e);
307 } catch (ExecutionError e) {
308 Object cause = e.getError();
309 throw new RuntimeException(e);
310 } catch (InterruptedException e) {
311 throw new RuntimeException(e);
316 public String hello(int[] args) throws testASM.MyException, InvokeException {
321 class StubClassLoader extends ClassLoader {
323 public StubClassLoader() {
327 public StubClassLoader(ClassLoader parent) {
332 protected Class<?> findClass(String name) throws ClassNotFoundException {
333 if (name.endsWith("_Stub")) {
334 Class<?> interfaze = loadClass(name.substring(0, name.length()-5));
335 ClassWriter cw = new ClassWriter(0);
336 createImpl(name, interfaze, cw);
337 byte[] b = cw.toByteArray();
338 Class<?> clazz = defineClass(name, b, 0, b.length);
341 return super.findClass(name);
344 static String classToTypeDescriptor(Class<?> clazz) {
345 if (clazz==void.class) return "V";
346 if (clazz==boolean.class) return "Z";
347 if (clazz==char.class) return "C";
348 if (clazz==byte.class) return "B";
349 if (clazz==short.class) return "S";
350 if (clazz==int.class) return "I";
351 if (clazz==float.class) return "F";
352 if (clazz==long.class) return "J";
353 if (clazz==double.class) return "D";
354 if (clazz==void.class) return "V";
355 if (clazz.isArray()) return clazz.getName();
356 return "L"+clazz.getName().replaceAll("\\.", "/")+";";
359 void createImpl(String className, Class<?> interfaze, ClassWriter cw) {
362 AnnotationVisitor av0;
364 java.lang.reflect.Method[] methods = interfaze.getMethods();
365 Arrays.sort(methods, MethodInterfaceUtil.methodComparator);
367 String classResourceName = className.replaceAll("\\.", "/");
368 String classTypeDescriptor = "L"+classResourceName+";";
369 String interfaceResourceName = classResourceName.substring(0, classResourceName.length()-5);
370 String interfaceTypeDescriptor = "L"+interfaceResourceName+";";
372 cw.visit(V1_6, ACC_SUPER | ACC_PUBLIC, classResourceName, null, "java/lang/Object", new String[] { interfaceResourceName });
375 Set<Class<?>> imports = new HashSet<Class<?>>();
376 imports.add(AsyncResult.class);
377 imports.add(ExecutionError.class);
378 imports.add(Method.class);
379 imports.add(interfaze);
381 for (java.lang.reflect.Method m : methods) {
382 for (Class<?> clazz : m.getExceptionTypes()) {
385 for (Class<?> clazz : m.getParameterTypes()) {
388 imports.add(m.getReturnType());
391 for (Class<?> clazz : imports) {
392 if (clazz.isPrimitive()) continue;
393 String name = clazz.getName();
394 if (name.startsWith("java.lang")) continue;
395 String resourceName = name.replaceAll("\\.", "/");
396 String outerName = resourceName.contains("$") ? resourceName.substring(0, resourceName.indexOf('$')) : null;
397 String className_ = clazz.isArray() ? clazz.getSimpleName().substring(0, clazz.getSimpleName().length()-2) : clazz.getSimpleName();
398 int access = ACC_PUBLIC + ACC_STATIC + (clazz.isInterface() ? ACC_INTERFACE + ACC_ABSTRACT : 0);
399 // System.out.printf("name=%s, outerName=%s, innerName=%s\n", resourceName, outerName, className_);
400 cw.visitInnerClass(resourceName, outerName, className_, access);
405 fv = cw.visitField(ACC_FINAL + ACC_STATIC, "interfaze", "Ljava/lang/Class;", "Ljava/lang/Class<*>;", null);
409 fv = cw.visitField(ACC_FINAL + ACC_STATIC, "bindings", "[Lorg/simantics/databoard/method/MethodBinding;", null, null);
413 fv = cw.visitField(0, "mi", "Lorg/simantics/data/session/MethodInterface;", null, null);
417 fv = cw.visitField(0, "methods", "[Lorg/simantics/data/session/MethodInterface$Method;", null, null);
421 // Init class - static {}
423 mv = cw.visitMethod(ACC_STATIC, "<clinit>", "()V", null, null);
425 Label l0 = new Label();
427 mv.visitLdcInsn(Type.getType(interfaceTypeDescriptor));
428 mv.visitFieldInsn(PUTSTATIC, classResourceName, "interfaze", "Ljava/lang/Class;");
429 Label l1 = new Label();
431 mv.visitFieldInsn(GETSTATIC, classResourceName, "interfaze", "Ljava/lang/Class;");
432 mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "getMethods", "()[Ljava/lang/reflect/Method;");
433 mv.visitVarInsn(ASTORE, 0);
434 Label l2 = new Label();
436 mv.visitVarInsn(ALOAD, 0);
437 mv.visitFieldInsn(GETSTATIC, "org/simantics/data/network/MethodInterfaceUtil", "methodComparator", "Ljava/util/Comparator;");
438 mv.visitMethodInsn(INVOKESTATIC, "java/util/Arrays", "sort", "([Ljava/lang/Object;Ljava/util/Comparator;)V");
439 Label l3 = new Label();
441 mv.visitVarInsn(ALOAD, 0);
442 mv.visitInsn(ARRAYLENGTH);
443 mv.visitTypeInsn(ANEWARRAY, "org/simantics/databoard/method/MethodBinding");
444 mv.visitFieldInsn(PUTSTATIC, classResourceName, "bindings", "[Lorg/simantics/databoard/method/MethodBinding;");
445 Label l4 = new Label();
447 mv.visitInsn(ICONST_0);
448 mv.visitVarInsn(ISTORE, 1);
449 Label l5 = new Label();
451 Label l6 = new Label();
452 mv.visitJumpInsn(GOTO, l6);
453 Label l7 = new Label();
455 mv.visitFrame(Opcodes.F_APPEND,2, new Object[] {"[Ljava/lang/reflect/Method;", Opcodes.INTEGER}, 0, null);
456 mv.visitFieldInsn(GETSTATIC, classResourceName, "bindings", "[Lorg/simantics/databoard/method/MethodBinding;");
457 mv.visitVarInsn(ILOAD, 1);
458 mv.visitVarInsn(ALOAD, 0);
459 mv.visitVarInsn(ILOAD, 1);
460 mv.visitInsn(AALOAD);
461 mv.visitMethodInsn(INVOKESTATIC, "org/simantics/databoard/DataTypes", "getMethodBinding", "(Ljava/lang/reflect/Method;)Lorg/simantics/databoard/method/MethodBinding;");
462 mv.visitInsn(AASTORE);
463 Label l8 = new Label();
465 mv.visitIincInsn(1, 1);
467 mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
468 mv.visitVarInsn(ILOAD, 1);
469 mv.visitFieldInsn(GETSTATIC, classResourceName, "bindings", "[Lorg/simantics/databoard/method/MethodBinding;");
470 mv.visitInsn(ARRAYLENGTH);
471 mv.visitJumpInsn(IF_ICMPLT, l7);
472 Label l9 = new Label();
474 mv.visitInsn(RETURN);
475 Label l10 = new Label();
477 mv.visitLocalVariable("methods", "[Ljava/lang/reflect/Method;", null, l2, l10, 0);
478 mv.visitLocalVariable("i", "I", null, l5, l9, 1);
485 mv = cw.visitMethod(ACC_PUBLIC, "<init>", "(Lorg/simantics/data/session/MethodInterface;)V", null, new String[] { "org/simantics/data/error/MethodNotSupportedException" });
487 Label l0 = new Label();
489 mv.visitVarInsn(ALOAD, 0);
490 mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
491 Label l1 = new Label();
493 mv.visitVarInsn(ALOAD, 0);
494 mv.visitVarInsn(ALOAD, 1);
495 mv.visitFieldInsn(PUTFIELD, classResourceName, "mi", "Lorg/simantics/data/session/MethodInterface;");
496 Label l2 = new Label();
498 mv.visitVarInsn(ALOAD, 0);
499 mv.visitFieldInsn(GETSTATIC, classResourceName, "bindings", "[Lorg/simantics/databoard/method/MethodBinding;");
500 mv.visitInsn(ARRAYLENGTH);
501 mv.visitTypeInsn(ANEWARRAY, "org/simantics/data/session/MethodInterface$Method");
502 mv.visitFieldInsn(PUTFIELD, classResourceName, "methods", "[Lorg/simantics/data/session/MethodInterface$Method;");
503 Label l3 = new Label();
505 mv.visitInsn(ICONST_0);
506 mv.visitVarInsn(ISTORE, 2);
507 Label l4 = new Label();
509 Label l5 = new Label();
510 mv.visitJumpInsn(GOTO, l5);
511 Label l6 = new Label();
513 mv.visitFrame(Opcodes.F_FULL, 3, new Object[] {classResourceName, "org/simantics/data/session/MethodInterface", Opcodes.INTEGER}, 0, new Object[] {});
514 mv.visitVarInsn(ALOAD, 0);
515 mv.visitFieldInsn(GETFIELD, classResourceName, "methods", "[Lorg/simantics/data/session/MethodInterface$Method;");
516 mv.visitVarInsn(ILOAD, 2);
517 mv.visitVarInsn(ALOAD, 1);
518 mv.visitFieldInsn(GETSTATIC, classResourceName, "bindings", "[Lorg/simantics/databoard/method/MethodBinding;");
519 mv.visitVarInsn(ILOAD, 2);
520 mv.visitInsn(AALOAD);
521 mv.visitMethodInsn(INVOKEINTERFACE, "org/simantics/data/session/MethodInterface", "getMethod", "(Lorg/simantics/databoard/method/MethodBinding;)Lorg/simantics/data/session/MethodInterface$Method;");
522 mv.visitInsn(AASTORE);
523 Label l7 = new Label();
525 mv.visitIincInsn(2, 1);
527 mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
528 mv.visitVarInsn(ILOAD, 2);
529 mv.visitFieldInsn(GETSTATIC, classResourceName, "bindings", "[Lorg/simantics/databoard/method/MethodBinding;");
530 mv.visitInsn(ARRAYLENGTH);
531 mv.visitJumpInsn(IF_ICMPLT, l6);
532 Label l8 = new Label();
534 mv.visitInsn(RETURN);
535 Label l9 = new Label();
537 mv.visitLocalVariable("this", classTypeDescriptor, null, l0, l9, 0);
538 mv.visitLocalVariable("mi", "Lorg/simantics/data/session/MethodInterface;", null, l0, l9, 1);
539 mv.visitLocalVariable("i", "I", null, l4, l8, 2);
545 int methodNumber = 0;
546 for (java.lang.reflect.Method m : methods)
548 String typeDescription = "";
549 Class<?>[] params = m.getParameterTypes();
550 for (int i=0; i<params.length; i++) {
551 if (i>0) typeDescription += ";";
552 typeDescription += classToTypeDescriptor(params[i]);
554 typeDescription = "("+typeDescription+")"+classToTypeDescriptor(m.getReturnType());
555 System.out.println(typeDescription+" "+m.getName());
557 Class<?>[] exceptions = m.getExceptionTypes();
558 String[] exceptionResourceNames = new String[exceptions.length];
559 for (int i=0; i<exceptionResourceNames.length; i++) {
560 exceptionResourceNames[i] = exceptions[i].getName().replaceAll("\\.", "/");
566 // argRegs+1 - method
567 // argRegs+2 - args (the array)
568 // argRegs+3 - AsyncResult
570 // argRegs+5 - ExecutionError.cause
574 for (int i=0; i<params.length; i++) {
575 Class<?> clazz = params[i];
577 if (clazz==long.class || clazz==float.class || clazz==Double.class) argRegs++;
580 mv = cw.visitMethod(ACC_PUBLIC, m.getName(), typeDescription, null, exceptionResourceNames);
582 Label l0 = new Label();
583 Label l1 = new Label();
584 Label l2 = new Label();
585 mv.visitTryCatchBlock(l0, l1, l2, "org/simantics/data/session/MethodInterface$ExecutionError");
586 Label l3 = new Label();
587 mv.visitTryCatchBlock(l0, l1, l3, "java/lang/InterruptedException");
588 Label l4 = new Label();
590 mv.visitVarInsn(ALOAD, 0);
591 mv.visitFieldInsn(GETFIELD, classResourceName, "methods", "[Lorg/simantics/data/session/MethodInterface$Method;");
592 // Method m and puts into register
593 mv.visitLdcInsn(Integer.valueOf(methodNumber));
594 mv.visitInsn(AALOAD);
595 mv.visitVarInsn(ASTORE, argRegs+1);
596 Label l5 = new Label();
598 mv.visitLdcInsn(Integer.valueOf(params.length));
599 mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
601 int register = 1; // argument register
602 for (int i=0; i<params.length; i++) {
603 Class<?> clazz = params[i];
605 mv.visitLdcInsn(Integer.valueOf(i));
607 if (clazz==byte.class) {
608 mv.visitVarInsn(ILOAD, register++);
609 mv.visitMethodInsn(INVOKESTATIC, "java/lang/Byte", "valueOf", "(B)Ljava/lang/Byte;");
610 } else if (clazz==char.class) {
611 mv.visitVarInsn(ILOAD, register++);
612 mv.visitMethodInsn(INVOKESTATIC, "java/lang/Character", "valueOf", "(C)Ljava/lang/Character;");
613 } else if (clazz==boolean.class) {
614 mv.visitVarInsn(ILOAD, register++);
615 mv.visitMethodInsn(INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;");
616 } else if (clazz==byte.class) {
617 mv.visitVarInsn(ILOAD, register++);
618 mv.visitMethodInsn(INVOKESTATIC, "java/lang/Short", "valueOf", "(S)Ljava/lang/Short;");
619 } else if (clazz==int.class) {
620 mv.visitVarInsn(ILOAD, register++);
621 mv.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;");
622 } else if (clazz==long.class) {
623 mv.visitVarInsn(LLOAD, register); register += 2;
624 mv.visitMethodInsn(INVOKESTATIC, "java/lang/Long", "valueOf", "(F)Ljava/lang/Long;");
625 } else if (clazz==float.class) {
626 mv.visitVarInsn(FLOAD, register); register += 2;
627 mv.visitMethodInsn(INVOKESTATIC, "java/lang/Float", "valueOf", "(F)Ljava/lang/Float;");
628 } else if (clazz==Double.class) {
629 mv.visitVarInsn(DLOAD, register); register += 2;
630 mv.visitMethodInsn(INVOKESTATIC, "java/lang/Double", "valueOf", "(D)Ljava/lang/Double;");
632 // Push argument to stack
633 mv.visitVarInsn(ALOAD, register++);
635 mv.visitInsn(AASTORE);
638 // Store args to argRegs+2
639 mv.visitVarInsn(ASTORE, argRegs+2);
640 Label l6 = new Label();
642 mv.visitVarInsn(ALOAD, argRegs+1 /* m */);
643 mv.visitVarInsn(ALOAD, argRegs+2 /*args*/);
644 mv.visitMethodInsn(INVOKEINTERFACE, "org/simantics/data/session/MethodInterface$Method", "invoke", "(Ljava/lang/Object;)Lorg/simantics/data/session/MethodInterface$AsyncResult;");
645 mv.visitVarInsn(ASTORE, argRegs+3);
647 mv.visitVarInsn(ALOAD, argRegs+3);
648 mv.visitMethodInsn(INVOKEINTERFACE, "org/simantics/data/session/MethodInterface$AsyncResult", "waitForResponse", "()Ljava/lang/Object;");
649 // TODO Return typecase result
650 Class<?> returnType = m.getReturnType();
652 if (returnType==void.class) {
654 mv.visitInsn(RETURN);
655 } else if (returnType==int.class) {
656 mv.visitTypeInsn(CHECKCAST, "java/lang/Integer");
657 mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Integer", "intValue", "()I");
659 mv.visitInsn(IRETURN);
660 } else if (returnType==byte.class) {
661 mv.visitTypeInsn(CHECKCAST, "java/lang/Byte");
662 mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Byte", "byteValue", "B()");
664 mv.visitInsn(IRETURN);
665 } else if (returnType==char.class) {
666 mv.visitTypeInsn(CHECKCAST, "java/lang/Character");
667 mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Character", "charValue", "()C");
669 mv.visitInsn(IRETURN);
670 } else if (returnType==boolean.class) {
671 mv.visitTypeInsn(CHECKCAST, "java/lang/Boolean");
672 mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z");
674 mv.visitInsn(IRETURN);
675 } else if (returnType==short.class) {
676 mv.visitTypeInsn(CHECKCAST, "java/lang/Short");
677 mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Short", "shortValue", "()S");
679 mv.visitInsn(IRETURN);
680 } else if (returnType==long.class) {
681 mv.visitTypeInsn(CHECKCAST, "java/lang/Long");
682 mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Long", "longValue", "()J");
684 mv.visitInsn(LRETURN);
685 } else if (returnType==double.class) {
686 mv.visitTypeInsn(CHECKCAST, "java/lang/Double");
687 mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Double", "doubleValue", "()D");
689 mv.visitInsn(DRETURN);
690 } else if (returnType==float.class) {
691 mv.visitTypeInsn(CHECKCAST, "java/lang/Float");
692 mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Float", "floatValue", "()F");
694 mv.visitInsn(FRETURN);
697 mv.visitTypeInsn(CHECKCAST, returnType.getName().replaceAll("\\.", "/"));
699 mv.visitInsn(ARETURN);
705 mv.visitFrame(Opcodes.F_FULL, argRegs+4, new Object[] {classResourceName, "java/lang/Integer", "org/simantics/data/session/MethodInterface$Method", "[Ljava/lang/Object;", "org/simantics/data/session/MethodInterface$AsyncResult"}, 1, new Object[] {"org/simantics/data/session/MethodInterface$ExecutionError"});
706 mv.visitVarInsn(ASTORE, argRegs+4);
707 Label l7 = new Label();
709 mv.visitVarInsn(ALOAD, argRegs+4);
710 mv.visitMethodInsn(INVOKEVIRTUAL, "org/simantics/data/session/MethodInterface$ExecutionError", "getError", "()Ljava/lang/Object;");
711 mv.visitVarInsn(ASTORE, argRegs+5); // argRegs+5 <- ExecutionError.cause
713 Class<?>[] exceptionClasses = m.getExceptionTypes();
714 Label nextException[] = new Label[exceptionClasses.length];
715 for (int i=0; i<exceptionClasses.length; i++)
717 Class<?> exceptionClass = exceptionClasses[i];
718 String exceptionClassResourceName = exceptionClass.getName().replaceAll("\\.", "/");
719 nextException[i] = new Label();
720 // If instanceof MyException
721 Label l8 = new Label();
723 mv.visitVarInsn(ALOAD, argRegs+5); // Cause
724 mv.visitTypeInsn(INSTANCEOF, exceptionClassResourceName);
725 mv.visitJumpInsn(IFEQ, nextException[i]); // If not, go to ExecutionError
727 mv.visitVarInsn(ALOAD, argRegs+5); // e
728 mv.visitTypeInsn(CHECKCAST, exceptionClassResourceName);
729 mv.visitInsn(ATHROW);
730 mv.visitLabel(nextException[i]);
734 mv.visitFrame(Opcodes.F_APPEND,argRegs+1, new Object[] {"org/simantics/data/session/MethodInterface$ExecutionError", "java/lang/Object"}, 0, null);
735 mv.visitTypeInsn(NEW, "java/lang/RuntimeException");
737 mv.visitVarInsn(ALOAD, argRegs+4);
738 mv.visitMethodInsn(INVOKESPECIAL, "java/lang/RuntimeException", "<init>", "(Ljava/lang/Throwable;)V");
739 mv.visitInsn(ATHROW);
741 // InteruptedException
743 mv.visitFrame(Opcodes.F_FULL, argRegs+4, new Object[] {classResourceName, "java/lang/Integer", "org/simantics/data/session/MethodInterface$Method", "[Ljava/lang/Object;", "org/simantics/data/session/MethodInterface$AsyncResult"}, 1, new Object[] {"java/lang/InterruptedException"});
744 mv.visitVarInsn(ASTORE, argRegs+4);
745 Label l10 = new Label();
747 mv.visitTypeInsn(NEW, "java/lang/RuntimeException");
749 mv.visitVarInsn(ALOAD, argRegs+4);
750 mv.visitMethodInsn(INVOKESPECIAL, "java/lang/RuntimeException", "<init>", "(Ljava/lang/Throwable;)V");
751 mv.visitInsn(ATHROW);
753 Label l11 = new Label();
755 mv.visitLocalVariable("this", classTypeDescriptor, null, l4, l11, 0);
756 // mv.visitLocalVariable("arg1", "Ljava/lang/Integer;", null, l4, l11, 1);
758 for (int i=0; i<params.length; i++) {
759 Class<?> clazz = params[i];
760 mv.visitLocalVariable("arg"+(i+1), classToTypeDescriptor(clazz), null, l4, l11, register);
762 if (clazz==long.class || clazz==float.class || clazz==Double.class) argRegs++;
764 mv.visitLocalVariable("m", "Lorg/simantics/data/session/MethodInterface$Method;", null, l5, l11, argRegs+1);
765 mv.visitLocalVariable("args", "[Ljava/lang/Object;", null, l6, l11, argRegs+2);
766 mv.visitLocalVariable("result", "Lorg/simantics/data/session/MethodInterface$AsyncResult;", null, l0, l11, argRegs+3);
767 mv.visitLocalVariable("e", "Lorg/simantics/data/session/MethodInterface$ExecutionError;", null, l7, l3, argRegs+4);
768 mv.visitLocalVariable("cause", "Ljava/lang/Object;", null, l7, l3, argRegs+5);
769 mv.visitLocalVariable("e", "Ljava/lang/InterruptedException;", null, l10, l11, argRegs+4);
770 mv.visitMaxs(argRegs+3, argRegs+6);