use of org.codehaus.groovy.classgen.AsmClassGenerator in project groovy by apache.
the class CompareIdentityExpression method visit.
@Override
public void visit(final GroovyCodeVisitor visitor) {
if (visitor instanceof AsmClassGenerator) {
AsmClassGenerator acg = (AsmClassGenerator) visitor;
WriterController controller = acg.getController();
controller.getTypeChooser().resolveType(leftExpression, controller.getClassNode());
controller.getTypeChooser().resolveType(rightExpression, controller.getClassNode());
MethodVisitor mv = controller.getMethodVisitor();
leftExpression.visit(acg);
controller.getOperandStack().box();
rightExpression.visit(acg);
controller.getOperandStack().box();
Label l1 = new Label();
mv.visitJumpInsn(IF_ACMPNE, l1);
mv.visitInsn(ICONST_1);
Label l2 = new Label();
mv.visitJumpInsn(GOTO, l2);
mv.visitLabel(l1);
mv.visitInsn(ICONST_0);
mv.visitLabel(l2);
controller.getOperandStack().replace(ClassHelper.boolean_TYPE, 2);
} else {
super.visit(visitor);
}
}
use of org.codehaus.groovy.classgen.AsmClassGenerator in project groovy by apache.
the class StaticInvocationWriter method loadArguments.
protected void loadArguments(List<Expression> argumentList, Parameter[] para) {
if (para.length == 0)
return;
ClassNode lastParaType = para[para.length - 1].getOriginType();
AsmClassGenerator acg = controller.getAcg();
TypeChooser typeChooser = controller.getTypeChooser();
OperandStack operandStack = controller.getOperandStack();
ClassNode lastArgType = !argumentList.isEmpty() ? typeChooser.resolveType(argumentList.get(argumentList.size() - 1), controller.getClassNode()) : null;
if (lastParaType.isArray() && ((argumentList.size() > para.length) || ((argumentList.size() == (para.length - 1)) && !lastParaType.equals(lastArgType)) || ((argumentList.size() == para.length && lastArgType != null && !lastArgType.isArray()) && (StaticTypeCheckingSupport.implementsInterfaceOrIsSubclassOf(lastArgType, lastParaType.getComponentType()))) || ClassHelper.GSTRING_TYPE.equals(lastArgType) && ClassHelper.STRING_TYPE.equals(lastParaType.getComponentType()))) {
int stackLen = operandStack.getStackLength() + argumentList.size();
MethodVisitor mv = controller.getMethodVisitor();
//mv = new org.objectweb.asm.util.TraceMethodVisitor(mv);
controller.setMethodVisitor(mv);
// first parameters as usual
for (int i = 0; i < para.length - 1; i++) {
Expression expression = argumentList.get(i);
expression.visit(acg);
if (!isNullConstant(expression)) {
operandStack.doGroovyCast(para[i].getType());
}
}
// last parameters wrapped in an array
List<Expression> lastParams = new LinkedList<Expression>();
for (int i = para.length - 1; i < argumentList.size(); i++) {
lastParams.add(argumentList.get(i));
}
ArrayExpression array = new ArrayExpression(lastParaType.getComponentType(), lastParams);
array.visit(acg);
// adjust stack length
while (operandStack.getStackLength() < stackLen) {
operandStack.push(ClassHelper.OBJECT_TYPE);
}
if (argumentList.size() == para.length - 1) {
operandStack.remove(1);
}
} else if (argumentList.size() == para.length) {
for (int i = 0; i < argumentList.size(); i++) {
Expression expression = argumentList.get(i);
expression.visit(acg);
if (!isNullConstant(expression)) {
operandStack.doGroovyCast(para[i].getType());
}
}
} else {
// method call with default arguments
ClassNode classNode = controller.getClassNode();
Expression[] arguments = new Expression[para.length];
for (int i = 0, j = 0; i < para.length; i++) {
Parameter curParam = para[i];
ClassNode curParamType = curParam.getType();
Expression curArg = j < argumentList.size() ? argumentList.get(j) : null;
Expression initialExpression = (Expression) curParam.getNodeMetaData(StaticTypesMarker.INITIAL_EXPRESSION);
if (initialExpression == null && curParam.hasInitialExpression())
initialExpression = curParam.getInitialExpression();
if (initialExpression == null && curParam.getNodeMetaData(Verifier.INITIAL_EXPRESSION) != null) {
initialExpression = (Expression) curParam.getNodeMetaData(Verifier.INITIAL_EXPRESSION);
}
ClassNode curArgType = curArg == null ? null : typeChooser.resolveType(curArg, classNode);
if (initialExpression != null && !compatibleArgumentType(curArgType, curParamType)) {
// use default expression
arguments[i] = initialExpression;
} else {
arguments[i] = curArg;
j++;
}
}
for (int i = 0; i < arguments.length; i++) {
Expression expression = arguments[i];
expression.visit(acg);
if (!isNullConstant(expression)) {
operandStack.doGroovyCast(para[i].getType());
}
}
}
}
use of org.codehaus.groovy.classgen.AsmClassGenerator 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.AsmClassGenerator in project groovy by apache.
the class InvocationWriter method invokeClosure.
private void invokeClosure(Expression arguments, String methodName) {
AsmClassGenerator acg = controller.getAcg();
acg.visitVariableExpression(new VariableExpression(methodName));
controller.getOperandStack().box();
if (arguments instanceof TupleExpression) {
arguments.visit(acg);
} else {
new TupleExpression(arguments).visit(acg);
}
invokeClosureMethod.call(controller.getMethodVisitor());
controller.getOperandStack().replace(ClassHelper.OBJECT_TYPE);
}
use of org.codehaus.groovy.classgen.AsmClassGenerator in project groovy by apache.
the class BinaryExpressionHelper method evaluateBinaryExpressionWithAssignment.
protected void evaluateBinaryExpressionWithAssignment(String method, BinaryExpression expression) {
Expression leftExpression = expression.getLeftExpression();
AsmClassGenerator acg = controller.getAcg();
OperandStack operandStack = controller.getOperandStack();
if (leftExpression instanceof BinaryExpression) {
BinaryExpression leftBinExpr = (BinaryExpression) leftExpression;
if (leftBinExpr.getOperation().getType() == Types.LEFT_SQUARE_BRACKET) {
evaluateArrayAssignmentWithOperator(method, expression, leftBinExpr);
return;
}
}
evaluateBinaryExpression(method, expression);
// br to leave a copy of rvalue on the stack. see also isPopRequired()
operandStack.dup();
controller.getCompileStack().pushLHS(true);
leftExpression.visit(acg);
controller.getCompileStack().popLHS();
}
Aggregations