List of usage examples for org.objectweb.asm Opcodes INTEGER
Integer INTEGER
To view the source code for org.objectweb.asm Opcodes INTEGER.
Click Source Link
From source file:org.jacoco.core.internal.instr.FrameTracker.java
License:Open Source License
@Override public void visitLdcInsn(final Object cst) { if (cst instanceof Integer) { push(Opcodes.INTEGER); } else if (cst instanceof Float) { push(Opcodes.FLOAT);//from www.jav a 2 s. c om } else if (cst instanceof Long) { push(Opcodes.LONG); push(Opcodes.TOP); } else if (cst instanceof Double) { push(Opcodes.DOUBLE); push(Opcodes.TOP); } else if (cst instanceof String) { push("java/lang/String"); } else if (cst instanceof Type) { push("java/lang/Class"); } else { throw new IllegalArgumentException(); } mv.visitLdcInsn(cst); }
From source file:org.jacoco.core.internal.instr.FrameTracker.java
License:Open Source License
@Override public void visitIincInsn(final int var, final int increment) { set(var, Opcodes.INTEGER); mv.visitIincInsn(var, increment); }
From source file:org.jacoco.core.internal.instr.FrameTracker.java
License:Open Source License
private void push(final Type type) { switch (type.getSort()) { case Type.VOID: break;//from w w w. j a v a2 s . c om case Type.BOOLEAN: case Type.BYTE: case Type.CHAR: case Type.INT: case Type.SHORT: push(Opcodes.INTEGER); break; case Type.FLOAT: push(Opcodes.FLOAT); break; case Type.LONG: push(Opcodes.LONG); push(Opcodes.TOP); break; case Type.DOUBLE: push(Opcodes.DOUBLE); push(Opcodes.TOP); break; case Type.ARRAY: case Type.OBJECT: push(type.getInternalName()); break; default: throw new AssertionError(type); } }
From source file:org.jacoco.core.internal.instr.FrameTracker.java
License:Open Source License
private void set(final int pos, final Type type) { switch (type.getSort()) { case Type.BOOLEAN: case Type.BYTE: case Type.CHAR: case Type.INT: case Type.SHORT: set(pos, Opcodes.INTEGER); break;/*from w w w .j av a2 s . c om*/ case Type.FLOAT: set(pos, Opcodes.FLOAT); break; case Type.LONG: set(pos, Opcodes.LONG); set(pos + 1, Opcodes.TOP); break; case Type.DOUBLE: set(pos, Opcodes.DOUBLE); set(pos + 1, Opcodes.TOP); break; case Type.ARRAY: case Type.OBJECT: set(pos, type.getInternalName()); break; default: throw new AssertionError(type); } }
From source file:org.jboss.byteman.agent.adapter.RuleGeneratorAdapter.java
License:Open Source License
private void dumpType(StringBuffer buffer, Object t) { if (t == Opcodes.TOP) { buffer.append("TOP"); } else if (t == null) { buffer.append("null"); } else if (t == Opcodes.INTEGER) { buffer.append("int"); } else if (t == Opcodes.FLOAT) { buffer.append("float"); } else if (t == Opcodes.DOUBLE) { buffer.append("double"); } else if (t == Opcodes.LONG) { buffer.append("long"); } else if (t == Opcodes.NULL) { buffer.append("null"); } else if (t == Opcodes.UNINITIALIZED_THIS) { buffer.append("uninit_this"); } else if (t instanceof String) { buffer.append((String) t); } else {//w w w. j a va 2s . co m buffer.append(((Label) t).getOffset()); } }
From source file:org.jboss.byteman.agent.adapter.RuleGeneratorAdapter.java
License:Open Source License
public void visitFrame(final int type, final int nLocal, final Object[] local, final int nStack, final Object[] stack) { if (type != Opcodes.F_NEW) { // uncompressed frame throw new IllegalStateException("ClassReader.accept() should be called with EXPAND_FRAMES flag"); }/*w w w .ja v a 2s. c o m*/ // dumpFrame(nLocal, local, nStack, stack); // adjust the local types array int toRemove = localTypes.size(); for (int i = toRemove; i > 0; i--) { localTypes.remove(i - 1); } int nextLocal = 0; for (int i = 0; i < nLocal; i++) { Object t = local[i]; if (t == Opcodes.TOP) { localTypes.add(null); } else if (t == null) { localTypes.add(null); } else if (t == Opcodes.INTEGER) { localTypes.add(Type.INT_TYPE); } else if (t == Opcodes.FLOAT) { localTypes.add(Type.FLOAT_TYPE); } else if (t == Opcodes.DOUBLE) { localTypes.add(Type.DOUBLE_TYPE); nextLocal++; localTypes.add(null); } else if (t == Opcodes.LONG) { localTypes.add(Type.LONG_TYPE); nextLocal++; localTypes.add(null); } else if (t == Opcodes.NULL) { localTypes.add(null); } else if (t == Opcodes.UNINITIALIZED_THIS) { localTypes.add(null); } else if (t instanceof String) { localTypes.add(Type.getObjectType((String) t)); } else { localTypes.add(null); } nextLocal++; } this.nextLocal = nextLocal; mv.visitFrame(type, nLocal, local, nStack, stack); }
From source file:org.kjots.json.object.JsonObjectGeneratorBase.java
License:Apache License
/** * Generate a get Java character primitive property method. * * @param classVisitor The class visitor. * @param jsonObjectImplType The type of the JSON object implementation. * @param method The method.//w w w. j ava 2 s.c om * @param propertyName The name of the property. */ private void generateGetJavaCharacterPrimitivePropertyMethod(ClassVisitor classVisitor, Type jsonObjectImplType, Method method, String propertyName) { Type jsonStringPrimitiveType = Type.getType(String.class); MethodVisitor methodVisitor = classVisitor.visitMethod(ACC_PUBLIC + ACC_FINAL, method, null, null); Label start = new Label(); Label l0 = new Label(); Label l1 = new Label(); Label end = new Label(); methodVisitor.visitCode(); methodVisitor.visitLabel(start); methodVisitor.visitVarInsn(ALOAD, 0); methodVisitor.visitLdcInsn(propertyName); methodVisitor.visitMethodInsn(INVOKEVIRTUAL, jsonObjectImplType, this.getGetJsonPrimitivePropertyMethod(jsonStringPrimitiveType)); methodVisitor.visitVarInsn(ASTORE, 1); methodVisitor.visitVarInsn(ALOAD, 1); methodVisitor.visitJumpInsn(IFNULL, l0); methodVisitor.visitVarInsn(ALOAD, 1); methodVisitor.visitMethodInsn(INVOKEVIRTUAL, jsonStringPrimitiveType, new Method("isEmpty", Type.BOOLEAN_TYPE, new Type[] {})); methodVisitor.visitJumpInsn(IFNE, l0); methodVisitor.visitVarInsn(ALOAD, 1); methodVisitor.visitInsn(ICONST_0); methodVisitor.visitMethodInsn(INVOKEVIRTUAL, jsonStringPrimitiveType, new Method("charAt", Type.CHAR_TYPE, new Type[] { Type.INT_TYPE })); methodVisitor.visitJumpInsn(GOTO, l1); methodVisitor.visitLabel(l0); methodVisitor.visitFrame(Opcodes.F_APPEND, 1, new Object[] { jsonStringPrimitiveType }, 0, null); methodVisitor.visitInsn(ICONST_0); methodVisitor.visitLabel(l1); methodVisitor.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] { Opcodes.INTEGER }); methodVisitor.visitInsn(IRETURN); methodVisitor.visitLabel(end); methodVisitor.visitLocalVariable("this", jsonObjectImplType, null, start, end, 0); methodVisitor.visitLocalVariable("_" + propertyName, jsonStringPrimitiveType, null, start, end, 1); methodVisitor.visitMaxs(2, 2); methodVisitor.visitEnd(); }
From source file:org.simantics.databoard.binding.reflection.AsmBindingClassLoader.java
License:Open Source License
public byte[] createBindingClass(ClassInfo ci, String bindingClassName) { //System.out.println("BindingFactory: "+bindingClassName+" (for "+ci.clazz.getClassLoader()+")"); int count = ci.fields.length; ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); ClassVisitor cv = cw;//new CheckClassAdapter(cw); FieldVisitor fv;/*from w w w . j av a2s. com*/ MethodVisitor mv; AnnotationVisitor av0; String className = ci.clazz.getName().replaceAll("\\.", "/"); bindingClassName = bindingClassName.replaceAll("\\.", "/"); Object[] classNameX = new Object[] { className }; String signature = "L" + bindingClassName + ";"; // Constructor String superClass = "org/simantics/databoard/binding/reflection/ClassBinding"; cv.visit(V1_6, ACC_PUBLIC + ACC_SUPER, bindingClassName, null, superClass, null); // Constructor { mv = cv.visitMethod(ACC_PUBLIC, "<init>", "(Lorg/simantics/databoard/type/RecordType;)V", null, new String[] { "org/simantics/databoard/binding/error/BindingConstructionException" }); mv.visitCode(); Label l0 = new Label(); mv.visitLabel(l0); mv.visitVarInsn(ALOAD, 0); mv.visitLdcInsn(Type.getType("L" + className + ";")); mv.visitMethodInsn(INVOKESPECIAL, superClass, "<init>", "(Ljava/lang/Class;)V"); Label l1 = new Label(); mv.visitLabel(l1); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitFieldInsn(PUTFIELD, bindingClassName, "type", "Lorg/simantics/databoard/type/Datatype;"); Label l2 = new Label(); mv.visitLabel(l2); mv.visitInsn(RETURN); Label l3 = new Label(); mv.visitLabel(l3); mv.visitLocalVariable("this", signature, null, l0, l3, 0); mv.visitLocalVariable("type", "Lorg/simantics/databoard/type/RecordType;", null, l0, l3, 1); mv.visitMaxs(2, 2); mv.visitEnd(); } // getComponent { mv = cv.visitMethod(ACC_PUBLIC, "getComponent", "(Ljava/lang/Object;I)Ljava/lang/Object;", null, new String[] { "org/simantics/databoard/binding/error/BindingException" }); mv.visitCode(); Label l0 = new Label(); mv.visitLabel(l0); mv.visitVarInsn(ALOAD, 1); mv.visitTypeInsn(CHECKCAST, className); mv.visitVarInsn(ASTORE, 3); Label l1 = new Label(); mv.visitLabel(l1); Label caseLabels[] = createFieldLabels(ci); Label elseLabel = new Label(); if (count > 0) { // Switch mv.visitVarInsn(ILOAD, 2); mv.visitTableSwitchInsn(0, count - 1, elseLabel, caseLabels); // case i: x.field = value[i] for (int i = 0; i < count; i++) { Label label = caseLabels[i]; Field field = ci.fields[i]; String fieldName = field.getName(); Class<?> fieldClass = ci.fields[i].getType(); String typeDescriptor = toTypeDescriptor(fieldClass); Method getter = ci.getters[i]; boolean useGetter = ((field.getModifiers() & Modifier.PUBLIC) == 0) && getter != null; mv.visitLabel(label); if (i == 0) { mv.visitFrame(Opcodes.F_APPEND, 1, classNameX, 0, null); } else { mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); } // Read instance argument mv.visitVarInsn(ALOAD, 3); if (useGetter) { // call getField mv.visitMethodInsn(INVOKEVIRTUAL, className, getter.getName(), "()" + typeDescriptor); } else { // Read field mv.visitFieldInsn(GETFIELD, className, fieldName, typeDescriptor); } // Box box(mv, fieldClass); mv.visitInsn(ARETURN); } } mv.visitLabel(elseLabel); if (count > 0) { mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); } mv.visitTypeInsn(NEW, "org/simantics/databoard/binding/error/BindingException"); mv.visitInsn(DUP); mv.visitLdcInsn("Illegal field index"); mv.visitMethodInsn(INVOKESPECIAL, "org/simantics/databoard/binding/error/BindingException", "<init>", "(Ljava/lang/String;)V"); mv.visitInsn(ATHROW); // End Label l19 = new Label(); mv.visitLabel(l19); mv.visitLocalVariable("this", "L" + className + ";", null, l0, l19, 0); mv.visitLocalVariable("obj", "Ljava/lang/Object;", null, l0, l19, 1); mv.visitLocalVariable("index", "I", null, l0, l19, 2); //mv.visitLocalVariable("x", "Lorg/simantics/databoard/binding/reflection/MyClass;", null, l1, l19, 3); mv.visitMaxs(3, 4); mv.visitEnd(); } // Create { mv = cv.visitMethod(ACC_PUBLIC + ACC_VARARGS, "create", "([Ljava/lang/Object;)Ljava/lang/Object;", null, new String[] { "org/simantics/databoard/binding/error/BindingException" }); if (ci.beanConstructor != null) { mv.visitCode(); Label l0 = new Label(); mv.visitLabel(l0); mv.visitTypeInsn(NEW, className); mv.visitInsn(DUP); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, className, "<init>", "(Lorg/simantics/databoard/binding/Binding;)V"); mv.visitVarInsn(ASTORE, 2); Label l1 = new Label(); mv.visitLabel(l1); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 2); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKEVIRTUAL, bindingClassName, "setComponents", "(Ljava/lang/Object;[Ljava/lang/Object;)V"); Label l2 = new Label(); mv.visitLabel(l2); mv.visitVarInsn(ALOAD, 2); mv.visitInsn(ARETURN); Label l3 = new Label(); mv.visitLabel(l3); mv.visitLocalVariable("this", "L" + bindingClassName + ";", null, l0, l3, 0); mv.visitLocalVariable("values", "[Ljava/lang/Object;", null, l0, l3, 1); //mv.visitLocalVariable("x", "L"+className+";", null, l1, l3, 2); mv.visitMaxs(3, 3); mv.visitEnd(); } else if (ci.argsConstructor != null) { mv.visitCode(); Label l0 = new Label(); mv.visitLabel(l0); mv.visitTypeInsn(NEW, className); mv.visitInsn(DUP); String constArgsDescriptor = "("; Class<?>[] args = ci.argsConstructor.getParameterTypes(); for (int i = 0; i < count; i++) { Label label = new Label(); Class<?> field = args[i]; String fieldName = field.getName(); Method getter = ci.getters[i]; Class<?> fieldClass = ci.fields[i].getType(); Class<?> boxClass = getBoxClass(fieldClass); String typeDescriptor = toTypeDescriptor(fieldClass); String boxTypeDescriptor = toTypeDescriptor(boxClass); constArgsDescriptor += typeDescriptor; mv.visitLabel(label); mv.visitVarInsn(ALOAD, 1); if (i < 6) { mv.visitInsn(ICONST_0 + i); } else { mv.visitIntInsn(BIPUSH, i); } mv.visitInsn(AALOAD); mv.visitTypeInsn(CHECKCAST, toClassCanonicalName(boxClass)); unbox(mv, fieldClass); } Label l17 = new Label(); mv.visitLabel(l17); constArgsDescriptor += ")V"; mv.visitMethodInsn(INVOKESPECIAL, className, "<init>", constArgsDescriptor); mv.visitInsn(ARETURN); Label l18 = new Label(); mv.visitLabel(l18); mv.visitLocalVariable("this", "L" + bindingClassName + ";", null, l0, l18, 0); mv.visitLocalVariable("values", "[Ljava/lang/Object;", null, l0, l18, 1); mv.visitMaxs(21, 2); mv.visitEnd(); } else { mv.visitCode(); Label l0 = new Label(); mv.visitLabel(l0); mv.visitTypeInsn(NEW, className); mv.visitInsn(DUP); mv.visitMethodInsn(INVOKESPECIAL, className, "<init>", "()V"); mv.visitVarInsn(ASTORE, 2); Label l1 = new Label(); mv.visitLabel(l1); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 2); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKEVIRTUAL, bindingClassName, "setComponents", "(Ljava/lang/Object;[Ljava/lang/Object;)V"); Label l2 = new Label(); mv.visitLabel(l2); mv.visitVarInsn(ALOAD, 2); mv.visitInsn(ARETURN); Label l3 = new Label(); mv.visitLabel(l3); mv.visitLocalVariable("this", "L" + bindingClassName + ";", null, l0, l3, 0); mv.visitLocalVariable("values", "[Ljava/lang/Object;", null, l0, l3, 1); //mv.visitLocalVariable("x", "L"+className+";", null, l1, l3, 2); mv.visitMaxs(3, 3); mv.visitEnd(); } } // CreatePartial mv = cv.visitMethod(ACC_PUBLIC, "createPartial", "()Ljava/lang/Object;", null, new String[] { "org/simantics/databoard/binding/error/BindingException" }); if (ci.beanConstructor != null) { mv.visitCode(); Label l0 = new Label(); mv.visitLabel(l0); mv.visitTypeInsn(NEW, className); mv.visitInsn(DUP); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, className, "<init>", "(Lorg/simantics/databoard/binding/Binding;)V"); mv.visitInsn(ARETURN); Label l1 = new Label(); mv.visitLabel(l1); mv.visitLocalVariable("this", "L" + bindingClassName + ";", null, l0, l1, 0); mv.visitMaxs(3, 1); mv.visitEnd(); } else if (ci.noArgsConstructor != null) { // return new MyClass(); mv.visitCode(); Label l0 = new Label(); mv.visitLabel(l0); mv.visitTypeInsn(NEW, className); mv.visitInsn(DUP); mv.visitMethodInsn(INVOKESPECIAL, className, "<init>", "()V"); mv.visitInsn(ARETURN); Label l1 = new Label(); mv.visitLabel(l1); mv.visitLocalVariable("this", "L" + bindingClassName + ";", null, l0, l1, 0); mv.visitMaxs(2, 1); mv.visitEnd(); } else { mv.visitCode(); Label l0 = new Label(); mv.visitLabel(l0); mv.visitIntInsn(BIPUSH, count); mv.visitTypeInsn(ANEWARRAY, "java/lang/Object"); mv.visitVarInsn(ASTORE, 1); Label l1 = new Label(); mv.visitLabel(l1); mv.visitInsn(ICONST_0); mv.visitVarInsn(ISTORE, 2); Label l2 = new Label(); mv.visitLabel(l2); Label l3 = new Label(); mv.visitJumpInsn(GOTO, l3); Label l4 = new Label(); mv.visitLabel(l4); mv.visitFrame(Opcodes.F_APPEND, 2, new Object[] { "[Ljava/lang/Object;", Opcodes.INTEGER }, 0, null); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, bindingClassName, "componentBindings", "[Lorg/simantics/databoard/binding/Binding;"); mv.visitVarInsn(ILOAD, 2); mv.visitInsn(AALOAD); mv.visitVarInsn(ASTORE, 3); Label l5 = new Label(); mv.visitLabel(l5); mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ILOAD, 2); mv.visitVarInsn(ALOAD, 3); mv.visitMethodInsn(INVOKEVIRTUAL, "org/simantics/databoard/binding/Binding", "createDefault", "()Ljava/lang/Object;"); mv.visitInsn(AASTORE); Label l6 = new Label(); mv.visitLabel(l6); mv.visitIincInsn(2, 1); mv.visitLabel(l3); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); mv.visitVarInsn(ILOAD, 2); mv.visitVarInsn(ALOAD, 1); mv.visitInsn(ARRAYLENGTH); mv.visitJumpInsn(IF_ICMPLT, l4); Label l7 = new Label(); mv.visitLabel(l7); mv.visitLineNumber(109, l7); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKEVIRTUAL, bindingClassName, "create", "([Ljava/lang/Object;)Ljava/lang/Object;"); mv.visitInsn(ARETURN); Label l8 = new Label(); mv.visitLabel(l8); mv.visitLocalVariable("this", "L" + bindingClassName + ";", null, l0, l8, 0); mv.visitLocalVariable("values", "[Ljava/lang/Object;", null, l1, l8, 1); mv.visitLocalVariable("i", "I", null, l2, l7, 2); mv.visitLocalVariable("fb", "Lorg/simantics/databoard/binding/Binding;", null, l5, l6, 3); mv.visitMaxs(3, 4); mv.visitEnd(); } // setComponent { mv = cv.visitMethod(ACC_PUBLIC, "setComponent", "(Ljava/lang/Object;ILjava/lang/Object;)V", null, new String[] { "org/simantics/databoard/binding/error/BindingException" }); mv.visitCode(); Label l0 = new Label(); mv.visitLabel(l0); mv.visitVarInsn(ALOAD, 1); mv.visitTypeInsn(CHECKCAST, className); mv.visitVarInsn(ASTORE, 4); Label endLabel = new Label(); Label l1 = new Label(); mv.visitLabel(l1); Label elseLabel = new Label(); Label labels[] = new Label[count]; for (int i = 0; i < count; i++) labels[i] = new Label(); if (count > 0) { mv.visitVarInsn(ILOAD, 2); mv.visitTableSwitchInsn(0, count - 1, elseLabel, labels); for (int i = 0; i < count; i++) { Label label = labels[i]; mv.visitLabel(label); Field field = ci.fields[i]; String fieldName = field.getName(); Class<?> fieldClass = ci.fields[i].getType(); Class<?> boxClass = getBoxClass(fieldClass); String typeDescriptor = toTypeDescriptor(fieldClass); String boxTypeDescriptor = toTypeDescriptor(boxClass); Method setter = ci.setters[i]; Class<?> setterClass = setter != null ? setter.getParameterTypes()[0] : null; boolean useSetter = ((field.getModifiers() & Modifier.PUBLIC) == 0) && setter != null; if (i == 0) { mv.visitFrame(Opcodes.F_APPEND, 1, classNameX, 0, null); } else { mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); } mv.visitVarInsn(ALOAD, 4); mv.visitVarInsn(ALOAD, 3); mv.visitTypeInsn(CHECKCAST, toClassCanonicalName(boxClass)); if (useSetter) { unbox(mv, setterClass); mv.visitMethodInsn(INVOKEVIRTUAL, className, setter.getName(), "(" + typeDescriptor + ")V"); } else { unbox(mv, fieldClass); mv.visitFieldInsn(PUTFIELD, className, field.getName(), typeDescriptor); } mv.visitInsn(RETURN); } } mv.visitLabel(elseLabel); mv.visitLineNumber(178, elseLabel); if (count > 0) { mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); } mv.visitTypeInsn(NEW, "org/simantics/databoard/binding/error/BindingException"); mv.visitInsn(DUP); mv.visitLdcInsn("Illegal field index"); mv.visitMethodInsn(INVOKESPECIAL, "org/simantics/databoard/binding/error/BindingException", "<init>", "(Ljava/lang/String;)V"); mv.visitInsn(ATHROW); mv.visitLabel(endLabel); mv.visitLocalVariable("this", "L" + bindingClassName + ";", null, l0, endLabel, 0); mv.visitLocalVariable("obj", "Ljava/lang/Object;", null, l0, endLabel, 1); mv.visitLocalVariable("index", "I", null, l0, endLabel, 2); mv.visitLocalVariable("value", "Ljava/lang/Object;", null, l0, endLabel, 3); //mv.visitLocalVariable("x", "L"+className+";", null, l1, endLabel, 4); mv.visitMaxs(3, 5); mv.visitEnd(); } // IsImmutable { mv = cv.visitMethod(ACC_PUBLIC, "isImmutable", "()Z", null, null); mv.visitCode(); Label l0 = new Label(); mv.visitLabel(l0); mv.visitInsn(ICONST_0); mv.visitInsn(IRETURN); Label l1 = new Label(); mv.visitLabel(l1); mv.visitLocalVariable("this", "L" + className + ";", null, l0, l1, 0); mv.visitMaxs(1, 1); mv.visitEnd(); } // IsInstance { mv = cv.visitMethod(ACC_PUBLIC, "isInstance", "(Ljava/lang/Object;)Z", null, null); mv.visitCode(); Label l0 = new Label(); mv.visitLabel(l0); mv.visitVarInsn(ALOAD, 1); mv.visitTypeInsn(INSTANCEOF, className); mv.visitInsn(IRETURN); Label l1 = new Label(); mv.visitLabel(l1); mv.visitLocalVariable("this", "L" + className + ";", null, l0, l1, 0); mv.visitLocalVariable("obj", "Ljava/lang/Object;", null, l0, l1, 1); mv.visitMaxs(1, 2); mv.visitEnd(); } // SetComponents { mv = cv.visitMethod(ACC_PUBLIC + ACC_VARARGS, "setComponents", "(Ljava/lang/Object;[Ljava/lang/Object;)V", null, new String[] { "org/simantics/databoard/binding/error/BindingException" }); mv.visitCode(); Label l0 = new Label(); mv.visitLabel(l0); mv.visitVarInsn(ALOAD, 1); mv.visitTypeInsn(CHECKCAST, className); mv.visitVarInsn(ASTORE, 3); Label firstLabel = l0; for (int i = 0; i < count; i++) { Label label = new Label(); if (firstLabel == l0) firstLabel = label; Field field = ci.fields[i]; String fieldName = field.getName(); Class<?> fieldClass = ci.fields[i].getType(); Class<?> boxClass = getBoxClass(fieldClass); String typeDescriptor = toTypeDescriptor(fieldClass); String boxTypeDescriptor = toTypeDescriptor(boxClass); Method setter = ci.setters[i]; Class<?> setterClass = setter != null ? setter.getParameterTypes()[0] : null; boolean useSetter = ((field.getModifiers() & Modifier.PUBLIC) == 0) && setter != null; mv.visitLabel(label); mv.visitVarInsn(ALOAD, 3); mv.visitVarInsn(ALOAD, 2); if (i < 6) { mv.visitInsn(ICONST_0 + i); } else { mv.visitIntInsn(BIPUSH, i); } mv.visitInsn(AALOAD); mv.visitTypeInsn(CHECKCAST, toClassCanonicalName(boxClass)); if (useSetter) { unbox(mv, setterClass); mv.visitMethodInsn(INVOKEVIRTUAL, className, setter.getName(), "(" + typeDescriptor + ")V"); } else { unbox(mv, fieldClass); mv.visitFieldInsn(PUTFIELD, className, field.getName(), typeDescriptor); } } Label l17 = new Label(); mv.visitLabel(l17); mv.visitInsn(RETURN); Label endLabel = new Label(); mv.visitLabel(endLabel); mv.visitLocalVariable("this", "L" + className + ";", null, l0, endLabel, 0); mv.visitLocalVariable("obj", "Ljava/lang/Object;", null, l0, endLabel, 1); mv.visitLocalVariable("value", "[Ljava/lang/Object;", null, l0, endLabel, 2); //mv.visitLocalVariable("x", "Lorg/simantics/databoard/binding/reflection/MyClass;", null, firstLabel, endLabel, 3); mv.visitMaxs(3, 4); mv.visitEnd(); } // Add primitive setters { addGetSetPrimitive(ci, cv, "Boolean", "Z", bindingClassName); addGetSetPrimitive(ci, cv, "Byte", "B", bindingClassName); addGetSetPrimitive(ci, cv, "Int", "I", bindingClassName); addGetSetPrimitive(ci, cv, "Long", "J", bindingClassName); addGetSetPrimitive(ci, cv, "Float", "F", bindingClassName); addGetSetPrimitive(ci, cv, "Double", "D", bindingClassName); } cv.visitEnd(); return cw.toByteArray(); }
From source file:org.simantics.databoard.tests.testASM.java
License:Open Source License
void createImpl(String className, Class<?> interfaze, ClassWriter cw) { FieldVisitor fv;// w w w . j a v a 2 s.c o m MethodVisitor mv; AnnotationVisitor av0; java.lang.reflect.Method[] methods = interfaze.getMethods(); Arrays.sort(methods, MethodInterfaceUtil.methodComparator); String classResourceName = className.replaceAll("\\.", "/"); String classTypeDescriptor = "L" + classResourceName + ";"; String interfaceResourceName = classResourceName.substring(0, classResourceName.length() - 5); String interfaceTypeDescriptor = "L" + interfaceResourceName + ";"; cw.visit(V1_6, ACC_SUPER | ACC_PUBLIC, classResourceName, null, "java/lang/Object", new String[] { interfaceResourceName }); // Imports Set<Class<?>> imports = new HashSet<Class<?>>(); imports.add(AsyncResult.class); imports.add(ExecutionError.class); imports.add(Method.class); imports.add(interfaze); for (java.lang.reflect.Method m : methods) { for (Class<?> clazz : m.getExceptionTypes()) { imports.add(clazz); } for (Class<?> clazz : m.getParameterTypes()) { imports.add(clazz); } imports.add(m.getReturnType()); } for (Class<?> clazz : imports) { if (clazz.isPrimitive()) continue; String name = clazz.getName(); if (name.startsWith("java.lang")) continue; String resourceName = name.replaceAll("\\.", "/"); String outerName = resourceName.contains("$") ? resourceName.substring(0, resourceName.indexOf('$')) : null; String className_ = clazz.isArray() ? clazz.getSimpleName().substring(0, clazz.getSimpleName().length() - 2) : clazz.getSimpleName(); int access = ACC_PUBLIC + ACC_STATIC + (clazz.isInterface() ? ACC_INTERFACE + ACC_ABSTRACT : 0); // System.out.printf("name=%s, outerName=%s, innerName=%s\n", resourceName, outerName, className_); cw.visitInnerClass(resourceName, outerName, className_, access); } // Fields { fv = cw.visitField(ACC_FINAL + ACC_STATIC, "interfaze", "Ljava/lang/Class;", "Ljava/lang/Class<*>;", null); fv.visitEnd(); } { fv = cw.visitField(ACC_FINAL + ACC_STATIC, "bindings", "[Lorg/simantics/databoard/method/MethodBinding;", null, null); fv.visitEnd(); } { fv = cw.visitField(0, "mi", "Lorg/simantics/data/session/MethodInterface;", null, null); fv.visitEnd(); } { fv = cw.visitField(0, "methods", "[Lorg/simantics/data/session/MethodInterface$Method;", null, null); fv.visitEnd(); } // Init class - static {} { mv = cw.visitMethod(ACC_STATIC, "<clinit>", "()V", null, null); mv.visitCode(); Label l0 = new Label(); mv.visitLabel(l0); mv.visitLdcInsn(Type.getType(interfaceTypeDescriptor)); mv.visitFieldInsn(PUTSTATIC, classResourceName, "interfaze", "Ljava/lang/Class;"); Label l1 = new Label(); mv.visitLabel(l1); mv.visitFieldInsn(GETSTATIC, classResourceName, "interfaze", "Ljava/lang/Class;"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "getMethods", "()[Ljava/lang/reflect/Method;"); mv.visitVarInsn(ASTORE, 0); Label l2 = new Label(); mv.visitLabel(l2); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETSTATIC, "org/simantics/data/network/MethodInterfaceUtil", "methodComparator", "Ljava/util/Comparator;"); mv.visitMethodInsn(INVOKESTATIC, "java/util/Arrays", "sort", "([Ljava/lang/Object;Ljava/util/Comparator;)V"); Label l3 = new Label(); mv.visitLabel(l3); mv.visitVarInsn(ALOAD, 0); mv.visitInsn(ARRAYLENGTH); mv.visitTypeInsn(ANEWARRAY, "org/simantics/databoard/method/MethodBinding"); mv.visitFieldInsn(PUTSTATIC, classResourceName, "bindings", "[Lorg/simantics/databoard/method/MethodBinding;"); Label l4 = new Label(); mv.visitLabel(l4); mv.visitInsn(ICONST_0); mv.visitVarInsn(ISTORE, 1); Label l5 = new Label(); mv.visitLabel(l5); Label l6 = new Label(); mv.visitJumpInsn(GOTO, l6); Label l7 = new Label(); mv.visitLabel(l7); mv.visitFrame(Opcodes.F_APPEND, 2, new Object[] { "[Ljava/lang/reflect/Method;", Opcodes.INTEGER }, 0, null); mv.visitFieldInsn(GETSTATIC, classResourceName, "bindings", "[Lorg/simantics/databoard/method/MethodBinding;"); mv.visitVarInsn(ILOAD, 1); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ILOAD, 1); mv.visitInsn(AALOAD); mv.visitMethodInsn(INVOKESTATIC, "org/simantics/databoard/DataTypes", "getMethodBinding", "(Ljava/lang/reflect/Method;)Lorg/simantics/databoard/method/MethodBinding;"); mv.visitInsn(AASTORE); Label l8 = new Label(); mv.visitLabel(l8); mv.visitIincInsn(1, 1); mv.visitLabel(l6); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); mv.visitVarInsn(ILOAD, 1); mv.visitFieldInsn(GETSTATIC, classResourceName, "bindings", "[Lorg/simantics/databoard/method/MethodBinding;"); mv.visitInsn(ARRAYLENGTH); mv.visitJumpInsn(IF_ICMPLT, l7); Label l9 = new Label(); mv.visitLabel(l9); mv.visitInsn(RETURN); Label l10 = new Label(); mv.visitLabel(l10); mv.visitLocalVariable("methods", "[Ljava/lang/reflect/Method;", null, l2, l10, 0); mv.visitLocalVariable("i", "I", null, l5, l9, 1); mv.visitMaxs(4, 2); mv.visitEnd(); } // Constructor { mv = cw.visitMethod(ACC_PUBLIC, "<init>", "(Lorg/simantics/data/session/MethodInterface;)V", null, new String[] { "org/simantics/data/error/MethodNotSupportedException" }); mv.visitCode(); Label l0 = new Label(); mv.visitLabel(l0); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V"); Label l1 = new Label(); mv.visitLabel(l1); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitFieldInsn(PUTFIELD, classResourceName, "mi", "Lorg/simantics/data/session/MethodInterface;"); Label l2 = new Label(); mv.visitLabel(l2); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETSTATIC, classResourceName, "bindings", "[Lorg/simantics/databoard/method/MethodBinding;"); mv.visitInsn(ARRAYLENGTH); mv.visitTypeInsn(ANEWARRAY, "org/simantics/data/session/MethodInterface$Method"); mv.visitFieldInsn(PUTFIELD, classResourceName, "methods", "[Lorg/simantics/data/session/MethodInterface$Method;"); Label l3 = new Label(); mv.visitLabel(l3); mv.visitInsn(ICONST_0); mv.visitVarInsn(ISTORE, 2); Label l4 = new Label(); mv.visitLabel(l4); Label l5 = new Label(); mv.visitJumpInsn(GOTO, l5); Label l6 = new Label(); mv.visitLabel(l6); mv.visitFrame(Opcodes.F_FULL, 3, new Object[] { classResourceName, "org/simantics/data/session/MethodInterface", Opcodes.INTEGER }, 0, new Object[] {}); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, classResourceName, "methods", "[Lorg/simantics/data/session/MethodInterface$Method;"); mv.visitVarInsn(ILOAD, 2); mv.visitVarInsn(ALOAD, 1); mv.visitFieldInsn(GETSTATIC, classResourceName, "bindings", "[Lorg/simantics/databoard/method/MethodBinding;"); mv.visitVarInsn(ILOAD, 2); mv.visitInsn(AALOAD); mv.visitMethodInsn(INVOKEINTERFACE, "org/simantics/data/session/MethodInterface", "getMethod", "(Lorg/simantics/databoard/method/MethodBinding;)Lorg/simantics/data/session/MethodInterface$Method;"); mv.visitInsn(AASTORE); Label l7 = new Label(); mv.visitLabel(l7); mv.visitIincInsn(2, 1); mv.visitLabel(l5); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); mv.visitVarInsn(ILOAD, 2); mv.visitFieldInsn(GETSTATIC, classResourceName, "bindings", "[Lorg/simantics/databoard/method/MethodBinding;"); mv.visitInsn(ARRAYLENGTH); mv.visitJumpInsn(IF_ICMPLT, l6); Label l8 = new Label(); mv.visitLabel(l8); mv.visitInsn(RETURN); Label l9 = new Label(); mv.visitLabel(l9); mv.visitLocalVariable("this", classTypeDescriptor, null, l0, l9, 0); mv.visitLocalVariable("mi", "Lorg/simantics/data/session/MethodInterface;", null, l0, l9, 1); mv.visitLocalVariable("i", "I", null, l4, l8, 2); mv.visitMaxs(5, 3); mv.visitEnd(); } // Method int methodNumber = 0; for (java.lang.reflect.Method m : methods) { String typeDescription = ""; Class<?>[] params = m.getParameterTypes(); for (int i = 0; i < params.length; i++) { if (i > 0) typeDescription += ";"; typeDescription += classToTypeDescriptor(params[i]); } typeDescription = "(" + typeDescription + ")" + classToTypeDescriptor(m.getReturnType()); System.out.println(typeDescription + " " + m.getName()); Class<?>[] exceptions = m.getExceptionTypes(); String[] exceptionResourceNames = new String[exceptions.length]; for (int i = 0; i < exceptionResourceNames.length; i++) { exceptionResourceNames[i] = exceptions[i].getName().replaceAll("\\.", "/"); } // Registers // 0 - this // 1..argRegs args // argRegs+1 - method // argRegs+2 - args (the array) // argRegs+3 - AsyncResult // argRegs+4 - e // argRegs+5 - ExecutionError.cause // argRegs+6 - e int argRegs = 0; for (int i = 0; i < params.length; i++) { Class<?> clazz = params[i]; argRegs++; if (clazz == long.class || clazz == float.class || clazz == Double.class) argRegs++; } mv = cw.visitMethod(ACC_PUBLIC, m.getName(), typeDescription, null, exceptionResourceNames); mv.visitCode(); Label l0 = new Label(); Label l1 = new Label(); Label l2 = new Label(); mv.visitTryCatchBlock(l0, l1, l2, "org/simantics/data/session/MethodInterface$ExecutionError"); Label l3 = new Label(); mv.visitTryCatchBlock(l0, l1, l3, "java/lang/InterruptedException"); Label l4 = new Label(); mv.visitLabel(l4); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, classResourceName, "methods", "[Lorg/simantics/data/session/MethodInterface$Method;"); // Method m and puts into register mv.visitLdcInsn(Integer.valueOf(methodNumber)); mv.visitInsn(AALOAD); mv.visitVarInsn(ASTORE, argRegs + 1); Label l5 = new Label(); mv.visitLabel(l5); mv.visitLdcInsn(Integer.valueOf(params.length)); mv.visitTypeInsn(ANEWARRAY, "java/lang/Object"); int register = 1; // argument register for (int i = 0; i < params.length; i++) { Class<?> clazz = params[i]; mv.visitInsn(DUP); mv.visitLdcInsn(Integer.valueOf(i)); if (clazz == byte.class) { mv.visitVarInsn(ILOAD, register++); mv.visitMethodInsn(INVOKESTATIC, "java/lang/Byte", "valueOf", "(B)Ljava/lang/Byte;"); } else if (clazz == char.class) { mv.visitVarInsn(ILOAD, register++); mv.visitMethodInsn(INVOKESTATIC, "java/lang/Character", "valueOf", "(C)Ljava/lang/Character;"); } else if (clazz == boolean.class) { mv.visitVarInsn(ILOAD, register++); mv.visitMethodInsn(INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;"); } else if (clazz == byte.class) { mv.visitVarInsn(ILOAD, register++); mv.visitMethodInsn(INVOKESTATIC, "java/lang/Short", "valueOf", "(S)Ljava/lang/Short;"); } else if (clazz == int.class) { mv.visitVarInsn(ILOAD, register++); mv.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;"); } else if (clazz == long.class) { mv.visitVarInsn(LLOAD, register); register += 2; mv.visitMethodInsn(INVOKESTATIC, "java/lang/Long", "valueOf", "(F)Ljava/lang/Long;"); } else if (clazz == float.class) { mv.visitVarInsn(FLOAD, register); register += 2; mv.visitMethodInsn(INVOKESTATIC, "java/lang/Float", "valueOf", "(F)Ljava/lang/Float;"); } else if (clazz == Double.class) { mv.visitVarInsn(DLOAD, register); register += 2; mv.visitMethodInsn(INVOKESTATIC, "java/lang/Double", "valueOf", "(D)Ljava/lang/Double;"); } else { // Push argument to stack mv.visitVarInsn(ALOAD, register++); } mv.visitInsn(AASTORE); } // Store args to argRegs+2 mv.visitVarInsn(ASTORE, argRegs + 2); Label l6 = new Label(); mv.visitLabel(l6); mv.visitVarInsn(ALOAD, argRegs + 1 /* m */); mv.visitVarInsn(ALOAD, argRegs + 2 /*args*/); mv.visitMethodInsn(INVOKEINTERFACE, "org/simantics/data/session/MethodInterface$Method", "invoke", "(Ljava/lang/Object;)Lorg/simantics/data/session/MethodInterface$AsyncResult;"); mv.visitVarInsn(ASTORE, argRegs + 3); mv.visitLabel(l0); mv.visitVarInsn(ALOAD, argRegs + 3); mv.visitMethodInsn(INVOKEINTERFACE, "org/simantics/data/session/MethodInterface$AsyncResult", "waitForResponse", "()Ljava/lang/Object;"); // TODO Return typecase result Class<?> returnType = m.getReturnType(); if (returnType == void.class) { mv.visitInsn(POP); mv.visitInsn(RETURN); } else if (returnType == int.class) { mv.visitTypeInsn(CHECKCAST, "java/lang/Integer"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Integer", "intValue", "()I"); mv.visitLabel(l1); mv.visitInsn(IRETURN); } else if (returnType == byte.class) { mv.visitTypeInsn(CHECKCAST, "java/lang/Byte"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Byte", "byteValue", "B()"); mv.visitLabel(l1); mv.visitInsn(IRETURN); } else if (returnType == char.class) { mv.visitTypeInsn(CHECKCAST, "java/lang/Character"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Character", "charValue", "()C"); mv.visitLabel(l1); mv.visitInsn(IRETURN); } else if (returnType == boolean.class) { mv.visitTypeInsn(CHECKCAST, "java/lang/Boolean"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z"); mv.visitLabel(l1); mv.visitInsn(IRETURN); } else if (returnType == short.class) { mv.visitTypeInsn(CHECKCAST, "java/lang/Short"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Short", "shortValue", "()S"); mv.visitLabel(l1); mv.visitInsn(IRETURN); } else if (returnType == long.class) { mv.visitTypeInsn(CHECKCAST, "java/lang/Long"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Long", "longValue", "()J"); mv.visitLabel(l1); mv.visitInsn(LRETURN); } else if (returnType == double.class) { mv.visitTypeInsn(CHECKCAST, "java/lang/Double"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Double", "doubleValue", "()D"); mv.visitLabel(l1); mv.visitInsn(DRETURN); } else if (returnType == float.class) { mv.visitTypeInsn(CHECKCAST, "java/lang/Float"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Float", "floatValue", "()F"); mv.visitLabel(l1); mv.visitInsn(FRETURN); } else { // Object mv.visitTypeInsn(CHECKCAST, returnType.getName().replaceAll("\\.", "/")); mv.visitLabel(l1); mv.visitInsn(ARETURN); } // Handle exceptions mv.visitLabel(l2); 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" }); mv.visitVarInsn(ASTORE, argRegs + 4); Label l7 = new Label(); mv.visitLabel(l7); mv.visitVarInsn(ALOAD, argRegs + 4); mv.visitMethodInsn(INVOKEVIRTUAL, "org/simantics/data/session/MethodInterface$ExecutionError", "getError", "()Ljava/lang/Object;"); mv.visitVarInsn(ASTORE, argRegs + 5); // argRegs+5 <- ExecutionError.cause Class<?>[] exceptionClasses = m.getExceptionTypes(); Label nextException[] = new Label[exceptionClasses.length]; for (int i = 0; i < exceptionClasses.length; i++) { Class<?> exceptionClass = exceptionClasses[i]; String exceptionClassResourceName = exceptionClass.getName().replaceAll("\\.", "/"); nextException[i] = new Label(); // If instanceof MyException Label l8 = new Label(); mv.visitLabel(l8); mv.visitVarInsn(ALOAD, argRegs + 5); // Cause mv.visitTypeInsn(INSTANCEOF, exceptionClassResourceName); mv.visitJumpInsn(IFEQ, nextException[i]); // If not, go to ExecutionError // If so, throw it mv.visitVarInsn(ALOAD, argRegs + 5); // e mv.visitTypeInsn(CHECKCAST, exceptionClassResourceName); mv.visitInsn(ATHROW); mv.visitLabel(nextException[i]); } // ExecutionError mv.visitFrame( Opcodes.F_APPEND, argRegs + 1, new Object[] { "org/simantics/data/session/MethodInterface$ExecutionError", "java/lang/Object" }, 0, null); mv.visitTypeInsn(NEW, "java/lang/RuntimeException"); mv.visitInsn(DUP); mv.visitVarInsn(ALOAD, argRegs + 4); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/RuntimeException", "<init>", "(Ljava/lang/Throwable;)V"); mv.visitInsn(ATHROW); // InteruptedException mv.visitLabel(l3); 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" }); mv.visitVarInsn(ASTORE, argRegs + 4); Label l10 = new Label(); mv.visitLabel(l10); mv.visitTypeInsn(NEW, "java/lang/RuntimeException"); mv.visitInsn(DUP); mv.visitVarInsn(ALOAD, argRegs + 4); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/RuntimeException", "<init>", "(Ljava/lang/Throwable;)V"); mv.visitInsn(ATHROW); Label l11 = new Label(); mv.visitLabel(l11); mv.visitLocalVariable("this", classTypeDescriptor, null, l4, l11, 0); // mv.visitLocalVariable("arg1", "Ljava/lang/Integer;", null, l4, l11, 1); register = 1; for (int i = 0; i < params.length; i++) { Class<?> clazz = params[i]; mv.visitLocalVariable("arg" + (i + 1), classToTypeDescriptor(clazz), null, l4, l11, register); register++; if (clazz == long.class || clazz == float.class || clazz == Double.class) argRegs++; } mv.visitLocalVariable("m", "Lorg/simantics/data/session/MethodInterface$Method;", null, l5, l11, argRegs + 1); mv.visitLocalVariable("args", "[Ljava/lang/Object;", null, l6, l11, argRegs + 2); mv.visitLocalVariable("result", "Lorg/simantics/data/session/MethodInterface$AsyncResult;", null, l0, l11, argRegs + 3); mv.visitLocalVariable("e", "Lorg/simantics/data/session/MethodInterface$ExecutionError;", null, l7, l3, argRegs + 4); mv.visitLocalVariable("cause", "Ljava/lang/Object;", null, l7, l3, argRegs + 5); mv.visitLocalVariable("e", "Ljava/lang/InterruptedException;", null, l10, l11, argRegs + 4); mv.visitMaxs(argRegs + 3, argRegs + 6); mv.visitEnd(); methodNumber++; } cw.visitEnd(); }
From source file:org.spongepowered.asm.util.Locals.java
License:MIT License
/** * <p>Attempts to identify available locals at an arbitrary point in the * bytecode specified by node.</p> * //from w w w .j av a 2s .c o m * <p>This method builds an approximate view of the locals available at an * arbitrary point in the bytecode by examining the following features in * the bytecode:</p> * <ul> * <li>Any available stack map frames</li> * <li>STORE opcodes</li> * <li>The local variable table</li> * </ul> * * <p>Inference proceeds by walking the bytecode from the start of the * method looking for stack frames and STORE opcodes. When either of these * is encountered, an attempt is made to cross-reference the values in the * stack map or STORE opcode with the value in the local variable table * which covers the code range. Stack map frames overwrite the entire * simulated local variable table with their own value types, STORE opcodes * overwrite only the local slot to which they pertain. Values in the * simulated locals array are spaced according to their size (unlike the * representation in FrameNode) and this TOP, NULL and UNINTITIALIZED_THIS * opcodes will be represented as null values in the simulated frame.</p> * * <p>This code does not currently simulate the prescribed JVM behaviour * where overwriting the second slot of a DOUBLE or LONG actually * invalidates the DOUBLE or LONG stored in the previous location, so we * have to hope (for now) that this behaviour isn't emitted by the compiler * or any upstream transformers. I may have to re-think this strategy if * this situation is encountered in the wild.</p> * * @param classNode ClassNode containing the method, used to initialise the * implicit "this" reference in simple methods with no stack frames * @param method MethodNode to explore * @param node Node indicating the position at which to determine the locals * state. The locals will be enumerated UP TO the specified node, so * bear in mind that if the specified node is itself a STORE opcode, * then we will be looking at the state of the locals PRIOR to its * invocation * @return A sparse array containing a view (hopefully) of the locals at the * specified location */ public static LocalVariableNode[] getLocalsAt(ClassNode classNode, MethodNode method, AbstractInsnNode node) { LocalVariableNode[] frame = new LocalVariableNode[method.maxLocals]; int local = 0, index = 0; // Initialise implicit "this" reference in non-static methods if ((method.access & Opcodes.ACC_STATIC) == 0) { frame[local++] = new LocalVariableNode("this", classNode.name, null, null, null, 0); } // Initialise method arguments for (Type argType : Type.getArgumentTypes(method.desc)) { frame[local] = new LocalVariableNode("arg" + index++, argType.toString(), null, null, null, local); local += argType.getSize(); } for (Iterator<AbstractInsnNode> iter = method.instructions.iterator(); iter.hasNext();) { AbstractInsnNode insn = iter.next(); if (insn instanceof FrameNode) { FrameNode frameNode = (FrameNode) insn; // localPos tracks the location in the frame node's locals list, which doesn't leave space for TOP entries for (int localPos = 0, framePos = 0; framePos < frame.length; framePos++, localPos++) { // Get the local at the current position in the FrameNode's locals list final Object localType = (localPos < frameNode.local.size()) ? frameNode.local.get(localPos) : null; if (localType instanceof String) { // String refers to a reference type frame[framePos] = Locals.getLocalVariableAt(classNode, method, node, framePos); } else if (localType instanceof Integer) { // Integer refers to a primitive type or other marker boolean isMarkerType = localType == Opcodes.UNINITIALIZED_THIS || localType == Opcodes.TOP || localType == Opcodes.NULL; boolean is32bitValue = localType == Opcodes.INTEGER || localType == Opcodes.FLOAT; boolean is64bitValue = localType == Opcodes.DOUBLE || localType == Opcodes.LONG; if (isMarkerType) { frame[framePos] = null; } else if (is32bitValue || is64bitValue) { frame[framePos] = Locals.getLocalVariableAt(classNode, method, node, framePos); if (is64bitValue) { framePos++; frame[framePos] = null; // TOP } } else { throw new RuntimeException( "Unrecognised locals opcode " + localType + " in locals array at position " + localPos + " in " + classNode.name + "." + method.name + method.desc); } } else if (localType == null) { frame[framePos] = null; } else { throw new RuntimeException("Invalid value " + localType + " in locals array at position " + localPos + " in " + classNode.name + "." + method.name + method.desc); } } } else if (insn instanceof VarInsnNode) { VarInsnNode varNode = (VarInsnNode) insn; frame[varNode.var] = Locals.getLocalVariableAt(classNode, method, node, varNode.var); } else if (insn == node) { break; } } return frame; }