private void addParameter2(int where, CtClass type, String desc) throws BadBytecode classInfo = methodInfo.getConstPool().addClassInfo(type); ca.insertLocalVar(where, size); LocalVariableAttribute va = (LocalVariableAttribute)ca.getAttribute(LocalVariableAttribute.tag); if (va != null) va.shiftIndex(where, size); = (LocalVariableTypeAttribute)ca.getAttribute(LocalVariableTypeAttribute.tag); if (lvta != null) lvta.shiftIndex(where, size); StackMapTable smt = (StackMapTable)ca.getAttribute(StackMapTable.tag); if (smt != null) smt.insertLocal(where, StackMapTable.typeTagOf(typeDesc), classInfo); StackMap sm = (StackMap)ca.getAttribute(StackMap.tag); if (sm != null) sm.insertLocal(where, StackMapTable.typeTagOf(typeDesc), classInfo);
cc.checkModify(); if (isClassInitializer()) throw new CannotCompileException("class initializer"); CodeAttribute ca = methodInfo.getCodeAttribute(); CodeIterator iterator = ca.iterator(); Bytecode b = new Bytecode(methodInfo.getConstPool(), ca.getMaxStack(), ca.getMaxLocals()); b.setStackDepth(ca.getMaxStack()); Javac jv = new Javac(b, cc); try { jv.recordParams(getParameterTypes(), false); jv.compileStmnt(src); ca.setMaxStack(b.getMaxStack()); ca.setMaxLocals(b.getMaxLocals()); iterator.skipConstructor(); int pos = iterator.insertEx(b.get()); iterator.insert(b.getExceptionTable(), pos); methodInfo.rebuildStackMapIf6(cc.getClassPool(), cc.getClassFile2()); throw new CannotCompileException(e); throw new CannotCompileException(e);
/** * Rebuilds a stack map table for J2ME (CLDC). If no stack map table is included, * a new one is created. If this <code>MethodInfo</code> does not * include a code attribute, nothing happens. * * @param pool used for making type hierarchy. * @see StackMap * @since 3.12 */ public void rebuildStackMapForME(ClassPool pool) throws BadBytecode { CodeAttribute ca = getCodeAttribute(); if (ca != null) { StackMap sm = MapMaker.make2(pool, this); ca.setAttribute(sm); } }
/** * Changes the index numbers of the local variables * to append a new parameter. * This method does not update <code>LocalVariableAttribute</code>, * <code>LocalVariableTypeAttribute</code>, * <code>StackMapTable</code>, or <code>StackMap</code>. * These attributes must be explicitly updated. * * @param where the index of the new parameter. * @param size the type size of the new parameter (1 or 2). * * @see LocalVariableAttribute#shiftIndex(int, int) * @see LocalVariableTypeAttribute#shiftIndex(int, int) * @see StackMapTable#insertLocal(int, int, int) * @see StackMap#insertLocal(int, int, int) */ public void insertLocalVar(int where, int size) throws BadBytecode { CodeIterator ci = iterator(); while (ci.hasNext()) shiftIndex(ci, where, size); setMaxLocals(getMaxLocals() + size); }
/** * Copies code. */ private byte[] copyCode(ConstPool destCp, Map classnames, ExceptionTable etable, CodeAttribute destCa) throws BadBytecode { int len = getCodeLength(); byte[] newCode = new byte[len]; destCa.info = newCode; LdcEntry ldc = copyCode(this.info, 0, len, this.getConstPool(), newCode, destCp, classnames); return LdcEntry.doit(newCode, ldc, etable, destCa); }
public BasicBlock[] make(MethodInfo minfo) throws BadBytecode { CodeAttribute ca = minfo.getCodeAttribute(); if (ca == null) return null; CodeIterator ci = ca.iterator(); return make(ci, 0, ci.getCodeLength(), ca.getExceptionTable()); }
final ConstPool constPool = aCtClass.getClassFile().getConstPool(); final ClassPool classPool = aCtClass.getClassPool(); for ( Object oMethod : aCtClass.getClassFile().getMethods() ) { final MethodInfo methodInfo = (MethodInfo) oMethod; final String methodName = methodInfo.getName(); if ( methodName.startsWith( "$$_hibernate_" ) || methodInfo.getCodeAttribute() == null ) { continue; final CodeIterator itr = methodInfo.getCodeAttribute().iterator(); while ( itr.hasNext() ) { int index = itr.next(); int op = itr.byteAt( index ); if ( op != Opcode.PUTFIELD && op != Opcode.GETFIELD ) { continue; String fieldName = constPool.getFieldrefName( itr.u16bitAt( index + 1 ) ); String fieldClassName = constPool.getClassInfo( constPool.getFieldrefClass( itr.u16bitAt( index + 1 ) ) ); CtClass targetCtClass = classPool.getCtClass( fieldClassName ); methodInfo.getCodeAttribute().setAttribute( MapMaker.make( classPool, methodInfo ) );
protected void enhanceAttributesAccess( CtClass managedCtClass, IdentityHashMap<String, PersistentAttributeAccessMethods> attributeDescriptorMap) { final ConstPool constPool = managedCtClass.getClassFile().getConstPool(); final ClassPool classPool = managedCtClass.getClassPool(); for ( Object oMethod : managedCtClass.getClassFile().getMethods() ) { final MethodInfo methodInfo = (MethodInfo) oMethod; final String methodName = methodInfo.getName(); if ( methodName.startsWith( "$$_hibernate_" ) || methodInfo.getCodeAttribute() == null ) { continue; final CodeIterator itr = methodInfo.getCodeAttribute().iterator(); while ( itr.hasNext() ) { final int index = itr.next(); final int op = itr.byteAt( index ); if ( op != Opcode.PUTFIELD && op != Opcode.GETFIELD ) { continue; if ( !managedCtClass.getName().equals( constPool.getFieldrefClassName( itr.u16bitAt( index + 1 ) ) ) ) { continue; final String fieldName = constPool.getFieldrefName( itr.u16bitAt( index + 1 ) ); final PersistentAttributeAccessMethods attributeMethods = attributeDescriptorMap.get( fieldName ); methodInfo.getCodeAttribute().setAttribute( MapMaker.make( classPool, methodInfo ) );
throws CannotCompileException CodeAttribute codeAttr = minfo.getCodeAttribute(); if (codeAttr == null) return false; CodeIterator iterator = codeAttr.iterator(); boolean edited = false; LoopContext context = new LoopContext(codeAttr.getMaxLocals()); while (iterator.hasNext()) if (loopBody(iterator, clazz, minfo, context)) edited = true; ExceptionTable et = codeAttr.getExceptionTable(); int n = et.size(); for (int i = 0; i < n; ++i) { if (codeAttr.getMaxLocals() < context.maxLocals) codeAttr.setMaxLocals(context.maxLocals); codeAttr.setMaxStack(codeAttr.getMaxStack() + context.maxStack); try { if (edited) minfo.rebuildStackMapIf6(clazz.getClassPool(), clazz.getClassFile2()); throw new CannotCompileException(b.getMessage(), b);
cc.checkModify(); ConstPool cp = methodInfo.getConstPool(); CodeAttribute ca = methodInfo.getCodeAttribute(); CodeIterator iterator = ca.iterator(); Bytecode b = new Bytecode(cp, ca.getMaxStack(), ca.getMaxLocals()); b.setStackDepth(1); Javac jv = new Javac(b, cc); int locals = b.getMaxLocals(); if (stack > ca.getMaxStack()) ca.setMaxStack(stack); if (locals > ca.getMaxLocals()) ca.setMaxLocals(locals); int len = iterator.getCodeLength(); int pos = iterator.append(b.get()); ca.getExceptionTable().add(getStartPosOfBody(ca), len, len, cp.addClassInfo(exceptionType)); iterator.append(b.getExceptionTable(), pos); methodInfo.rebuildStackMapIf6(cc.getClassPool(), cc.getClassFile2()); throw new CannotCompileException(e); throw new CannotCompileException(e); } catch (BadBytecode e) { throw new CannotCompileException(e);
CodeIterator iterator = ca.iterator(); int retAddr = ca.getMaxLocals(); Bytecode b = new Bytecode(pool, 0, retAddr + 1); b.setStackDepth(ca.getMaxStack() + 1); Javac jv = new Javac(b, cc); try { int handlerPos = iterator.getCodeLength(); if (asFinally) ca.getExceptionTable().add(getStartPosOfBody(ca), handlerPos, handlerPos, 0); while (iterator.hasNext()) { int pos = iterator.next(); if (pos >= handlerPos) break; ca.setMaxStack(b.getMaxStack()); ca.setMaxLocals(b.getMaxLocals()); methodInfo.rebuildStackMapIf6(cc.getClassPool(), cc.getClassFile2()); throw new CannotCompileException(e); throw new CannotCompileException(e);
CodeAttribute codeAttribute = method.getCodeAttribute(); int maxLocals = codeAttribute.getMaxLocals(); int maxStack = codeAttribute.getMaxStack(); int codeLength = codeAttribute.getCodeLength(); CodeIterator iter = codeAttribute.iterator(); IntQueue queue = new IntQueue(); subroutines = scanner.scan(method); Executor executor = new Executor(clazz.getClassPool(), method.getConstPool()); frames = new Frame[codeLength]; frames[iter.lookAhead()] = firstFrame(method, maxLocals, maxStack); queue.add(iter.next()); while (!queue.isEmpty()) { analyzeNextEntry(method, iter, queue, executor);
/** * Prints the bytecode instructions of a given method. */ public void print(CtMethod method) { MethodInfo info = method.getMethodInfo2(); ConstPool pool = info.getConstPool(); CodeAttribute code = info.getCodeAttribute(); if (code == null) return; CodeIterator iterator = code.iterator(); while (iterator.hasNext()) { int pos; try { pos = iterator.next(); } catch (BadBytecode e) { throw new RuntimeException(e); } stream.println(pos + ": " + instructionString(iterator, pos, pool)); } }
throws CannotCompileException declaringClass.checkModify(); ConstPool cp = methodInfo.getConstPool(); CodeAttribute ca = methodInfo.getCodeAttribute(); if (ca == null) throw new CannotCompileException("no method body"); LocalVariableAttribute va = (LocalVariableAttribute)ca.getAttribute( LocalVariableAttribute.tag); if (va == null) { va = new LocalVariableAttribute(cp); ca.getAttributes().add(va); int maxLocals = ca.getMaxLocals(); String desc = Descriptor.of(type); va.addEntry(0, ca.getCodeLength(), cp.addUtf8Info(name), cp.addUtf8Info(desc), maxLocals); ca.setMaxLocals(maxLocals + Descriptor.dataSize(desc));
public int transform(CtClass tclazz, int pos, CodeIterator iterator, ConstPool cp) throws BadBytecode int c = iterator.byteAt(pos); if (c == PUTFIELD || c == PUTSTATIC) { int index = iterator.u16bitAt(pos + 1); String typedesc = isField(tclazz.getClassPool(), cp, fieldClass, fieldname, isPrivate, index); if (typedesc != null) { if (c == PUTSTATIC) { CodeAttribute ca = iterator.get(); iterator.move(pos); char c0 = typedesc.charAt(0); iterator.writeByte(DUP_X2, pos + 1); iterator.writeByte(POP, pos + 2); ca.setMaxStack(ca.getMaxStack() + 2); iterator.writeByte(ACONST_NULL, pos); iterator.writeByte(SWAP, pos + 1); ca.setMaxStack(ca.getMaxStack() + 1); int mi = cp.addClassInfo(methodClassname); String type = "(Ljava/lang/Object;" + typedesc + ")V"; int methodref = cp.addMethodrefInfo(mi, methodName, type); iterator.writeByte(INVOKESTATIC, pos); iterator.write16bit(methodref, pos + 1);
/** * Returns true if the constructor (or static initializer) * is the default one. This method returns true if the constructor * takes some arguments but it does not perform anything except * calling <code>super()</code> (the no-argument constructor of * the super class). */ public boolean isEmpty() { CodeAttribute ca = getMethodInfo2().getCodeAttribute(); if (ca == null) return false; // native or abstract?? // they are not allowed, though. ConstPool cp = ca.getConstPool(); CodeIterator it = ca.iterator(); try { int pos, desc; int op0 = it.byteAt(it.next()); return op0 == Opcode.RETURN // empty static initializer || (op0 == Opcode.ALOAD_0 && it.byteAt(pos = it.next()) == Opcode.INVOKESPECIAL && (desc = cp.isConstructor(getSuperclassName(), it.u16bitAt(pos + 1))) != 0 && "()V".equals(cp.getUtf8Info(desc)) && it.byteAt(it.next()) == Opcode.RETURN && !it.hasNext()); } catch (BadBytecode e) {} return false; }
code.setMaxStack(stacksize); code.setMaxLocals(localsize); m = new MethodInfo(cf.getConstPool(), "<clinit>", "()V"); m.setAccessFlags(AccessFlag.STATIC); m.setCodeAttribute(code.toCodeAttribute()); cf.addMethod(m); CtMember.Cache cache = hasMemberCache(); CodeAttribute codeAttr = m.getCodeAttribute(); if (codeAttr == null) throw new CannotCompileException("empty <clinit>"); CodeIterator it = codeAttr.iterator(); int pos = it.insertEx(code.get()); it.insert(code.getExceptionTable(), pos); int maxstack = codeAttr.getMaxStack(); if (maxstack < stacksize) codeAttr.setMaxStack(stacksize); int maxlocals = codeAttr.getMaxLocals(); if (maxlocals < localsize) codeAttr.setMaxLocals(localsize); throw new CannotCompileException(e); throw new CannotCompileException(e);
@Override public void scan(Object cls) { final MetadataAdapter md = getMetadataAdapter(); for (Object method : md.getMethods(cls)) { String key = md.getMethodFullKey(cls, method); if (acceptResult(key)) { LocalVariableAttribute table = (LocalVariableAttribute) ((MethodInfo) method).getCodeAttribute().getAttribute(LocalVariableAttribute.tag); int length = table.tableLength(); int i = Modifier.isStatic(((MethodInfo) method).getAccessFlags()) ? 0 : 1; //skip this if (i < length) { List<String> names = new ArrayList<String>(length - i); while (i < length) names.add(((MethodInfo) method).getConstPool().getUtf8Info(table.nameIndex(i++))); getStore().put(key, Joiner.on(", ").join(names)); } } } } }
/** * Returns true if the method body is empty, that is, <code>{}</code>. * It also returns true if the method is an abstract method. */ public boolean isEmpty() { CodeAttribute ca = getMethodInfo2().getCodeAttribute(); if (ca == null) // abstract or native return (getModifiers() & Modifier.ABSTRACT) != 0; CodeIterator it = ca.iterator(); try { return it.hasNext() && it.byteAt(it.next()) == Opcode.RETURN && !it.hasNext(); } catch (BadBytecode e) {} return false; }
if (!isConstructor()) return; CodeAttribute ca = getCodeAttribute(); byte[] code = ca.getCode(); CodeIterator iterator = ca.iterator(); int pos = iterator.skipSuperConstructor(); if (pos >= 0) { // not this() ConstPool cp = constPool; int mref = ByteArray.readU16bit(code, pos + 1); int nt = cp.getMethodrefNameAndType(mref); int sc = cp.addClassInfo(superclass); int mref2 = cp.addMethodrefInfo(sc, nt); ByteArray.write16bit(mref2, code, pos + 1);