use of org.codehaus.groovy.classgen.BytecodeExpression in project groovy-core by groovy.
the class StaticTypesUnaryExpressionHelper method writeUnaryMinus.
@Override
public void writeUnaryMinus(final UnaryMinusExpression expression) {
expression.getExpression().visit(controller.getAcg());
if (isPrimitiveOnTop()) {
final ClassNode top = getTopOperand();
if (top != boolean_TYPE) {
BytecodeExpression bytecodeExpression = new BytecodeExpression() {
@Override
public void visit(final MethodVisitor mv) {
if (int_TYPE == top || short_TYPE == top || byte_TYPE == top || char_TYPE == top) {
mv.visitInsn(INEG);
if (byte_TYPE == top) {
mv.visitInsn(I2B);
} else if (char_TYPE == top) {
mv.visitInsn(I2C);
} else if (short_TYPE == top) {
mv.visitInsn(I2S);
}
} else if (long_TYPE == top) {
mv.visitInsn(LNEG);
} else if (float_TYPE == top) {
mv.visitInsn(FNEG);
} else if (double_TYPE == top) {
mv.visitInsn(DNEG);
}
}
};
bytecodeExpression.visit(controller.getAcg());
controller.getOperandStack().remove(1);
return;
}
}
// we already visited the sub expression
super.writeUnaryMinus(EMPTY_UNARY_MINUS);
}
use of org.codehaus.groovy.classgen.BytecodeExpression in project groovy-core by groovy.
the class StaticTypesUnaryExpressionHelper method writeNotExpression.
@Override
public void writeNotExpression(final NotExpression expression) {
TypeChooser typeChooser = controller.getTypeChooser();
Expression subExpression = expression.getExpression();
ClassNode classNode = controller.getClassNode();
if (typeChooser.resolveType(subExpression, classNode) == boolean_TYPE) {
subExpression.visit(controller.getAcg());
controller.getOperandStack().doGroovyCast(boolean_TYPE);
BytecodeExpression bytecodeExpression = new BytecodeExpression() {
@Override
public void visit(final MethodVisitor mv) {
Label ne = new Label();
mv.visitJumpInsn(IFNE, ne);
mv.visitInsn(ICONST_1);
Label out = new Label();
mv.visitJumpInsn(GOTO, out);
mv.visitLabel(ne);
mv.visitInsn(ICONST_0);
mv.visitLabel(out);
}
};
bytecodeExpression.visit(controller.getAcg());
controller.getOperandStack().remove(1);
return;
}
super.writeNotExpression(expression);
}
use of org.codehaus.groovy.classgen.BytecodeExpression in project groovy-core by groovy.
the class StaticTypesCallSiteWriter method makeGroovyObjectGetPropertySite.
@Override
public void makeGroovyObjectGetPropertySite(final Expression receiver, final String methodName, final boolean safe, final boolean implicitThis) {
TypeChooser typeChooser = controller.getTypeChooser();
ClassNode classNode = controller.getClassNode();
ClassNode receiverType = typeChooser.resolveType(receiver, classNode);
if (receiver instanceof VariableExpression && ((VariableExpression) receiver).isThisExpression() && !controller.isInClosure()) {
receiverType = classNode;
}
String property = methodName;
if (implicitThis) {
if (controller.getInvocationWriter() instanceof StaticInvocationWriter) {
MethodCallExpression currentCall = ((StaticInvocationWriter) controller.getInvocationWriter()).getCurrentCall();
if (currentCall != null && currentCall.getNodeMetaData(StaticTypesMarker.IMPLICIT_RECEIVER) != null) {
property = (String) currentCall.getNodeMetaData(StaticTypesMarker.IMPLICIT_RECEIVER);
String[] props = property.split("\\.");
BytecodeExpression thisLoader = new BytecodeExpression() {
@Override
public void visit(final MethodVisitor mv) {
// load this
mv.visitVarInsn(ALOAD, 0);
}
};
thisLoader.setType(CLOSURE_TYPE);
Expression pexp = new PropertyExpression(thisLoader, new ConstantExpression(props[0]), safe);
for (int i = 1, propsLength = props.length; i < propsLength; i++) {
final String prop = props[i];
pexp.putNodeMetaData(StaticTypesMarker.INFERRED_TYPE, CLOSURE_TYPE);
pexp = new PropertyExpression(pexp, prop);
}
pexp.visit(controller.getAcg());
return;
}
}
}
if (makeGetPropertyWithGetter(receiver, receiverType, property, safe, implicitThis))
return;
if (makeGetPrivateFieldWithBridgeMethod(receiver, receiverType, property, safe, implicitThis))
return;
if (makeGetField(receiver, receiverType, property, safe, implicitThis, samePackages(receiverType.getPackageName(), classNode.getPackageName())))
return;
MethodCallExpression call = new MethodCallExpression(receiver, "getProperty", new ArgumentListExpression(new ConstantExpression(property)));
call.setImplicitThis(implicitThis);
call.setSafe(safe);
call.setMethodTarget(GROOVYOBJECT_GETPROPERTY_METHOD);
call.visit(controller.getAcg());
return;
}
use of org.codehaus.groovy.classgen.BytecodeExpression in project groovy-core by groovy.
the class StaticTypesCallSiteWriter method writeListDotProperty.
private void writeListDotProperty(final Expression receiver, final String methodName, final MethodVisitor mv, final boolean safe) {
ClassNode componentType = (ClassNode) receiver.getNodeMetaData(StaticCompilationMetadataKeys.COMPONENT_TYPE);
if (componentType == null) {
componentType = OBJECT_TYPE;
}
// for lists, replace list.foo with:
// def result = new ArrayList(list.size())
// for (e in list) { result.add (e.foo) }
// result
CompileStack compileStack = controller.getCompileStack();
Label exit = new Label();
if (safe) {
receiver.visit(controller.getAcg());
Label doGet = new Label();
mv.visitJumpInsn(IFNONNULL, doGet);
controller.getOperandStack().remove(1);
mv.visitInsn(ACONST_NULL);
mv.visitJumpInsn(GOTO, exit);
mv.visitLabel(doGet);
}
Variable tmpList = new VariableExpression("tmpList", make(ArrayList.class));
int var = compileStack.defineTemporaryVariable(tmpList, false);
Variable iterator = new VariableExpression("iterator", Iterator_TYPE);
int it = compileStack.defineTemporaryVariable(iterator, false);
Variable nextVar = new VariableExpression("next", componentType);
final int next = compileStack.defineTemporaryVariable(nextVar, false);
mv.visitTypeInsn(NEW, "java/util/ArrayList");
mv.visitInsn(DUP);
receiver.visit(controller.getAcg());
mv.visitMethodInsn(INVOKEINTERFACE, "java/util/List", "size", "()I", true);
controller.getOperandStack().remove(1);
mv.visitMethodInsn(INVOKESPECIAL, "java/util/ArrayList", "<init>", "(I)V", false);
mv.visitVarInsn(ASTORE, var);
Label l1 = new Label();
mv.visitLabel(l1);
receiver.visit(controller.getAcg());
mv.visitMethodInsn(INVOKEINTERFACE, "java/util/List", "iterator", "()Ljava/util/Iterator;", true);
controller.getOperandStack().remove(1);
mv.visitVarInsn(ASTORE, it);
Label l2 = new Label();
mv.visitLabel(l2);
mv.visitVarInsn(ALOAD, it);
mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Iterator", "hasNext", "()Z", true);
Label l3 = new Label();
mv.visitJumpInsn(IFEQ, l3);
mv.visitVarInsn(ALOAD, it);
mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Iterator", "next", "()Ljava/lang/Object;", true);
mv.visitTypeInsn(CHECKCAST, BytecodeHelper.getClassInternalName(componentType));
mv.visitVarInsn(ASTORE, next);
Label l4 = new Label();
mv.visitLabel(l4);
mv.visitVarInsn(ALOAD, var);
final ClassNode finalComponentType = componentType;
PropertyExpression pexp = new PropertyExpression(new BytecodeExpression() {
@Override
public void visit(final MethodVisitor mv) {
mv.visitVarInsn(ALOAD, next);
}
@Override
public ClassNode getType() {
return finalComponentType;
}
}, methodName);
pexp.visit(controller.getAcg());
controller.getOperandStack().box();
controller.getOperandStack().remove(1);
mv.visitMethodInsn(INVOKEINTERFACE, "java/util/List", "add", "(Ljava/lang/Object;)Z", true);
mv.visitInsn(POP);
Label l5 = new Label();
mv.visitLabel(l5);
mv.visitJumpInsn(GOTO, l2);
mv.visitLabel(l3);
mv.visitVarInsn(ALOAD, var);
if (safe) {
mv.visitLabel(exit);
}
controller.getOperandStack().push(make(ArrayList.class));
controller.getCompileStack().removeVar(next);
controller.getCompileStack().removeVar(it);
controller.getCompileStack().removeVar(var);
}
use of org.codehaus.groovy.classgen.BytecodeExpression in project groovy by apache.
the class BinaryExpressionHelper method writePostOrPrefixMethod.
protected void writePostOrPrefixMethod(int op, String method, Expression expression, Expression orig) {
final OperandStack operandStack = controller.getOperandStack();
// at this point the receiver will be already on the stack.
// in a[1]++ the method will be "++" aka "next" and the receiver a[1]
ClassNode BEType = controller.getTypeChooser().resolveType(expression, controller.getClassNode());
Expression callSiteReceiverSwap = new BytecodeExpression(BEType) {
@Override
public void visit(MethodVisitor mv) {
// CallSite is normally not showing up on the
// operandStack, so we place a dummy here with same
// slot length.
operandStack.push(ClassHelper.OBJECT_TYPE);
// change (receiver,callsite) to (callsite,receiver)
operandStack.swap();
setType(operandStack.getTopOperand());
// no need to keep any of those on the operand stack
// after this expression is processed, the operand stack
// will contain callSiteReceiverSwap.getType()
operandStack.remove(2);
}
};
// execute method
// this will load the callsite and the receiver normally in the wrong
// order since the receiver is already present, but before the callsite
// Therefore we use callSiteReceiverSwap to correct the order.
// After this call the JVM operand stack will contain the the result of
// the method call... usually simply Object in operandStack
controller.getCallSiteWriter().makeCallSite(callSiteReceiverSwap, method, MethodCallExpression.NO_ARGUMENTS, false, false, false, false);
// now rhs is completely done and we need only to store. In a[1]++ this
// would be a.getAt(1).next() for the rhs, "lhs" code is a.putAt(1, rhs)
}
Aggregations