use of org.codehaus.groovy.classgen.asm.BytecodeVariable in project groovy by apache.
the class StaticTypesStatementWriter method writeOptimizedForEachLoop.
private void writeOptimizedForEachLoop(CompileStack compileStack, OperandStack operandStack, MethodVisitor mv, ForStatement loop, Expression collectionExpression, ClassNode collectionType, Parameter loopVariable) {
BytecodeVariable variable = compileStack.defineVariable(loopVariable, false);
Label continueLabel = compileStack.getContinueLabel();
Label breakLabel = compileStack.getBreakLabel();
AsmClassGenerator acg = controller.getAcg();
// load array on stack
collectionExpression.visit(acg);
mv.visitInsn(DUP);
int array = compileStack.defineTemporaryVariable("$arr", collectionType, true);
mv.visitJumpInsn(IFNULL, breakLabel);
// $len = array.length
mv.visitVarInsn(ALOAD, array);
mv.visitInsn(ARRAYLENGTH);
operandStack.push(ClassHelper.int_TYPE);
int arrayLen = compileStack.defineTemporaryVariable("$len", ClassHelper.int_TYPE, true);
// $idx = 0
mv.visitInsn(ICONST_0);
operandStack.push(ClassHelper.int_TYPE);
int loopIdx = compileStack.defineTemporaryVariable("$idx", ClassHelper.int_TYPE, true);
mv.visitLabel(continueLabel);
// $idx<$len?
mv.visitVarInsn(ILOAD, loopIdx);
mv.visitVarInsn(ILOAD, arrayLen);
mv.visitJumpInsn(IF_ICMPGE, breakLabel);
// get array element
loadFromArray(mv, variable, array, loopIdx);
// $idx++
mv.visitIincInsn(loopIdx, 1);
// loop body
loop.getLoopBlock().visit(acg);
mv.visitJumpInsn(GOTO, continueLabel);
mv.visitLabel(breakLabel);
compileStack.removeVar(loopIdx);
compileStack.removeVar(arrayLen);
compileStack.removeVar(array);
}
use of org.codehaus.groovy.classgen.asm.BytecodeVariable in project groovy by apache.
the class StaticTypesStatementWriter method writeEnumerationBasedForEachLoop.
private void writeEnumerationBasedForEachLoop(CompileStack compileStack, OperandStack operandStack, MethodVisitor mv, ForStatement loop, Expression collectionExpression, ClassNode collectionType, Parameter loopVariable) {
// Declare the loop counter.
BytecodeVariable variable = compileStack.defineVariable(loopVariable, false);
collectionExpression.visit(controller.getAcg());
// Then get the iterator and generate the loop control
int enumIdx = compileStack.defineTemporaryVariable("$enum", ENUMERATION_CLASSNODE, true);
Label continueLabel = compileStack.getContinueLabel();
Label breakLabel = compileStack.getBreakLabel();
mv.visitLabel(continueLabel);
mv.visitVarInsn(ALOAD, enumIdx);
ENUMERATION_HASMORE_METHOD.call(mv);
// note: ifeq tests for ==0, a boolean is 0 if it is false
mv.visitJumpInsn(IFEQ, breakLabel);
mv.visitVarInsn(ALOAD, enumIdx);
ENUMERATION_NEXT_METHOD.call(mv);
operandStack.push(ClassHelper.OBJECT_TYPE);
operandStack.storeVar(variable);
// Generate the loop body
loop.getLoopBlock().visit(controller.getAcg());
mv.visitJumpInsn(GOTO, continueLabel);
mv.visitLabel(breakLabel);
}
use of org.codehaus.groovy.classgen.asm.BytecodeVariable in project groovy by apache.
the class AsmClassGenerator method visitVariableExpression.
/**
* Visits a bare (unqualified) variable expression.
*/
public void visitVariableExpression(VariableExpression expression) {
String variableName = expression.getName();
//-----------------------------------------------------------------------
// SPECIAL CASES
// "this" for static methods is the Class instance
ClassNode classNode = controller.getClassNode();
if (variableName.equals("this")) {
if (controller.isStaticMethod() || (!controller.getCompileStack().isImplicitThis() && controller.isStaticContext())) {
if (controller.isInClosure())
classNode = controller.getOutermostClass();
visitClassExpression(new ClassExpression(classNode));
} else {
loadThis(expression);
}
return;
}
// "super" also requires special handling
if (variableName.equals("super")) {
if (controller.isStaticMethod()) {
visitClassExpression(new ClassExpression(classNode.getSuperClass()));
} else {
loadThis(expression);
}
return;
}
BytecodeVariable variable = controller.getCompileStack().getVariable(variableName, false);
if (variable == null) {
processClassVariable(variableName);
} else {
controller.getOperandStack().loadOrStoreVariable(variable, expression.isUseReferenceDirectly());
}
if (!controller.getCompileStack().isLHS())
controller.getAssertionWriter().record(expression);
}
use of org.codehaus.groovy.classgen.asm.BytecodeVariable in project groovy-core by groovy.
the class AsmClassGenerator method visitVariableExpression.
/**
* Visits a bare (unqualified) variable expression.
*/
public void visitVariableExpression(VariableExpression expression) {
String variableName = expression.getName();
//-----------------------------------------------------------------------
// SPECIAL CASES
// "this" for static methods is the Class instance
ClassNode classNode = controller.getClassNode();
if (variableName.equals("this")) {
if (controller.isStaticMethod() || (!controller.getCompileStack().isImplicitThis() && controller.isStaticContext())) {
if (controller.isInClosure())
classNode = controller.getOutermostClass();
visitClassExpression(new ClassExpression(classNode));
} else {
loadThis(expression);
}
return;
}
// "super" also requires special handling
if (variableName.equals("super")) {
if (controller.isStaticMethod()) {
visitClassExpression(new ClassExpression(classNode.getSuperClass()));
} else {
loadThis(expression);
}
return;
}
BytecodeVariable variable = controller.getCompileStack().getVariable(variableName, false);
if (variable == null) {
processClassVariable(variableName);
} else {
controller.getOperandStack().loadOrStoreVariable(variable, expression.isUseReferenceDirectly());
}
if (!controller.getCompileStack().isLHS())
controller.getAssertionWriter().record(expression);
}
use of org.codehaus.groovy.classgen.asm.BytecodeVariable in project groovy by apache.
the class StaticTypesStatementWriter method writeIteratorBasedForEachLoop.
private void writeIteratorBasedForEachLoop(CompileStack compileStack, OperandStack operandStack, MethodVisitor mv, ForStatement loop, Expression collectionExpression, ClassNode collectionType, Parameter loopVariable) {
// Declare the loop counter.
BytecodeVariable variable = compileStack.defineVariable(loopVariable, false);
if (StaticTypeCheckingSupport.implementsInterfaceOrIsSubclassOf(collectionType, ITERABLE_CLASSNODE)) {
MethodCallExpression iterator = new MethodCallExpression(collectionExpression, "iterator", new ArgumentListExpression());
iterator.setMethodTarget(collectionType.getMethod("iterator", Parameter.EMPTY_ARRAY));
iterator.setImplicitThis(false);
iterator.visit(controller.getAcg());
} else {
collectionExpression.visit(controller.getAcg());
mv.visitMethodInsn(INVOKESTATIC, "org/codehaus/groovy/runtime/DefaultGroovyMethods", "iterator", "(Ljava/lang/Object;)Ljava/util/Iterator;", false);
operandStack.replace(ClassHelper.Iterator_TYPE);
}
// Then get the iterator and generate the loop control
int iteratorIdx = compileStack.defineTemporaryVariable("iterator", ClassHelper.Iterator_TYPE, true);
Label continueLabel = compileStack.getContinueLabel();
Label breakLabel = compileStack.getBreakLabel();
mv.visitLabel(continueLabel);
mv.visitVarInsn(ALOAD, iteratorIdx);
writeIteratorHasNext(mv);
// note: ifeq tests for ==0, a boolean is 0 if it is false
mv.visitJumpInsn(IFEQ, breakLabel);
mv.visitVarInsn(ALOAD, iteratorIdx);
writeIteratorNext(mv);
operandStack.push(ClassHelper.OBJECT_TYPE);
operandStack.storeVar(variable);
// Generate the loop body
loop.getLoopBlock().visit(controller.getAcg());
mv.visitJumpInsn(GOTO, continueLabel);
mv.visitLabel(breakLabel);
compileStack.removeVar(iteratorIdx);
}
Aggregations