X Tutup
package org.python.compiler; import java.util.BitSet; import java.util.Vector; import org.objectweb.asm.AnnotationVisitor; import org.objectweb.asm.Attribute; import org.objectweb.asm.Handle; import org.objectweb.asm.Label; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; public class Code extends MethodVisitor implements Opcodes { MethodVisitor mv; String sig; String locals[]; int nlocals; int argcount; int returnLocal; BitSet finallyLocals = new java.util.BitSet(); //XXX: I'd really like to get sig and access out of here since MethodVistitor // should already have this information. public Code(MethodVisitor mv, String sig, int access) { super(ASM7); this.mv = mv; this.sig = sig; nlocals = -sigSize(sig, false); if ((access & ACC_STATIC) != ACC_STATIC) nlocals = nlocals+1; argcount = nlocals; locals = new String[nlocals+128]; } public int getLocal(String type) { //Could optimize this to skip arguments? for(int l = argcount; l= locals.length) { String[] new_locals = new String[locals.length*2]; System.arraycopy(locals, 0, new_locals, 0, locals.length); locals = new_locals; } locals[nlocals] = type; nlocals += 1; return nlocals-1; } public void freeLocal(int l) { if (locals[l] == null) { System.out.println("Double free:" + l); } locals[l] = null; } public int getFinallyLocal(String type) { int l = getLocal(type); finallyLocals.set(l); return l; } public void freeFinallyLocal(int l) { finallyLocals.clear(l); freeLocal(l); } public int getReturnLocal() { if (returnLocal == 0) returnLocal = getLocal("return"); return returnLocal; } public Vector getActiveLocals() { Vector ret = new Vector(); ret.setSize(nlocals); for (int l = argcount; l= Byte.MIN_VALUE) { switch (value) { case -1: iconst_m1(); break; case 0: iconst_0(); break; case 1: iconst_1(); break; case 2: iconst_2(); break; case 3: iconst_3(); break; case 4: iconst_4(); break; case 5: iconst_5(); break; default: bipush(value); break; } } else if (value <= Short.MAX_VALUE && value >= Short.MIN_VALUE) { sipush(value); } else { ldc(value); } } public void iconst_m1() { mv.visitInsn(ICONST_M1); } public void iconst_0() { mv.visitInsn(ICONST_0); } public void iconst_1() { mv.visitInsn(ICONST_1); } public void iconst_2() { mv.visitInsn(ICONST_2); } public void iconst_3() { mv.visitInsn(ICONST_3); } public void iconst_4() { mv.visitInsn(ICONST_4); } public void iconst_5() { mv.visitInsn(ICONST_5); } public void ifeq(Label label) { mv.visitJumpInsn(IFEQ, label); } public void ifle(Label label) { mv.visitJumpInsn(IFLE, label); } public void ifne(Label label) { mv.visitJumpInsn(IFNE, label); } public void ifnull(Label label) { mv.visitJumpInsn(IFNULL, label); } public void ifnonnull(Label label) { mv.visitJumpInsn(IFNONNULL, label); } public void if_acmpne(Label label) { mv.visitJumpInsn(IF_ACMPNE, label); } public void if_acmpeq(Label label) { mv.visitJumpInsn(IF_ACMPEQ, label); } public void if_icmple(Label label) { mv.visitJumpInsn(IF_ICMPLE, label); } public void if_icmpgt(Label label) { mv.visitJumpInsn(IF_ICMPGT, label); } public void if_icmplt(Label label) { mv.visitJumpInsn(IF_ICMPLT, label); } public void if_icmpne(Label label) { mv.visitJumpInsn(IF_ICMPNE, label); } public void if_icmpeq(Label label) { mv.visitJumpInsn(IF_ICMPEQ, label); } public void iadd() { mv.visitInsn(IADD); } public void iaload() { mv.visitInsn(IALOAD); } public void iinc() { mv.visitInsn(IINC); } public void iload(int index) { mv.visitVarInsn(ILOAD, index); } public void instanceof_(String type) { mv.visitTypeInsn(INSTANCEOF, type); } public void invokeinterface(String owner, String name, String type) { mv.visitMethodInsn(INVOKEINTERFACE, owner, name, type, false); } public void invokeinterface(String owner, String name, String type, boolean itf) { mv.visitMethodInsn(INVOKEINTERFACE, owner, name, type, itf); } public void invokespecial(String owner, String name, String type) { mv.visitMethodInsn(INVOKESPECIAL, owner, name, type, false); } public void invokestatic(String owner, String name, String type) { mv.visitMethodInsn(INVOKESTATIC, owner, name, type, false); } public void invokevirtual(String owner, String name, String type) { mv.visitMethodInsn(INVOKEVIRTUAL, owner, name, type, false); } public void ireturn() { mv.visitInsn(IRETURN); } public void istore(int index) { mv.visitVarInsn(ISTORE, index); } public void isub() { mv.visitInsn(ISUB); } public void label(Label label) { mv.visitLabel(label); } public void lconst_0() { mv.visitInsn(LCONST_0); } public void ldc(Object cst) { if (cst instanceof String) { String value = (String) cst; final int len = value.length(); // 65535 / 4 (max utf-8 expansion for non BMP characters) final int maxlen = 16000; if (len > maxlen) { new_("java/lang/StringBuilder"); dup(); iconst(len); invokespecial("java/lang/StringBuilder", "", "(I)V"); for (int i = 0; i < len; i += maxlen) { int j = i + maxlen; if (j > len) { j = len; } mv.visitLdcInsn(value.substring(i, j)); invokevirtual("java/lang/StringBuilder", "append", "(Ljava/lang/String;)" + "Ljava/lang/StringBuilder;"); } invokevirtual("java/lang/StringBuilder", "toString", "()Ljava/lang/String;"); } else { mv.visitLdcInsn(value); } } else { mv.visitLdcInsn(cst); } } public void lload(int index) { mv.visitVarInsn(LLOAD, index); } public void lreturn() { mv.visitInsn(LRETURN); } public void newarray(int atype) { mv.visitIntInsn(NEWARRAY, atype); } public void new_(String type) { mv.visitTypeInsn(NEW, type); } public void nop() { mv.visitInsn(NOP); } public void pop() { mv.visitInsn(POP); } public void pop2() { mv.visitInsn(POP2); } public void putstatic(String owner, String name, String type) { mv.visitFieldInsn(PUTSTATIC, owner, name, type); } public void putfield(String owner, String name, String type) { mv.visitFieldInsn(PUTFIELD, owner, name, type); } public void ret(int index) { mv.visitVarInsn(RET, index); } public void return_() { mv.visitInsn(RETURN); } public void sipush(int value) { mv.visitIntInsn(SIPUSH, value); } public void swap() { mv.visitInsn(SWAP); } public void swap2() { dup2_x2(); pop2(); } public void tableswitch(int arg0, int arg1, Label arg2, Label[] arg3) { mv.visitTableSwitchInsn(arg0, arg1, arg2, arg3); } public void trycatch(Label start, Label end, Label handlerStart, String type) { mv.visitTryCatchBlock(start, end, handlerStart, type); } public void setline(int line) { mv.visitLineNumber(line, new Label()); } @Override public void visitInvokeDynamicInsn(String name, String descriptor, Handle bsmHandle, Object... bmsArgs) { mv.visitInvokeDynamicInsn(name, descriptor, bsmHandle, bmsArgs); } }
X Tutup