All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.python.compiler.Module Maven / Gradle / Ivy

// Copyright (c) Corporation for National Research Initiatives

package org.python.compiler;

import java.io.*;
import java.util.*;
import org.python.parser.*;
import org.python.parser.ast.*;
import org.python.core.Py;
import org.python.core.PyException;

class PyIntegerConstant extends Constant implements ClassConstants
{
    int value;

    public PyIntegerConstant(int value) {
        this.value = value;
    }

    public void get(Code c) throws IOException {
        c.getstatic(module.classfile.name, name, $pyInteger);
    }

    public void put(Code c) throws IOException {
        module.classfile.addField(name, $pyInteger, access);
        c.iconst(value);
        int mref_newInteger = c.pool.Methodref(
            "org/python/core/Py",
            "newInteger",
            "(I)" + $pyInteger);
        c.invokestatic(mref_newInteger);
        c.putstatic(module.classfile.name, name, $pyInteger);
    }

    public int hashCode() {
        return value;
    }

    public boolean equals(Object o) {
        if (o instanceof PyIntegerConstant)
            return ((PyIntegerConstant)o).value == value;
        else
            return false;
    }
}

class PyFloatConstant extends Constant implements ClassConstants
{
    double value;

    public PyFloatConstant(double value) {
        this.value = value;
    }

    public void get(Code c) throws IOException {
        c.getstatic(module.classfile.name, name, $pyFloat);
    }

    public void put(Code c) throws IOException {
        module.classfile.addField(name, $pyFloat, access);
        c.ldc(c.pool.Double(value));
        int mref_newFloat = c.pool.Methodref("org/python/core/Py",
                                             "newFloat",
                                             "(D)" + $pyFloat);
        c.invokestatic(mref_newFloat);
        c.putstatic(module.classfile.name, name, $pyFloat);
    }

    public int hashCode() {
        return (int)value;
    }

    public boolean equals(Object o) {
        if (o instanceof PyFloatConstant)
            return ((PyFloatConstant)o).value == value;
        else
            return false;
    }
}

class PyComplexConstant extends Constant implements ClassConstants
{
    double value;

    public PyComplexConstant(double value) {
        this.value = value;
    }

    public void get(Code c) throws IOException {
        c.getstatic(module.classfile.name, name, $pyComplex);
    }

    public void put(Code c) throws IOException {
        module.classfile.addField(name, $pyComplex, access);
        c.ldc(c.pool.Double(value));
        int mref_newImaginary = c.pool.Methodref(
            "org/python/core/Py",
            "newImaginary",
            "(D)" + $pyComplex);
        c.invokestatic(mref_newImaginary);
        c.putstatic(module.classfile.name, name, $pyComplex);
    }

    public int hashCode() {
        return (int)value;
    }

    public boolean equals(Object o) {
        if (o instanceof PyComplexConstant)
            return ((PyComplexConstant)o).value == value;
        else
            return false;
    }
}

class PyStringConstant extends Constant implements ClassConstants
{
    String value;

    public PyStringConstant(String value) {
        this.value = value;
    }

    public void get(Code c) throws IOException {
        c.getstatic(module.classfile.name, name, $pyStr);
    }

    public void put(Code c) throws IOException {
        module.classfile.addField(name, $pyStr, access);
        c.ldc(value);
        int mref_newString = c.pool.Methodref(
            "org/python/core/Py",
            "newString",
            "(" + $str + ")" + $pyStr);
        c.invokestatic(mref_newString);
        c.putstatic(module.classfile.name, name, $pyStr);
    }

    public int hashCode() {
        return value.hashCode();
    }

    public boolean equals(Object o) {
        if (o instanceof PyStringConstant)
            return ((PyStringConstant)o).value.equals(value);
        else
            return false;
    }
}

class PyUnicodeConstant extends Constant implements ClassConstants
{
    String value;

    public PyUnicodeConstant(String value) {
        this.value = value;
    }

    public void get(Code c) throws IOException {
        c.getstatic(module.classfile.name, name, $pyUnicode);
    }

    public void put(Code c) throws IOException {
        module.classfile.addField(name, $pyUnicode, access);
        c.ldc(value);
        int mref_newString = c.pool.Methodref(
            "org/python/core/Py",
            "newUnicode",
            "(" + $str + ")" + $pyUnicode);
        c.invokestatic(mref_newString);
        c.putstatic(module.classfile.name, name, $pyUnicode);
    }

    public int hashCode() {
        return value.hashCode();
    }

    public boolean equals(Object o) {
        if (o instanceof PyUnicodeConstant)
            return ((PyUnicodeConstant)o).value.equals(value);
        else
            return false;
    }
}

class PyLongConstant extends Constant implements ClassConstants
{
    String value;

    public PyLongConstant(String value) {
        this.value = value;
    }

