Beispiel #1
0
namespace pyston {

int GLOBAL_VERBOSITY = 0;

int PYTHON_VERSION_MAJOR = DEFAULT_PYTHON_MAJOR_VERSION;
int PYTHON_VERSION_MINOR = DEFAULT_PYTHON_MINOR_VERSION;
int PYTHON_VERSION_MICRO = DEFAULT_PYTHON_MICRO_VERSION;

int PYTHON_VERSION_HEX = version_hex(PYTHON_VERSION_MAJOR, PYTHON_VERSION_MINOR, PYTHON_VERSION_MICRO);

int MAX_OPT_ITERATIONS = 1;

bool FORCE_OPTIMIZE = false;
bool SHOW_DISASM = false;
bool BENCH = false;
bool PROFILE = false;
bool DUMPJIT = false;
bool TRAP = false;
bool USE_STRIPPED_STDLIB = true; // always true
bool ENABLE_INTERPRETER = true;
bool ENABLE_PYPA_PARSER = false;

static bool _GLOBAL_ENABLE = 1;
bool ENABLE_ICS = 1 && _GLOBAL_ENABLE;
bool ENABLE_ICGENERICS = 1 && ENABLE_ICS;
bool ENABLE_ICGETITEMS = 1 && ENABLE_ICS;
bool ENABLE_ICSETITEMS = 1 && ENABLE_ICS;
bool ENABLE_ICDELITEMS = 1 && ENABLE_ICS;
bool ENABLE_ICCALLSITES = 1 && ENABLE_ICS;
bool ENABLE_ICSETATTRS = 1 && ENABLE_ICS;
bool ENABLE_ICGETATTRS = 1 && ENABLE_ICS;
bool ENALBE_ICDELATTRS = 1 && ENABLE_ICS;
bool ENABLE_ICGETGLOBALS = 1 && ENABLE_ICS;
bool ENABLE_ICBINEXPS = 1 && ENABLE_ICS;
bool ENABLE_ICNONZEROS = 1 && ENABLE_ICS;
bool ENABLE_SPECULATION = 1 && _GLOBAL_ENABLE;
bool ENABLE_OSR = 1 && _GLOBAL_ENABLE;
bool ENABLE_LLVMOPTS = 1 && _GLOBAL_ENABLE;
bool ENABLE_INLINING = 1 && _GLOBAL_ENABLE;
bool ENABLE_REOPT = 1 && _GLOBAL_ENABLE;
bool ENABLE_PYSTON_PASSES = 1 && _GLOBAL_ENABLE;
bool ENABLE_TYPE_FEEDBACK = 1 && _GLOBAL_ENABLE;
bool ENABLE_RUNTIME_ICS = 1 && _GLOBAL_ENABLE;

bool ENABLE_FRAME_INTROSPECTION = 1;
bool BOOLS_AS_I64 = ENABLE_FRAME_INTROSPECTION;
}
Beispiel #2
0
namespace pyston {

struct FutureOption {
    int optional_version_hex;
    int mandatory_version_hex;
    int ff_mask;
};

const std::map<std::string, FutureOption> future_options
    = { { "absolute_import", { version_hex(2, 5, 0), version_hex(3, 0, 0), FF_ABSOLUTE_IMPORT } },
        { "division", { version_hex(2, 2, 0), version_hex(3, 0, 0), FF_DIVISION } },
        { "generators", { version_hex(2, 2, 0), version_hex(3, 0, 0), FF_GENERATOR } },
        { "unicode_literals", { version_hex(2, 6, 0), version_hex(3, 0, 0), FF_UNICODE_LITERALS } },
        { "print_function", { version_hex(2, 6, 0), version_hex(3, 0, 0), FF_PRINT_FUNCTION } },
        { "nested_scopes", { version_hex(2, 1, 0), version_hex(2, 2, 0), FF_NESTED_SCOPES } },
        { "with_statement", { version_hex(2, 5, 0), version_hex(3, 6, 0), FF_WITH_STATEMENT } } };

void raiseFutureImportErrorNotFound(const char* file, AST* node, const char* name) {
    raiseSyntaxErrorHelper(file, "", node, "future feature %s is not defined", name);
}

void raiseFutureImportErrorNotBeginning(const char* file, AST* node) {
    raiseSyntaxErrorHelper(file, "", node, "from __future__ imports must occur at the beginning of the file");
}

class BadFutureImportVisitor : public NoopASTVisitor {
public:
    virtual bool visit_importfrom(AST_ImportFrom* node) {
        if (node->module.str() == "__future__") {
            raiseFutureImportErrorNotBeginning(file, node);
        }
        return true;
    }

