List of usage examples for org.objectweb.asm MethodVisitor visitLdcInsn
public void visitLdcInsn(final Object value)
From source file:org.codehaus.groovy.classgen.asm.CallSiteWriter.java
License:Apache License
public void prepareCallSite(String message) { MethodVisitor mv = controller.getMethodVisitor(); if (controller.isNotClinit()) { mv.visitVarInsn(ALOAD, callSiteArrayVarIndex); } else {//from w w w. j ava 2 s . c o m mv.visitMethodInsn(INVOKESTATIC, controller.getClassName(), GET_CALLSITE_METHOD, GET_CALLSITE_DESC, false); } final int index = allocateIndex(message); mv.visitLdcInsn(index); mv.visitInsn(AALOAD); }
From source file:org.codehaus.groovy.classgen.asm.CompileStack.java
License:Apache License
private static void pushInitValue(ClassNode type, MethodVisitor mv) { if (ClassHelper.isPrimitiveType(type)) { if (type == ClassHelper.long_TYPE) { mv.visitInsn(LCONST_0);//from w ww. ja v a 2 s. c o m } else if (type == ClassHelper.double_TYPE) { mv.visitInsn(DCONST_0); } else if (type == ClassHelper.float_TYPE) { mv.visitInsn(FCONST_0); } else { mv.visitLdcInsn(0); } } else { mv.visitInsn(ACONST_NULL); } }
From source file:org.codehaus.groovy.classgen.asm.InvocationWriter.java
License:Apache License
private void makeMOPBasedConstructorCall(final List<ConstructorNode> constructors, final ConstructorCallExpression call, final ClassNode callNode) { MethodVisitor mv = controller.getMethodVisitor(); OperandStack operandStack = controller.getOperandStack(); call.getArguments().visit(controller.getAcg()); // keep Object[] on stack mv.visitInsn(DUP);/*from w w w.ja v a 2 s. co m*/ // to select the constructor we need also the number of // available constructors and the class we want to make // the call on BytecodeHelper.pushConstant(mv, -1); controller.getAcg().visitClassExpression(new ClassExpression(callNode)); operandStack.remove(1); // removes one Object[] leaves the int containing the // call flags and the constructor number selectConstructorAndTransformArguments.call(mv); //load "this" if (controller.isConstructor()) { mv.visitVarInsn(ALOAD, 0); } else { mv.visitTypeInsn(NEW, BytecodeHelper.getClassInternalName(callNode)); } mv.visitInsn(SWAP); TreeMap<Integer, ConstructorNode> sortedConstructors = new TreeMap<>(); for (ConstructorNode constructor : constructors) { String typeDescriptor = BytecodeHelper.getMethodDescriptor(ClassHelper.VOID_TYPE, constructor.getParameters()); int hash = BytecodeHelper.hashCode(typeDescriptor); ConstructorNode sameHashNode = sortedConstructors.put(hash, constructor); if (sameHashNode != null) { controller.getSourceUnit() .addError(new SyntaxException( "Unable to compile class " + controller.getClassNode().getName() + " due to hash collision in constructors", call.getLineNumber(), call.getColumnNumber())); } } Label[] targets = new Label[constructors.size()]; int[] indices = new int[constructors.size()]; Iterator<Integer> hashIt = sortedConstructors.keySet().iterator(); Iterator<ConstructorNode> constructorIt = sortedConstructors.values().iterator(); for (int i = 0, n = targets.length; i < n; i += 1) { targets[i] = new Label(); indices[i] = hashIt.next(); } // create switch targets Label defaultLabel = new Label(); Label afterSwitch = new Label(); mv.visitLookupSwitchInsn(defaultLabel, indices, targets); for (Label target : targets) { mv.visitLabel(target); // to keep the stack height, we need to leave // one Object[] on the stack as last element. At the // same time, we need the Object[] on top of the stack // to extract the parameters. if (controller.isConstructor()) { // in this case we need one "this", so a SWAP will exchange // "this" and Object[], a DUP_X1 will then copy the Object[] /// to the last place in the stack: // Object[],this -SWAP-> this,Object[] // this,Object[] -DUP_X1-> Object[],this,Object[] mv.visitInsn(SWAP); mv.visitInsn(DUP_X1); } else { // in this case we need two "this" in between and the Object[] // at the bottom of the stack as well as on top for our invokeSpecial // So we do DUP_X1, DUP2_X1, POP // Object[],this -DUP_X1-> this,Object[],this // this,Object[],this -DUP2_X1-> Object[],this,this,Object[],this // Object[],this,this,Object[],this -POP-> Object[],this,this,Object[] mv.visitInsn(DUP_X1); mv.visitInsn(DUP2_X1); mv.visitInsn(POP); } ConstructorNode cn = constructorIt.next(); String descriptor = BytecodeHelper.getMethodDescriptor(ClassHelper.VOID_TYPE, cn.getParameters()); // unwrap the Object[] and make transformations if needed // that means, to duplicate the Object[], make a cast with possible // unboxing and then swap it with the Object[] for each parameter // vargs need special attention and transformation though Parameter[] parameters = cn.getParameters(); int lengthWithoutVargs = parameters.length; if (parameters.length > 0 && parameters[parameters.length - 1].getType().isArray()) { lengthWithoutVargs -= 1; } for (int p = 0; p < lengthWithoutVargs; p += 1) { loadAndCastElement(operandStack, mv, parameters, p); } if (parameters.length > lengthWithoutVargs) { ClassNode type = parameters[lengthWithoutVargs].getType(); BytecodeHelper.pushConstant(mv, lengthWithoutVargs); controller.getAcg().visitClassExpression(new ClassExpression(type)); operandStack.remove(1); castToVargsArray.call(mv); BytecodeHelper.doCast(mv, type); } else { // at the end we remove the Object[] // the vargs case simply the last swap so no pop is needed mv.visitInsn(POP); } // make the constructor call mv.visitMethodInsn(INVOKESPECIAL, BytecodeHelper.getClassInternalName(callNode), "<init>", descriptor, false); mv.visitJumpInsn(GOTO, afterSwitch); } mv.visitLabel(defaultLabel); // this part should never be reached! mv.visitTypeInsn(NEW, "java/lang/IllegalArgumentException"); mv.visitInsn(DUP); mv.visitLdcInsn( "This class has been compiled with a super class which is binary incompatible with the current super class found on classpath. You should recompile this class with the new version."); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/IllegalArgumentException", "<init>", "(Ljava/lang/String;)V", false); mv.visitInsn(ATHROW); mv.visitLabel(afterSwitch); // For a special constructor call inside a constructor we don't need // any result object on the stack, for outside the constructor we do. // to keep the stack height for the able we kept one object as dummy // result on the stack, which we can remove now if inside a constructor. if (!controller.isConstructor()) { // in case we are not in a constructor we have an additional // object on the stack, the result of our constructor call // which we want to keep, so we swap with the dummy object and // do normal removal of it. In the end, the call result will be // on the stack then mv.visitInsn(SWAP); operandStack.push(callNode); // for call result } mv.visitInsn(POP); }
From source file:org.codehaus.groovy.classgen.asm.OperandStack.java
License:Apache License
/** * load the constant on the operand stack. *//*from w ww. j a va 2 s . co m*/ public void pushConstant(ConstantExpression expression) { MethodVisitor mv = controller.getMethodVisitor(); Object value = expression.getValue(); ClassNode origType = expression.getType().redirect(); ClassNode type = ClassHelper.getUnwrapper(origType); boolean boxing = origType != type; boolean asPrimitive = boxing || ClassHelper.isPrimitiveType(type); if (value == null) { mv.visitInsn(ACONST_NULL); } else if (boxing && value instanceof Boolean) { // special path for boxed boolean Boolean bool = (Boolean) value; String text = bool ? "TRUE" : "FALSE"; mv.visitFieldInsn(GETSTATIC, "java/lang/Boolean", text, "Ljava/lang/Boolean;"); boxing = false; type = origType; } else if (asPrimitive) { pushPrimitiveConstant(mv, value, type); } else if (value instanceof BigDecimal) { newInstance(mv, value); } else if (value instanceof BigInteger) { newInstance(mv, value); } else if (value instanceof String) { mv.visitLdcInsn(value); } else { throw new ClassGeneratorException( "Cannot generate bytecode for constant: " + value + " of type: " + type.getName()); } push(type); if (boxing) box(); }
From source file:org.codehaus.groovy.classgen.asm.OperandStack.java
License:Apache License
private static void newInstance(MethodVisitor mv, Object value) { String className = BytecodeHelper.getClassInternalName(value.getClass().getName()); mv.visitTypeInsn(NEW, className);/* www . j a v a 2 s . c o m*/ mv.visitInsn(DUP); mv.visitLdcInsn(value.toString()); mv.visitMethodInsn(INVOKESPECIAL, className, "<init>", "(Ljava/lang/String;)V", false); }
From source file:org.codehaus.groovy.classgen.asm.OperandStack.java
License:Apache License
private static void pushPrimitiveConstant(final MethodVisitor mv, final Object value, final ClassNode type) { boolean isInt = ClassHelper.int_TYPE.equals(type); boolean isShort = ClassHelper.short_TYPE.equals(type); boolean isByte = ClassHelper.byte_TYPE.equals(type); boolean isChar = ClassHelper.char_TYPE.equals(type); if (isInt || isShort || isByte || isChar) { int val = isInt ? (Integer) value : isShort ? (Short) value : isChar ? (Character) value : (Byte) value; BytecodeHelper.pushConstant(mv, val); } else if (ClassHelper.long_TYPE.equals(type)) { if ((Long) value == 0L) { mv.visitInsn(LCONST_0);//from ww w . j a v a 2 s . co m } else if ((Long) value == 1L) { mv.visitInsn(LCONST_1); } else { mv.visitLdcInsn(value); } } else if (ClassHelper.float_TYPE.equals(type)) { if ((Float) value == 0f) { mv.visitInsn(FCONST_0); } else if ((Float) value == 1f) { mv.visitInsn(FCONST_1); } else if ((Float) value == 2f) { mv.visitInsn(FCONST_2); } else { mv.visitLdcInsn(value); } } else if (ClassHelper.double_TYPE.equals(type)) { if ((Double) value == 0d) { mv.visitInsn(DCONST_0); } else if ((Double) value == 1d) { mv.visitInsn(DCONST_1); } else { mv.visitLdcInsn(value); } } else if (ClassHelper.boolean_TYPE.equals(type)) { boolean b = (Boolean) value; if (b) { mv.visitInsn(ICONST_1); } else { mv.visitInsn(ICONST_0); } } else { mv.visitLdcInsn(value); } }
From source file:org.codehaus.groovy.classgen.asm.OperandStack.java
License:Apache License
public void pushBool(boolean inclusive) { MethodVisitor mv = controller.getMethodVisitor(); mv.visitLdcInsn(inclusive); push(ClassHelper.boolean_TYPE); }
From source file:org.codehaus.groovy.classgen.asm.sc.StaticTypesCallSiteWriter.java
License:Apache License
private void writeMapDotProperty(final Expression receiver, final String propertyName, final MethodVisitor mv, final boolean safe) { receiver.visit(controller.getAcg()); // load receiver Label exit = new Label(); if (safe) {/*from ww w . java 2s .co m*/ Label doGet = new Label(); mv.visitJumpInsn(IFNONNULL, doGet); controller.getOperandStack().remove(1); mv.visitInsn(ACONST_NULL); mv.visitJumpInsn(GOTO, exit); mv.visitLabel(doGet); receiver.visit(controller.getAcg()); } mv.visitLdcInsn(propertyName); // load property name mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Map", "get", "(Ljava/lang/Object;)Ljava/lang/Object;", true); if (safe) { mv.visitLabel(exit); } controller.getOperandStack().replace(OBJECT_TYPE); }
From source file:org.codehaus.groovy.classgen.asm.sc.StaticTypesUnaryExpressionHelper.java
License:Apache License
@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//from ww w .j ava 2 s.co m 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); }
From source file:org.codehaus.groovy.classgen.AsmClassGenerator.java
License:Apache License
private void visitStdMethod(final MethodNode node, final boolean isConstructor, final Parameter[] parameters, final Statement code) { controller.getCompileStack().init(node.getVariableScope(), parameters); controller.getCallSiteWriter().makeSiteEntry(); MethodVisitor mv = controller.getMethodVisitor(); final ClassNode superClass = controller.getClassNode().getSuperClass(); if (isConstructor && (code == null || !((ConstructorNode) node).firstStatementIsSpecialConstructorCall())) { boolean hasCallToSuper = false; if (code != null && controller.getClassNode() instanceof InnerClassNode) { // if the class not is an inner class node, there are chances that the call to super is already added // so we must ensure not to add it twice (see GROOVY-4471) if (code instanceof BlockStatement) { for (Statement statement : ((BlockStatement) code).getStatements()) { if (statement instanceof ExpressionStatement) { final Expression expression = ((ExpressionStatement) statement).getExpression(); if (expression instanceof ConstructorCallExpression) { ConstructorCallExpression call = (ConstructorCallExpression) expression; if (call.isSuperCall()) { hasCallToSuper = true; break; }/* www . j a v a 2 s .c om*/ } } } } } if (!hasCallToSuper) { // invokes the super class constructor mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, BytecodeHelper.getClassInternalName(superClass), "<init>", "()V", false); } } // handle body super.visitConstructorOrMethod(node, isConstructor); controller.getCompileStack().clear(); if (node.isVoidMethod()) { mv.visitInsn(RETURN); } else { // we make a dummy return for label ranges that reach here ClassNode type = node.getReturnType().redirect(); if (ClassHelper.isPrimitiveType(type)) { mv.visitLdcInsn(0); controller.getOperandStack().push(ClassHelper.int_TYPE); controller.getOperandStack().doGroovyCast(type); BytecodeHelper.doReturn(mv, type); controller.getOperandStack().remove(1); } else { mv.visitInsn(ACONST_NULL); BytecodeHelper.doReturn(mv, type); } } }