    public void get(Code c) throws IOException {
        c.getstatic(module.classfile.name, name, $pyLong);
    }

    public void put(Code c) throws IOException {
        module.classfile.addField(name, $pyLong, access);
        c.ldc(value);
        int mref_newLong = c.pool.Methodref(
            "org/python/core/Py",
            "newLong",
            "(" + $str + ")" + $pyLong);
        c.invokestatic(mref_newLong);
        c.putstatic(module.classfile.name, name, $pyLong);
    }

    public int hashCode() {
        return value.hashCode();
    }

    public boolean equals(Object o) {
        if (o instanceof PyLongConstant)
            return ((PyLongConstant)o).value.equals(value);
        else return false;
    }
}

class PyCodeConstant extends Constant implements ClassConstants
{
    public String co_name;
    public int argcount;
    public String[] names;
    public int id;
    public int co_firstlineno;
    public boolean arglist, keywordlist;
    String fname;

    // for nested scopes
    public String[] cellvars;
    public String[] freevars;
    public int jy_npurecell;

    public int moreflags;

    public PyCodeConstant() { ;
    }

    public void get(Code c) throws IOException {
        c.getstatic(module.classfile.name, name, $pyCode);
    }

    public void put(Code c) throws IOException {
        module.classfile.addField(name, $pyCode, access);
        c.iconst(argcount);

        //Make all names
        if (names != null) {
            CodeCompiler.makeStrings(c, names, names.length);
        } else { // classdef
             CodeCompiler.makeStrings(c, null, 0);
        }

        c.aload(1);
        c.ldc(co_name);
        c.iconst(co_firstlineno);

        c.iconst(arglist ? 1 : 0);
        c.iconst(keywordlist ? 1 : 0);

        int mref_self = c.pool.Fieldref(module.classfile.name,
                                        "self",
                                        "L"+module.classfile.name+";");
        c.getstatic(mref_self);
        //c.aconst_null();

        c.iconst(id);

        if (cellvars != null)
            CodeCompiler.makeStrings(c, cellvars, cellvars.length);
        else
            c.aconst_null();
        if (freevars != null)
            CodeCompiler.makeStrings(c, freevars, freevars.length);
        else
            c.aconst_null();

        c.iconst(jy_npurecell);

        c.iconst(moreflags);

        int mref_newCode = c.pool.Methodref(
            "org/python/core/Py",
            "newCode",
            "(I" + $strArr + $str + $str + "IZZ" + $pyFuncTbl + "I" +
                $strArr + $strArr + "II)" + $pyCode);

        c.invokestatic(mref_newCode);
        //c.aconst_null();
        c.putstatic(module.classfile.name, name, $pyCode);
    }
}

public class Module implements ClassConstants, CompilationContext
{
    ClassFile classfile;
    Constant filename;
    String sfilename;
    public Constant mainCode;
    public boolean linenumbers;
    public boolean setFile=true;
    Future futures;
    Hashtable scopes;

    public Module(String name, String filename, boolean linenumbers) {
        this.linenumbers = linenumbers;
        classfile = new ClassFile(name, "org/python/core/PyFunctionTable",
                                  ClassFile.SYNCHRONIZED | ClassFile.PUBLIC);
        constants = new Hashtable();
        sfilename = filename;
        if (filename != null)
            this.filename = PyString(filename);
        else
            this.filename = null;
        codes = new Vector();
        futures = new Future();
        scopes = new Hashtable();
    }

    public Module(String name) {
        this(name, name+".py", true);
    }

    // This block of code handles the pool of Python Constants
    Hashtable constants;

    private Constant findConstant(Constant c) {
        Constant ret = (Constant)constants.get(c);
        if (ret != null)
            return ret;
        ret = c;
        c.module = this;
        //More sophisticated name mappings might be nice
        c.name = "_"+constants.size();
        constants.put(ret, ret);
        return ret;
    }

    public Constant PyInteger(int value) {
        return findConstant(new PyIntegerConstant(value));
    }

    public Constant PyFloat(double value) {
        return findConstant(new PyFloatConstant(value));
    }

    public Constant PyComplex(double value) {
        return findConstant(new PyComplexConstant(value));
    }

    public Constant PyString(String value) {
        return findConstant(new PyStringConstant(value));
    }
    public Constant PyUnicode(String value) {
        return findConstant(new PyUnicodeConstant(value));
    }
    public Constant PyLong(String value) {
        return findConstant(new PyLongConstant(value));
    }