    // TODO optimization: have it skip things like expressions that you know
    // there is no need to descend into

    BadFutureImportVisitor(const char* file) : file(file) {}
    const char* file;
};

inline bool is_stmt_string(AST_stmt* stmt) {
    return stmt->type == AST_TYPE::Expr && static_cast<AST_Expr*>(stmt)->value->type == AST_TYPE::Str;
}

FutureFlags getFutureFlags(AST_Module* m, const char* file) {
    FutureFlags ff = 0;

    // Set the defaults for the future flags depending on what version we are
    for (const std::pair<std::string, FutureOption>& p : future_options) {
        if (PYTHON_VERSION_HEX >= p.second.mandatory_version_hex) {
            ff |= p.second.ff_mask;
        }
    }

    // Find all the __future__ imports, raising an error for those that do not
    // occur at the beginning of the file.
    bool future_import_allowed = true;
    BadFutureImportVisitor import_visitor(file);
    for (int i = 0; i < m->body.size(); i++) {
        AST_stmt* stmt = m->body[i];

        if (stmt->type == AST_TYPE::ImportFrom && static_cast<AST_ImportFrom*>(stmt)->module.str() == "__future__") {
            if (future_import_allowed) {
                // We have a `from __future__` import statement, and we are
                // still at the top of the file, so just set the appropriate
                // future flag for each imported option.

                for (AST_alias* alias : static_cast<AST_ImportFrom*>(stmt)->names) {
                    const std::string& option_name = alias->name.str();
                    auto iter = future_options.find(option_name);
                    if (iter == future_options.end()) {
                        // If it's not one of the available options, throw an error.
                        // Note: the __future__ module also exposes "all_feature_names",
                        // but you still can't import that using a from-import, so we
                        // don't need to worry about that here.
                        raiseFutureImportErrorNotFound(file, alias, option_name.c_str());
                    } else {
                        const FutureOption& fo = iter->second;
                        if (PYTHON_VERSION_HEX >= fo.optional_version_hex) {
                            ff |= fo.ff_mask;
                        } else {
                            raiseFutureImportErrorNotFound(file, alias, option_name.c_str());
                        }
                    }
                }
            } else {
                raiseFutureImportErrorNotBeginning(file, stmt);
            }
        } else {
            // A docstring is allowed at the beginning of a module; otherwise,
            // we cannot permit any __future__ import after this point.
            if (i > 0 || !is_stmt_string(stmt)) {
                // Recurse on the node and throw an error if it has any
                // `from __future__` import statement.
                stmt->accept(&import_visitor);

                future_import_allowed = false;
            }
        }
    }

    return ff;
}
}
Beispiel #3
0
namespace pyston {

int GLOBAL_VERBOSITY = 0;

int PYSTON_VERSION_MAJOR = 0;
int PYSTON_VERSION_MINOR = 3;

int PYTHON_VERSION_MAJOR = DEFAULT_PYTHON_MAJOR_VERSION;
int PYTHON_VERSION_MINOR = DEFAULT_PYTHON_MINOR_VERSION;
int PYTHON_VERSION_MICRO = DEFAULT_PYTHON_MICRO_VERSION;

int PYTHON_VERSION_HEX = version_hex(PYTHON_VERSION_MAJOR, PYTHON_VERSION_MINOR, PYTHON_VERSION_MICRO);

int MAX_OPT_ITERATIONS = 1;

bool FORCE_INTERPRETER = false;
bool FORCE_OPTIMIZE = false;
bool SHOW_DISASM = false;
bool PROFILE = false;
bool DUMPJIT = false;
bool TRAP = false;
bool USE_STRIPPED_STDLIB = true; // always true
bool ENABLE_INTERPRETER = true;
bool ENABLE_PYPA_PARSER = true;
bool USE_REGALLOC_BASIC = true;

int OSR_THRESHOLD_INTERPRETER = 200;
int REOPT_THRESHOLD_INTERPRETER = 100;
int OSR_THRESHOLD_BASELINE = 10000;
int REOPT_THRESHOLD_BASELINE = 250;
int OSR_THRESHOLD_T2 = 10000;
int REOPT_THRESHOLD_T2 = 10000;
int SPECULATION_THRESHOLD = 100;

static bool _GLOBAL_ENABLE = 1;
bool ENABLE_ICS = 1 && _GLOBAL_ENABLE;
bool ENABLE_ICGENERICS = 1 && ENABLE_ICS;
bool ENABLE_ICGETITEMS = 1 && ENABLE_ICS;
bool ENABLE_ICSETITEMS = 1 && ENABLE_ICS;
bool ENABLE_ICDELITEMS = 1 && ENABLE_ICS;
bool ENABLE_ICCALLSITES = 1 && ENABLE_ICS;
bool ENABLE_ICSETATTRS = 1 && ENABLE_ICS;
bool ENABLE_ICGETATTRS = 1 && ENABLE_ICS;
bool ENALBE_ICDELATTRS = 1 && ENABLE_ICS;
bool ENABLE_ICGETGLOBALS = 1 && ENABLE_ICS;
bool ENABLE_ICBINEXPS = 1 && ENABLE_ICS;
bool ENABLE_ICNONZEROS = 1 && ENABLE_ICS;
bool ENABLE_SPECULATION = 1 && _GLOBAL_ENABLE;
bool ENABLE_OSR = 1 && _GLOBAL_ENABLE;
bool ENABLE_LLVMOPTS = 1 && _GLOBAL_ENABLE;
bool ENABLE_INLINING = 1 && _GLOBAL_ENABLE;
bool ENABLE_REOPT = 1 && _GLOBAL_ENABLE;
bool ENABLE_PYSTON_PASSES = 1 && _GLOBAL_ENABLE;
bool ENABLE_TYPE_FEEDBACK = 1 && _GLOBAL_ENABLE;
bool ENABLE_RUNTIME_ICS = 1 && _GLOBAL_ENABLE;

bool ENABLE_FRAME_INTROSPECTION = 1;
bool BOOLS_AS_I64 = ENABLE_FRAME_INTROSPECTION;

extern "C" {
int Py_FrozenFlag = 1;
int Py_IgnoreEnvironmentFlag = 0;
int Py_NoSiteFlag = 0;
int Py_OptimizeFlag = 0;
int Py_VerboseFlag = 0;
}
}
Beispiel #4
0
namespace pyston {

struct FutureOption {
    int optional_version_hex;
    int mandatory_version_hex;
    int ff_mask;
};

const std::map<std::string, FutureOption> future_options
    = { { "absolute_import", { version_hex(2, 5, 0), version_hex(3, 0, 0), FF_ABSOLUTE_IMPORT } },
        { "division", { version_hex(2, 2, 0), version_hex(3, 0, 0), FF_DIVISION } },
        { "generators", { version_hex(2, 2, 0), version_hex(3, 0, 0), FF_GENERATOR } },
        { "unicode_literals", { version_hex(2, 6, 0), version_hex(3, 0, 0), FF_UNICODE_LITERALS } },
        { "print_functions", { version_hex(2, 6, 0), version_hex(3, 0, 0), FF_PRINT_FUNCTIONS } },
        { "nested_scopes", { version_hex(2, 1, 0), version_hex(2, 2, 0), FF_NESTED_SCOPES } },
        { "with_statement", { version_hex(2, 5, 0), version_hex(3, 6, 0), FF_WITH_STATEMENT } } };

// Helper function:
void raiseSyntaxError(const char* file, AST* node_at, const char* msg, ...) {
    va_list ap;
    va_start(ap, msg);

    char buf[1024];
    vsnprintf(buf, sizeof(buf), msg, ap);


    // TODO I'm not sure that it's safe to raise an exception here, since I think
    // there will be things that end up not getting cleaned up.
    // Then again, there are a huge number of things that don't get cleaned up even
    // if an exception doesn't get thrown...

    // TODO output is still a little wrong, should be, for example
    //
    //  File "../test/tests/future_non_existent.py", line 1
    //    from __future__ import rvalue_references # should cause syntax error
    //
    // but instead it is
    //
    // Traceback (most recent call last):
    //  File "../test/tests/future_non_existent.py", line -1, in :
    //    from __future__ import rvalue_references # should cause syntax error
    ::pyston::raiseSyntaxError(buf, node_at->lineno, node_at->col_offset, file, "");
}

void raiseFutureImportErrorNotFound(const char* file, AST* node, const char* name) {
    raiseSyntaxError(file, node, "future feature %s is not defined", name);
}

void raiseFutureImportErrorNotBeginning(const char* file, AST* node) {
    raiseSyntaxError(file, node, "from __future__ imports must occur at the beginning of the file");
}

class BadFutureImportVisitor : public NoopASTVisitor {
public:
    virtual bool visit_importfrom(AST_ImportFrom* node) {
        if (node->module == "__future__") {
            raiseFutureImportErrorNotBeginning(file, node);
        }
        return true;
    }

