Example usage for org.objectweb.asm MethodVisitor visitLabel

List of usage examples for org.objectweb.asm MethodVisitor visitLabel

Introduction

In this page you can find the example usage for org.objectweb.asm MethodVisitor visitLabel.

Prototype

public void visitLabel(final Label label) 

Source Link

Document

Visits a label.

Usage

From source file:de.zib.sfs.instrument.FileChannelImplAdapter.java

License:BSD License

protected void wrapFileChannelImplMethod(int access, String name, Type returnType, Type[] argumentTypes,
        String signature, String[] exceptions, String callbackName, String oppositeCallbackName,
        Type additionalCallbackArgumentType, int bufferArgumentTypeIndex, boolean isTransferMethod) {
    String methodDescriptor = Type.getMethodDescriptor(returnType, argumentTypes);

    // <access> <returnType> <name>(<argumentTypes> arguments) throws
    // <exceptions> {
    MethodVisitor mv = this.cv.visitMethod(access, name, methodDescriptor, signature, exceptions);
    mv.visitCode();/* w w  w.j  a v a  2  s.  c om*/

    // if (isInstrumentationActive()) {
    isInstrumentationActive(mv);
    Label instrumentationActiveLabel = new Label();
    mv.visitJumpInsn(Opcodes.IFEQ, instrumentationActiveLabel);

    // return methodPrefix<name>(arguments);
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    int argumentIndex = 1;
    for (Type argument : argumentTypes) {
        mv.visitVarInsn(argument.getOpcode(Opcodes.ILOAD), argumentIndex);
        argumentIndex += argument.getSize();
    }
    mv.visitMethodInsn(Opcodes.INVOKESPECIAL, this.instrumentedTypeInternalName, this.methodPrefix + name,
            methodDescriptor, false);
    mv.visitInsn(returnType.getOpcode(Opcodes.IRETURN));

    // }
    mv.visitLabel(instrumentationActiveLabel);

    // setInstrumentationActive(true);
    setInstrumentationActive(mv, true);

    // we need to set the instrumentation flag for the source/destination
    // buffer(s) as well

    // boolean bufferInstrumentationActive = false;
    int bufferInstrumentationActiveIndex = 1;
    for (Type argument : argumentTypes) {
        bufferInstrumentationActiveIndex += argument.getSize();
    }
    mv.visitInsn(Opcodes.ICONST_0);
    mv.visitVarInsn(Opcodes.ISTORE, bufferInstrumentationActiveIndex);

    // obtain actual index of the buffer(s) in the argument list
    int bufferArgumentIndex = 1;
    for (int i = 0; i < bufferArgumentTypeIndex; ++i) {
        bufferArgumentIndex += argumentTypes[i].getSize();
    }

    if (argumentTypes[bufferArgumentTypeIndex].getSort() == Type.ARRAY) {
        // If the first buffer in the array is a MappedByteBuffer, assume
        // they all are. If not, this will crash the users' program.

        // if (<buffers>[0] instanceof MappedByteBuffer) {
        mv.visitVarInsn(Opcodes.ALOAD, bufferArgumentIndex);
        mv.visitInsn(Opcodes.ICONST_0);
        mv.visitInsn(Opcodes.AALOAD);
        mv.visitTypeInsn(Opcodes.INSTANCEOF, Type.getInternalName(MappedByteBuffer.class));
        Label bufferInstanceofMappedByteBufferLabel = new Label();
        mv.visitJumpInsn(Opcodes.IFEQ, bufferInstanceofMappedByteBufferLabel);

        // only trace mmapped file channels if desired
        if (this.traceMmap) {
            // if (<buffers>[0].isFromFileChannel()) {
            mv.visitVarInsn(Opcodes.ALOAD, bufferArgumentIndex);
            mv.visitInsn(Opcodes.ICONST_0);
            mv.visitInsn(Opcodes.AALOAD);
            mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(MappedByteBuffer.class),
                    "isFromFileChannel", Type.getMethodDescriptor(Type.BOOLEAN_TYPE), false);
            Label fromFileChannelLabel = new Label();
            mv.visitJumpInsn(Opcodes.IFEQ, fromFileChannelLabel);

            int iIndex = bufferInstrumentationActiveIndex + 1;

            // for (int i = 0; i < <buffers>.length; ++i) {
            // <buffers>[i].setInstrumentationActive(true);
            // }
            mv.visitInsn(Opcodes.ICONST_0);
            mv.visitVarInsn(Opcodes.ISTORE, iIndex);
            Label loopConditionLabel = new Label();
            mv.visitJumpInsn(Opcodes.GOTO, loopConditionLabel);
            Label loopStartLabel = new Label();
            mv.visitLabel(loopStartLabel);
            mv.visitVarInsn(Opcodes.ALOAD, bufferArgumentIndex);
            mv.visitVarInsn(Opcodes.ILOAD, iIndex);
            mv.visitInsn(Opcodes.AALOAD);
            mv.visitInsn(Opcodes.ICONST_1);
            mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(MappedByteBuffer.class),
                    "setInstrumentationActive", Type.getMethodDescriptor(Type.VOID_TYPE, Type.BOOLEAN_TYPE),
                    false);
            mv.visitIincInsn(iIndex, 1);
            mv.visitLabel(loopConditionLabel);
            mv.visitVarInsn(Opcodes.ILOAD, iIndex);
            mv.visitVarInsn(Opcodes.ALOAD, bufferArgumentIndex);
            mv.visitInsn(Opcodes.ARRAYLENGTH);
            mv.visitJumpInsn(Opcodes.IF_ICMPLT, loopStartLabel);

            // bufferInstrumentationActive = true;
            mv.visitInsn(Opcodes.ICONST_1);
            mv.visitVarInsn(Opcodes.ISTORE, bufferInstrumentationActiveIndex);

            // }
            mv.visitLabel(fromFileChannelLabel);
        }

        // }
        mv.visitLabel(bufferInstanceofMappedByteBufferLabel);
    } else {
        // We need to handle the transferFrom/transferTo methods a little
        // differently. Their "buffers" only need to be FileChannelImpls,
        // the rest remains the same.

        // if (buffer instanceof MappedByteBuffer) {
        // if (buffer instanceof FileChannelImpl) {
        mv.visitVarInsn(Opcodes.ALOAD, bufferArgumentIndex);
        if (!isTransferMethod) {
            mv.visitTypeInsn(Opcodes.INSTANCEOF, Type.getInternalName(MappedByteBuffer.class));
        } else {
            mv.visitTypeInsn(Opcodes.INSTANCEOF, Type.getInternalName(FileChannelImpl.class));
        }
        Label bufferInstanceofMappedByteBufferLabel = new Label();
        mv.visitJumpInsn(Opcodes.IFEQ, bufferInstanceofMappedByteBufferLabel);

        // additional check required if the buffer is a MappedByteBuffer,
        // and we want to trace those
        Label fromFileChannelLabel = new Label();
        if (!isTransferMethod && this.traceMmap) {
            // if (buffer.isFromFileChannel()) {
            mv.visitVarInsn(Opcodes.ALOAD, bufferArgumentIndex);
            mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(MappedByteBuffer.class),
                    "isFromFileChannel", Type.getMethodDescriptor(Type.BOOLEAN_TYPE), false);
            mv.visitJumpInsn(Opcodes.IFEQ, fromFileChannelLabel);
        }

        // either we're dealing with a FileChannelImpl (in a
        // transferTo/transferFrom method), or this is a regular read or
        // write and we want to count in mmapped buffers
        if (isTransferMethod || this.traceMmap) {
            // buffer.setInstrumentationActive(true);
            mv.visitVarInsn(Opcodes.ALOAD, bufferArgumentIndex);
            mv.visitInsn(Opcodes.ICONST_1);
            mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
                    !isTransferMethod ? Type.getInternalName(MappedByteBuffer.class)
                            : Type.getInternalName(FileChannelImpl.class),
                    "setInstrumentationActive", Type.getMethodDescriptor(Type.VOID_TYPE, Type.BOOLEAN_TYPE),
                    false);

            // bufferInstrumentationActive = true;
            mv.visitInsn(Opcodes.ICONST_1);
            mv.visitVarInsn(Opcodes.ISTORE, bufferInstrumentationActiveIndex);
        }

        if (!isTransferMethod && this.traceMmap) {
            // }
            mv.visitLabel(fromFileChannelLabel);
        }

        // }
        mv.visitLabel(bufferInstanceofMappedByteBufferLabel);
    }

    // long startTime = System.nanoTime();
    int startTimeIndex = bufferInstrumentationActiveIndex + 1;
    storeTime(mv, startTimeIndex);

    // <returnType> result = methodPrefix<name>(arguments);
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    argumentIndex = 1;
    for (Type argument : argumentTypes) {
        mv.visitVarInsn(argument.getOpcode(Opcodes.ILOAD), argumentIndex);
        argumentIndex += argument.getSize();
    }
    mv.visitMethodInsn(Opcodes.INVOKESPECIAL, this.instrumentedTypeInternalName, this.methodPrefix + name,
            methodDescriptor, false);
    int resultIndex = startTimeIndex + 2;
    mv.visitVarInsn(returnType.getOpcode(Opcodes.ISTORE), resultIndex);
    int endTimeIndex = resultIndex + returnType.getSize();

    // long endTime = System.nanoTime();
    storeTime(mv, endTimeIndex);

    // if map(...) was involved in this, then it may have reset the
    // instrumentationActive flag if we don't trace mmap calls, so we need
    // to check again whether instrumentation is still active, and only
    // report the data then

    // if (isInstrumentationActive()) {
    isInstrumentationActive(mv);
    Label instrumentationStillActiveLabel = new Label();
    mv.visitJumpInsn(Opcodes.IFEQ, instrumentationStillActiveLabel);

    // callback.<callbackName>(startTime, endTime, result);
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    mv.visitFieldInsn(Opcodes.GETFIELD, this.instrumentedTypeInternalName, "callback",
            this.callbackTypeDescriptor);
    mv.visitVarInsn(Opcodes.LLOAD, startTimeIndex);
    mv.visitVarInsn(Opcodes.LLOAD, endTimeIndex);
    mv.visitVarInsn(returnType.getOpcode(Opcodes.ILOAD), resultIndex);
    mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, this.callbackTypeInternalName, callbackName,
            Type.getMethodDescriptor(Type.VOID_TYPE, Type.LONG_TYPE, Type.LONG_TYPE,
                    additionalCallbackArgumentType),
            false);

    // }
    mv.visitLabel(instrumentationStillActiveLabel);

    // same for the buffer

    if (argumentTypes[bufferArgumentTypeIndex].getSort() != Type.ARRAY) {
        // if (buffer instanceof MappedByteBuffer) {
        // if (buffer instanceof FileChannelImpl) {
        mv.visitVarInsn(Opcodes.ALOAD, bufferArgumentIndex);
        if (!isTransferMethod) {
            mv.visitTypeInsn(Opcodes.INSTANCEOF, Type.getInternalName(MappedByteBuffer.class));
        } else {
            mv.visitTypeInsn(Opcodes.INSTANCEOF, Type.getInternalName(FileChannelImpl.class));
        }
        Label bufferInstanceofMappedByteBufferLabel = new Label();
        mv.visitJumpInsn(Opcodes.IFEQ, bufferInstanceofMappedByteBufferLabel);

        // additional check required if the buffer is a MappedByteBuffer,
        // and we want to trace those
        Label fromFileChannelLabel = new Label();
        if (!isTransferMethod && this.traceMmap) {
            // if (buffer.isFromFileChannel()) {
            mv.visitVarInsn(Opcodes.ALOAD, bufferArgumentIndex);
            mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(MappedByteBuffer.class),
                    "isFromFileChannel", Type.getMethodDescriptor(Type.BOOLEAN_TYPE), false);
            mv.visitJumpInsn(Opcodes.IFEQ, fromFileChannelLabel);
        }

        // either we're dealing with a FileChannelImpl (in a
        // transferTo/transferFrom method), which might have flipped its
        // instrumentationActive flag because mmap was used, or this is a
        // regular read or write and we want to count in mmapped buffers
        if (isTransferMethod || this.traceMmap) {
            // if traceMmap is true, then we could actually just set
            // bufferInstrumentationActive to true

            // bufferInstrumentationActive =
            // buffer.isInstrumentationActive();
            mv.visitVarInsn(Opcodes.ALOAD, bufferArgumentIndex);
            mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
                    !isTransferMethod ? Type.getInternalName(MappedByteBuffer.class)
                            : Type.getInternalName(FileChannelImpl.class),
                    "isInstrumentationActive", Type.getMethodDescriptor(Type.BOOLEAN_TYPE), false);
            mv.visitVarInsn(Opcodes.ISTORE, bufferInstrumentationActiveIndex);
        }

        if (!isTransferMethod && this.traceMmap) {
            // }
            mv.visitLabel(fromFileChannelLabel);
        }

        // }
        mv.visitLabel(bufferInstanceofMappedByteBufferLabel);
    }

    // if (bufferInstrumentationActive) {
    mv.visitVarInsn(Opcodes.ILOAD, bufferInstrumentationActiveIndex);
    Label bufferInstrumentationActiveLabel = new Label();
    mv.visitJumpInsn(Opcodes.IFEQ, bufferInstrumentationActiveLabel);

    // callback.<oppositeCallbackName>(buffer.getFileDescriptor(),
    // startTime, endTime, result);
    if (!isTransferMethod) {
        if (argumentTypes[bufferArgumentTypeIndex].getSort() == Type.ARRAY) {
            // TODO this calls the opposite callback only on the first
            // element in the buffer array, but there is not really a way to
            // tell which buffer has received how many bytes, and thus which
            // file
            mv.visitVarInsn(Opcodes.ALOAD, bufferArgumentIndex);
            mv.visitInsn(Opcodes.ICONST_0);
            mv.visitInsn(Opcodes.AALOAD);
        } else {
            mv.visitVarInsn(Opcodes.ALOAD, bufferArgumentIndex);
        }
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(MappedByteBuffer.class),
                "getFileDescriptor", Type.getMethodDescriptor(Type.getType(FileDescriptor.class)), false);
    } else {
        mv.visitVarInsn(Opcodes.ALOAD, bufferArgumentIndex);
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(FileChannelImpl.class),
                "getFileDescriptor", Type.getMethodDescriptor(Type.getType(FileDescriptor.class)), false);
    }
    mv.visitVarInsn(Opcodes.LLOAD, startTimeIndex);
    mv.visitVarInsn(Opcodes.LLOAD, endTimeIndex);
    mv.visitVarInsn(returnType.getOpcode(Opcodes.ILOAD), resultIndex);
    mv.visitMethodInsn(Opcodes.INVOKESTATIC, this.callbackTypeInternalName, oppositeCallbackName,
            Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(FileDescriptor.class), Type.LONG_TYPE,
                    Type.LONG_TYPE, additionalCallbackArgumentType),
            false);

    // revert the active instrumentation flag for the buffer
    if (argumentTypes[bufferArgumentTypeIndex].getSort() == Type.ARRAY) {
        int iIndex = bufferInstrumentationActiveIndex + 1;

        // for (int i = 0; i < <buffers>.length; ++i) {
        // <buffers>[i].setInstrumentationActive(false);
        // }
        mv.visitInsn(Opcodes.ICONST_0);
        mv.visitVarInsn(Opcodes.ISTORE, iIndex);
        Label loopConditionLabel = new Label();
        mv.visitJumpInsn(Opcodes.GOTO, loopConditionLabel);
        Label loopStartLabel = new Label();
        mv.visitLabel(loopStartLabel);
        mv.visitVarInsn(Opcodes.ALOAD, bufferArgumentIndex);
        mv.visitVarInsn(Opcodes.ILOAD, iIndex);
        mv.visitInsn(Opcodes.AALOAD);
        mv.visitInsn(Opcodes.ICONST_0);
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(MappedByteBuffer.class),
                "setInstrumentationActive", Type.getMethodDescriptor(Type.VOID_TYPE, Type.BOOLEAN_TYPE), false);
        mv.visitIincInsn(iIndex, 1);
        mv.visitLabel(loopConditionLabel);
        mv.visitVarInsn(Opcodes.ILOAD, iIndex);
        mv.visitVarInsn(Opcodes.ALOAD, bufferArgumentIndex);
        mv.visitInsn(Opcodes.ARRAYLENGTH);
        mv.visitJumpInsn(Opcodes.IF_ICMPLT, loopStartLabel);
    } else {
        // buffer.setInstrumentationActive(false);
        mv.visitVarInsn(Opcodes.ALOAD, bufferArgumentIndex);
        mv.visitInsn(Opcodes.ICONST_0);
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
                !isTransferMethod ? Type.getInternalName(MappedByteBuffer.class)
                        : Type.getInternalName(FileChannelImpl.class),
                "setInstrumentationActive", Type.getMethodDescriptor(Type.VOID_TYPE, Type.BOOLEAN_TYPE), false);
    }

    // }
    mv.visitLabel(bufferInstrumentationActiveLabel);

    // setInstrumentationActive(false);
    setInstrumentationActive(mv, false);

    // return result;
    // }
    mv.visitVarInsn(returnType.getOpcode(Opcodes.ILOAD), resultIndex);
    mv.visitInsn(returnType.getOpcode(Opcodes.IRETURN));
    mv.visitMaxs(0, 0);
    mv.visitEnd();
}

