use of org.objectweb.asm.MethodVisitor in project groovy-core by groovy.
the class StatementWriter method writeSynchronized.
public void writeSynchronized(SynchronizedStatement statement) {
controller.getAcg().onLineNumber(statement, "visitSynchronizedStatement");
writeStatementLabel(statement);
final MethodVisitor mv = controller.getMethodVisitor();
CompileStack compileStack = controller.getCompileStack();
statement.getExpression().visit(controller.getAcg());
controller.getOperandStack().box();
final int index = compileStack.defineTemporaryVariable("synchronized", ClassHelper.OBJECT_TYPE, true);
final Label synchronizedStart = new Label();
final Label synchronizedEnd = new Label();
final Label catchAll = new Label();
mv.visitVarInsn(ALOAD, index);
mv.visitInsn(MONITORENTER);
mv.visitLabel(synchronizedStart);
// place holder for "empty" synchronized blocks, for example
// if there is only a break/continue.
mv.visitInsn(NOP);
Runnable finallyPart = new Runnable() {
public void run() {
mv.visitVarInsn(ALOAD, index);
mv.visitInsn(MONITOREXIT);
}
};
BlockRecorder fb = new BlockRecorder(finallyPart);
fb.startRange(synchronizedStart);
compileStack.pushBlockRecorder(fb);
statement.getCode().visit(controller.getAcg());
fb.closeRange(catchAll);
compileStack.writeExceptionTable(fb, catchAll, null);
//pop fb
compileStack.pop();
finallyPart.run();
mv.visitJumpInsn(GOTO, synchronizedEnd);
mv.visitLabel(catchAll);
finallyPart.run();
mv.visitInsn(ATHROW);
mv.visitLabel(synchronizedEnd);
}
use of org.objectweb.asm.MethodVisitor in project groovy-core by groovy.
the class StatementWriter method writeReturn.
public void writeReturn(ReturnStatement statement) {
controller.getAcg().onLineNumber(statement, "visitReturnStatement");
writeStatementLabel(statement);
MethodVisitor mv = controller.getMethodVisitor();
OperandStack operandStack = controller.getOperandStack();
ClassNode returnType = controller.getReturnType();
if (returnType == ClassHelper.VOID_TYPE) {
if (!(statement.isReturningNullOrVoid())) {
//TODO: move to Verifier
controller.getAcg().throwException("Cannot use return statement with an expression on a method that returns void");
}
controller.getCompileStack().applyBlockRecorder();
mv.visitInsn(RETURN);
return;
}
Expression expression = statement.getExpression();
expression.visit(controller.getAcg());
operandStack.doGroovyCast(returnType);
if (controller.getCompileStack().hasBlockRecorder()) {
ClassNode type = operandStack.getTopOperand();
int returnValueIdx = controller.getCompileStack().defineTemporaryVariable("returnValue", returnType, true);
controller.getCompileStack().applyBlockRecorder();
operandStack.load(type, returnValueIdx);
}
BytecodeHelper.doReturn(mv, returnType);
operandStack.remove(1);
}
use of org.objectweb.asm.MethodVisitor in project groovy-core by groovy.
the class StatementWriter method writeWhileLoop.
public void writeWhileLoop(WhileStatement loop) {
controller.getAcg().onLineNumber(loop, "visitWhileLoop");
writeStatementLabel(loop);
MethodVisitor mv = controller.getMethodVisitor();
controller.getCompileStack().pushLoop(loop.getStatementLabels());
Label continueLabel = controller.getCompileStack().getContinueLabel();
Label breakLabel = controller.getCompileStack().getBreakLabel();
mv.visitLabel(continueLabel);
Expression bool = loop.getBooleanExpression();
boolean boolHandled = false;
if (bool instanceof ConstantExpression) {
ConstantExpression constant = (ConstantExpression) bool;
if (constant.getValue() == Boolean.TRUE) {
boolHandled = true;
// do nothing
} else if (constant.getValue() == Boolean.FALSE) {
boolHandled = true;
mv.visitJumpInsn(GOTO, breakLabel);
}
}
if (!boolHandled) {
bool.visit(controller.getAcg());
controller.getOperandStack().jump(IFEQ, breakLabel);
}
loop.getLoopBlock().visit(controller.getAcg());
mv.visitJumpInsn(GOTO, continueLabel);
mv.visitLabel(breakLabel);
controller.getCompileStack().pop();
}
use of org.objectweb.asm.MethodVisitor in project groovy-core by groovy.
the class StaticTypesStatementWriter method writeForInLoop.
@Override
protected void writeForInLoop(final ForStatement loop) {
controller.getAcg().onLineNumber(loop, "visitForLoop");
writeStatementLabel(loop);
CompileStack compileStack = controller.getCompileStack();
MethodVisitor mv = controller.getMethodVisitor();
OperandStack operandStack = controller.getOperandStack();
compileStack.pushLoop(loop.getVariableScope(), loop.getStatementLabels());
// Identify type of collection
TypeChooser typeChooser = controller.getTypeChooser();
Expression collectionExpression = loop.getCollectionExpression();
ClassNode collectionType = typeChooser.resolveType(collectionExpression, controller.getClassNode());
Parameter loopVariable = loop.getVariable();
int size = operandStack.getStackLength();
if (collectionType.isArray() && loopVariable.getOriginType().equals(collectionType.getComponentType())) {
writeOptimizedForEachLoop(compileStack, operandStack, mv, loop, collectionExpression, collectionType, loopVariable);
} else if (ENUMERATION_CLASSNODE.equals(collectionType)) {
writeEnumerationBasedForEachLoop(compileStack, operandStack, mv, loop, collectionExpression, collectionType, loopVariable);
} else {
writeIteratorBasedForEachLoop(compileStack, operandStack, mv, loop, collectionExpression, collectionType, loopVariable);
}
operandStack.popDownTo(size);
compileStack.pop();
}
use of org.objectweb.asm.MethodVisitor in project groovy-core by groovy.
the class OperandStack method storeVar.
public void storeVar(BytecodeVariable variable) {
MethodVisitor mv = controller.getMethodVisitor();
int idx = variable.getIndex();
ClassNode type = variable.getType();
// value is on stack
if (variable.isHolder()) {
doGroovyCast(type);
box();
mv.visitVarInsn(ALOAD, idx);
mv.visitTypeInsn(CHECKCAST, "groovy/lang/Reference");
mv.visitInsn(SWAP);
mv.visitMethodInsn(INVOKEVIRTUAL, "groovy/lang/Reference", "set", "(Ljava/lang/Object;)V", false);
} else {
doGroovyCast(type);
if (type == ClassHelper.double_TYPE) {
mv.visitVarInsn(DSTORE, idx);
} else if (type == ClassHelper.float_TYPE) {
mv.visitVarInsn(FSTORE, idx);
} else if (type == ClassHelper.long_TYPE) {
mv.visitVarInsn(LSTORE, idx);
} else if (type == ClassHelper.boolean_TYPE || type == ClassHelper.char_TYPE || type == ClassHelper.byte_TYPE || type == ClassHelper.int_TYPE || type == ClassHelper.short_TYPE) {
mv.visitVarInsn(ISTORE, idx);
} else {
mv.visitVarInsn(ASTORE, idx);
}
}
// remove RHS value from operand stack
remove(1);
}
Aggregations