Exemple #1
0
extern "C" Box* boolRepr(BoxedBool* v) {
    static BoxedString* true_str = internStringImmortal("True");
    static BoxedString* false_str = internStringImmortal("False");

    if (v == True)
        return true_str;
    return false_str;
}
Exemple #2
0
static Box* createAndRunModule(BoxedString* name, const std::string& fn, const std::string& module_path) {
    BoxedModule* module = createModule(name, fn.c_str());

    Box* b_path = boxString(module_path);

    BoxedList* path_list = new BoxedList();
    listAppendInternal(path_list, b_path);

    static BoxedString* path_str = internStringImmortal("__path__");
    module->setattr(path_str, path_list, NULL);

    AST_Module* ast = caching_parse_file(fn.c_str(), /* future_flags = */ 0);
    assert(ast);
    try {
        compileAndRunModule(ast, module);
    } catch (ExcInfo e) {
        removeModule(name);
        throw e;
    }

    Box* r = getSysModulesDict()->getOrNull(name);
    if (!r)
        raiseExcHelper(ImportError, "Loaded module %.200s not found in sys.modules", name->c_str());
    return r;
}
Exemple #3
0
static Box* importSub(const std::string& name, BoxedString* full_name, Box* parent_module) {
    BoxedDict* sys_modules = getSysModulesDict();
    if (sys_modules->d.find(full_name) != sys_modules->d.end()) {
        return sys_modules->d[full_name];
    }

    BoxedList* path_list;
    if (parent_module == NULL || parent_module == None) {
        path_list = NULL;
    } else {
        static BoxedString* path_str = internStringImmortal("__path__");
        path_list = static_cast<BoxedList*>(getattrInternal<ExceptionStyle::CXX>(parent_module, path_str));
        if (path_list == NULL || path_list->cls != list_cls) {
            return None;
        }
    }

    SearchResult sr = findModule(name, full_name, path_list);

    if (sr.type != SearchResult::SEARCH_ERROR) {
        Box* module;

        try {
            if (sr.type == SearchResult::PY_SOURCE)
                module = createAndRunModule(full_name, sr.path);
            else if (sr.type == SearchResult::PKG_DIRECTORY)
                module = createAndRunModule(full_name, sr.path + "/__init__.py", sr.path);
            else if (sr.type == SearchResult::C_EXTENSION)
                module = importCExtension(full_name, name, sr.path);
            else if (sr.type == SearchResult::IMP_HOOK) {
                static BoxedString* loadmodule_str = internStringImmortal("load_module");
                CallattrFlags callattr_flags{.cls_only = false,
                                             .null_on_nonexistent = false,
                                             .argspec = ArgPassSpec(1) };
                module = callattr(sr.loader, loadmodule_str, callattr_flags, full_name, NULL, NULL, NULL, NULL);
            } else
                RELEASE_ASSERT(0, "%d", sr.type);
        } catch (ExcInfo e) {
            removeModule(full_name);
            throw e;
        }

        if (parent_module && parent_module != None)
            parent_module->setattr(internStringMortal(name), module, NULL);
        return module;
    }
Exemple #4
0
BoxedString* getReverseOpName(int op_type) {
    bool reversed = false;
    op_type = getReverseCmpOp(op_type, reversed);
    if (reversed)
        return getOpName(op_type);
    BoxedString* normal_name = getOpName(op_type);
    // TODO inefficient
    return internStringImmortal(("__r" + normal_name->s().substr(2).str()).c_str());
}
Exemple #5
0
InternedString InternedStringPool::get(llvm::StringRef arg) {
    // HACK: should properly track this liveness:
    BoxedString* s = internStringImmortal(arg);

#ifndef NDEBUG
    return InternedString(s, this);
#else
    return InternedString(s);
#endif
}
Exemple #6
0
// Ported from the CPython version:
BoxedClass* supercheck(BoxedClass* type, Box* obj) {
    if (PyType_Check(obj) && isSubclass(static_cast<BoxedClass*>(obj), type))
        return static_cast<BoxedClass*>(obj);

    if (isSubclass(obj->cls, type)) {
        return obj->cls;
    }

    static BoxedString* class_str = internStringImmortal("__class__");
    Box* class_attr = obj->getattr(class_str);
    if (class_attr && PyType_Check(class_attr) && class_attr != obj->cls) {
        Py_FatalError("warning: this path never tested"); // blindly copied from CPython
        return static_cast<BoxedClass*>(class_attr);
    }

    raiseExcHelper(TypeError, "super(type, obj): obj must be an instance or subtype of type");
}
Exemple #7
0
void prependToSysPath(llvm::StringRef path) {
    BoxedList* sys_path = getSysPath();
    static BoxedString* insert_str = internStringImmortal("insert");
    CallattrFlags callattr_flags{.cls_only = false, .null_on_nonexistent = false, .argspec = ArgPassSpec(2) };
    callattr(sys_path, insert_str, callattr_flags, boxInt(0), boxString(path), NULL, NULL, NULL);
}

static BoxedClass* sys_flags_cls;
class BoxedSysFlags : public Box {
public:
    Box* division_warning, *bytes_warning, *no_user_site, *optimize;

    BoxedSysFlags() {
        auto zero = boxInt(0);
        assert(zero);
        division_warning = zero;
        bytes_warning = zero;
        no_user_site = zero;
        optimize = zero;
    }

    DEFAULT_CLASS(sys_flags_cls);

    static void gcHandler(GCVisitor* v, Box* _b) {
        assert(_b->cls == sys_flags_cls);
        Box::gcHandler(v, _b);

        BoxedSysFlags* self = static_cast<BoxedSysFlags*>(_b);
        v->visit(self->division_warning);
        v->visit(self->bytes_warning);
        v->visit(self->no_user_site);
        v->visit(self->optimize);
    }

    static Box* __new__(Box* cls, Box* args, Box* kwargs) {
        raiseExcHelper(TypeError, "cannot create 'sys.flags' instances");
    }
};

static std::string generateVersionString() {
    std::ostringstream oss;
    oss << PYTHON_VERSION_MAJOR << '.' << PYTHON_VERSION_MINOR << '.' << PYTHON_VERSION_MICRO;
    oss << '\n';
    oss << "[Pyston " << PYSTON_VERSION_MAJOR << '.' << PYSTON_VERSION_MINOR << "]";
    return oss.str();
}
Exemple #8
0
// Ported from the CPython version:
template <ExceptionStyle S> BoxedClass* superCheck(BoxedClass* type, Box* obj) noexcept(S == CAPI) {
    if (PyType_Check(obj) && isSubclass(static_cast<BoxedClass*>(obj), type))
        return static_cast<BoxedClass*>(obj);

    if (isSubclass(obj->cls, type)) {
        return obj->cls;
    }

    static BoxedString* class_str = internStringImmortal("__class__");
    Box* class_attr = obj->getattr(class_str);
    if (class_attr && PyType_Check(class_attr) && class_attr != obj->cls) {
        Py_FatalError("warning: this path never tested"); // blindly copied from CPython
        return static_cast<BoxedClass*>(class_attr);
    }

    if (S == CXX)
        raiseExcHelper(TypeError, "super(type, obj): obj must be an instance or subtype of type");
    else
        PyErr_SetString(TypeError, "super(type, obj): obj must be an instance or subtype of type");
    return NULL;
}
Exemple #9
0
extern "C" PyObject* PyString_InternFromString(const char* s) noexcept {
    RELEASE_ASSERT(s, "");
    return internStringImmortal(s);
}
Exemple #10
0
BoxedString* getInplaceOpName(int op_type) {
    BoxedString* normal_name = getOpName(op_type);
    // TODO inefficient
    return internStringImmortal(("__i" + normal_name->s().substr(2).str()).c_str());
}
Exemple #11
0
/* Return the package that an import is being performed in.  If globals comes
   from the module foo.bar.bat (not itself a package), this returns the
   sys.modules entry for foo.bar.  If globals is from a package's __init__.py,
   the package's entry in sys.modules is returned, as a borrowed reference.

   The *name* of the returned package is returned in buf.

   If globals doesn't come from a package or a module in a package, or a
   corresponding entry is not found in sys.modules, Py_None is returned.
*/
static Box* getParent(Box* globals, int level, std::string& buf) {
    int orig_level = level;

    if (globals == NULL || globals == None || level == 0)
        return None;

    static BoxedString* package_str = internStringImmortal("__package__");
    BoxedString* pkgname = static_cast<BoxedString*>(getFromGlobals(globals, package_str));
    if (pkgname != NULL && pkgname != None) {
        /* __package__ is set, so use it */
        if (pkgname->cls != str_cls) {
            raiseExcHelper(ValueError, "__package__ set to non-string");
        }
        size_t len = pkgname->size();
        if (len == 0) {
            if (level > 0) {
                raiseExcHelper(ValueError, "Attempted relative import in non-package");
            }
            return None;
        }
        if (len > PATH_MAX) {
            raiseExcHelper(ValueError, "Package name too long");
        }
        buf += pkgname->s();
    } else {
        static BoxedString* name_str = internStringImmortal("__name__");

        /* __package__ not set, so figure it out and set it */
        BoxedString* modname = static_cast<BoxedString*>(getFromGlobals(globals, name_str));
        if (modname == NULL || modname->cls != str_cls)
            return None;

        static BoxedString* path_str = internStringImmortal("__path__");
        Box* modpath = getFromGlobals(globals, path_str);

        if (modpath != NULL) {
            /* __path__ is set, so modname is already the package name */
            if (modname->size() > PATH_MAX) {
                raiseExcHelper(ValueError, "Module name too long");
            }
            buf += modname->s();
            setGlobal(globals, package_str, modname);
        } else {
            /* Normal module, so work out the package name if any */
            size_t lastdot = modname->s().rfind('.');
            if (lastdot == std::string::npos && level > 0) {
                raiseExcHelper(ValueError, "Attempted relative import in non-package");
            }
            if (lastdot == std::string::npos) {
                setGlobal(globals, package_str, None);
                return None;
            }
            if (lastdot >= PATH_MAX) {
                raiseExcHelper(ValueError, "Module name too long");
            }

            buf = std::string(modname->s(), 0, lastdot);
            setGlobal(globals, package_str, boxString(buf));
        }
    }

    size_t dot = buf.size() - 1;
    while (--level > 0) {
        dot = buf.rfind('.', dot);
        if (dot == std::string::npos) {
            raiseExcHelper(ValueError, "Attempted relative import beyond toplevel package");
        }
        dot--;
    }

    buf = std::string(buf, 0, dot + 1);

    BoxedDict* sys_modules = getSysModulesDict();
    Box* boxed_name = boxString(buf);
    Box* parent = sys_modules->d.find(boxed_name) != sys_modules->d.end() ? sys_modules->d[boxed_name] : NULL;
    if (parent == NULL) {
        if (orig_level < 1) {
            printf("Warning: Parent module '%.200s' not found "
                   "while handling absolute import\n",
                   buf.c_str());
        } else {
            raiseExcHelper(SystemError, "Parent module '%.200s' not loaded, "
                                        "cannot perform relative import",
                           buf.c_str());
        }
    }
    return parent;
    /* We expect, but can't guarantee, if parent != None, that:
       - parent.__name__ == buf
       - parent.__dict__ is globals
       If this is violated...  Who cares? */
}
Exemple #12
0
SearchResult findModule(const std::string& name, BoxedString* full_name, BoxedList* path_list) {
    static BoxedString* meta_path_str = internStringImmortal("meta_path");
    BoxedList* meta_path = static_cast<BoxedList*>(sys_module->getattr(meta_path_str));
    if (!meta_path || meta_path->cls != list_cls)
        raiseExcHelper(RuntimeError, "sys.meta_path must be a list of import hooks");

    static BoxedString* findmodule_str = internStringImmortal("find_module");
    for (int i = 0; i < meta_path->size; i++) {
        Box* finder = meta_path->elts->elts[i];

        auto path_pass = path_list ? path_list : None;
        CallattrFlags callattr_flags{.cls_only = false, .null_on_nonexistent = false, .argspec = ArgPassSpec(2) };
        Box* loader = callattr(finder, findmodule_str, callattr_flags, full_name, path_pass, NULL, NULL, NULL);

        if (loader != None)
            return SearchResult(loader);
    }

    if (!path_list)
        path_list = getSysPath();

    if (path_list == NULL || path_list->cls != list_cls) {
        raiseExcHelper(RuntimeError, "sys.path must be a list of directory names");
    }

    static BoxedString* path_hooks_str = internStringImmortal("path_hooks");
    BoxedList* path_hooks = static_cast<BoxedList*>(sys_module->getattr(path_hooks_str));
    if (!path_hooks || path_hooks->cls != list_cls)
        raiseExcHelper(RuntimeError, "sys.path_hooks must be a list of import hooks");

    static BoxedString* path_importer_cache_str = internStringImmortal("path_importer_cache");
    BoxedDict* path_importer_cache = static_cast<BoxedDict*>(sys_module->getattr(path_importer_cache_str));
    if (!path_importer_cache || path_importer_cache->cls != dict_cls)
        raiseExcHelper(RuntimeError, "sys.path_importer_cache must be a dict");

    llvm::SmallString<128> joined_path;
    for (int i = 0; i < path_list->size; i++) {
        Box* _p = path_list->elts->elts[i];
        if (_p->cls != str_cls)
            continue;
        BoxedString* p = static_cast<BoxedString*>(_p);

        joined_path.clear();
        llvm::sys::path::append(joined_path, p->s(), name);
        std::string dn(joined_path.str());

        llvm::sys::path::append(joined_path, "__init__.py");
        std::string fn(joined_path.str());

        PyObject* importer = get_path_importer(path_importer_cache, path_hooks, _p);
        if (importer == NULL)
            throwCAPIException();

        if (importer != None) {
            CallattrFlags callattr_flags{.cls_only = false, .null_on_nonexistent = false, .argspec = ArgPassSpec(1) };
            Box* loader = callattr(importer, findmodule_str, callattr_flags, full_name, NULL, NULL, NULL, NULL);
            if (loader != None)
                return SearchResult(loader);
        }

        if (pathExists(fn))
            return SearchResult(std::move(dn), SearchResult::PKG_DIRECTORY);

        joined_path.clear();
        llvm::sys::path::append(joined_path, std::string(p->s()), name + ".py");
        fn = joined_path.str();

        if (pathExists(fn))
            return SearchResult(std::move(fn), SearchResult::PY_SOURCE);

        joined_path.clear();
        llvm::sys::path::append(joined_path, p->s(), name + ".pyston.so");
        fn = joined_path.str();

        if (pathExists(fn))
            return SearchResult(std::move(fn), SearchResult::C_EXTENSION);
    }

    return SearchResult("", SearchResult::SEARCH_ERROR);
}

PyObject* PyImport_GetImporter(PyObject* path) noexcept {
    PyObject* importer = NULL, * path_importer_cache = NULL, * path_hooks = NULL;

    if ((path_importer_cache = PySys_GetObject("path_importer_cache"))) {
        if ((path_hooks = PySys_GetObject("path_hooks"))) {
            importer = get_path_importer(path_importer_cache, path_hooks, path);
        }
    }
    Py_XINCREF(importer); /* get_path_importer returns a borrowed reference */
    return importer;
}