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-standalone Show documentation
Show all versions of jython-standalone 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.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
class Code implements MethodVisitor, 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) {
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());
}
}