List of usage examples for org.objectweb.asm MethodVisitor visitTableSwitchInsn
public void visitTableSwitchInsn(final int min, final int max, final Label dflt, final Label... labels)
From source file:org.jadira.reflection.access.asm.AsmClassAccess.java
License:Apache License
private static void enhanceForInvokeMethod(ClassVisitor cw, String accessClassNm, String clazzNm, Method[] methods) {//from www. j a v a2 s .co m MethodVisitor mv = cw.visitMethod(ACC_PUBLIC + ACC_VARARGS, "invokeMethod", "(Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;", null, null); mv.visitCode(); if (methods.length > 0) { mv.visitVarInsn(ALOAD, 1); mv.visitTypeInsn(CHECKCAST, clazzNm); mv.visitVarInsn(ASTORE, 4); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 2); mv.visitMethodInsn(INVOKESPECIAL, "org/jadira/reflection/access/asm/AsmClassAccess", "getMethodIndex", "(Ljava/lang/reflect/Method;)I"); mv.visitVarInsn(ISTORE, 5); mv.visitVarInsn(ILOAD, 5); Label[] labels = constructLabels(methods); Label defaultLabel = new Label(); mv.visitTableSwitchInsn(0, labels.length - 1, defaultLabel, labels); for (int i = 0; i < labels.length; i++) { Method method = methods[i]; Class<?>[] parameterTypes = method.getParameterTypes(); mv.visitLabel(labels[i]); if (i == 0) { mv.visitFrame(F_APPEND, 1, new Object[] { clazzNm }, 0, null); } else { mv.visitFrame(F_SAME, 0, null, 0, null); } mv.visitVarInsn(ALOAD, 4); StringBuilder methodDescriptor = new StringBuilder("("); for (int parameterIdx = 0; parameterIdx < parameterTypes.length; parameterIdx++) { Type type = Type.getType(parameterTypes[parameterIdx]); mv.visitVarInsn(ALOAD, 3); mv.visitIntInsn(BIPUSH, parameterIdx); mv.visitInsn(AALOAD); switch (type.getSort()) { case Type.BOOLEAN: mv.visitTypeInsn(CHECKCAST, "java/lang/Boolean"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z"); break; case Type.BYTE: mv.visitTypeInsn(CHECKCAST, "java/lang/Byte"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Byte", "byteValue", "()B"); break; case Type.CHAR: mv.visitTypeInsn(CHECKCAST, "java/lang/Character"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Character", "charValue", "()C"); break; case Type.SHORT: mv.visitTypeInsn(CHECKCAST, "java/lang/Short"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Short", "shortValue", "()S"); break; case Type.INT: mv.visitTypeInsn(CHECKCAST, "java/lang/Integer"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Integer", "intValue", "()I"); break; case Type.FLOAT: mv.visitTypeInsn(CHECKCAST, "java/lang/Float"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Float", "floatValue", "()F"); break; case Type.LONG: mv.visitTypeInsn(CHECKCAST, "java/lang/Long"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Long", "longValue", "()J"); break; case Type.DOUBLE: mv.visitTypeInsn(CHECKCAST, "java/lang/Double"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Double", "doubleValue", "()D"); break; case Type.ARRAY: mv.visitTypeInsn(CHECKCAST, type.getDescriptor()); break; case Type.OBJECT: mv.visitTypeInsn(CHECKCAST, type.getInternalName()); break; } methodDescriptor.append(type.getDescriptor()); } methodDescriptor.append(')'); methodDescriptor.append(Type.getDescriptor(method.getReturnType())); mv.visitMethodInsn(INVOKEVIRTUAL, clazzNm, method.getName(), methodDescriptor.toString()); switch (Type.getType(method.getReturnType()).getSort()) { case Type.VOID: mv.visitInsn(ACONST_NULL); break; case Type.BOOLEAN: mv.visitMethodInsn(INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;"); break; case Type.BYTE: mv.visitMethodInsn(INVOKESTATIC, "java/lang/Byte", "valueOf", "(B)Ljava/lang/Byte;"); break; case Type.CHAR: mv.visitMethodInsn(INVOKESTATIC, "java/lang/Character", "valueOf", "(C)Ljava/lang/Character;"); break; case Type.SHORT: mv.visitMethodInsn(INVOKESTATIC, "java/lang/Short", "valueOf", "(S)Ljava/lang/Short;"); break; case Type.INT: mv.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;"); break; case Type.FLOAT: mv.visitMethodInsn(INVOKESTATIC, "java/lang/Float", "valueOf", "(F)Ljava/lang/Float;"); break; case Type.LONG: mv.visitMethodInsn(INVOKESTATIC, "java/lang/Long", "valueOf", "(J)Ljava/lang/Long;"); break; case Type.DOUBLE: mv.visitMethodInsn(INVOKESTATIC, "java/lang/Double", "valueOf", "(D)Ljava/lang/Double;"); break; } mv.visitInsn(ARETURN); } mv.visitLabel(defaultLabel); mv.visitFrame(F_SAME, 0, null, 0, null); } enhanceForThrowingException(mv, IllegalArgumentException.class, "Method not found", "Ljava/lang/Object;", ALOAD, 2); mv.visitMaxs(8, 6); mv.visitEnd(); }
From source file:org.jupiter.common.util.FastMethodAccessor.java
License:Apache License
private static FastMethodAccessor create(Class<?> type) { ArrayList<Method> methods = Lists.newArrayList(); boolean isInterface = type.isInterface(); if (!isInterface) { Class nextClass = type;/*from w ww . j av a2 s .c om*/ while (nextClass != Object.class) { addDeclaredMethodsToList(nextClass, methods); nextClass = nextClass.getSuperclass(); } } else { recursiveAddInterfaceMethodsToList(type, methods); } int n = methods.size(); String[] methodNames = new String[n]; Class<?>[][] parameterTypes_s = new Class[n][]; Class<?>[] returnTypes = new Class[n]; for (int i = 0; i < n; i++) { Method method = methods.get(i); methodNames[i] = method.getName(); parameterTypes_s[i] = method.getParameterTypes(); returnTypes[i] = method.getReturnType(); } String className = type.getName(); String accessorClassName = className + "_FastMethodAccessor"; String accessorClassNameInternal = accessorClassName.replace('.', '/'); String classNameInternal = className.replace('.', '/'); String superClassNameInternal = FastMethodAccessor.class.getName().replace('.', '/'); ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); MethodVisitor mv; cw.visit(V1_1, ACC_PUBLIC + ACC_SUPER, accessorClassNameInternal, null, superClassNameInternal, null); // ? { mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, superClassNameInternal, "<init>", "()V", false); mv.visitInsn(RETURN); mv.visitMaxs(0, 0); mv.visitEnd(); } // : public Object invoke(Object obj, int methodIndex, Object... args); { mv = cw.visitMethod(ACC_PUBLIC + ACC_VARARGS, "invoke", "(Ljava/lang/Object;I[Ljava/lang/Object;)Ljava/lang/Object;", null, null); mv.visitCode(); if (n > 0) { // ?? obj (Class<?> type) mv.visitVarInsn(ALOAD, 1); mv.visitTypeInsn(CHECKCAST, classNameInternal); mv.visitVarInsn(ASTORE, 4); // ? switch ? mv.visitVarInsn(ILOAD, 2); Label[] labels = new Label[n]; for (int i = 0; i < n; i++) { labels[i] = new Label(); } Label defaultLabel = new Label(); // the default handler block mv.visitTableSwitchInsn(0, labels.length - 1, defaultLabel, labels); StringBuilder buf = new StringBuilder(128); for (int i = 0; i < n; i++) { mv.visitLabel(labels[i]); if (i == 0) { mv.visitFrame(Opcodes.F_APPEND, 1, new Object[] { classNameInternal }, 0, null); } else { mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); } mv.visitVarInsn(ALOAD, 4); buf.setLength(0); buf.append('('); Class<?>[] parameterTypes = parameterTypes_s[i]; Class<?> returnType = returnTypes[i]; for (int p_index = 0; p_index < parameterTypes.length; p_index++) { mv.visitVarInsn(ALOAD, 3); mv.visitIntInsn(BIPUSH, p_index); mv.visitInsn(AALOAD); // ?, (?) Type p_type = Type.getType(parameterTypes[p_index]); switch (p_type.getSort()) { case Type.BOOLEAN: mv.visitTypeInsn(CHECKCAST, "java/lang/Boolean"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z", false); break; case Type.BYTE: mv.visitTypeInsn(CHECKCAST, "java/lang/Byte"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Byte", "byteValue", "()B", false); break; case Type.CHAR: mv.visitTypeInsn(CHECKCAST, "java/lang/Character"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Character", "charValue", "()C", false); break; case Type.SHORT: mv.visitTypeInsn(CHECKCAST, "java/lang/Short"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Short", "shortValue", "()S", false); break; case Type.INT: mv.visitTypeInsn(CHECKCAST, "java/lang/Integer"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Integer", "intValue", "()I", false); break; case Type.FLOAT: mv.visitTypeInsn(CHECKCAST, "java/lang/Float"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Float", "floatValue", "()F", false); break; case Type.LONG: mv.visitTypeInsn(CHECKCAST, "java/lang/Long"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Long", "longValue", "()J", false); break; case Type.DOUBLE: mv.visitTypeInsn(CHECKCAST, "java/lang/Double"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Double", "doubleValue", "()D", false); break; case Type.ARRAY: mv.visitTypeInsn(CHECKCAST, p_type.getDescriptor()); break; case Type.OBJECT: mv.visitTypeInsn(CHECKCAST, p_type.getInternalName()); break; } buf.append(p_type.getDescriptor()); } buf.append(')').append(Type.getDescriptor(returnType)); // ??, ??? if (isInterface) { mv.visitMethodInsn(INVOKEINTERFACE, classNameInternal, methodNames[i], buf.toString(), true); } else if (Modifier.isStatic(methods.get(i).getModifiers())) { mv.visitMethodInsn(INVOKESTATIC, classNameInternal, methodNames[i], buf.toString(), false); } else { mv.visitMethodInsn(INVOKEVIRTUAL, classNameInternal, methodNames[i], buf.toString(), false); } Type r_type = Type.getType(returnType); switch (r_type.getSort()) { case Type.VOID: mv.visitInsn(ACONST_NULL); break; case Type.BOOLEAN: mv.visitMethodInsn(INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;", false); break; case Type.BYTE: mv.visitMethodInsn(INVOKESTATIC, "java/lang/Byte", "valueOf", "(B)Ljava/lang/Byte;", false); break; case Type.CHAR: mv.visitMethodInsn(INVOKESTATIC, "java/lang/Character", "valueOf", "(C)Ljava/lang/Character;", false); break; case Type.SHORT: mv.visitMethodInsn(INVOKESTATIC, "java/lang/Short", "valueOf", "(S)Ljava/lang/Short;", false); break; case Type.INT: mv.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;", false); break; case Type.FLOAT: mv.visitMethodInsn(INVOKESTATIC, "java/lang/Float", "valueOf", "(F)Ljava/lang/Float;", false); break; case Type.LONG: mv.visitMethodInsn(INVOKESTATIC, "java/lang/Long", "valueOf", "(J)Ljava/lang/Long;", false); break; case Type.DOUBLE: mv.visitMethodInsn(INVOKESTATIC, "java/lang/Double", "valueOf", "(D)Ljava/lang/Double;", false); break; } mv.visitInsn(ARETURN); } mv.visitLabel(defaultLabel); // default ?? mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); } // throw exception (method not found) mv.visitTypeInsn(NEW, "java/lang/IllegalArgumentException"); mv.visitInsn(DUP); mv.visitTypeInsn(NEW, "java/lang/StringBuilder"); mv.visitInsn(DUP); mv.visitLdcInsn("method not found: "); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "(Ljava/lang/String;)V", false); mv.visitVarInsn(ILOAD, 2); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(I)Ljava/lang/StringBuilder;", false); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;", false); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/IllegalArgumentException", "<init>", "(Ljava/lang/String;)V", false); mv.visitInsn(ATHROW); mv.visitMaxs(0, 0); mv.visitEnd(); } cw.visitEnd(); byte[] bytes = cw.toByteArray(); AccessorClassLoader loader = AccessorClassLoader.get(type); Class<?> accessorClass = loader.defineClass(accessorClassName, bytes); try { FastMethodAccessor accessor = (FastMethodAccessor) accessorClass.newInstance(); accessor.methodNames = methodNames; accessor.parameterTypes_s = parameterTypes_s; return accessor; } catch (Throwable t) { throw new RuntimeException("Error constructing method access class: " + accessorClass, t); } }
From source file:org.mbte.groovypp.compiler.asm.VisitTableSwitchInsn.java
License:Apache License
public void visit(MethodVisitor mv) { mv.visitTableSwitchInsn(min, max, dflt, labels); }
From source file:org.openquark.cal.internal.javamodel.AsmJavaBytecodeGenerator.java
License:Open Source License
private static boolean encodeSwitchStatement(JavaStatement.SwitchStatement switchStatement, GenerationContext context) throws JavaGenerationException { MethodVisitor mv = context.getMethodVisitor(); // Append the instructions to evaluate the condition, leaving the result on the operand stack. JavaExpression condition = switchStatement.getCondition(); encodeExpr(condition, context);// w w w. jav a2 s. c om // Follow (what seems to be) javac's rule for deciding between a lookup switch and a table switch: // Use a table switch if allowed by maxTableSize, where // maxTableSize = (# cases - 2) * 5 , (# cases) doesn't include the default. // // eg. if there are 2 case alternatives (+ default): // maxTableSize = ((2 - 2) * 5) = 0, so always use a lookup switch. // if there are cases {1, 2, 3, 4, 15}: // maxTableSize = ((5 - 2) * 5) = 15. A table would contain 15 entries {1, 2, .., 15}, so use a table switch. // if there are cases {1, 2, 3, 4, 16}: // A table would contain 16 entries {1, 2, .., 16}, so use a lookup switch. List<IntCaseGroup> caseGroups = switchStatement.getCaseGroups(); int nTotalCases = 0; // Calculate the first and last values. int firstValue = Integer.MAX_VALUE; int lastValue = Integer.MIN_VALUE; for (int caseN = 0; caseN < caseGroups.size(); ++caseN) { SwitchStatement.IntCaseGroup switchCaseGroup = caseGroups.get(caseN); for (int i = 0, nCaseLabels = switchCaseGroup.getNCaseLabels(); i < nCaseLabels; i++) { nTotalCases++; int caseLabel = switchCaseGroup.getNthCaseLabel(i); if (firstValue > caseLabel) { firstValue = caseLabel; } if (lastValue < caseLabel) { lastValue = caseLabel; } } } if (nTotalCases == 0) { // If the switch statement contains no cases, javac's behaviour is to generate a pop instruction // to pop the condition value off the operand stack. mv.visitInsn(Opcodes.POP); } else { int nSpannedCases = lastValue - firstValue + 1; int maxTableSize = (nTotalCases - 2) * 5; boolean useTableSwitch = !(nSpannedCases > maxTableSize); // Create the default label and declare the other case labels. Label defaultLabel = new Label(); // (SwitchStatement.IntCaseGroup->Label) A map from case group to label. Map<IntCaseGroup, Label> caseGroupToLabelMap = new HashMap<IntCaseGroup, Label>(); if (!useTableSwitch) { // A lookup switch. Each case match gets its own label. // Map from case label to label, sorted by case label. SortedMap<Integer, Label> caseLabelToLabelMap = new TreeMap<Integer, Label>(); // A count of the number of case labels. int nCaseLabels = 0; // Create the labels, and populate the map. for (int caseN = 0; caseN < caseGroups.size(); ++caseN) { SwitchStatement.IntCaseGroup switchCaseGroup = caseGroups.get(caseN); // The label for this case group. Label label = new Label(); caseGroupToLabelMap.put(switchCaseGroup, label); for (int i = 0, nCaseGroupLabels = switchCaseGroup .getNCaseLabels(); i < nCaseGroupLabels; i++) { int caseLabel = switchCaseGroup.getNthCaseLabel(i); caseLabelToLabelMap.put(Integer.valueOf(caseLabel), label); nCaseLabels++; } } // Create the array for case matches and the corresponding labels. int[] caseMatches = new int[nCaseLabels]; Label[] labels = new Label[nCaseLabels]; int index = 0; for (final Map.Entry<Integer, Label> entry : caseLabelToLabelMap.entrySet()) { Integer caseLabelInteger = entry.getKey(); caseMatches[index] = caseLabelInteger.intValue(); labels[index] = entry.getValue(); index++; } // Visit the lookup switch instruction. mv.visitLookupSwitchInsn(defaultLabel, caseMatches, labels); } else { // A table switch // The cases which aren't given should be set to the default case. Label[] labels = new Label[nSpannedCases]; // Initially set all elements to the default label, if they won't all be set to something else later. if (nSpannedCases != nTotalCases) { Arrays.fill(labels, defaultLabel); } // For each switch case provided, create a new label. for (int caseN = 0; caseN < caseGroups.size(); ++caseN) { SwitchStatement.IntCaseGroup switchCaseGroup = caseGroups.get(caseN); // The label for this case group. Label label = new Label(); caseGroupToLabelMap.put(switchCaseGroup, label); for (int i = 0, nCaseGroupLabels = switchCaseGroup .getNCaseLabels(); i < nCaseGroupLabels; i++) { int caseLabel = switchCaseGroup.getNthCaseLabel(i); int labelArrayIndex = caseLabel - firstValue; labels[labelArrayIndex] = label; } } // Visit the table switch instruction. mv.visitTableSwitchInsn(firstValue, lastValue, defaultLabel, labels); } // Iterate over the cases. for (int caseN = 0; caseN < caseGroups.size(); ++caseN) { SwitchStatement.IntCaseGroup switchCase = caseGroups.get(caseN); JavaStatement caseStatementGroup = switchCase.getStatement(); // Add a local scope.. GenerationContext innerContext = new GenerationContext(context); // Get the label to visit.. Label labelToVisit = caseGroupToLabelMap.get(switchCase); //mark the location of the code for the i'th case. mv.visitLabel(labelToVisit); // get the instructions for the case statement. boolean caseStatementIsTerminating = encodeStatement(caseStatementGroup, innerContext); context.addJumpReturnLabelInfo(innerContext); // We don't (yet) handle non-terminating code in a case block. if (!caseStatementIsTerminating) { throw new JavaGenerationException("Can't (yet) handle non-terminating code in a case block."); } } JavaStatement defaultStatementGroup = switchStatement.getDefaultStatement(); //mark the location of the default statements (even if there are none, this means just progress to the next instruction..) mv.visitLabel(defaultLabel); if (defaultStatementGroup != null) { // Add a local scope.. GenerationContext innerContext = new GenerationContext(context); boolean defaultStatementIsTerminating = encodeStatement(defaultStatementGroup, innerContext); context.addJumpReturnLabelInfo(innerContext); // We don't (yet) handle non-terminating code in a case block. if (!defaultStatementIsTerminating) { throw new JavaGenerationException("Can't (yet) handle non-terminating code in a case block."); } } } // Note: we should add GOTO instructions to each case block to jump to after the switch statement if necessary. // But for now it's not necessary since all cases are terminated. boolean isTerminating = true; return isTerminating; }
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;// w w w . j a v a2s .c om 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.springframework.migrationanalyzer.contributions.bytecode.DelegatingMethodVisitor.java
License:Apache License
@Override public void visitTableSwitchInsn(int min, int max, Label dflt, Label[] labels) { for (MethodVisitor delegate : this.delegates) { delegate.visitTableSwitchInsn(min, max, dflt, labels); }//from w w w. j ava2 s .c om }
From source file:org.xnio.http.tool.Generator.java
License:Open Source License
public static void main(String[] args) { MethodVisitor mv = null; mv.visitCode();/*from w ww . ja v a 2 s .c o m*/ final Label unknownMethod = new Label(); final Label readMethod = new Label(); final Label readUri = new Label(); final Label readUriSubsequent = new Label(); final Label readProto = new Label(); final Label readProtoSubsequent = new Label(); final Label readHeaders = new Label(); final Label matchC = new Label(); final Label matchCO = new Label(); final Label matchCON = new Label(); final Label matchCONN = new Label(); final Label matchCONNE = new Label(); final Label matchCONNEC = new Label(); final Label matchCONNECT = new Label(); final Label matchD = new Label(); final Label matchDE = new Label(); final Label matchDEL = new Label(); final Label matchDELE = new Label(); final Label matchDELET = new Label(); final Label matchDELETE = new Label(); final Label matchG = new Label(); final Label matchGE = new Label(); final Label matchGET = new Label(); final Label matchH = new Label(); final Label matchHE = new Label(); final Label matchHEA = new Label(); final Label matchHEAD = new Label(); final Label matchO = new Label(); final Label matchOP = new Label(); final Label matchOPT = new Label(); final Label matchOPTI = new Label(); final Label matchOPTIO = new Label(); final Label matchOPTION = new Label(); final Label matchOPTIONS = new Label(); final Label matchP = new Label(); final Label matchPO = new Label(); final Label matchPOS = new Label(); final Label matchPOST = new Label(); final Label matchPU = new Label(); final Label matchPUT = new Label(); final Label matchT = new Label(); final Label matchTR = new Label(); final Label matchTRA = new Label(); final Label matchTRAC = new Label(); final Label matchTRACE = new Label(); final Label doReturn = new Label(); final Label badState = new Label(); final Label badRequest = new Label(); mv.visitFieldInsn(GETFIELD, READ_LISTENER, "state", "I"); final Label[] states = { readMethod, matchC, matchCO, matchCON, matchCONN, matchCONNE, matchCONNEC, matchCONNECT, matchD, matchDE, matchDEL, matchDELE, matchDELET, matchDELETE, matchG, matchGE, matchGET, matchH, matchHE, matchHEA, matchHEAD, matchO, matchOP, matchOPT, matchOPTI, matchOPTIO, matchOPTION, matchOPTIONS, matchP, matchPO, matchPOS, matchPOST, matchPU, matchPUT, matchT, matchTR, matchTRA, matchTRAC, matchTRACE, unknownMethod, readUri, readUriSubsequent, readProto, readProtoSubsequent, readHeaders, }; mv.visitTableSwitchInsn(0, states.length - 1, badState, states); int c = 0; // Read an HTTP method mv.visitLabel(readMethod); visitRead(mv); final Label exitReadMethod = new Label(); mv.visitLookupSwitchInsn(unknownMethod, new int[] { -1, 'C', 'D', 'G', 'H', 'O', 'P', 'T' }, new Label[] { exitReadMethod, matchC, matchD, matchG, matchH, matchO, matchP, matchT }); mv.visitLabel(exitReadMethod); mv.visitIntInsn(BIPUSH, c++); mv.visitLabel(doReturn); mv.visitFieldInsn(PUTFIELD, READ_LISTENER, "state", "I"); mv.visitIntInsn(BIPUSH, 1); mv.visitInsn(IRETURN); mv.visitLabel(badRequest); mv.visitIntInsn(BIPUSH, 0); mv.visitInsn(IRETURN); // match CONNECT doFirstStep(mv, c++, 'C', 'O', readUri, doReturn, unknownMethod, matchC, matchCO, badRequest); doSimpleStep(mv, c++, "CO", 'N', readUri, doReturn, unknownMethod, matchCO, matchCON, badRequest); doSimpleStep(mv, c++, "CON", 'N', readUri, doReturn, unknownMethod, matchCON, matchCONN, badRequest); doSimpleStep(mv, c++, "CONN", 'E', readUri, doReturn, unknownMethod, matchCONN, matchCONNE, badRequest); doSimpleStep(mv, c++, "CONNE", 'C', readUri, doReturn, unknownMethod, matchCONNE, matchCONNEC, badRequest); doSimpleStep(mv, c++, "CONNEC", 'T', readUri, doReturn, unknownMethod, matchCONNEC, matchCONNECT, badRequest); doFinalStep(mv, c++, "CONNECT", readUri, doReturn, unknownMethod, matchCONNECT, badRequest); // match DELETE doFirstStep(mv, c++, 'D', 'E', readUri, doReturn, unknownMethod, matchD, matchDE, badRequest); doSimpleStep(mv, c++, "DE", 'L', readUri, doReturn, unknownMethod, matchDE, matchDEL, badRequest); doSimpleStep(mv, c++, "DEL", 'E', readUri, doReturn, unknownMethod, matchDEL, matchDELE, badRequest); doSimpleStep(mv, c++, "DELE", 'T', readUri, doReturn, unknownMethod, matchDELE, matchDELET, badRequest); doSimpleStep(mv, c++, "DELET", 'E', readUri, doReturn, unknownMethod, matchDELET, matchDELETE, badRequest); doFinalStep(mv, c++, "DELETE", readUri, doReturn, unknownMethod, matchDELETE, badRequest); // match GET doFirstStep(mv, c++, 'G', 'E', readUri, doReturn, unknownMethod, matchG, matchGE, badRequest); doSimpleStep(mv, c++, "GE", 'T', readUri, doReturn, unknownMethod, matchGE, matchGET, badRequest); doFinalStep(mv, c++, "GET", readUri, doReturn, unknownMethod, matchGET, badRequest); // match HEAD doFirstStep(mv, c++, 'H', 'E', readUri, doReturn, unknownMethod, matchH, matchHE, badRequest); doSimpleStep(mv, c++, "HE", 'A', readUri, doReturn, unknownMethod, matchHE, matchHEA, badRequest); doSimpleStep(mv, c++, "HEA", 'D', readUri, doReturn, unknownMethod, matchHEA, matchHEAD, badRequest); doFinalStep(mv, c++, "HEAD", readUri, doReturn, unknownMethod, matchHEAD, badRequest); // match OPTIONS doFirstStep(mv, c++, 'O', 'P', readUri, doReturn, unknownMethod, matchO, matchOP, badRequest); doSimpleStep(mv, c++, "OP", 'T', readUri, doReturn, unknownMethod, matchOP, matchOPT, badRequest); doSimpleStep(mv, c++, "OPT", 'I', readUri, doReturn, unknownMethod, matchOPT, matchOPTI, badRequest); doSimpleStep(mv, c++, "OPTI", 'O', readUri, doReturn, unknownMethod, matchOPTI, matchOPTIO, badRequest); doSimpleStep(mv, c++, "OPTIO", 'N', readUri, doReturn, unknownMethod, matchOPTIO, matchOPTION, badRequest); doSimpleStep(mv, c++, "OPTION", 'S', readUri, doReturn, unknownMethod, matchOPTION, matchOPTIONS, badRequest); doFinalStep(mv, c++, "OPTIONS", readUri, doReturn, unknownMethod, matchOPTIONS, badRequest); // match POST or PUT doTwoStep(mv, c++, 'P', 'O', 'U', readUri, doReturn, unknownMethod, matchP, matchPO, matchPU, badRequest); // match POST doSimpleStep(mv, c++, "PO", 'S', readUri, doReturn, unknownMethod, matchPO, matchPOS, badRequest); doSimpleStep(mv, c++, "POS", 'T', readUri, doReturn, unknownMethod, matchPOS, matchPOST, badRequest); doFinalStep(mv, c++, "POST", readUri, doReturn, unknownMethod, matchPOST, badRequest); // match PUT doSimpleStep(mv, c++, "PU", 'T', readUri, doReturn, unknownMethod, matchPU, matchPUT, badRequest); doFinalStep(mv, c++, "PUT", readUri, doReturn, unknownMethod, matchPUT, badRequest); // match TRACE doFirstStep(mv, c++, 'T', 'R', readUri, doReturn, unknownMethod, matchT, matchTR, badRequest); doSimpleStep(mv, c++, "TR", 'A', readUri, doReturn, unknownMethod, matchTR, matchTRA, badRequest); doSimpleStep(mv, c++, "TRA", 'C', readUri, doReturn, unknownMethod, matchTRA, matchTRAC, badRequest); doSimpleStep(mv, c++, "TRAC", 'E', readUri, doReturn, unknownMethod, matchTRAC, matchTRACE, badRequest); doFinalStep(mv, c++, "TRACE", readUri, doReturn, unknownMethod, matchTRACE, badRequest); // build method from string using string builder mv.visitLabel(unknownMethod); visitRead(mv); mv.visitInsn(DUP); mv.visitMethodInsn(INVOKESTATIC, "java/lang/Character", "isControl", "(C)Z"); mv.visitJumpInsn(IFNE, badRequest); final Label doAppendMethod = new Label(); final Label exitReadMethodBuild = new Label(); final Label prepareReadUri = new Label(); mv.visitLookupSwitchInsn(doAppendMethod, new int[] { -1, ' ' }, new Label[] { exitReadMethodBuild, prepareReadUri }); mv.visitLabel(doAppendMethod); mv.visitVarInsn(ALOAD, STRING_BUILDER); mv.visitVarInsn(ILOAD, CH); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(C)Ljava/lang/StringBuilder;"); mv.visitJumpInsn(GOTO, unknownMethod); mv.visitLabel(exitReadMethodBuild); // ran out of buffer mv.visitIntInsn(BIPUSH, c++); mv.visitJumpInsn(GOTO, doReturn); mv.visitLabel(prepareReadUri); // finished reading method, clear builder and move on to URI mv.visitVarInsn(ALOAD, STRING_BUILDER); mv.visitInsn(DUP); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;"); mv.visitFieldInsn(PUTFIELD, READ_LISTENER, "method", "Ljava/lang/String;"); mv.visitIntInsn(BIPUSH, 0); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "setLength", "(I)V"); //mv.visitJumpInsn(GOTO, readUri); // fall through // read URI mv.visitLabel(readUri); visitRead(mv); mv.visitInsn(DUP); mv.visitMethodInsn(INVOKESTATIC, "java/lang/Character", "isControl", "(C)Z"); mv.visitJumpInsn(IFNE, badRequest); final Label doAppendUri = new Label(); final Label exitReadUri = new Label(); mv.visitLookupSwitchInsn(doAppendUri, new int[] { -1, ' ' }, new Label[] { exitReadUri, readUri }); mv.visitLabel(exitReadUri); mv.visitIntInsn(BIPUSH, c++); mv.visitJumpInsn(GOTO, doReturn); mv.visitLabel(doAppendUri); mv.visitVarInsn(ALOAD, STRING_BUILDER); mv.visitVarInsn(ILOAD, CH); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(C)Ljava/lang/StringBuilder;"); //mv.visitJumpInsn(GOTO, readUriSubsequent); // fall through mv.visitLabel(readUriSubsequent); visitRead(mv); mv.visitInsn(DUP); mv.visitMethodInsn(INVOKESTATIC, "java/lang/Character", "isControl", "(C)Z"); mv.visitJumpInsn(IFNE, badRequest); final Label exitReadUriSubsequent = new Label(); final Label prepareReadProtocol = new Label(); mv.visitLookupSwitchInsn(doAppendUri, new int[] { -1, ' ', }, new Label[] { exitReadUriSubsequent, prepareReadProtocol }); mv.visitLabel(exitReadUriSubsequent); mv.visitIntInsn(BIPUSH, c++); mv.visitJumpInsn(GOTO, doReturn); mv.visitLabel(prepareReadProtocol); mv.visitVarInsn(ALOAD, STRING_BUILDER); mv.visitInsn(DUP); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;"); mv.visitFieldInsn(PUTFIELD, READ_LISTENER, "requestUri", "Ljava/lang/String;"); mv.visitIntInsn(BIPUSH, 0); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "setLength", "(I)V"); //mv.visitJumpInsn(GOTO, readProto); // fall through mv.visitLabel(readProto); visitRead(mv); final Label doAppendProto = new Label(); final Label exitReadProto = new Label(); mv.visitLookupSwitchInsn(doAppendProto, new int[] { -1, ' ' }, new Label[] { exitReadProto, readProto }); mv.visitLabel(exitReadProto); mv.visitIntInsn(BIPUSH, c++); mv.visitJumpInsn(GOTO, doReturn); mv.visitLabel(doAppendProto); mv.visitVarInsn(ILOAD, CH); mv.visitMethodInsn(INVOKESTATIC, "java/lang/Character", "isControl", "(C)Z"); mv.visitJumpInsn(IFNE, badRequest); mv.visitVarInsn(ALOAD, STRING_BUILDER); mv.visitVarInsn(ILOAD, CH); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(C)Ljava/lang/StringBuilder;"); //mv.visitJumpInsn(GOTO, readProtoSubsequent); // fall through mv.visitLabel(readProtoSubsequent); visitRead(mv); final Label exitReadProtoSubsequent = new Label(); final Label prepareReadHeaders = new Label(); mv.visitLookupSwitchInsn(doAppendProto, new int[] { -1, '\r', ' ' }, new Label[] { exitReadProtoSubsequent, prepareReadHeaders, badRequest }); mv.visitLabel(exitReadProtoSubsequent); mv.visitIntInsn(BIPUSH, c++); mv.visitJumpInsn(GOTO, doReturn); mv.visitLabel(prepareReadHeaders); // done! mv.visitMaxs(); }