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);
 }
Example #6
0
 public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {
   visitor.visitTryCatchBlock(start, end, handler, type);
 }
Example #7
0
  /**
   * {@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);
  }