use of org.codehaus.groovy.classgen.AsmClassGenerator in project groovy-core by groovy.
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.size() > 0 ? 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();
MethodVisitor orig = mv;
//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-core by groovy.
the class StaticTypesBinaryExpressionMultiTypeDispatcher method assignToArray.
protected void assignToArray(Expression parent, Expression receiver, Expression index, Expression rhsValueLoader) {
ClassNode current = getController().getClassNode();
ClassNode arrayType = getController().getTypeChooser().resolveType(receiver, current);
ClassNode arrayComponentType = arrayType.getComponentType();
int operationType = getOperandType(arrayComponentType);
BinaryExpressionWriter bew = binExpWriter[operationType];
AsmClassGenerator acg = getController().getAcg();
if (bew.arraySet(true) && arrayType.isArray()) {
super.assignToArray(parent, receiver, index, rhsValueLoader);
} else {
/******
/ This code path is needed because ACG creates array access expressions
*******/
WriterController controller = getController();
StaticTypeCheckingVisitor visitor = new StaticCompilationVisitor(controller.getSourceUnit(), controller.getClassNode());
// let's replace this assignment to a subscript operator with a
// method call
// e.g. x[5] = 10
// -> (x, [], 5), =, 10
// -> methodCall(x, "putAt", [5, 10])
ArgumentListExpression ae = new ArgumentListExpression(index, rhsValueLoader);
if (rhsValueLoader instanceof VariableSlotLoader && parent instanceof BinaryExpression) {
// GROOVY-6061
Expression right = ((BinaryExpression) parent).getRightExpression();
rhsValueLoader.putNodeMetaData(StaticTypesMarker.INFERRED_TYPE, controller.getTypeChooser().resolveType(parent, controller.getClassNode()));
}
MethodCallExpression mce = new MethodCallExpression(receiver, "putAt", ae);
mce.setSourcePosition(parent);
visitor.visitMethodCallExpression(mce);
OperandStack operandStack = controller.getOperandStack();
int height = operandStack.getStackLength();
mce.visit(controller.getAcg());
operandStack.pop();
operandStack.remove(operandStack.getStackLength() - height);
// return value of assignment
rhsValueLoader.visit(controller.getAcg());
}
}
use of org.codehaus.groovy.classgen.AsmClassGenerator in project groovy-core by groovy.
the class CompareIdentityExpression method visit.
@Override
public void visit(final GroovyCodeVisitor visitor) {
if (visitor instanceof AsmClassGenerator) {
AsmClassGenerator acg = (AsmClassGenerator) visitor;
WriterController controller = acg.getController();
ClassNode leftType = controller.getTypeChooser().resolveType(leftExpression, controller.getClassNode());
ClassNode rightType = 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-core by groovy.
the class TemporaryVariableExpression method visit.
@Override
public void visit(final GroovyCodeVisitor visitor) {
if (visitor instanceof AsmClassGenerator) {
if (variable == null) {
AsmClassGenerator acg = (AsmClassGenerator) visitor;
WriterController controller = acg.getController();
variable = new ExpressionAsVariableSlot(controller, expression);
}
variable.visit(visitor);
} else {
expression.visit(visitor);
}
}
use of org.codehaus.groovy.classgen.AsmClassGenerator in project groovy-core by groovy.
the class CompareToNullExpression method visit.
@Override
public void visit(final GroovyCodeVisitor visitor) {
if (visitor instanceof AsmClassGenerator) {
AsmClassGenerator acg = (AsmClassGenerator) visitor;
WriterController controller = acg.getController();
MethodVisitor mv = controller.getMethodVisitor();
objectExpression.visit(acg);
ClassNode top = controller.getOperandStack().getTopOperand();
if (ClassHelper.isPrimitiveType(top)) {
controller.getOperandStack().pop();
mv.visitInsn(ICONST_0);
controller.getOperandStack().push(ClassHelper.boolean_TYPE);
return;
}
Label zero = new Label();
mv.visitJumpInsn(equalsNull ? IFNONNULL : IFNULL, zero);
mv.visitInsn(ICONST_1);
Label end = new Label();
mv.visitJumpInsn(GOTO, end);
mv.visitLabel(zero);
mv.visitInsn(ICONST_0);
mv.visitLabel(end);
controller.getOperandStack().replace(ClassHelper.boolean_TYPE);
} else {
super.visit(visitor);
}
}
Aggregations