    /*public PyCodeConstant PyCode(SimpleNode tree, String name,
      ArgListCompiler ac,
      boolean fast_locals, boolean class_body)
      throws Exception {
      return PyCode(tree, name, ac, fast_locals, class_body, false, 0);
      }
      public PyCodeConstant PyCode(SimpleNode tree, String name,
      ArgListCompiler ac,
      boolean fast_locals, boolean class_body,
      int firstlineno)
      throws Exception {
      return PyCode(tree, name, ac, fast_locals, class_body, false,
                    firstlineno);
      }
      public PyCodeConstant PyCode(SimpleNode tree, String name,
      ArgListCompiler ac,
      boolean fast_locals, boolean class_body,
      boolean printResults)
      throws Exception {
      return PyCode(tree, name, ac, fast_locals, class_body, printResults, 0);
      }*/

    Vector codes;
    private boolean isJavaIdentifier(String s) {
        char[] chars = s.toCharArray();
        if (chars.length == 0)
            return false;
        if (!Character.isJavaIdentifierStart(chars[0]))
            return false;

        for(int i=1; i 0) {
            ac.appendInitCode((Suite) tree);
        }

        if (scope != null) {
          int nparamcell = scope.jy_paramcells.size();
          if (nparamcell > 0) {
            if (to_cell == 0) {
                to_cell = classfile.pool.Methodref("org/python/core/PyFrame",
                    "to_cell","(II)V");
            }
            Hashtable tbl = scope.tbl;
            Vector paramcells = scope.jy_paramcells;
            for (int i = 0; i < nparamcell; i++) {
                c.aload(1);
                SymInfo syminf = (SymInfo)tbl.get(paramcells.elementAt(i));
                c.iconst(syminf.locals_index);
                c.iconst(syminf.env_index);
                c.invokevirtual(to_cell);
            }
          }
        }

        compiler.parse(tree, c, fast_locals, className, classBody,
                       scope, cflags);

        if (scope.generator) {
            genswitch.setPosition();
            c.aload(1);
            if (compiler.f_lasti == 0) {
                compiler.f_lasti = c.pool.Fieldref(
                        "org/python/core/PyFrame", "f_lasti", "I"); 
            }
            c.getfield(compiler.f_lasti);

            Label[] yields = new Label[compiler.yields.size()+1];

            yields[0] = start;
            for (int i = 1; i < yields.length; i++) {
                yields[i] = (Label) compiler.yields.elementAt(i-1);
            }
            c.tableswitch(start, 0, yields);
            // XXX: Generate an error
        }

        // !classdef only
        if (!classBody) code.names = toNameAr(compiler.names,false);

        if (scope != null) {
            code.cellvars = toNameAr(scope.cellvars,true);
            code.freevars = toNameAr(scope.freevars,true);
            code.jy_npurecell = scope.jy_npurecell;
        }

        if (compiler.optimizeGlobals) {
            code.moreflags |= org.python.core.PyTableCode.CO_OPTIMIZED;
        }
        if (compiler.my_scope.generator) {
            code.moreflags |= org.python.core.PyTableCode.CO_GENERATOR;
        }
        if (cflags != null) {
            if (cflags.generator_allowed) {
                code.moreflags |= org.python.core.PyTableCode.CO_GENERATOR_ALLOWED;
            }
            if (cflags.division) {
                code.moreflags |= org.python.core.PyTableCode.CO_FUTUREDIVISION;
            }
        }

        code.module = this;
        code.name = code.fname;
        return code;
    }

    //This block of code writes out the various standard methods
    public void addInit() throws IOException {
        Code c = classfile.addMethod("", "(Ljava/lang/String;)V", ClassFile.PUBLIC);
        c.aload(0);
        c.invokespecial(c.pool.Methodref("org/python/core/PyFunctionTable",
                                         "",
                                         "()V"));
        addConstants(c);
    }

    public void addRunnable() throws IOException {
        Code c = classfile.addMethod("getMain",
                                     "()" + $pyCode,
                                     ClassFile.PUBLIC);
        mainCode.get(c);
        c.areturn();
    }

    public void addMain() throws IOException {
        Code c = classfile.addMethod("main", "(" + $strArr + ")V",
                ClassFile.PUBLIC | ClassFile.STATIC);
        c.new_(c.pool.Class(classfile.name));
        c.dup();
        c.ldc(classfile.name);
        c.invokespecial(c.pool.Methodref(classfile.name, "", "(" + $str + ")V"));
        c.aload(0);
        c.invokestatic(c.pool.Methodref("org/python/core/Py", "runMain", "("
                + $pyRunnable + $strArr + ")V"));
        c.return_();
    }

    public void addConstants(Code c) throws IOException {
        classfile.addField("self", "L"+classfile.name+";",
                           ClassFile.STATIC|ClassFile.FINAL);
        c.aload(0);
        c.putstatic(c.pool.Fieldref(classfile.name,
                                    "self",
                                    "L"+classfile.name+";"));

        Enumeration e = constants.elements();

        while (e.hasMoreElements()) {
            Constant constant = (Constant)e.nextElement();
            constant.put(c);
        }

        for(int i=0; i




© 2015 - 2024 Weber Informatics LLC | Privacy Policy