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;
}
use of org.objectweb.asm.MethodVisitor in project groovy by apache.
the class StaticTypesUnaryExpressionHelper method writeBitwiseNegate.
@Override
public void writeBitwiseNegate(final BitwiseNegationExpression expression) {
expression.getExpression().visit(controller.getAcg());
if (isPrimitiveOnTop()) {
final ClassNode top = getTopOperand();
if (top == int_TYPE || top == short_TYPE || top == byte_TYPE || top == char_TYPE || top == long_TYPE) {
BytecodeExpression bytecodeExpression = new BytecodeExpression() {
@Override
public void visit(final MethodVisitor mv) {
if (long_TYPE == top) {
mv.visitLdcInsn(-1);
mv.visitInsn(LXOR);
} else {
mv.visitInsn(ICONST_M1);
mv.visitInsn(IXOR);
if (byte_TYPE == top) {
mv.visitInsn(I2B);
} else if (char_TYPE == top) {
mv.visitInsn(I2C);
} else if (short_TYPE == top) {
mv.visitInsn(I2S);
}
}
}
};
bytecodeExpression.visit(controller.getAcg());
controller.getOperandStack().remove(1);
return;
}
}
super.writeBitwiseNegate(EMPTY_BITWISE_NEGATE);
}
use of org.objectweb.asm.MethodVisitor in project groovy by apache.
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);
}
Aggregations