src.org.python.compiler.Code Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jython Show documentation
Show all versions of jython Show documentation
Jython is an implementation of the high-level, dynamic, object-oriented
language Python written in 100% Pure Java, and seamlessly integrated with
the Java platform. It thus allows you to run Python on any Java platform.
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(ASM4);
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);
}
public void invokespecial(String owner, String name, String type) {
mv.visitMethodInsn(INVOKESPECIAL, owner, name, type);
}
public void invokestatic(String owner, String name, String type) {
mv.visitMethodInsn(INVOKESTATIC, owner, name, type);
}
public void invokevirtual(String owner, String name, String type) {
mv.visitMethodInsn(INVOKEVIRTUAL, owner, name, type);
}
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);
}
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);
}
}