From source file:dijkstra.gen.DijkstraCodeGenerator.java

License:Open Source License

public byte[] visit(ClassDeclarationNode classDecl) {
    // prolog/*  ww w.  ja  va 2 s. c  om*/
    cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
    programName = classDecl.getID().getName();
    fullPath = classPackage + "/" + classDecl.getID().getName();
    cw.visit(V1_8, ACC_PUBLIC + ACC_STATIC, fullPath, null, "java/lang/Object", null);
    cw.visitSource(classDecl.getID().getName() + ".java", null);

    FieldVisitor fv;
    List<Symbol> classSymbols = new ArrayList<Symbol>();
    classSymbols.addAll(SymbolTableManager.getInstance().getClassSymbolManager(programName)
            .getCurrentSymbolTable().getSymbols());
    for (ASTNode property : classDecl.getProperties()) {
        classSymbols.add(((PropertyNode) property).getID().symbol);
    }
    for (Symbol symbol : classSymbols) {
        String type;
        if (symbol.getType() == DijkstraType.ARRAY) {
            ArraySymbol as = (ArraySymbol) symbol;
            if (as.getArrayType() == DijkstraType.INT) {
                type = "[J";
            } else if (as.getArrayType() == DijkstraType.FLOAT) {
                type = "[D";
            } else {
                type = "[Z";
            }
        } else {
            if (symbol.getType() == DijkstraType.INT) {
                type = "J";
            } else if (symbol.getType() == DijkstraType.FLOAT) {
                type = "D";
            } else {
                type = "Z";
            }
        }
        fv = cw.visitField(ACC_PUBLIC, symbol.getId(), type, null, null);
        fv.visitEnd();
    }
    final StringBuilder sig = new StringBuilder();
    sig.append('(');
    for (Symbol property : ((ClassSymbol) classDecl.getID().symbol).getPropertySymbols()) {
        if (property.getType() == DijkstraType.INT) {
            sig.append('J');
        } else if (property.getType() == DijkstraType.FLOAT) {
            sig.append('D');
        } else {
            sig.append('Z');
        }
    }
    sig.append(")V");
    mvStack.push(cw.visitMethod(ACC_PUBLIC, "<init>", sig.toString(), null, null));
    MethodVisitor mv = mvStack.peek();
    mv.visitCode();
    final Label startLabel = new Label();
    mv.visitLabel(startLabel);
    mv.visitVarInsn(ALOAD, 0);
    mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);

    int localAddr = 1;
    for (Symbol param : ((ClassSymbol) classDecl.getID().symbol).getPropertySymbols()) {
        mv.visitVarInsn(ALOAD, 0);
        if (param.getType() == DijkstraType.INT) {
            mv.visitVarInsn(LLOAD, localAddr);
            mv.visitFieldInsn(PUTFIELD, fullPath, param.getId(), "J");
            localAddr += 2;
        } else if (param.getType() == DijkstraType.FLOAT) {
            mv.visitVarInsn(DLOAD, localAddr);
            mv.visitFieldInsn(PUTFIELD, fullPath, param.getId(), "D");
            localAddr += 2;
        } else {
            mv.visitVarInsn(ILOAD, localAddr);
            mv.visitFieldInsn(PUTFIELD, fullPath, param.getId(), "Z");
            localAddr += 1;
        }
    }

    processingClassFields = true;
    inClass = true;
    for (ASTNode body : classDecl.getDeclarations()) {
        body.accept(this);
    }
    inClass = false;
    processingClassFields = false;

    mv.visitInsn(RETURN);
    final Label endLabel = new Label();
    mv.visitLabel(endLabel);
    mv.visitLocalVariable("this", "L" + fullPath + ";", null, startLabel, endLabel, 0);
    int paramLoc = 1;
    for (Symbol param : ((ClassSymbol) classDecl.getID().symbol).getPropertySymbols()) {
        if (param.getType() == DijkstraType.INT) {
            mv.visitLocalVariable(param.getId(), "J", null, startLabel, endLabel, paramLoc);
            paramLoc += 2;
        } else if (param.getType() == DijkstraType.FLOAT) {
            mv.visitLocalVariable(param.getId(), "D", null, startLabel, endLabel, paramLoc);
            paramLoc += 2;
        } else {
            mv.visitLocalVariable(param.getId(), "Z", null, startLabel, endLabel, paramLoc);
            paramLoc += 1;
        }
    }
    mv.visitMaxs(0, 0);
    mv.visitEnd();
    mvStack.pop();

    inClass = true;
    for (ASTNode body : classDecl.getDeclarations()) {
        body.accept(this);
    }
    inClass = false;

    // Actual end of generation
    cw.visitEnd();
    return cw.toByteArray();
}

