use of org.codehaus.groovy.classgen.AsmClassGenerator in project groovy by apache.
the class BinaryExpressionMultiTypeDispatcher method evaluateBinaryExpression.
@Override
protected void evaluateBinaryExpression(final String message, BinaryExpression binExp) {
int operation = removeAssignment(binExp.getOperation().getType());
ClassNode current = getController().getClassNode();
Expression leftExp = binExp.getLeftExpression();
ClassNode leftTypeOrig = getController().getTypeChooser().resolveType(leftExp, current);
ClassNode leftType = leftTypeOrig;
Expression rightExp = binExp.getRightExpression();
ClassNode rightType = getController().getTypeChooser().resolveType(rightExp, current);
AsmClassGenerator acg = getController().getAcg();
OperandStack os = getController().getOperandStack();
if (operation == LEFT_SQUARE_BRACKET) {
leftType = leftTypeOrig.getComponentType();
int operationType = getOperandType(leftType);
BinaryExpressionWriter bew = binExpWriter[operationType];
if (leftTypeOrig.isArray() && isIntCastableType(rightExp) && bew.arrayGet(operation, true)) {
leftExp.visit(acg);
os.doGroovyCast(leftTypeOrig);
rightExp.visit(acg);
os.doGroovyCast(int_TYPE);
bew.arrayGet(operation, false);
os.replace(bew.getArrayGetResultType(), 2);
} else {
super.evaluateBinaryExpression(message, binExp);
}
} else if (operation == DIVIDE) {
int operationType = getOperandType(getController().getTypeChooser().resolveType(binExp, current));
BinaryExpressionWriter bew = binExpWriter[operationType];
if (bew.writeDivision(true)) {
leftExp.visit(acg);
os.doGroovyCast(bew.getDevisionOpResultType());
rightExp.visit(acg);
os.doGroovyCast(bew.getDevisionOpResultType());
bew.writeDivision(false);
} else {
super.evaluateBinaryExpression(message, binExp);
}
} else {
int operationType = getOperandConversionType(leftType, rightType);
BinaryExpressionWriter bew = binExpWriter[operationType];
if (isShiftOperation(operation) && isIntCastableType(rightExp) && bew.write(operation, true)) {
leftExp.visit(acg);
os.doGroovyCast(bew.getNormalOpResultType());
rightExp.visit(acg);
os.doGroovyCast(int_TYPE);
bew.write(operation, false);
} else if (bew.write(operation, true)) {
leftExp.visit(acg);
os.doGroovyCast(bew.getNormalOpResultType());
rightExp.visit(acg);
os.doGroovyCast(bew.getNormalOpResultType());
bew.write(operation, false);
} else {
super.evaluateBinaryExpression(message, binExp);
}
}
}
use of org.codehaus.groovy.classgen.AsmClassGenerator in project groovy by apache.
the class BinaryExpressionMultiTypeDispatcher method assignToArray.
@Override
protected void assignToArray(Expression orig, 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()) {
OperandStack operandStack = getController().getOperandStack();
// load the array
receiver.visit(acg);
operandStack.doGroovyCast(arrayType);
// load index
index.visit(acg);
operandStack.doGroovyCast(int_TYPE);
// load rhs
rhsValueLoader.visit(acg);
operandStack.doGroovyCast(arrayComponentType);
// store value in array
bew.arraySet(false);
// load return value && correct operand stack stack
operandStack.remove(3);
rhsValueLoader.visit(acg);
} else {
super.assignToArray(orig, receiver, index, rhsValueLoader);
}
}
use of org.codehaus.groovy.classgen.AsmClassGenerator in project groovy by apache.
the class BinaryExpressionMultiTypeDispatcher method doPrimitiveCompare.
protected boolean doPrimitiveCompare(ClassNode leftType, ClassNode rightType, BinaryExpression binExp) {
Expression leftExp = binExp.getLeftExpression();
Expression rightExp = binExp.getRightExpression();
int operation = binExp.getOperation().getType();
int operationType = getOperandConversionType(leftType, rightType);
BinaryExpressionWriter bew = binExpWriter[operationType];
if (!bew.write(operation, true))
return false;
AsmClassGenerator acg = getController().getAcg();
OperandStack os = getController().getOperandStack();
leftExp.visit(acg);
os.doGroovyCast(bew.getNormalOpResultType());
rightExp.visit(acg);
os.doGroovyCast(bew.getNormalOpResultType());
bew.write(operation, false);
return true;
}
use of org.codehaus.groovy.classgen.AsmClassGenerator in project groovy by apache.
the class InvocationWriter method makeUncachedCall.
protected void makeUncachedCall(Expression origin, ClassExpression sender, Expression receiver, Expression message, Expression arguments, MethodCallerMultiAdapter adapter, boolean safe, boolean spreadSafe, boolean implicitThis, boolean containsSpreadExpression) {
OperandStack operandStack = controller.getOperandStack();
CompileStack compileStack = controller.getCompileStack();
AsmClassGenerator acg = controller.getAcg();
// ensure VariableArguments are read, not stored
compileStack.pushLHS(false);
// sender only for call sites
if (adapter == AsmClassGenerator.setProperty) {
ConstantExpression.NULL.visit(acg);
} else {
sender.visit(acg);
}
String methodName = getMethodName(message);
if (adapter == invokeMethodOnSuper && methodName != null) {
controller.getSuperMethodNames().add(methodName);
}
// receiver
compileStack.pushImplicitThis(implicitThis);
receiver.visit(acg);
operandStack.box();
compileStack.popImplicitThis();
int operandsToRemove = 2;
// message
if (message != null) {
message.visit(acg);
operandStack.box();
operandsToRemove++;
}
// arguments
int numberOfArguments = containsSpreadExpression ? -1 : AsmClassGenerator.argumentSize(arguments);
if (numberOfArguments > MethodCallerMultiAdapter.MAX_ARGS || containsSpreadExpression) {
ArgumentListExpression ae = makeArgumentList(arguments);
if (containsSpreadExpression) {
acg.despreadList(ae.getExpressions(), true);
} else {
ae.visit(acg);
}
} else if (numberOfArguments > 0) {
operandsToRemove += numberOfArguments;
TupleExpression te = (TupleExpression) arguments;
for (int i = 0; i < numberOfArguments; i++) {
Expression argument = te.getExpression(i);
argument.visit(acg);
operandStack.box();
if (argument instanceof CastExpression)
acg.loadWrapper(argument);
}
}
if (adapter == null)
adapter = invokeMethod;
adapter.call(controller.getMethodVisitor(), numberOfArguments, safe, spreadSafe);
compileStack.popLHS();
operandStack.replace(ClassHelper.OBJECT_TYPE, operandsToRemove);
}
use of org.codehaus.groovy.classgen.AsmClassGenerator in project groovy by apache.
the class InvocationWriter method loadArguments.
// load arguments
protected void loadArguments(List<Expression> argumentList, Parameter[] para) {
if (para.length == 0)
return;
ClassNode lastParaType = para[para.length - 1].getOriginType();
AsmClassGenerator acg = controller.getAcg();
OperandStack operandStack = controller.getOperandStack();
if (lastParaType.isArray() && (argumentList.size() > para.length || argumentList.size() == para.length - 1 || !lastIsArray(argumentList, para.length - 1))) {
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++) {
argumentList.get(i).visit(acg);
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 {
for (int i = 0; i < argumentList.size(); i++) {
argumentList.get(i).visit(acg);
operandStack.doGroovyCast(para[i].getType());
}
}
}
Aggregations