private static <T> void appendCellValue( CellSetter<T>[] setters, boolean ignoreException, ClassWriter cw, String classType) { MethodVisitor mv; mv = cw.visitMethod(ACC_PUBLIC, "cellValue", "([CIII)V", null, null); mv.visitCode(); if (setters.length != 0) { if (ignoreException) { callCellValue(mv, classType); } else { Label l0 = new Label(); Label l1 = new Label(); Label l2 = new Label(); mv.visitTryCatchBlock(l0, l1, l2, "java/lang/Exception"); mv.visitLabel(l0); callCellValue(mv, classType); mv.visitLabel(l1); Label l3 = new Label(); mv.visitJumpInsn(GOTO, l3); mv.visitLabel(l2); mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"java/lang/Exception"}); mv.visitVarInsn(ASTORE, 5); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ILOAD, 4); mv.visitVarInsn(ALOAD, 5); mv.visitMethodInsn( INVOKEVIRTUAL, classType, "fieldError", "(ILjava/lang/Exception;)V", false); mv.visitLabel(l3); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); } } mv.visitInsn(RETURN); mv.visitMaxs(5, 6); mv.visitEnd(); }
private void writeNonAbstractMethodWrapper( ClassVisitor visitor, Type generatedType, Class<?> managedTypeClass, Method method) { Label start = new Label(); Label end = new Label(); Label handler = new Label(); MethodVisitor methodVisitor = declareMethod(visitor, method); methodVisitor.visitTryCatchBlock(start, end, handler, null); setCanCallSettersField(methodVisitor, generatedType, false); methodVisitor.visitLabel(start); invokeSuperMethod(methodVisitor, managedTypeClass, method); methodVisitor.visitLabel(end); setCanCallSettersField(methodVisitor, generatedType, true); methodVisitor.visitInsn(ARETURN); methodVisitor.visitLabel(handler); setCanCallSettersField(methodVisitor, generatedType, true); methodVisitor.visitInsn(ATHROW); methodVisitor.visitMaxs(0, 0); methodVisitor.visitEnd(); }
@Override public void visitTryCatchBlock(Label start, Label end, Label handler, String type) { _touchBranch(); super.visitTryCatchBlock(start, end, handler, type); }
@Override public void visitTryCatchBlock( final Label start, final Label end, final Label handler, final String type) { checkStartCode(); checkEndCode(); checkLabel(start, false, "start label"); checkLabel(end, false, "end label"); checkLabel(handler, false, "handler label"); checkNonDebugLabel(start); checkNonDebugLabel(end); checkNonDebugLabel(handler); if (labels.get(start) != null || labels.get(end) != null || labels.get(handler) != null) { throw new IllegalStateException("Try catch blocks must be visited before their labels"); } if (type != null) { checkInternalName(type, "type"); } super.visitTryCatchBlock(start, end, handler, type); handlers.add(start); handlers.add(end); }
public void visitTryCatchBlock(Label label, Label label1, Label label2, String s) { System.out.println( "visitTryCatchBlock(" + label + ", " + label1 + ", " + label2 + ", '" + s + "')"); methodVisitor.visitTryCatchBlock(label, label1, label2, s); }
public void visitTryCatchBlock(Label start, Label end, Label handler, String type) { visitor.visitTryCatchBlock(start, end, handler, type); }
/** * {@inheritDoc} Generation method for {@link BlockStruct} objects, by performing the following * operations: * * <ol> * <li>Fetching the global 'COMMON-LISP-USER' package * <li>Finding the {@link SymbolStruct} with the {@link BlockStruct#name} value in the fetched * 'COMMON-LISP-USER' package * <li>Initializing a try-catch block * <li>Generating each of the {@link BlockStruct#forms} inside the try block, ensuring to store * the final result into a variable * <li>Catching the expected {@link ReturnFromException} * <li>Grabbing the {@link ReturnFromException#name} {@link SymbolStruct} and comparing it for * equality against the previously fetched {@link BlockStruct#name} * <li>If the {@link SymbolStruct}s are equal, the final result variable is assigned the {@link * ReturnFromException#result} value * <li>If the {@link SymbolStruct}s are not equal, the {@link ReturnFromException} is re-thrown * </ol> * * As an example, it will transform {@code (block foo)} into the following Java code: * * <pre>{@code * private LispStruct block_1(Closure var1) { * PackageStruct var2 = PackageStruct.findPackage("COMMON-LISP-USER"); * SymbolStruct var3 = var2.findSymbol("FOO").getSymbol(); * LispStruct var4; * try { * var4 = NILStruct.INSTANCE; * } catch (ReturnFromException var7) { * SymbolStruct var6 = var7.getName(); * if(!var6.equals(var3)) { * throw var7; * } * var4 = var8.getResult(); * } * return var4; * } * }</pre> * * @param input the {@link BlockStruct} input value to generate code for * @param generatorState stateful object used to hold the current state of the code generation * process * @param methodBuilder {@link JavaMethodBuilder} used for building a Java method body * @param closureArgStore the storage location index on the stack where the {@link Closure} * argument exists */ @Override protected void generateSpecialOperator( final BlockStruct input, final GeneratorState generatorState, final JavaMethodBuilder methodBuilder, final int closureArgStore) { final MethodVisitor mv = methodBuilder.getMethodVisitor(); final int namePackageStore = methodBuilder.getNextAvailableStore(); final int nameSymbolStore = methodBuilder.getNextAvailableStore(); final SymbolStruct name = input.getName(); CodeGenerators.generateSymbol(name, generatorState, namePackageStore, nameSymbolStore); final Label tryBlockStart = new Label(); final Label tryBlockEnd = new Label(); final Label catchBlockStart = new Label(); final Label catchBlockEnd = new Label(); mv.visitTryCatchBlock( tryBlockStart, tryBlockEnd, catchBlockStart, GenerationConstants.RETURN_FROM_EXCEPTION_NAME); // Start 'try{}' mv.visitLabel(tryBlockStart); final PrognStruct forms = input.getForms(); codeGenerator.generate(forms, generatorState); final int resultStore = methodBuilder.getNextAvailableStore(); mv.visitVarInsn(Opcodes.ASTORE, resultStore); // End 'try{}' mv.visitLabel(tryBlockEnd); mv.visitJumpInsn(Opcodes.GOTO, catchBlockEnd); // Start 'catch(ReturnFromException rfe){}' mv.visitLabel(catchBlockStart); final int returnFromExceptionStore = methodBuilder.getNextAvailableStore(); mv.visitVarInsn(Opcodes.ASTORE, returnFromExceptionStore); mv.visitVarInsn(Opcodes.ALOAD, returnFromExceptionStore); mv.visitMethodInsn( Opcodes.INVOKEVIRTUAL, GenerationConstants.RETURN_FROM_EXCEPTION_NAME, GenerationConstants.RETURN_FROM_EXCEPTION_GET_NAME_METHOD_NAME, GenerationConstants.RETURN_FROM_EXCEPTION_GET_NAME_METHOD_DESC, false); final int returnFromExceptionNameStore = methodBuilder.getNextAvailableStore(); mv.visitVarInsn(Opcodes.ASTORE, returnFromExceptionNameStore); mv.visitVarInsn(Opcodes.ALOAD, returnFromExceptionNameStore); mv.visitVarInsn(Opcodes.ALOAD, nameSymbolStore); mv.visitMethodInsn( Opcodes.INVOKEVIRTUAL, GenerationConstants.JAVA_OBJECT_NAME, GenerationConstants.JAVA_EQUALS_METHOD_NAME, GenerationConstants.JAVA_EQUALS_METHOD_DESC, false); final Label rethrowException = new Label(); mv.visitJumpInsn(Opcodes.IFEQ, rethrowException); mv.visitVarInsn(Opcodes.ALOAD, returnFromExceptionStore); mv.visitMethodInsn( Opcodes.INVOKEVIRTUAL, GenerationConstants.RETURN_FROM_EXCEPTION_NAME, GenerationConstants.RETURN_FROM_EXCEPTION_GET_RESULT_METHOD_NAME, GenerationConstants.RETURN_FROM_EXCEPTION_GET_RESULT_METHOD_DESC, false); mv.visitVarInsn(Opcodes.ASTORE, resultStore); mv.visitJumpInsn(Opcodes.GOTO, catchBlockEnd); mv.visitLabel(rethrowException); mv.visitVarInsn(Opcodes.ALOAD, returnFromExceptionStore); mv.visitInsn(Opcodes.ATHROW); // End 'catch(ReturnFromException rfe){}' mv.visitLabel(catchBlockEnd); mv.visitVarInsn(Opcodes.ALOAD, resultStore); mv.visitInsn(Opcodes.ARETURN); }