From source file:dijkstra.gen.DijkstraCodeGenerator.java

License:Open Source License

public byte[] visit(AlternativeNode alternative) {
    final MethodVisitor mv = mvStack.peek();
    final Label endLabel = new Label();
    guardLabelStack.push(endLabel);// w w  w  . ja  v  a  2  s  . co  m
    visitChildren(alternative);
    guardLabelStack.pop();
    mv.visitIntInsn(BIPUSH, alternative.getLineNumber());
    mv.visitMethodInsn(INVOKESTATIC, "dijkstra/runtime/DijkstraRuntime", "abortNoAlternative", "(I)V", false);
    mv.visitLabel(endLabel);
    return null;
}

From source file:dijkstra.gen.DijkstraCodeGenerator.java

License:Open Source License

public byte[] visit(IterativeNode iterator) {
    final MethodVisitor mv = mvStack.peek();
    final Label startLabel = new Label();
    guardLabelStack.push(startLabel);// w w w  .j a va 2  s .  c  o m
    mv.visitLabel(startLabel);
    visitChildren(iterator);
    guardLabelStack.pop();
    return null;
}

From source file:dijkstra.gen.DijkstraCodeGenerator.java

License:Open Source License

public byte[] visit(GuardNode guard) {
    final MethodVisitor mv = mvStack.peek();
    final Label failLabel = new Label();
    guard.getExpression().accept(this);
    mv.visitJumpInsn(IFEQ, failLabel);/*from  ww  w  .j ava 2s .  co  m*/
    guard.getStatement().accept(this);
    mv.visitJumpInsn(GOTO, guardLabelStack.peek());
    mv.visitLabel(failLabel);
    return null;
}

