List of usage examples for org.objectweb.asm Opcodes INVOKESPECIAL
int INVOKESPECIAL
To view the source code for org.objectweb.asm Opcodes INVOKESPECIAL.
Click Source Link
From source file:org.jvnet.jax_ws_commons.beans_generator.ambassador.impl.asm.ASMResponseBeanGenerator.java
License:Open Source License
private void generateNoArgsConstructor() { MethodVisitor mv = writer.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null); mv.visitCode();/*from ww w .j a va 2 s . c o m*/ mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V"); mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(1, 1); mv.visitEnd(); }
From source file:org.kantega.notsoserial.CreateBytesIT.java
License:Apache License
private byte[] createTransletBytes() { ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); cw.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC, "com/example/InvokingTranslet", null, Type.getType(AbstractTranslet.class).getInternalName(), new String[] { Type.getType(Serializable.class).getInternalName() }); MethodVisitor init = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null); init.visitCode();/*from ww w .jav a 2 s. co m*/ init.visitVarInsn(Opcodes.ALOAD, 0); init.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getType(AbstractTranslet.class).getInternalName(), "<init>", "()V"); init.visitVarInsn(Opcodes.ALOAD, 0); init.visitIntInsn(Opcodes.BIPUSH, 101); init.visitFieldInsn(Opcodes.PUTFIELD, Type.getType(AbstractTranslet.class).getInternalName(), "transletVersion", "I"); init.visitInsn(Opcodes.RETURN); init.visitMaxs(2, 2); init.visitEnd(); MethodVisitor transformMethod = cw.visitMethod(Opcodes.ACC_PUBLIC, "transform", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { Type.getType(DOM.class), Type.getType(DTMAxisIterator.class) }), null, new String[] { Type.getType(TransletException.class).getInternalName() }); transformMethod.visitCode(); transformMethod.visitInsn(Opcodes.RETURN); transformMethod.visitEnd(); MethodVisitor mv = cw.visitMethod(Opcodes.ACC_STATIC, "<clinit>", "()V", null, null); mv.visitCode(); mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;"); mv.visitLdcInsn("HMM.."); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V"); mv.visitLdcInsn("pwned"); mv.visitLdcInsn("true"); mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/System", "setProperty", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;"); mv.visitInsn(Opcodes.POP); mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(2, 0); mv.visitEnd(); cw.visitEnd(); return cw.toByteArray(); }
From source file:org.lambdamatic.analyzer.ast.LambdaExpressionReader.java
License:Open Source License
/** * Reads the bytecode from the given {@link InsnCursor}'s <strong>current position</strong>, until * there is no further instruction to proceed. It is the responsability of the caller to set the * cursor position.//from w ww . j a v a 2 s .c om * * @param insnCursor the instruction cursor used to read the bytecode. * @param expressionStack the expression stack to put on or pop from. * @param localVariables the local variables * @return a {@link List} of {@link Statement} containing the {@link Statement} */ private List<Statement> readStatements(final InsnCursor insnCursor, final Stack<Expression> expressionStack, final List<CapturedArgument> capturedArguments, final LocalVariables localVariables) { final List<Statement> statements = new ArrayList<>(); while (insnCursor.hasCurrent()) { final AbstractInsnNode currentInstruction = insnCursor.getCurrent(); switch (currentInstruction.getType()) { case AbstractInsnNode.VAR_INSN: final VarInsnNode varInstruction = (VarInsnNode) currentInstruction; switch (currentInstruction.getOpcode()) { // load a reference onto the stack from a local variable case Opcodes.ALOAD: case Opcodes.ILOAD: // load an int value from a local variable // Note: The 'var' operand is the index of a local variable // all captured arguments come before the local variable in the method signature, // which means that the local variables table is empty on the first slots which are // "allocated" // for the captured arguments. if (varInstruction.var < capturedArguments.size()) { // if the variable index matches a captured argument // note: not using actual captured argument but rather, use a _reference_ to it. final Object capturedArgumentValue = capturedArguments.get(varInstruction.var).getValue(); final Class<?> capturedArgumentValueType = capturedArgumentValue != null ? capturedArgumentValue.getClass() : Object.class; final CapturedArgumentRef capturedArgumentRef = new CapturedArgumentRef(varInstruction.var, capturedArgumentValueType); expressionStack.add(capturedArgumentRef); } else { // the variable index matches a local variable final LocalVariableNode var = localVariables.load(varInstruction.var); expressionStack.add(new LocalVariable(var.index, var.name, readSignature(var.desc))); } break; case Opcodes.ASTORE: // store a reference into a local variable localVariables.store(varInstruction.var); break; default: throw new AnalyzeException( "Unexpected Variable instruction code: " + varInstruction.getOpcode()); } break; case AbstractInsnNode.LDC_INSN: // let's move this instruction on top of the stack until it // is used as an argument during a method call final LdcInsnNode ldcInsnNode = (LdcInsnNode) currentInstruction; final Expression constant = ExpressionFactory.getExpression(ldcInsnNode.cst); LOGGER.trace("Stacking constant {}", constant); expressionStack.add(constant); break; case AbstractInsnNode.FIELD_INSN: final FieldInsnNode fieldInsnNode = (FieldInsnNode) currentInstruction; switch (fieldInsnNode.getOpcode()) { case Opcodes.GETSTATIC: final Type ownerType = Type.getType(fieldInsnNode.desc); final FieldAccess staticFieldAccess = new FieldAccess(new ClassLiteral(getType(ownerType)), fieldInsnNode.name); expressionStack.add(staticFieldAccess); break; case Opcodes.GETFIELD: final Expression fieldAccessParent = expressionStack.pop(); final FieldAccess fieldAccess = new FieldAccess(fieldAccessParent, fieldInsnNode.name); expressionStack.add(fieldAccess); break; case Opcodes.PUTFIELD: final Expression fieldAssignationValue = expressionStack.pop(); final Expression parentSource = expressionStack.pop(); final FieldAccess source = new FieldAccess(parentSource, fieldInsnNode.name); final Assignment assignmentExpression = new Assignment(source, fieldAssignationValue); statements.add(new ExpressionStatement(assignmentExpression)); break; default: throw new AnalyzeException("Unexpected field instruction type: " + fieldInsnNode.getOpcode()); } break; case AbstractInsnNode.METHOD_INSN: final MethodInsnNode methodInsnNode = (MethodInsnNode) currentInstruction; final Type[] argumentTypes = Type.getArgumentTypes(methodInsnNode.desc); final List<Expression> args = new ArrayList<>(); final List<Class<?>> parameterTypes = new ArrayList<>(); Stream.of(argumentTypes).forEach(argumentType -> { final Expression arg = expressionStack.pop(); final String argumentClassName = argumentType.getClassName(); args.add(castOperand(arg, argumentClassName)); try { parameterTypes.add(ClassUtils.getClass(argumentClassName)); } catch (Exception e) { throw new AnalyzeException("Failed to find class '" + argumentClassName + "'", e); } }); // arguments appear in reverse order in the bytecode Collections.reverse(args); switch (methodInsnNode.getOpcode()) { case Opcodes.INVOKEINTERFACE: case Opcodes.INVOKEVIRTUAL: case Opcodes.INVOKESPECIAL: // object instantiation if (methodInsnNode.name.equals("<init>")) { final ObjectInstanciation objectVariable = (ObjectInstanciation) expressionStack.pop(); objectVariable.setInitArguments(args); } else { final Expression sourceExpression = expressionStack.pop(); final Method javaMethod = ReflectionUtils.findJavaMethod(sourceExpression.getJavaType(), methodInsnNode.name, parameterTypes); final Class<?> returnType = findReturnType(insnCursor, javaMethod); final MethodInvocation invokedMethod = new MethodInvocation(sourceExpression, javaMethod, returnType, args); expressionStack.add(invokedMethod); } break; case Opcodes.INVOKESTATIC: final Type type = Type.getObjectType(methodInsnNode.owner); try { final Class<?> sourceClass = Class.forName(type.getClassName()); final Method javaMethod = ReflectionUtils.findJavaMethod(sourceClass, methodInsnNode.name, parameterTypes); final Class<?> returnType = findReturnType(insnCursor, javaMethod); final MethodInvocation invokedStaticMethod = new MethodInvocation( new ClassLiteral(sourceClass), javaMethod, returnType, args); expressionStack.add(invokedStaticMethod); } catch (ClassNotFoundException e) { throw new AnalyzeException("Failed to retrieve class for " + methodInsnNode.owner, e); } break; default: throw new AnalyzeException("Unexpected method invocation type: " + methodInsnNode.getOpcode()); } break; case AbstractInsnNode.INVOKE_DYNAMIC_INSN: final InvokeDynamicInsnNode invokeDynamicInsnNode = (InvokeDynamicInsnNode) currentInstruction; final Handle handle = (Handle) invokeDynamicInsnNode.bsmArgs[1]; final int argNumber = Type.getArgumentTypes(invokeDynamicInsnNode.desc).length; final List<CapturedArgumentRef> lambdaArgs = new ArrayList<>(); for (int i = 0; i < argNumber; i++) { final Expression expr = expressionStack.pop(); if (expr.getExpressionType() != ExpressionType.CAPTURED_ARGUMENT_REF) { throw new AnalyzeException("Unexpected argument type when following InvokeDynamic call: " + expr.getExpressionType()); } lambdaArgs.add((CapturedArgumentRef) expr); // , expr.getValue() } Collections.reverse(lambdaArgs); final EmbeddedSerializedLambdaInfo lambdaInfo = new EmbeddedSerializedLambdaInfo(handle.getOwner(), handle.getName(), handle.getDesc(), lambdaArgs, capturedArguments); final LambdaExpression lambdaExpression = LambdaExpressionAnalyzer.getInstance() .analyzeExpression(lambdaInfo); expressionStack.add(lambdaExpression); break; case AbstractInsnNode.JUMP_INSN: statements.addAll( readJumpInstruction(insnCursor, expressionStack, capturedArguments, localVariables)); return statements; case AbstractInsnNode.INT_INSN: readIntInstruction((IntInsnNode) currentInstruction, expressionStack, localVariables); break; case AbstractInsnNode.INSN: final List<Statement> instructionStatement = readInstruction(insnCursor, expressionStack, capturedArguments, localVariables); statements.addAll(instructionStatement); break; case AbstractInsnNode.TYPE_INSN: readTypeInstruction((TypeInsnNode) currentInstruction, expressionStack, localVariables); break; default: throw new AnalyzeException( "This is embarrassing... We've reached an unexpected instruction operator: " + currentInstruction.getType()); } insnCursor.next(); } return statements; }
From source file:org.mbte.groovypp.compiler.bytecode.BytecodeExpr.java
License:Apache License
/** * box the primitive value on the stack//from w w w.j a va 2 s. co m * * @param type * @param mv */ public void quickBoxIfNecessary(ClassNode type, MethodVisitor mv) { String descr = getTypeDescription(type); if (type == boolean_TYPE) { boxBoolean(mv); } else if (isPrimitiveType(type) && type != VOID_TYPE) { ClassNode wrapper = TypeUtil.wrapSafely(type); String internName = getClassInternalName(wrapper); mv.visitTypeInsn(Opcodes.NEW, internName); mv.visitInsn(Opcodes.DUP); if (type == double_TYPE || type == long_TYPE) { mv.visitInsn(Opcodes.DUP2_X2); mv.visitInsn(Opcodes.POP2); } else { mv.visitInsn(Opcodes.DUP2_X1); mv.visitInsn(Opcodes.POP2); } mv.visitMethodInsn(Opcodes.INVOKESPECIAL, internName, "<init>", "(" + descr + ")V"); } }
From source file:org.mbte.groovypp.compiler.bytecode.BytecodeExpr.java
License:Apache License
/** * load the constant on the operand stack. primitives auto-boxed. */// ww w . j a v a2 s .c om void loadConstant(Object value, MethodVisitor mv) { if (value == null) { mv.visitInsn(Opcodes.ACONST_NULL); } else if (value instanceof String) { mv.visitLdcInsn(value); } else if (value instanceof Character) { String className = "java/lang/Character"; mv.visitTypeInsn(Opcodes.NEW, className); mv.visitInsn(Opcodes.DUP); mv.visitLdcInsn(value); String methodType = "(C)V"; mv.visitMethodInsn(Opcodes.INVOKESPECIAL, className, "<init>", methodType); } else if (value instanceof Number) { /** todo it would be more efficient to generate class constants */ Number n = (Number) value; String className = BytecodeHelper.getClassInternalName(value.getClass().getName()); mv.visitTypeInsn(Opcodes.NEW, className); mv.visitInsn(Opcodes.DUP); String methodType; if (n instanceof Integer) { //pushConstant(n.intValue()); mv.visitLdcInsn(n); methodType = "(I)V"; } else if (n instanceof Double) { mv.visitLdcInsn(n); methodType = "(D)V"; } else if (n instanceof Float) { mv.visitLdcInsn(n); methodType = "(F)V"; } else if (n instanceof Long) { mv.visitLdcInsn(n); methodType = "(J)V"; } else if (n instanceof BigDecimal) { mv.visitLdcInsn(n.toString()); methodType = "(Ljava/lang/String;)V"; } else if (n instanceof BigInteger) { mv.visitLdcInsn(n.toString()); methodType = "(Ljava/lang/String;)V"; } else if (n instanceof Short) { mv.visitLdcInsn(n); methodType = "(S)V"; } else if (n instanceof Byte) { mv.visitLdcInsn(n); methodType = "(B)V"; } else { throw new ClassGeneratorException("Cannot generate bytecode for constant: " + value + " of type: " + value.getClass().getName() + ". Numeric constant type not supported."); } mv.visitMethodInsn(Opcodes.INVOKESPECIAL, className, "<init>", methodType); } else if (value instanceof Boolean) { Boolean bool = (Boolean) value; String text = (bool.booleanValue()) ? "TRUE" : "FALSE"; mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Boolean", text, "Ljava/lang/Boolean;"); } else if (value instanceof Class) { Class vc = (Class) value; if (vc.getName().equals("java.lang.Void")) { // load nothing here for void } else { throw new ClassGeneratorException("Cannot generate bytecode for constant: " + value + " of type: " + value.getClass().getName()); } } else { throw new ClassGeneratorException( "Cannot generate bytecode for constant: " + value + " of type: " + value.getClass().getName()); } }
From source file:org.mbte.groovypp.compiler.ClosureUtil.java
License:Apache License
public static void instantiateClass(ClassNode type, CompilerTransformer compiler, Parameter[] constrParams, Expression superArgs, MethodVisitor mv) { TraitASTTransformFinal.improveAbstractMethods(type); type.getModule().addClass(type);//from ww w. j ava2 s .c o m final String classInternalName = BytecodeHelper.getClassInternalName(type); mv.visitTypeInsn(Opcodes.NEW, classInternalName); mv.visitInsn(Opcodes.DUP); final ConstructorNode constructorNode = type.getDeclaredConstructors().get(0); for (int i = 0; i != constrParams.length; i++) { String name = constrParams[i].getName(); if ("this$0".equals(name)) { mv.visitVarInsn(Opcodes.ALOAD, 0); } else { final Register var = compiler.compileStack.getRegister(name, false); if (var != null) { FieldNode field = type.getDeclaredField(name); BytecodeExpr.load(field.getType(), var.getIndex(), mv); if (!constrParams[i].getType().equals(var.getType()) && !ClassHelper.isPrimitiveType(field.getType())) { BytecodeExpr.checkCast(constrParams[i].getType(), mv); } } else { FieldNode field = compiler.methodNode.getDeclaringClass().getDeclaredField(name); mv.visitVarInsn(Opcodes.ALOAD, 0); if (field == null) // @Field name = compiler.methodNode.getName() + "$" + name; mv.visitFieldInsn(Opcodes.GETFIELD, BytecodeHelper.getClassInternalName(compiler.methodNode.getDeclaringClass()), name, BytecodeHelper.getTypeDescription(constrParams[i].getType())); } } } if (superArgs != null) { final List<Expression> list = ((ArgumentListExpression) superArgs).getExpressions(); for (int i = 0; i != list.size(); ++i) ((BytecodeExpr) list.get(i)).visit(mv); } mv.visitMethodInsn(Opcodes.INVOKESPECIAL, classInternalName, "<init>", BytecodeHelper.getMethodDescriptor(ClassHelper.VOID_TYPE, constructorNode.getParameters())); }
From source file:org.nanocontainer.picometer.PicoMeterMethodVisitor.java
License:Open Source License
public void visitMethodInsn(int opcode, String owner, String name, String desc) { boolean isNew = (Opcodes.INVOKESPECIAL == opcode) && owner.equals(lastType) && "<init>".equals(name); if (isNew) {// w w w. ja va2 s . c o m String className = owner.replace('/', '.'); final Instantiation instantiation = new Instantiation(className, picoMeterClass); try { instantiation.setBytecodeLine(currentLine); } catch (IOException e) { throw new RuntimeException(e.getMessage()); } instantiations.add(instantiation); } }
From source file:org.openquark.cal.internal.javamodel.AsmJavaBytecodeGenerator.java
License:Open Source License
/** * Add the <init> method for the given constructor. This also includes initializing the non-static fields that * have initializers.// www. j a v a 2 s . com * @param classRep * @param javaConstructor * @param cv * @throws JavaGenerationException */ private static void encodeConstructor(JavaClassRep classRep, JavaConstructor javaConstructor, ClassVisitor cv) throws JavaGenerationException { // gather info on the thrown exceptions final int nThrownExceptions = javaConstructor.getNThrownExceptions(); String[] thrownExceptions = new String[nThrownExceptions]; for (int i = 0; i < nThrownExceptions; ++i) { thrownExceptions[i] = javaConstructor.getThrownException(i).getJVMInternalName(); } MethodVisitor mv = cv.visitMethod(javaConstructor.getModifiers(), "<init>", javaConstructor.getJVMMethodDescriptor(), null, thrownExceptions); final Map<String, JavaTypeName> methodVarToTypeMap = new HashMap<String, JavaTypeName>(); final Map<String, Integer> methodVarToIndexMap = new HashMap<String, Integer>(); methodVarToTypeMap.put("this", classRep.getClassName()); methodVarToIndexMap.put("this", Integer.valueOf(0)); int indexOfNextSlot = 1; for (int i = 0, nParams = javaConstructor.getNParams(); i < nParams; ++i) { JavaTypeName varType = javaConstructor.getParamType(i); final int typeSize = getTypeSize(varType); String varName = javaConstructor.getParamName(i); methodVarToTypeMap.put(varName, varType); methodVarToIndexMap.put(varName, Integer.valueOf(indexOfNextSlot)); indexOfNextSlot += typeSize; } // Start the method's code. mv.visitCode(); // Invoke the superclass initializer. if (javaConstructor.getSuperConstructorParamTypes().length == 0) { //push the "this" reference on the stack mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, classRep.getSuperclassName().getJVMInternalName(), "<init>", "()V"); } else { GenerationContext context = new GenerationContext(methodVarToTypeMap, methodVarToIndexMap, indexOfNextSlot, mv, classRep.getClassName()); MethodInvocation mi = new MethodInvocation.Instance(null, "<init>", classRep.getSuperclassName(), javaConstructor.getSuperConstructorParamValues(), javaConstructor.getSuperConstructorParamTypes(), JavaTypeName.VOID, MethodInvocation.InvocationType.SPECIAL); encodeMethodInvocationExpr(mi, context); } // Add initializers for the non-statically-initialized fields. final int nFields = classRep.getNFieldDeclarations(); for (int i = 0; i < nFields; ++i) { JavaFieldDeclaration fieldDecl = classRep.getFieldDeclaration(i); JavaExpression initializer = fieldDecl.getInitializer(); if (initializer != null && !Modifier.isStatic(fieldDecl.getModifiers())) { GenerationContext context = new GenerationContext(methodVarToTypeMap, methodVarToIndexMap, indexOfNextSlot, mv, classRep.getClassName()); //push the "this" reference mv.visitVarInsn(Opcodes.ALOAD, 0); //evaluate the initializer encodeExpr(initializer, context); //do the assignment mv.visitFieldInsn(Opcodes.PUTFIELD, classRep.getClassName().getJVMInternalName(), fieldDecl.getFieldName(), fieldDecl.getFieldType().getJVMDescriptor()); } } // Add the body code for the constructor GenerationContext context = new GenerationContext(methodVarToTypeMap, methodVarToIndexMap, indexOfNextSlot, mv, classRep.getClassName()); boolean isTerminating = encodeStatement(javaConstructor.getBodyCode(), context); // Add any implicit "return" statement. if (!isTerminating) { mv.visitInsn(Opcodes.RETURN); } //mark the end of encoding the constructor mv.visitMaxs(0, 0); // End the method. mv.visitEnd(); }
From source file:org.openquark.cal.internal.javamodel.AsmJavaBytecodeGenerator.java
License:Open Source License
/** * Encodes the Java code for a given Java operator expression. * /* w ww.j a va2 s. c o m*/ * @param operatorExpr the java operator expression * @param context * @return JavaTypeName * @throws JavaGenerationException */ private static JavaTypeName encodeOperatorExpr(JavaExpression.OperatorExpression operatorExpr, GenerationContext context) throws JavaGenerationException { MethodVisitor mv = context.getMethodVisitor(); JavaOperator operator = operatorExpr.getJavaOperator(); String symbol = operator.getSymbol(); JavaTypeName valueType = operator.getValueType(); // Now carry out the operation according to its type. if (operator.isArithmeticOp()) { // Add the instructions to evaluate the first argument. JavaTypeName arg1Type = encodeExpr(operatorExpr.getArgument(0), context); if (operatorExpr instanceof OperatorExpression.Unary) { if (symbol.equals("-")) { // number negation mv.visitInsn(getNegateOpCode(arg1Type)); return arg1Type; } throw new JavaGenerationException("Unknown unary arithmetic operator " + symbol + "."); } // Add an instruction to widen the argument if necessary. int wideningOpCode = getWideningOpCode(arg1Type, valueType); if (wideningOpCode != Opcodes.NOP) { mv.visitInsn(wideningOpCode); } // Add the instructions to evaluate the second argument. JavaTypeName arg2Type = encodeExpr(operatorExpr.getArgument(1), context); // Add an instruction to widen the argument if necessary. wideningOpCode = getWideningOpCode(arg2Type, valueType); if (wideningOpCode != Opcodes.NOP) { mv.visitInsn(wideningOpCode); } // Evaluate. mv.visitInsn(getArithmeticBinaryOpCode(symbol, valueType)); return valueType; } if (operator.isBitOp()) { // Add the instructions to evaluate the first argument. JavaTypeName arg1Type = encodeExpr(operatorExpr.getArgument(0), context); // Add an instruction to widen the argument if necessary. int wideningOpCode = getWideningOpCode(arg1Type, valueType); if (wideningOpCode != Opcodes.NOP) { mv.visitInsn(wideningOpCode); } if (operatorExpr instanceof OperatorExpression.Unary) { if (symbol.equals("~")) { // number negation if (valueType == JavaTypeName.INT) { mv.visitInsn(Opcodes.ICONST_M1); mv.visitInsn(Opcodes.IXOR); return valueType; } else if (valueType == JavaTypeName.LONG) { encodePushLongValue(new Long(-1), context); mv.visitInsn(Opcodes.LXOR); return valueType; } } throw new JavaGenerationException("Unknown unary arithmetic operator " + symbol + "."); } // Add the instructions to evaluate the second argument. JavaTypeName arg2Type = encodeExpr(operatorExpr.getArgument(1), context); // If this is >>, >>>, or << we may need to narrow the second argument to an int if (symbol.equals(">>") || symbol.equals(">>>") || symbol.equals("<<")) { if (arg2Type == JavaTypeName.LONG) { mv.visitInsn(Opcodes.L2I); } } else { // Add an instruction to widen the argument if necessary. wideningOpCode = getWideningOpCode(arg2Type, valueType); if (wideningOpCode != Opcodes.NOP) { mv.visitInsn(wideningOpCode); } } // Evaluate. mv.visitInsn(getArithmeticBinaryOpCode(symbol, valueType)); return valueType; } if (operator.isLogicalOp() || operator.isRelationalOp()) { // Logical op: {"!", "&&", "||"} // Relational op: {">", ">=", "<", "<=", "==", "!="} Label trueContinuation = new Label(); Label falseContinuation = new Label(); encodeBooleanValuedOperatorHelper(operatorExpr, context, trueContinuation, falseContinuation); return encodeThenTrueElseFalse(trueContinuation, falseContinuation, context); } if (operator == JavaOperator.STRING_CONCATENATION) { // Create an uninitialized StringBuilder, duplicate the reference (so we can invoke the initializer). mv.visitTypeInsn(Opcodes.NEW, "java/lang/StringBuilder"); mv.visitInsn(Opcodes.DUP); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "()V"); // append the first arg. JavaTypeName firstArgType = encodeExpr(operatorExpr.getArgument(0), context); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "append", getAppendJVMDescriptor(firstArgType)); // Append the results of evaluation of the second arg. // Note that, conveniently, StringBuilder has an append() method for all the different types. JavaTypeName secondArgType = encodeExpr(operatorExpr.getArgument(1), context); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "append", getAppendJVMDescriptor(secondArgType)); // Call toString() on the result. mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;"); return JavaTypeName.STRING; } return encodeTernaryOperatorExpr((OperatorExpression.Ternary) operatorExpr, context); }
From source file:org.openquark.cal.internal.javamodel.AsmJavaBytecodeGenerator.java
License:Open Source License
/** * Create the Java code for a given method invocation. * The expression result to be pushed onto the stack. * @param mi the method invocation /* www . j a v a2 s .com*/ * @param context * @return JavaTypeName the type of the result on the operand stack. * @throws JavaGenerationException */ private static JavaTypeName encodeMethodInvocationExpr(JavaExpression.MethodInvocation mi, GenerationContext context) throws JavaGenerationException { MethodInvocation.InvocationType invocationType = mi.getInvocationType(); int invocationCode; JavaTypeName invocationClassType; if (invocationType != MethodInvocation.InvocationType.STATIC) { JavaExpression invocationTarget = ((MethodInvocation.Instance) mi).getInvocationTarget(); if (invocationTarget == null) { //push a reference to 'this' onto the stack. invocationClassType = encodeThis(context); } else { //push a reference to the invoking expression onto the stack invocationClassType = encodeExpr(invocationTarget, context); } // The MethodInvocation may contain an explicit invoking class type. If it does // use it in preference to the type of the invocation target. if (mi instanceof MethodInvocation.Instance && ((MethodInvocation.Instance) mi).getDeclaringClass() != null) { invocationClassType = ((MethodInvocation.Instance) mi).getDeclaringClass(); } if (invocationType == MethodInvocation.InvocationType.VIRTUAL) { invocationCode = Opcodes.INVOKEVIRTUAL; } else if (invocationType == MethodInvocation.InvocationType.INTERFACE) { if (invocationClassType.isInterface()) { invocationCode = Opcodes.INVOKEINTERFACE; } else { //if we invoke an interface method on a reference that is known to be a Class, then we must use invoke virtual //to avoid getting a IncompatibleClassChangeError. invocationCode = Opcodes.INVOKEVIRTUAL; } } else if (invocationType == MethodInvocation.InvocationType.SPECIAL) { invocationCode = Opcodes.INVOKESPECIAL; } else { throw new JavaGenerationException("Unknown invocation type: " + invocationType); } } else { //static invocation. No object reference needs to be pushed. invocationCode = Opcodes.INVOKESTATIC; invocationClassType = ((MethodInvocation.Static) mi).getInvocationClass(); } //push the arguments onto the stack for (int i = 0, nArgs = mi.getNArgs(); i < nArgs; ++i) { encodeExpr(mi.getArg(i), context); } //invoke the method context.getMethodVisitor().visitMethodInsn(invocationCode, invocationClassType.getJVMInternalName(), mi.getMethodName(), mi.getJVMMethodDescriptor()); return mi.getReturnType(); }