use of org.objectweb.asm.MethodVisitor in project groovy by apache.
the class StaticTypesCallSiteWriter method writeOperatorCall.
private void writeOperatorCall(Expression receiver, Expression arguments, String operator) {
prepareSiteAndReceiver(receiver, operator, false, controller.getCompileStack().isLHS());
controller.getOperandStack().doGroovyCast(Number_TYPE);
visitBoxedArgument(arguments);
controller.getOperandStack().doGroovyCast(Number_TYPE);
MethodVisitor mv = controller.getMethodVisitor();
mv.visitMethodInsn(INVOKESTATIC, "org/codehaus/groovy/runtime/typehandling/NumberMath", operator, "(Ljava/lang/Number;Ljava/lang/Number;)Ljava/lang/Number;", false);
controller.getOperandStack().replace(Number_TYPE, 2);
}
use of org.objectweb.asm.MethodVisitor in project groovy by apache.
the class StaticTypesCallSiteWriter method writePowerCall.
private void writePowerCall(Expression receiver, Expression arguments, final ClassNode rType, ClassNode aType) {
OperandStack operandStack = controller.getOperandStack();
int m1 = operandStack.getStackLength();
//slow Path
prepareSiteAndReceiver(receiver, "power", false, controller.getCompileStack().isLHS());
operandStack.doGroovyCast(getWrapper(rType));
visitBoxedArgument(arguments);
operandStack.doGroovyCast(getWrapper(aType));
int m2 = operandStack.getStackLength();
MethodVisitor mv = controller.getMethodVisitor();
if (BigDecimal_TYPE.equals(rType) && Integer_TYPE.equals(getWrapper(aType))) {
mv.visitMethodInsn(INVOKESTATIC, "org/codehaus/groovy/runtime/DefaultGroovyMethods", "power", "(Ljava/math/BigDecimal;Ljava/lang/Integer;)Ljava/lang/Number;", false);
} else if (BigInteger_TYPE.equals(rType) && Integer_TYPE.equals(getWrapper(aType))) {
mv.visitMethodInsn(INVOKESTATIC, "org/codehaus/groovy/runtime/DefaultGroovyMethods", "power", "(Ljava/math/BigInteger;Ljava/lang/Integer;)Ljava/lang/Number;", false);
} else if (Long_TYPE.equals(getWrapper(rType)) && Integer_TYPE.equals(getWrapper(aType))) {
mv.visitMethodInsn(INVOKESTATIC, "org/codehaus/groovy/runtime/DefaultGroovyMethods", "power", "(Ljava/lang/Long;Ljava/lang/Integer;)Ljava/lang/Number;", false);
} else if (Integer_TYPE.equals(getWrapper(rType)) && Integer_TYPE.equals(getWrapper(aType))) {
mv.visitMethodInsn(INVOKESTATIC, "org/codehaus/groovy/runtime/DefaultGroovyMethods", "power", "(Ljava/lang/Integer;Ljava/lang/Integer;)Ljava/lang/Number;", false);
} else {
mv.visitMethodInsn(INVOKESTATIC, "org/codehaus/groovy/runtime/DefaultGroovyMethods", "power", "(Ljava/lang/Number;Ljava/lang/Number;)Ljava/lang/Number;", false);
}
controller.getOperandStack().replace(Number_TYPE, m2 - m1);
}
use of org.objectweb.asm.MethodVisitor in project groovy by apache.
the class StaticTypesCallSiteWriter method makeGetField.
boolean makeGetField(final Expression receiver, final ClassNode receiverType, final String fieldName, final boolean safe, final boolean implicitThis, final boolean samePackage) {
FieldNode field = receiverType.getField(fieldName);
// or we are in an inner class
if (field != null && isDirectAccessAllowed(field, controller.getClassNode(), samePackage)) {
CompileStack compileStack = controller.getCompileStack();
MethodVisitor mv = controller.getMethodVisitor();
ClassNode replacementType = field.getOriginType();
OperandStack operandStack = controller.getOperandStack();
if (field.isStatic()) {
mv.visitFieldInsn(GETSTATIC, BytecodeHelper.getClassInternalName(field.getOwner()), fieldName, BytecodeHelper.getTypeDescription(replacementType));
operandStack.push(replacementType);
} else {
if (implicitThis) {
compileStack.pushImplicitThis(implicitThis);
}
receiver.visit(controller.getAcg());
if (implicitThis)
compileStack.popImplicitThis();
Label exit = new Label();
if (safe) {
mv.visitInsn(DUP);
Label doGet = new Label();
mv.visitJumpInsn(IFNONNULL, doGet);
mv.visitInsn(POP);
mv.visitInsn(ACONST_NULL);
mv.visitJumpInsn(GOTO, exit);
mv.visitLabel(doGet);
}
if (!operandStack.getTopOperand().isDerivedFrom(field.getOwner())) {
mv.visitTypeInsn(CHECKCAST, BytecodeHelper.getClassInternalName(field.getOwner()));
}
mv.visitFieldInsn(GETFIELD, BytecodeHelper.getClassInternalName(field.getOwner()), fieldName, BytecodeHelper.getTypeDescription(replacementType));
if (safe) {
if (ClassHelper.isPrimitiveType(replacementType)) {
operandStack.replace(replacementType);
operandStack.box();
replacementType = operandStack.getTopOperand();
}
mv.visitLabel(exit);
}
}
operandStack.replace(replacementType);
return true;
}
for (ClassNode intf : receiverType.getInterfaces()) {
// GROOVY-7039
if (intf != receiverType && makeGetField(receiver, intf, fieldName, safe, implicitThis, false)) {
return true;
}
}
ClassNode superClass = receiverType.getSuperClass();
if (superClass != null) {
return makeGetField(receiver, superClass, fieldName, safe, implicitThis, false);
}
return false;
}
use of org.objectweb.asm.MethodVisitor in project groovy by apache.
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.objectweb.asm.MethodVisitor in project groovy by apache.
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;
}
Aggregations