From source file:dijkstra.gen.DijkstraCodeGenerator.java

License:Open Source License

/**
 * Evaluate the child expression and then negate it (logical or arithmetic). Logical
 * negation is more difficult because there is no logical negate instruction in the 
 * JVM instruction set./*from   w w w .  j a va  2 s.c o  m*/
 * @see dijkstra.ast.ASTVisitor#visit(dijkstra.ast.ASTNodeFactory.UnaryExpressionNode)
 */
public byte[] visit(UnaryExpressionNode unary) {
    final MethodVisitor mv = mvStack.peek();
    visitChildren(unary); // Evaluate the expression
    // TOS = the child expression
    if (unary.type == DijkstraType.INT) {
        mv.visitInsn(LNEG);
    } else if (unary.type == DijkstraType.FLOAT) {
        mv.visitInsn(DNEG);
    } else { // Boolean ~
        final Label l1 = new Label();
        final Label l2 = new Label();
        mv.visitJumpInsn(IFEQ, l1);
        mv.visitInsn(ICONST_0); // true -> false
        mv.visitJumpInsn(GOTO, l2);
        mv.visitLabel(l1);
        mv.visitInsn(ICONST_1); // false -> true
        mv.visitLabel(l2);
    }
    return null;
}

From source file:dijkstra.gen.DijkstraCodeGenerator.java