    // TODO optimization: have it skip things like expressions that you know
    // there is no need to descend into

    BadFutureImportVisitor(const char* file) : file(file) {}
    const char* file;
};

inline bool is_stmt_string(AST_stmt* stmt) {
    return stmt->type == AST_TYPE::Expr && static_cast<AST_Expr*>(stmt)->value->type == AST_TYPE::Str;
}

FutureFlags getFutureFlags(AST_Module* m, const char* file) {
    FutureFlags ff = 0;

    // Set the defaults for the future flags depending on what version we are
    for (const std::pair<std::string, FutureOption>& p : future_options) {
        if (PYTHON_VERSION_HEX >= p.second.mandatory_version_hex) {
            ff |= p.second.ff_mask;
        }
    }

    // Find all the __future__ imports, raising an error for those that do not
    // occur at the beginning of the file.
    bool future_import_allowed = true;
    BadFutureImportVisitor import_visitor(file);
    for (int i = 0; i < m->body.size(); i++) {
        AST_stmt* stmt = m->body[i];

        if (stmt->type == AST_TYPE::ImportFrom && static_cast<AST_ImportFrom*>(stmt)->module == "__future__") {
            if (future_import_allowed) {
                // We have a `from __future__` import statement, and we are
                // still at the top of the file, so just set the appropriate
                // future flag for each imported option.

                for (AST_alias* alias : static_cast<AST_ImportFrom*>(stmt)->names) {
                    const std::string& option_name = alias->name;
                    auto iter = future_options.find(option_name);
                    if (iter == future_options.end()) {
                        // If it's not one of the available options, throw an error.
                        // Note: the __future__ module also exposes "all_feature_names",
                        // but you still can't import that using a from-import, so we
                        // don't need to worry about that here.
                        raiseFutureImportErrorNotFound(file, alias, option_name.c_str());
                    } else {
                        const FutureOption& fo = iter->second;
                        if (PYTHON_VERSION_HEX >= fo.optional_version_hex) {
                            ff |= fo.ff_mask;
                        } else {
                            raiseFutureImportErrorNotFound(file, alias, option_name.c_str());
                        }
                    }
                }
            } else {
                raiseFutureImportErrorNotBeginning(file, stmt);
            }
        } else {
            // A docstring is allowed at the beginning of a module; otherwise,
            // we cannot permit any __future__ import after this point.
            if (i > 0 || !is_stmt_string(stmt)) {
                // Recurse on the node and throw an error if it has any
                // `from __future__` import statement.
                stmt->accept(&import_visitor);

                future_import_allowed = false;
            }
        }
    }

    return ff;
}
}