List of usage examples for org.objectweb.asm Opcodes DRETURN
int DRETURN
To view the source code for org.objectweb.asm Opcodes DRETURN.
Click Source Link
From source file:asmlib.Type.java
License:Open Source License
/** Mtodo que retorna o opcode certo para o tipo de varivel que se quer fazer return. * Opcodes disponveis:/*www.j a v a 2 s . c o m*/ * - IRETURN para boolean, byte, char, short, int * - LRETURN para long * - FRETURN para float * - DRETURN para double * - ARETURN para referncia (objecto ou array) * - RETURN para mtodos void **/ public int getReturnInsn() { char c = bytecodeName().charAt(0); switch (c) { case 'Z': // boolean case 'B': // byte case 'C': // char case 'S': // short case 'I': // int return Opcodes.IRETURN; case 'J': // long return Opcodes.LRETURN; case 'F': // float return Opcodes.FRETURN; case 'D': // double return Opcodes.DRETURN; case '[': // Algum tipo de array case 'L': // objecto case 'T': // objecto (generics) return Opcodes.ARETURN; case 'V': // void return Opcodes.RETURN; } throw new InstrumentationException("Unknown fieldType in getReturnInsn"); }
From source file:bytecode.InstructionExporter.java
License:Apache License
/** * Outputs a return instruction, selecting the correct type variant. * * @param instruction Return instruction. * @return <code>null</code> *//*from w ww.j a v a 2 s. c o m*/ @Override public Void visit(ValueReturn instruction) { switch (instruction.getType().getSort()) { case LONG: mv.visitInsn(Opcodes.LRETURN); break; case FLOAT: mv.visitInsn(Opcodes.FRETURN); break; case DOUBLE: mv.visitInsn(Opcodes.DRETURN); break; case REF: mv.visitInsn(Opcodes.ARETURN); break; default: mv.visitInsn(Opcodes.IRETURN); break; } return null; }
From source file:bytecode.MethodImporter.java
License:Apache License
/** * Imports instructions with no immediate operands. * * @param opcode Opcode./*from w ww. j a v a 2s . c o m*/ */ @Override public void visitInsn(final int opcode) { Producer a, b, c, d; Type top; switch (opcode) { // Constants case Opcodes.ACONST_NULL: createConstant(null); break; case Opcodes.ICONST_M1: createConstant(new Integer(-1)); break; case Opcodes.ICONST_0: createConstant(new Integer(0)); break; case Opcodes.ICONST_1: createConstant(new Integer(1)); break; case Opcodes.ICONST_2: createConstant(new Integer(2)); break; case Opcodes.ICONST_3: createConstant(new Integer(3)); break; case Opcodes.ICONST_4: createConstant(new Integer(4)); break; case Opcodes.ICONST_5: createConstant(new Integer(5)); break; case Opcodes.LCONST_0: createConstant(new Long(0)); break; case Opcodes.LCONST_1: createConstant(new Long(1)); break; case Opcodes.FCONST_0: createConstant(new Float(0.0f)); break; case Opcodes.FCONST_1: createConstant(new Float(1.0f)); break; case Opcodes.FCONST_2: createConstant(new Float(2.0f)); break; case Opcodes.DCONST_0: createConstant(new Double(0.0f)); break; case Opcodes.DCONST_1: createConstant(new Double(1.0f)); break; // Binary Operations case Opcodes.IADD: createArithmetic(Arithmetic.Operator.ADD, Type.INT); break; case Opcodes.LADD: createArithmetic(Arithmetic.Operator.ADD, Type.LONG); break; case Opcodes.FADD: createArithmetic(Arithmetic.Operator.ADD, Type.FLOAT); break; case Opcodes.DADD: createArithmetic(Arithmetic.Operator.ADD, Type.DOUBLE); break; case Opcodes.ISUB: createArithmetic(Arithmetic.Operator.SUB, Type.INT); break; case Opcodes.LSUB: createArithmetic(Arithmetic.Operator.SUB, Type.LONG); break; case Opcodes.FSUB: createArithmetic(Arithmetic.Operator.SUB, Type.FLOAT); break; case Opcodes.DSUB: createArithmetic(Arithmetic.Operator.SUB, Type.DOUBLE); break; case Opcodes.IMUL: createArithmetic(Arithmetic.Operator.MUL, Type.INT); break; case Opcodes.LMUL: createArithmetic(Arithmetic.Operator.MUL, Type.LONG); break; case Opcodes.FMUL: createArithmetic(Arithmetic.Operator.MUL, Type.FLOAT); break; case Opcodes.DMUL: createArithmetic(Arithmetic.Operator.MUL, Type.DOUBLE); break; case Opcodes.IDIV: createArithmetic(Arithmetic.Operator.DIV, Type.INT); break; case Opcodes.LDIV: createArithmetic(Arithmetic.Operator.DIV, Type.LONG); break; case Opcodes.FDIV: createArithmetic(Arithmetic.Operator.DIV, Type.FLOAT); break; case Opcodes.DDIV: createArithmetic(Arithmetic.Operator.DIV, Type.DOUBLE); break; case Opcodes.IREM: createArithmetic(Arithmetic.Operator.REM, Type.INT); break; case Opcodes.LREM: createArithmetic(Arithmetic.Operator.REM, Type.LONG); break; case Opcodes.FREM: createArithmetic(Arithmetic.Operator.REM, Type.FLOAT); break; case Opcodes.DREM: createArithmetic(Arithmetic.Operator.REM, Type.DOUBLE); break; case Opcodes.IAND: createArithmetic(Arithmetic.Operator.AND, Type.INT); break; case Opcodes.LAND: createArithmetic(Arithmetic.Operator.AND, Type.LONG); break; case Opcodes.IOR: createArithmetic(Arithmetic.Operator.OR, Type.INT); break; case Opcodes.LOR: createArithmetic(Arithmetic.Operator.OR, Type.LONG); break; case Opcodes.IXOR: createArithmetic(Arithmetic.Operator.XOR, Type.INT); break; case Opcodes.LXOR: createArithmetic(Arithmetic.Operator.XOR, Type.LONG); break; case Opcodes.ISHL: createArithmetic(Arithmetic.Operator.SHL, Type.INT); break; case Opcodes.LSHL: createArithmetic(Arithmetic.Operator.SHL, Type.LONG); break; case Opcodes.ISHR: createArithmetic(Arithmetic.Operator.SHR, Type.INT); break; case Opcodes.LSHR: createArithmetic(Arithmetic.Operator.SHR, Type.LONG); break; case Opcodes.IUSHR: createArithmetic(Arithmetic.Operator.USHR, Type.INT); break; case Opcodes.LUSHR: createArithmetic(Arithmetic.Operator.USHR, Type.LONG); break; case Opcodes.LCMP: createCompare(false, Type.LONG); break; case Opcodes.FCMPL: createCompare(false, Type.FLOAT); break; case Opcodes.FCMPG: createCompare(true, Type.FLOAT); break; case Opcodes.DCMPL: createCompare(false, Type.DOUBLE); break; case Opcodes.DCMPG: createCompare(true, Type.DOUBLE); break; case Opcodes.INEG: createNegate(); break; case Opcodes.LNEG: createNegate(); break; case Opcodes.FNEG: createNegate(); break; case Opcodes.DNEG: createNegate(); break; case Opcodes.I2L: createConvert(Type.LONG); break; case Opcodes.I2F: createConvert(Type.FLOAT); break; case Opcodes.I2D: createConvert(Type.DOUBLE); break; case Opcodes.I2B: createConvert(Type.BYTE); break; case Opcodes.I2C: createConvert(Type.CHAR); break; case Opcodes.I2S: createConvert(Type.SHORT); break; case Opcodes.L2I: createConvert(Type.INT); break; case Opcodes.L2F: createConvert(Type.FLOAT); break; case Opcodes.L2D: createConvert(Type.DOUBLE); break; case Opcodes.F2I: createConvert(Type.INT); break; case Opcodes.F2L: createConvert(Type.LONG); break; case Opcodes.F2D: createConvert(Type.DOUBLE); break; case Opcodes.D2I: createConvert(Type.INT); break; case Opcodes.D2F: createConvert(Type.FLOAT); break; case Opcodes.D2L: createConvert(Type.LONG); break; case Opcodes.IALOAD: createArrayRead(Type.INT); break; case Opcodes.LALOAD: createArrayRead(Type.LONG); break; case Opcodes.FALOAD: createArrayRead(Type.FLOAT); break; case Opcodes.DALOAD: createArrayRead(Type.DOUBLE); break; case Opcodes.AALOAD: createArrayRead(Type.getFreshRef()); break; case Opcodes.BALOAD: createArrayRead(Type.BYTE); break; case Opcodes.CALOAD: createArrayRead(Type.CHAR); break; case Opcodes.SALOAD: createArrayRead(Type.SHORT); break; case Opcodes.IASTORE: createArrayWrite(Type.INT); break; case Opcodes.LASTORE: createArrayWrite(Type.LONG); break; case Opcodes.FASTORE: createArrayWrite(Type.FLOAT); break; case Opcodes.DASTORE: createArrayWrite(Type.DOUBLE); break; case Opcodes.AASTORE: createArrayWrite(Type.getFreshRef()); break; case Opcodes.BASTORE: createArrayWrite(Type.BYTE); break; case Opcodes.CASTORE: createArrayWrite(Type.CHAR); break; case Opcodes.SASTORE: createArrayWrite(Type.SHORT); break; case Opcodes.IRETURN: createReturn(Type.INT); break; case Opcodes.LRETURN: createReturn(Type.LONG); break; case Opcodes.FRETURN: createReturn(Type.FLOAT); break; case Opcodes.DRETURN: createReturn(Type.DOUBLE); break; case Opcodes.ARETURN: createReturn(Type.REF); break; case Opcodes.RETURN: createReturn(null); break; case Opcodes.ATHROW: createThrow(); break; // Array Length case Opcodes.ARRAYLENGTH: ordered.add(stack.push(new ArrayLength(stack.pop()))); break; // Swap case Opcodes.SWAP: a = stack.pop(); b = stack.pop(); stack.push(a); stack.push(b); ordered.add(new StackOperation(StackOperation.Sort.SWAP)); break; // Duplicates case Opcodes.DUP: stack.push(stack.peek()); ordered.add(new StackOperation(StackOperation.Sort.DUP)); break; case Opcodes.DUP2: top = stack.peek().getType(); // Type 2 Values if (top.getSize() == 2) { stack.push(stack.peek()); // Type 1 Values } else { b = stack.pop(); a = stack.pop(); stack.push(a); stack.push(b); stack.push(a); stack.push(b); } ordered.add(new StackOperation(StackOperation.Sort.DUP2)); break; case Opcodes.DUP_X1: b = stack.pop(); a = stack.pop(); stack.push(b); stack.push(a); stack.push(b); ordered.add(new StackOperation(StackOperation.Sort.DUP_X1)); break; case Opcodes.DUP_X2: top = stack.peek().getType(); // Type 2 Values if (top.getSize() == 2) { b = stack.pop(); a = stack.pop(); stack.push(b); stack.push(a); stack.push(b); // Type 1 Values } else { c = stack.pop(); b = stack.pop(); a = stack.pop(); stack.push(c); stack.push(a); stack.push(b); stack.push(c); } ordered.add(new StackOperation(StackOperation.Sort.DUP_X2)); break; // Pops case Opcodes.POP: stack.pop(); ordered.add(new StackOperation(StackOperation.Sort.POP)); break; case Opcodes.POP2: top = stack.peek().getType(); // Type 2 Values if (top.getSize() == 2) { stack.pop(); // Type 1 Values } else { stack.pop(); stack.pop(); } ordered.add(new StackOperation(StackOperation.Sort.POP2)); break; // TODO: DUP2_X1, DUP2_X2, MONITORENTER, MONITOREXIT case Opcodes.MONITORENTER: throw new RuntimeException("visitInsn: MONITORENTER"); case Opcodes.MONITOREXIT: throw new RuntimeException("visitInsn: MONITOREXIT"); case Opcodes.DUP2_X1: throw new RuntimeException("visitInsn: DUP2_X1"); case Opcodes.DUP2_X2: throw new RuntimeException("visitInsn: DUP2_X2"); default: throw new RuntimeException("visitInsn: " + opcode); } }
From source file:co.paralleluniverse.fibers.instrument.InstrumentMethod.java
License:Open Source License
private void dumpCodeBlock(MethodVisitor mv, int idx, int skip) { int start = codeBlocks[idx].endInstruction; int end = codeBlocks[idx + 1].endInstruction; for (int i = start + skip; i < end; i++) { AbstractInsnNode ins = mn.instructions.get(i); switch (ins.getOpcode()) { case Opcodes.RETURN: case Opcodes.ARETURN: case Opcodes.IRETURN: case Opcodes.LRETURN: case Opcodes.FRETURN: case Opcodes.DRETURN: emitPopMethod(mv);/* w ww . j a v a 2s . co m*/ break; case Opcodes.MONITORENTER: case Opcodes.MONITOREXIT: if (!db.isAllowMonitors()) { if (!className.equals("clojure/lang/LazySeq")) throw new UnableToInstrumentException("synchronization", className, mn.name, mn.desc); } else if (!warnedAboutMonitors) { warnedAboutMonitors = true; db.log(LogLevel.WARNING, "Method %s#%s%s contains synchronization", className, mn.name, mn.desc); } break; case Opcodes.INVOKESPECIAL: MethodInsnNode min = (MethodInsnNode) ins; if ("<init>".equals(min.name)) { int argSize = TypeAnalyzer.getNumArguments(min.desc); Frame frame = frames[i]; int stackIndex = frame.getStackSize() - argSize - 1; Value thisValue = frame.getStack(stackIndex); if (stackIndex >= 1 && isNewValue(thisValue, true) && isNewValue(frame.getStack(stackIndex - 1), false)) { NewValue newValue = (NewValue) thisValue; if (newValue.omitted) { emitNewAndDup(mv, frame, stackIndex, min); } } else { db.log(LogLevel.WARNING, "Expected to find a NewValue on stack index %d: %s", stackIndex, frame); } } break; } ins.accept(mv); } }
From source file:com.android.tools.layoutlib.create.StubMethodAdapter.java
License:Apache License
private void generateInvoke() { /* Generates the code: * OverrideMethod.invoke("signature", mIsNative ? true : false, null or this); *//*ww w. j a va 2 s .c o m*/ mParentVisitor.visitLdcInsn(mInvokeSignature); // push true or false mParentVisitor.visitInsn(mIsNative ? Opcodes.ICONST_1 : Opcodes.ICONST_0); // push null or this if (mIsStatic) { mParentVisitor.visitInsn(Opcodes.ACONST_NULL); } else { mParentVisitor.visitVarInsn(Opcodes.ALOAD, 0); } int sort = mReturnType != null ? mReturnType.getSort() : Type.VOID; switch (sort) { case Type.VOID: mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC, "com/android/tools/layoutlib/create/OverrideMethod", "invokeV", "(Ljava/lang/String;ZLjava/lang/Object;)V"); mParentVisitor.visitInsn(Opcodes.RETURN); break; case Type.BOOLEAN: case Type.CHAR: case Type.BYTE: case Type.SHORT: case Type.INT: mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC, "com/android/tools/layoutlib/create/OverrideMethod", "invokeI", "(Ljava/lang/String;ZLjava/lang/Object;)I"); switch (sort) { case Type.BOOLEAN: Label l1 = new Label(); mParentVisitor.visitJumpInsn(Opcodes.IFEQ, l1); mParentVisitor.visitInsn(Opcodes.ICONST_1); mParentVisitor.visitInsn(Opcodes.IRETURN); mParentVisitor.visitLabel(l1); mParentVisitor.visitInsn(Opcodes.ICONST_0); break; case Type.CHAR: mParentVisitor.visitInsn(Opcodes.I2C); break; case Type.BYTE: mParentVisitor.visitInsn(Opcodes.I2B); break; case Type.SHORT: mParentVisitor.visitInsn(Opcodes.I2S); break; } mParentVisitor.visitInsn(Opcodes.IRETURN); break; case Type.LONG: mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC, "com/android/tools/layoutlib/create/OverrideMethod", "invokeL", "(Ljava/lang/String;ZLjava/lang/Object;)J"); mParentVisitor.visitInsn(Opcodes.LRETURN); break; case Type.FLOAT: mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC, "com/android/tools/layoutlib/create/OverrideMethod", "invokeF", "(Ljava/lang/String;ZLjava/lang/Object;)F"); mParentVisitor.visitInsn(Opcodes.FRETURN); break; case Type.DOUBLE: mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC, "com/android/tools/layoutlib/create/OverrideMethod", "invokeD", "(Ljava/lang/String;ZLjava/lang/Object;)D"); mParentVisitor.visitInsn(Opcodes.DRETURN); break; case Type.ARRAY: case Type.OBJECT: mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC, "com/android/tools/layoutlib/create/OverrideMethod", "invokeA", "(Ljava/lang/String;ZLjava/lang/Object;)Ljava/lang/Object;"); mParentVisitor.visitTypeInsn(Opcodes.CHECKCAST, mReturnType.getInternalName()); mParentVisitor.visitInsn(Opcodes.ARETURN); break; } }
From source file:com.android.tools.layoutlib.create.StubMethodAdapter.java
License:Apache License
/** * For non-constructor, rewrite existing "return" instructions to write the message. *///w ww .j a v a2 s . co m public void visitInsn(int opcode) { if (mIsInitMethod) { switch (opcode) { case Opcodes.RETURN: case Opcodes.ARETURN: case Opcodes.DRETURN: case Opcodes.FRETURN: case Opcodes.IRETURN: case Opcodes.LRETURN: // Pop the last word from the stack since invoke will generate its own return. generatePop(); generateInvoke(); mMessageGenerated = true; default: mParentVisitor.visitInsn(opcode); } } }
From source file:com.android.tools.lint.checks.FieldGetterDetector.java
License:Apache License
private static Map<String, String> checkMethods(ClassNode classNode, Set<String> names) { Map<String, String> validGetters = Maps.newHashMap(); @SuppressWarnings("rawtypes") List methods = classNode.methods; String fieldName = null;//from ww w . j av a2 s. c o m checkMethod: for (Object methodObject : methods) { MethodNode method = (MethodNode) methodObject; if (names.contains(method.name) && method.desc.startsWith("()")) { //$NON-NLS-1$ // (): No arguments InsnList instructions = method.instructions; int mState = 1; for (AbstractInsnNode curr = instructions.getFirst(); curr != null; curr = curr.getNext()) { switch (curr.getOpcode()) { case -1: // Skip label and line number nodes continue; case Opcodes.ALOAD: if (mState == 1) { fieldName = null; mState = 2; } else { continue checkMethod; } break; case Opcodes.GETFIELD: if (mState == 2) { FieldInsnNode field = (FieldInsnNode) curr; fieldName = field.name; mState = 3; } else { continue checkMethod; } break; case Opcodes.ARETURN: case Opcodes.FRETURN: case Opcodes.IRETURN: case Opcodes.DRETURN: case Opcodes.LRETURN: case Opcodes.RETURN: if (mState == 3) { validGetters.put(method.name, fieldName); } continue checkMethod; default: continue checkMethod; } } } } return validGetters; }
From source file:com.android.tools.lint.checks.WakelockDetector.java
License:Apache License
/** Search from the given node towards the target; return false if we reach * an exit point such as a return or a call on the way there that is not within * a try/catch clause.//from ww w . j a v a 2 s.c om * * @param node the current node * @return true if the target was reached * XXX RETURN VALUES ARE WRONG AS OF RIGHT NOW */ protected int dfs(ControlFlowGraph.Node node) { AbstractInsnNode instruction = node.instruction; if (instruction.getType() == AbstractInsnNode.JUMP_INSN) { int opcode = instruction.getOpcode(); if (opcode == Opcodes.RETURN || opcode == Opcodes.ARETURN || opcode == Opcodes.LRETURN || opcode == Opcodes.IRETURN || opcode == Opcodes.DRETURN || opcode == Opcodes.FRETURN || opcode == Opcodes.ATHROW) { if (DEBUG) { System.out.println("Found exit via explicit return: " //$NON-NLS-1$ + node.toString(false)); } return SEEN_RETURN; } } if (!DEBUG) { // There are no cycles, so no *NEED* for this, though it does avoid // researching shared labels. However, it makes debugging harder (no re-entry) // so this is only done when debugging is off if (node.visit != 0) { return 0; } node.visit = 1; } // Look for the target. This is any method call node which is a release on the // lock (later also check it's the same instance, though that's harder). // This is because finally blocks tend to be inlined so from a single try/catch/finally // with a release() in the finally, the bytecode can contain multiple repeated // (inlined) release() calls. if (instruction.getType() == AbstractInsnNode.METHOD_INSN) { MethodInsnNode method = (MethodInsnNode) instruction; if (method.name.equals(RELEASE_METHOD) && method.owner.equals(WAKELOCK_OWNER)) { return SEEN_TARGET; } else if (method.name.equals(ACQUIRE_METHOD) && method.owner.equals(WAKELOCK_OWNER)) { // OK } else if (method.name.equals(IS_HELD_METHOD) && method.owner.equals(WAKELOCK_OWNER)) { // OK } else { // Some non acquire/release method call: if this is not associated with a // try-catch block, it would mean the exception would exit the method, // which would be an error if (node.exceptions == null || node.exceptions.isEmpty()) { // Look up the corresponding frame, if any AbstractInsnNode curr = method.getPrevious(); boolean foundFrame = false; while (curr != null) { if (curr.getType() == AbstractInsnNode.FRAME) { foundFrame = true; break; } curr = curr.getPrevious(); } if (!foundFrame) { if (DEBUG) { System.out.println("Found exit via unguarded method call: " //$NON-NLS-1$ + node.toString(false)); } return SEEN_RETURN; } } } } // if (node.instruction is a call, and the call is not caught by // a try/catch block (provided the release is not inside the try/catch block) // then return false int status = 0; boolean implicitReturn = true; List<Node> successors = node.successors; List<Node> exceptions = node.exceptions; if (exceptions != null) { if (!exceptions.isEmpty()) { implicitReturn = false; } for (Node successor : exceptions) { status = dfs(successor) | status; if ((status & SEEN_RETURN) != 0) { if (DEBUG) { System.out.println("Found exit via exception: " //$NON-NLS-1$ + node.toString(false)); } return status; } } if (status != 0) { status |= SEEN_EXCEPTION; } } if (successors != null) { if (!successors.isEmpty()) { implicitReturn = false; if (successors.size() > 1) { status |= SEEN_BRANCH; } } for (Node successor : successors) { status = dfs(successor) | status; if ((status & SEEN_RETURN) != 0) { if (DEBUG) { System.out.println("Found exit via branches: " //$NON-NLS-1$ + node.toString(false)); } return status; } } } if (implicitReturn) { status |= SEEN_RETURN; if (DEBUG) { System.out.println("Found exit: via implicit return: " //$NON-NLS-1$ + node.toString(false)); } } return status; }
From source file:com.codename1.tools.ikvm.Parser.java
/** * Parses an InputStream containing a class. * @param input The input stream with a class. * @return If a transformation occurred, the bytes for the changed class will be returned. Otherwise null will be returned. * @throws Exception /*from w ww. j ava2 s . co m*/ */ public static byte[] parse(InputStream input, ClassLoader classLoader) throws Exception { ClassReader r = new ClassReader(input); Parser p = new Parser(); //ClassWriter w = new ClassWriter(r, 0); ClassNode classNode = new ClassNode(); //p.classNode = classNode; r.accept(classNode, 0); //r.accept(p, ClassReader.EXPAND_FRAMES) List<MethodNode> methodsToAdd = new ArrayList<MethodNode>(); int methodNum = 0; for (Object o : classNode.methods) { methodNum++; MethodNode methodNode = (MethodNode) o; boolean synchronizedMethod = (methodNode.access & Opcodes.ACC_SYNCHRONIZED) == Opcodes.ACC_SYNCHRONIZED; if (synchronizedMethod) { // Check for a try statement final boolean[] tryCatchFound = new boolean[1]; //System.out.println("Found sync method "+methodNode.name+". Checking for try blocks"); methodNode.accept(new MethodVisitor(Opcodes.ASM5) { @Override public void visitTryCatchBlock(Label label, Label label1, Label label2, String string) { tryCatchFound[0] = true; } }); if (!tryCatchFound[0]) { continue; } //System.out.println("Instructions: "+Arrays.toString(methodNode.instructions.toArray())); System.out.println("Transforming method " + methodNode.name + " of class " + classNode.name); MethodDescriptor md = new MethodDescriptor(methodNode.access, methodNode.name, methodNode.desc); //methodNode.access = methodNode.access & ~Opcodes.ACC_SYNCHRONIZED; String privateMethodName = (md.constructor ? "___cn1init__" : methodNode.name) + "___cn1sync" + (methodNum); MethodNode syncMethod = new MethodNode(methodNode.access, methodNode.name, methodNode.desc, methodNode.signature, (String[]) methodNode.exceptions.toArray(new String[methodNode.exceptions.size()])); methodNode.name = privateMethodName; methodNode.access = (methodNode.access | Opcodes.ACC_PRIVATE) & ~Opcodes.ACC_PUBLIC & ~Opcodes.ACC_PROTECTED & ~Opcodes.ACC_SYNCHRONIZED; LabelNode startLabel = new LabelNode(); syncMethod.instructions.add(startLabel); LabelNode endLabel = new LabelNode(); int argIndex = 0; if (!md.staticMethod) { //System.out.println(methodNode.name + " is not static"); syncMethod.localVariables.add(new LocalVariableNode("arg" + (argIndex), "L" + classNode.name + ";", null, startLabel, endLabel, argIndex)); syncMethod.instructions.add(new VarInsnNode(Opcodes.ALOAD, argIndex++)); } for (ByteCodeMethodArg arg : md.arguments) { char typeChar = arg.type; if (arg.dim > 0) { typeChar = 'L'; } if (arg.desc == null || arg.desc.isEmpty()) { throw new RuntimeException( "Invalid arg description for arg " + argIndex + " of method " + methodNode.name); } syncMethod.localVariables.add(new LocalVariableNode("arg" + (argIndex), arg.desc, arg.desc, startLabel, endLabel, argIndex)); switch (typeChar) { case 'L': syncMethod.instructions.add(new VarInsnNode(Opcodes.ALOAD, argIndex++)); //syncMethod.localVariables.add(new LocalVariableNode("arg"+(argIndex-1), arg.desc, null, startLabel, endLabel, argIndex-1)); break; case 'S': case 'I': case 'B': case 'Z': case 'C': syncMethod.instructions.add(new VarInsnNode(Opcodes.ILOAD, argIndex++)); break; case 'J': syncMethod.instructions.add(new VarInsnNode(Opcodes.LLOAD, argIndex++)); argIndex++; // arg index increments 2 for double size args break; case 'F': syncMethod.instructions.add(new VarInsnNode(Opcodes.FLOAD, argIndex++)); break; case 'D': syncMethod.instructions.add(new VarInsnNode(Opcodes.DLOAD, argIndex++)); argIndex++;// arg index increments 2 for double size args break; default: throw new IllegalArgumentException("Unsupported argument type " + arg.type); } } if (md.staticMethod) { syncMethod.instructions.add(new MethodInsnNode(Opcodes.INVOKESTATIC, classNode.name, privateMethodName, methodNode.desc)); } else { syncMethod.instructions.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, classNode.name, privateMethodName, methodNode.desc)); } if (md.returnType != null) { char typeChar = md.returnType.type; if (md.returnType.dim > 0) { typeChar = 'L'; } switch (typeChar) { case 'L': syncMethod.instructions.add(new InsnNode(Opcodes.ARETURN)); break; case 'S': case 'I': case 'B': case 'Z': case 'C': syncMethod.instructions.add(new InsnNode(Opcodes.IRETURN)); break; case 'J': syncMethod.instructions.add(new InsnNode(Opcodes.LRETURN)); break; case 'F': syncMethod.instructions.add(new InsnNode(Opcodes.FRETURN)); break; case 'D': syncMethod.instructions.add(new InsnNode(Opcodes.DRETURN)); break; case 'V': syncMethod.instructions.add(new InsnNode(Opcodes.RETURN)); break; default: throw new IllegalArgumentException("Unsupported argument type " + md.returnType.type); } } else { syncMethod.instructions.add(new InsnNode(Opcodes.DRETURN)); } syncMethod.instructions.add(endLabel); methodsToAdd.add(syncMethod); } } if (!methodsToAdd.isEmpty()) { changed = true; System.out .println("Transforming " + methodsToAdd.size() + " synchronized methods in " + classNode.name); classNode.methods.addAll(methodsToAdd); ClassWriter w = new ClassWriter(ClassWriter.COMPUTE_MAXS); classNode.accept(w); byte[] out = w.toByteArray(); if (verify) { verify(out, classLoader); } return out; } else { ClassWriter w = new ClassWriter(0); classNode.accept(w); byte[] out = w.toByteArray(); return out; } }
From source file:com.codename1.tools.translator.BytecodeMethod.java
License:Open Source License
public void appendMethodC(StringBuilder b) { if (nativeMethod) { return;/*from w ww . java 2 s.co m*/ } appendCMethodPrefix(b, ""); b.append(" {\n"); if (eliminated) { if (returnType.isVoid()) { b.append(" return;\n}\n\n"); } else { b.append(" return 0;\n}\n\n"); } return; } b.append(declaration); boolean hasInstructions = true; if (optimizerOn) { hasInstructions = optimize(); } if (hasInstructions) { Set<String> added = new HashSet<String>(); for (LocalVariable lv : localVariables) { String variableName = lv.getQualifier() + "locals_" + lv.getIndex() + "_"; if (!added.contains(variableName) && lv.getQualifier() != 'o') { added.add(variableName); b.append(" volatile "); switch (lv.getQualifier()) { case 'i': b.append("JAVA_INT"); break; case 'l': b.append("JAVA_LONG"); break; case 'f': b.append("JAVA_FLOAT"); break; case 'd': b.append("JAVA_DOUBLE"); break; } b.append(" ").append(lv.getQualifier()).append("locals_").append(lv.getIndex()) .append("_ = 0; /* ").append(lv.getOrigName()).append(" */\n"); } } if (staticMethod) { if (methodName.equals("__CLINIT__")) { b.append(" DEFINE_METHOD_STACK("); } else { b.append(" __STATIC_INITIALIZER_"); b.append(clsName.replace('/', '_').replace('$', '_')); b.append("(threadStateData);\n DEFINE_METHOD_STACK("); } } else { b.append(" DEFINE_INSTANCE_METHOD_STACK("); } b.append(maxStack); b.append(", "); b.append(maxLocals); b.append(", 0, "); b.append(Parser.addToConstantPool(clsName)); b.append(", "); b.append(Parser.addToConstantPool(methodName)); b.append(");\n"); int startOffset = 0; if (synchronizedMethod) { if (staticMethod) { b.append(" monitorEnter(threadStateData, (JAVA_OBJECT)&class__"); b.append(clsName); b.append(");\n"); } else { b.append(" monitorEnter(threadStateData, __cn1ThisObject);\n"); } } if (!staticMethod) { b.append(" locals[0].data.o = __cn1ThisObject; locals[0].type = CN1_TYPE_OBJECT; "); startOffset++; } int localsOffset = startOffset; for (int iter = 0; iter < arguments.size(); iter++) { ByteCodeMethodArg arg = arguments.get(iter); if (arg.getQualifier() == 'o') { b.append(" locals["); b.append(localsOffset); b.append("].data."); b.append(arg.getQualifier()); b.append(" = __cn1Arg"); b.append(iter + 1); b.append(";\n"); b.append(" locals["); b.append(localsOffset); b.append("].type = CN1_TYPE_OBJECT;\n"); } else { b.append(" "); if (!hasLocalVariableWithIndex(arg.getQualifier(), localsOffset)) { switch (arg.getQualifier()) { case 'i': b.append("JAVA_INT"); break; case 'f': b.append("JAVA_FLOAT"); break; case 'd': b.append("JAVA_DOUBLE"); break; case 'l': b.append("JAVA_LONG"); break; default: b.append("JAVA_INT"); break; } b.append(" "); } b.append(arg.getQualifier()); b.append("locals_"); b.append(localsOffset); b.append("_"); b.append(" = __cn1Arg"); b.append(iter + 1); b.append(";\n"); } // For now we'll still allocate space for locals that we're not using // so we keep the indexes the same for objects. localsOffset++; if (arg.isDoubleOrLong()) { localsOffset++; } } } BasicInstruction.setSynchronizedMethod(synchronizedMethod, staticMethod, clsName); TryCatch.reset(); BasicInstruction.setHasInstructions(hasInstructions); for (Instruction i : instructions) { i.setMaxes(maxStack, maxLocals); i.appendInstruction(b, instructions); } if (instructions.size() == 0) { if (returnType.isVoid()) { b.append(" return;\n}\n\n"); } else { b.append(" return 0;\n}\n\n"); } return; } Instruction inst = instructions.get(instructions.size() - 1); int lastInstruction = inst.getOpcode(); if (lastInstruction == -1 || inst instanceof LabelInstruction) { if (instructions.size() > 2) { inst = instructions.get(instructions.size() - 2); lastInstruction = inst.getOpcode(); } } if (lastInstruction == Opcodes.RETURN || lastInstruction == Opcodes.ARETURN || lastInstruction == Opcodes.IRETURN || lastInstruction == Opcodes.LRETURN || lastInstruction == Opcodes.FRETURN || lastInstruction == Opcodes.DRETURN || lastInstruction == -1) { b.append("}\n\n"); } else { if (returnType.isVoid()) { b.append(" return;\n}\n\n"); } else { b.append(" return 0;\n}\n\n"); } } }