License:Open Source License

/**
 * Get the values of the left and right children on the stack and then perform
 * the operation./* www .  j a v  a  2s .  c  om*/
 * @see dijkstra.ast.ASTVisitor#visit(dijkstra.ast.ASTNodeFactory.BinaryExpressionNode)
 */
public byte[] visit(BinaryExpressionNode binary) {
    final MethodVisitor mv = mvStack.peek();
    DijkstraType childOneType = binary.getExpr1().getType();
    if (childOneType == DijkstraType.ARRAY) {
        childOneType = ((ArraySymbol) ((ArrayAccessorNode) binary.getExpr1()).getId().symbol).getArrayType();
    }
    DijkstraType childTwoType = binary.getExpr2().getType();
    if (childTwoType == DijkstraType.ARRAY) {
        childTwoType = ((ArraySymbol) ((ArrayAccessorNode) binary.getExpr2()).getId().symbol).getArrayType();
    }
    Label lab1, lab2;
    if (binary.getOp() == DijkstraParser.AMP) {
        lab1 = new Label();
        lab2 = new Label();
        binary.getExpr1().accept(this);
        mv.visitJumpInsn(IFEQ, lab1);
        binary.getExpr2().accept(this);
        mv.visitJumpInsn(IFEQ, lab1);
        mv.visitInsn(ICONST_1);
        mv.visitJumpInsn(GOTO, lab2);
        mv.visitLabel(lab1);
        mv.visitInsn(ICONST_0);
        mv.visitLabel(lab2);
    } else if (binary.getOp() == DijkstraParser.PIPE) {
        lab1 = new Label();
        lab2 = new Label();
        binary.getExpr1().accept(this);
        mv.visitJumpInsn(IFNE, lab1);
        binary.getExpr2().accept(this);
        mv.visitJumpInsn(IFNE, lab1);
        mv.visitInsn(ICONST_0);
        mv.visitJumpInsn(GOTO, lab2);
        mv.visitLabel(lab1);
        mv.visitInsn(ICONST_1);
        mv.visitLabel(lab2);
    } else {
        binary.getExpr1().accept(this);
        if ((childOneType == DijkstraType.INT && childTwoType == DijkstraType.FLOAT)
                || (binary.getOp() == DijkstraParser.SLASH && childOneType == DijkstraType.INT)) {
            mv.visitInsn(L2D);
        }
        binary.getExpr2().accept(this);
        if ((childOneType == DijkstraType.FLOAT && childTwoType == DijkstraType.INT)
                || (binary.getOp() == DijkstraParser.SLASH && childTwoType == DijkstraType.INT)) {
            mv.visitInsn(L2D);
        }
        switch (binary.getOp()) {
        case DijkstraParser.LT:
            lab1 = new Label();
            lab2 = new Label();
            if (childOneType == DijkstraType.INT && childTwoType == DijkstraType.INT) {
                mv.visitInsn(LCMP);
            } else {
                mv.visitInsn(DCMPL);
            }
            mv.visitJumpInsn(IFGE, lab1);
            mv.visitInsn(ICONST_1); // left < right
            mv.visitJumpInsn(GOTO, lab2);
            mv.visitLabel(lab1);
            mv.visitInsn(ICONST_0); // right >= left
            mv.visitLabel(lab2);
            break;
        case DijkstraParser.LTEQ:
            lab1 = new Label();
            lab2 = new Label();
            if (childOneType == DijkstraType.INT && childTwoType == DijkstraType.INT) {
                mv.visitInsn(LCMP);
            } else {
                mv.visitInsn(DCMPL);
            }
            mv.visitJumpInsn(IFGT, lab1);
            mv.visitInsn(ICONST_1); // left <= right
            mv.visitJumpInsn(GOTO, lab2);
            mv.visitLabel(lab1);
            mv.visitInsn(ICONST_0); // right > left
            mv.visitLabel(lab2);
            break;
        case DijkstraParser.GT:
            lab1 = new Label();
            lab2 = new Label();
            if (childOneType == DijkstraType.INT && childTwoType == DijkstraType.INT) {
                mv.visitInsn(LCMP);
            } else {
                mv.visitInsn(DCMPL);
            }
            mv.visitJumpInsn(IFLE, lab1);
            mv.visitInsn(ICONST_1); // left > right
            mv.visitJumpInsn(GOTO, lab2);
            mv.visitLabel(lab1);
            mv.visitInsn(ICONST_0); // right <= left
            mv.visitLabel(lab2);
            break;
        case DijkstraParser.GTEQ:
            lab1 = new Label();
            lab2 = new Label();
            if (childOneType == DijkstraType.INT && childTwoType == DijkstraType.INT) {
                mv.visitInsn(LCMP);
            } else {
                mv.visitInsn(DCMPL);
            }
            mv.visitJumpInsn(IFLT, lab1);
            mv.visitInsn(ICONST_1); // left >= right
            mv.visitJumpInsn(GOTO, lab2);
            mv.visitLabel(lab1);
            mv.visitInsn(ICONST_0); // right < left
            mv.visitLabel(lab2);
            break;
        case DijkstraParser.PLUS:
            if (childOneType == DijkstraType.INT && childTwoType == DijkstraType.INT) {
                mv.visitInsn(LADD);
            } else {
                mv.visitInsn(DADD);
            }
            break;
        case DijkstraParser.MINUS:
            if (childOneType == DijkstraType.INT && childTwoType == DijkstraType.INT) {
                mv.visitInsn(LSUB);
            } else {
                mv.visitInsn(DSUB);
            }
            break;
        case DijkstraParser.STAR:
            if (childOneType == DijkstraType.INT && childTwoType == DijkstraType.INT) {
                mv.visitInsn(LMUL);
            } else {
                mv.visitInsn(DMUL);
            }
            break;
        case DijkstraParser.SLASH:
            mv.visitInsn(DDIV);
            break;
        case DijkstraParser.MOD:
            mv.visitInsn(LREM);
            break;
        case DijkstraParser.DIV:
            mv.visitInsn(LDIV);
            break;
        case DijkstraParser.EQ:
            lab1 = new Label();
            lab2 = new Label();
            if (childOneType == DijkstraType.INT && childTwoType == DijkstraType.INT) {
                mv.visitInsn(LCMP);
                mv.visitJumpInsn(IFNE, lab1);
            } else if (childOneType == DijkstraType.BOOLEAN) {
                mv.visitJumpInsn(IF_ICMPNE, lab1);
            } else {
                mv.visitInsn(DCMPL);
                mv.visitJumpInsn(IFNE, lab1);
            }
            mv.visitInsn(ICONST_1);
            mv.visitJumpInsn(GOTO, lab2);
            mv.visitLabel(lab1);
            mv.visitInsn(ICONST_0);
            mv.visitLabel(lab2);
            break;
        case DijkstraParser.NEQ:
            lab1 = new Label();
            lab2 = new Label();
            if (childOneType == DijkstraType.INT && childTwoType == DijkstraType.INT) {
                mv.visitInsn(LCMP);
                mv.visitJumpInsn(IFEQ, lab1);
            } else if (childOneType == DijkstraType.BOOLEAN) {
                mv.visitJumpInsn(IF_ICMPEQ, lab1);
            } else {
                mv.visitInsn(DCMPL);
                mv.visitJumpInsn(IFEQ, lab1);
            }
            mv.visitInsn(ICONST_1); // left != right
            mv.visitJumpInsn(GOTO, lab2);
            mv.visitLabel(lab1);
            mv.visitInsn(ICONST_0); // left = right
            mv.visitLabel(lab2);
            break;
        }
    }
    return null;
}

From source file:dijkstra.gen.DijkstraCodeGenerator.java

License:Open Source License

public byte[] visit(ProcedureDeclarationNode procDeclNode) {
    if (processingClassFields) {
        return null;
    }/* w w w  .j  av  a2  s  . c o  m*/
    final String methodName = procDeclNode.getIDNode().getName();
    final StringBuilder sig = new StringBuilder();
    sig.append('(');
    for (IDNode param : procDeclNode.getParamList()) {
        if (param.getType() == DijkstraType.INT) {
            sig.append('J');
        } else if (param.getType() == DijkstraType.FLOAT) {
            sig.append('D');
        } else {
            sig.append('Z');
        }
    }
    sig.append(")V");
    if (inClass) {
        mvStack.push(cw.visitMethod(ACC_PUBLIC, methodName, sig.toString(), null, null));
    } else {
        mvStack.push(cw.visitMethod(ACC_PUBLIC + ACC_STATIC, methodName, sig.toString(), null, null));
    }
    final MethodVisitor mv = mvStack.peek();

    JVMInfo.enterScope(inClass);
    // Load the parameters into the JVMInfo so it knows the proper addresses
    for (IDNode param : procDeclNode.getParamList()) {
        param.getAddress();
    }
    mv.visitCode();
    final Label startLabel = new Label();
    mv.visitLabel(startLabel);

    procDeclNode.getCompoundNode().accept(this);

    mv.visitInsn(RETURN);
    final Label endLabel = new Label();
    mv.visitLabel(endLabel);
    int paramLoc = 0;
    for (IDNode param : procDeclNode.getParamList()) {
        if (param.getType() == DijkstraType.INT) {
            mv.visitLocalVariable(param.getName(), "J", null, startLabel, endLabel, paramLoc);
            paramLoc += 2;
        } else if (param.getType() == DijkstraType.FLOAT) {
            mv.visitLocalVariable(param.getName(), "D", null, startLabel, endLabel, paramLoc);
            paramLoc += 2;
        } else {
            mv.visitLocalVariable(param.getName(), "Z", null, startLabel, endLabel, paramLoc);
            paramLoc += 1;
        }
    }
    mv.visitMaxs(0, 0);
    mv.visitEnd();
    JVMInfo.exitScope();
    mvStack.pop();
    return null;
}

From source file:dijkstra.gen.DijkstraCodeGenerator.java

License:Open Source License

public byte[] visit(FunctionDeclarationNode funDeclNode) {
    if (processingClassFields) {
        return null;
    }/*from   www  . j a  v a  2 s. c  o m*/
    final String methodName = funDeclNode.getIDNode().getName();
    final StringBuilder sig = new StringBuilder();
    sig.append('(');
    for (IDNode param : funDeclNode.getParamList()) {
        if (param.getType() == DijkstraType.INT) {
            sig.append('J');
        } else if (param.getType() == DijkstraType.FLOAT) {
            sig.append('D');
        } else {
            sig.append('Z');
        }
    }
    sig.append(')');
    sig.append("[Ljava/lang/Object;");

    if (inClass) {
        mvStack.push(cw.visitMethod(ACC_PUBLIC, methodName, sig.toString(), null, null));
    } else {
        mvStack.push(cw.visitMethod(ACC_PUBLIC + ACC_STATIC, methodName, sig.toString(), null, null));
    }
    final MethodVisitor mv = mvStack.peek();

    JVMInfo.enterScope(inClass);
    // Load the parameters into the JVMInfo so it knows the proper addresses
    for (IDNode param : funDeclNode.getParamList()) {
        param.getAddress();
    }

    mv.visitIntInsn(SIPUSH, funDeclNode.getReturnTypes().size());
    mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
    returnArrayStack.push(new ArraySymbol(null, UNDEFINED));
    mv.visitVarInsn(ASTORE, JVMInfo.getAddressForSymbol(returnArrayStack.peek()));

    mv.visitInsn(ICONST_0);
    returnIndexStack.push(new Symbol(null, UNDEFINED));
    mv.visitVarInsn(ISTORE, JVMInfo.getAddressForSymbol(returnIndexStack.peek()));

    mv.visitCode();
    final Label startLabel = new Label();
    mv.visitLabel(startLabel);

    funDeclNode.getCompoundNode().accept(this);

    returnIndexStack.pop();
    mv.visitVarInsn(ALOAD, JVMInfo.getAddressForSymbol(returnArrayStack.pop()));
    mv.visitInsn(ARETURN);
    final Label endLabel = new Label();
    mv.visitLabel(endLabel);
    int paramLoc = 0;
    for (IDNode param : funDeclNode.getParamList()) {
        if (param.getType() == DijkstraType.INT) {
            mv.visitLocalVariable(param.getName(), "J", null, startLabel, endLabel, paramLoc);
            paramLoc += 2;
        } else if (param.getType() == DijkstraType.FLOAT) {
            mv.visitLocalVariable(param.getName(), "D", null, startLabel, endLabel, paramLoc);
            paramLoc += 2;
        } else {
            mv.visitLocalVariable(param.getName(), "Z", null, startLabel, endLabel, paramLoc);
            paramLoc += 1;
        }
    }
    mv.visitMaxs(0, 0);
    mv.visitEnd();
    JVMInfo.exitScope();
    mvStack.pop();
    return null;
}

From source file:edu.illinois.nondex.instr.IdentityHashMapShufflingAdder.java

License:Open Source License

public void addNextIndex() {
    MethodVisitor mv = super.visitMethod(Opcodes.ACC_PROTECTED, "nextIndex", "()I", null, null);
    mv.visitCode();/*from w w  w. jav a  2s . c o  m*/
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    mv.visitFieldInsn(Opcodes.GETFIELD, "java/util/IdentityHashMap$IdentityHashMapIterator", "this$0",
            "Ljava/util/IdentityHashMap;");
    mv.visitFieldInsn(Opcodes.GETFIELD, "java/util/IdentityHashMap", "modCount", "I");
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    mv.visitFieldInsn(Opcodes.GETFIELD, "java/util/IdentityHashMap$IdentityHashMapIterator", "expectedModCount",
            "I");
    Label l0 = new Label();
    mv.visitJumpInsn(Opcodes.IF_ICMPEQ, l0);
    mv.visitTypeInsn(Opcodes.NEW, "java/util/ConcurrentModificationException");
    mv.visitInsn(Opcodes.DUP);
    mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/util/ConcurrentModificationException", "<init>", "()V",
            false);
    mv.visitInsn(Opcodes.ATHROW);
    mv.visitLabel(l0);
    mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/util/IdentityHashMap$IdentityHashMapIterator", "hasNext",
            "()Z", false);
    Label l1 = new Label();
    mv.visitJumpInsn(Opcodes.IFNE, l1);
    mv.visitTypeInsn(Opcodes.NEW, "java/util/NoSuchElementException");
    mv.visitInsn(Opcodes.DUP);
    mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/util/NoSuchElementException", "<init>", "()V", false);
    mv.visitInsn(Opcodes.ATHROW);
    mv.visitLabel(l1);
    mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    mv.visitFieldInsn(Opcodes.GETFIELD, "java/util/IdentityHashMap$IdentityHashMapIterator", "keys",
            "Ljava/util/List;");
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    mv.visitInsn(Opcodes.DUP);
    mv.visitFieldInsn(Opcodes.GETFIELD, "java/util/IdentityHashMap$IdentityHashMapIterator", "idx", "I");
    mv.visitInsn(Opcodes.DUP_X1);
    mv.visitInsn(Opcodes.ICONST_1);
    mv.visitInsn(Opcodes.IADD);
    mv.visitFieldInsn(Opcodes.PUTFIELD, "java/util/IdentityHashMap$IdentityHashMapIterator", "idx", "I");
    mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/List", "get", "(I)Ljava/lang/Object;", true);
    mv.visitVarInsn(Opcodes.ASTORE, 1);
    mv.visitInsn(Opcodes.ICONST_0);
    mv.visitVarInsn(Opcodes.ISTORE, 2);
    Label l2 = new Label();
    mv.visitLabel(l2);
    mv.visitFrame(Opcodes.F_APPEND, 2, new Object[] { "java/lang/Object", Opcodes.INTEGER }, 0, null);
    mv.visitVarInsn(Opcodes.ILOAD, 2);
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    mv.visitFieldInsn(Opcodes.GETFIELD, "java/util/IdentityHashMap$IdentityHashMapIterator", "this$0",
            "Ljava/util/IdentityHashMap;");
    mv.visitFieldInsn(Opcodes.GETFIELD, "java/util/IdentityHashMap", "table", "[Ljava/lang/Object;");
    mv.visitInsn(Opcodes.ARRAYLENGTH);
    Label l3 = new Label();
    mv.visitJumpInsn(Opcodes.IF_ICMPGE, l3);
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    mv.visitFieldInsn(Opcodes.GETFIELD, "java/util/IdentityHashMap$IdentityHashMapIterator", "this$0",
            "Ljava/util/IdentityHashMap;");
    mv.visitFieldInsn(Opcodes.GETFIELD, "java/util/IdentityHashMap", "table", "[Ljava/lang/Object;");
    mv.visitVarInsn(Opcodes.ILOAD, 2);
    mv.visitInsn(Opcodes.AALOAD);
    mv.visitVarInsn(Opcodes.ALOAD, 1);
    Label l4 = new Label();
    mv.visitJumpInsn(Opcodes.IF_ACMPNE, l4);
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    mv.visitVarInsn(Opcodes.ILOAD, 2);
    mv.visitFieldInsn(Opcodes.PUTFIELD, "java/util/IdentityHashMap$IdentityHashMapIterator",
            "lastReturnedIndex", "I");
    mv.visitJumpInsn(Opcodes.GOTO, l3);
    mv.visitLabel(l4);
    mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
    mv.visitIincInsn(2, 2);
    mv.visitJumpInsn(Opcodes.GOTO, l2);
    mv.visitLabel(l3);
    mv.visitFrame(Opcodes.F_CHOP, 1, null, 0, null);
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    mv.visitFieldInsn(Opcodes.GETFIELD, "java/util/IdentityHashMap$IdentityHashMapIterator",
            "lastReturnedIndex", "I");
    mv.visitInsn(Opcodes.IRETURN);
    mv.visitMaxs(5, 3);
    mv.visitEnd();
}