Esempio n. 1
0
// Have a special helper function for syntax errors, since we want to include the location
// of the syntax error in the traceback, even though it is not part of the execution:
void raiseSyntaxError(const char* msg, int lineno, int col_offset, llvm::StringRef file, llvm::StringRef func) {
    Box* exc = runtimeCall(SyntaxError, ArgPassSpec(1), boxString(msg), NULL, NULL, NULL, NULL);

    auto tb = new BoxedTraceback(LineInfo(lineno, col_offset, boxString(file), boxString(func)), None);
    assert(!PyErr_Occurred());
    throw ExcInfo(exc->cls, exc, tb);
}
Esempio n. 2
0
static Box* setRepr(BoxedSet* self) {
    RELEASE_ASSERT(PyAnySet_Check(self), "");

    std::vector<char> chars;
    int status = Py_ReprEnter((PyObject*)self);

    if (status != 0) {
        if (status < 0)
            throwCAPIException();

        std::string ty = std::string(self->cls->tp_name);
        chars.insert(chars.end(), ty.begin(), ty.end());
        chars.push_back('(');
        chars.push_back('.');
        chars.push_back('.');
        chars.push_back('.');
        chars.push_back(')');

        return boxString(llvm::StringRef(&chars[0], chars.size()));
    }

    try {
        std::string ty = std::string(self->cls->tp_name);
        chars.insert(chars.end(), ty.begin(), ty.end());

        chars.push_back('(');
        chars.push_back('[');

        bool first = true;
        for (auto&& elt : self->s) {

            if (!first) {
                chars.push_back(',');
                chars.push_back(' ');
            }
            BoxedString* str = static_cast<BoxedString*>(repr(elt.value));
            AUTO_DECREF(str);
            chars.insert(chars.end(), str->s().begin(), str->s().end());

            first = false;
        }
        chars.push_back(']');
        chars.push_back(')');
    } catch (ExcInfo e) {
        Py_ReprLeave((PyObject*)self);
        throw e;
    }
    Py_ReprLeave((PyObject*)self);
    return boxString(llvm::StringRef(&chars[0], chars.size()));
}
Esempio n. 3
0
Box* tupleRepr(BoxedTuple* t) {

    assert(isSubclass(t->cls, tuple_cls));
    int n;
    std::vector<char> chars;
    int status = Py_ReprEnter((PyObject*)t);
    n = t->size();
    if (n == 0) {
        chars.push_back('(');
        chars.push_back(')');
        return boxString(llvm::StringRef(&chars[0], chars.size()));
    }

    if (status != 0) {
        if (status < 0)
            throwCAPIException();
        chars.push_back('(');
        chars.push_back('.');
        chars.push_back('.');
        chars.push_back('.');
        chars.push_back(')');

        return boxString(llvm::StringRef(&chars[0], chars.size()));
    }

    try {
        chars.push_back('(');
        for (int i = 0; i < n; i++) {
            if (i) {
                chars.push_back(',');
                chars.push_back(' ');
            }
            BoxedString* elt_repr = static_cast<BoxedString*>(repr(t->elts[i]));
            chars.insert(chars.end(), elt_repr->s().begin(), elt_repr->s().end());
        }

        if (n == 1)
            chars.push_back(',');

        chars.push_back(')');
    } catch (ExcInfo e) {
        Py_ReprLeave((PyObject*)t);
        throw e;
    }
    Py_ReprLeave((PyObject*)t);

    return boxString(llvm::StringRef(&chars[0], chars.size()));
}
Esempio n. 4
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;
}
Esempio n. 5
0
void addToSysArgv(const char* str) {
    static BoxedString* argv_str = getStaticString("argv");
    Box* sys_argv = sys_module->getattr(argv_str);
    assert(sys_argv);
    assert(sys_argv->cls == list_cls);
    listAppendInternalStolen(sys_argv, boxString(str));
}
Esempio n. 6
0
Box* fileRead(BoxedFile* self, Box* _size) {
    assert(self->cls == file_cls);
    if (_size->cls != int_cls) {
        fprintf(stderr, "TypeError: an integer is required\n");
        raiseExcHelper(TypeError, "");
    }
    int64_t size = static_cast<BoxedInt*>(_size)->n;

    if (self->closed) {
        fprintf(stderr, "IOError: file not open for reading\n");
        raiseExcHelper(IOError, "");
    }

    std::ostringstream os("");

    if (size < 0)
        size = 1L << 60;

    i64 read = 0;
    while (read < size) {
        const int BUF_SIZE = 1024;
        char buf[BUF_SIZE];
        size_t more_read = fread(buf, 1, std::min((i64)BUF_SIZE, size - read), self->f);
        if (more_read == 0) {
            ASSERT(!ferror(self->f), "%d", ferror(self->f));
            break;
        }

        read += more_read;
        // this is probably inefficient:
        os << std::string(buf, more_read);
    }
    return boxString(os.str());
}
Esempio n. 7
0
static Box* methodGetDoc(Box* b, void*) {
    assert(b->cls == method_cls);
    const char* s = static_cast<BoxedMethodDescriptor*>(b)->method->ml_doc;
    if (s)
        return boxString(s);
    return None;
}
Esempio n. 8
0
Box* typeRepr(BoxedClass* self) {
    if (isUserDefined(self)) {
        std::ostringstream os;
        os << "<class '";

        Box* m = self->getattr("__module__");
        RELEASE_ASSERT(m, "");
        if (m->cls == str_cls) {
            BoxedString* sm = static_cast<BoxedString*>(m);
            os << sm->s << '.';
        }

        Box* n = self->getattr("__name__");
        RELEASE_ASSERT(n, "");
        RELEASE_ASSERT(n->cls == str_cls, "should have prevented you from setting __name__ to non-string");
        BoxedString* sn = static_cast<BoxedString*>(n);
        os << sn->s;

        os << "'>";

        return boxString(os.str());
    } else {
        char buf[80];
        snprintf(buf, 80, "<type '%s'>", getNameOfClass(self)->c_str());
        return boxStrConstant(buf);
    }
}
Esempio n. 9
0
static Box* _fileRead(BoxedFile* self, i64 size) {
    if (self->closed) {
        fprintf(stderr, "IOError: file not open for reading\n");
        raiseExc();
    }

    std::ostringstream os("");

    if (size < 0)
        size = 1L << 60;

    i64 read = 0;
    while (read < size) {
        const int BUF_SIZE = 1024;
        char buf[BUF_SIZE];
        size_t more_read = fread(buf, 1, std::min((i64)BUF_SIZE, size - read), self->f);
        if (more_read == 0) {
            ASSERT(!ferror(self->f), "%d", ferror(self->f));
            break;
        }

        read += more_read;
        // this is probably inefficient:
        os << std::string(buf, more_read);
    }
    return boxString(os.str());
}
Esempio n. 10
0
extern "C" BoxedString* intRepr(BoxedInt* v) {
    if (!isSubclass(v->cls, int_cls))
        raiseExcHelper(TypeError, "descriptor '__repr__' requires a 'int' object but received a '%s'", getTypeName(v));

    char buf[80];
    int len = snprintf(buf, 80, "%ld", v->n);
    return static_cast<BoxedString*>(boxString(llvm::StringRef(buf, len)));
}
Esempio n. 11
0
BoxedCode::BoxedCode(int num_args, bool takes_varargs, bool takes_kwargs, const char* name, const char* doc,
                     const ParamNames& param_names)
    : source(nullptr),
      // TODO what to do with this?
      filename(nullptr),
      name(boxString(name)),
      // TODO what to do with this?
      firstlineno(-1),
      _doc(doc[0] == '\0' ? incref(Py_None) : boxString(doc)),

      param_names(param_names),
      takes_varargs(takes_varargs),
      takes_kwargs(takes_kwargs),
      num_args(num_args),
      times_interpreted(0),
      internal_callable(NULL, NULL) {
}
Esempio n. 12
0
File: code.cpp Progetto: jmgc/pyston
    static Box* varnames(Box* b, void*) {
        RELEASE_ASSERT(b->cls == code_cls, "");
        BoxedCode* code = static_cast<BoxedCode*>(b);

        auto& param_names = code->f->param_names;
        if (!param_names.takes_param_names)
            return EmptyTuple;

        std::vector<Box*, StlCompatAllocator<Box*>> elts;
        for (auto sr : param_names.args)
            elts.push_back(boxString(sr));
        if (param_names.vararg.size())
            elts.push_back(boxString(param_names.vararg));
        if (param_names.kwarg.size())
            elts.push_back(boxString(param_names.kwarg));
        return BoxedTuple::create(elts.size(), &elts[0]);
    }
Esempio n. 13
0
Box* BoxedTraceback::getLines(Box* b) {
    assert(b->cls == traceback_cls);

    BoxedTraceback* tb = static_cast<BoxedTraceback*>(b);

    if (!tb->py_lines) {
        BoxedList* lines = new BoxedList();
        for (BoxedTraceback* wtb = tb; wtb && wtb != None; wtb = static_cast<BoxedTraceback*>(wtb->tb_next)) {
            auto& line = wtb->line;
            auto l = BoxedTuple::create({ boxString(line.file), boxString(line.func), boxInt(line.line) });
            listAppendInternal(lines, l);
        }
        tb->py_lines = lines;
    }

    return tb->py_lines;
}
Esempio n. 14
0
void setupThread() {
    // Hacky: we want to use some of CPython's implementation of the thread module (the threading local stuff),
    // and some of ours (thread handling).  Start off by calling a cut-down version of initthread, and then
    // add our own attributes to the module it creates.
    initthread();
    RELEASE_ASSERT(!PyErr_Occurred(), "");

    Box* thread_module = getSysModulesDict()->getOrNull(boxString("thread"));
    assert(thread_module);

    thread_module->giveAttr("start_new_thread", new BoxedBuiltinFunctionOrMethod(
                                                    boxRTFunction((void*)startNewThread, BOXED_INT, 3, 1, false, false),
                                                    "start_new_thread", { NULL }));
    thread_module->giveAttr("allocate_lock", new BoxedBuiltinFunctionOrMethod(
                                                 boxRTFunction((void*)allocateLock, UNKNOWN, 0), "allocate_lock"));
    thread_module->giveAttr(
        "get_ident", new BoxedBuiltinFunctionOrMethod(boxRTFunction((void*)getIdent, BOXED_INT, 0), "get_ident"));
    thread_module->giveAttr(
        "stack_size", new BoxedBuiltinFunctionOrMethod(boxRTFunction((void*)stackSize, BOXED_INT, 0), "stack_size"));

    thread_lock_cls = BoxedHeapClass::create(type_cls, object_cls, NULL, 0, 0, sizeof(BoxedThreadLock), false, "lock");
    thread_lock_cls->tp_dealloc = BoxedThreadLock::threadLockDestructor;
    thread_lock_cls->has_safe_tp_dealloc = true;

    thread_lock_cls->giveAttr("__module__", boxString("thread"));
    thread_lock_cls->giveAttr(
        "acquire", new BoxedFunction(boxRTFunction((void*)BoxedThreadLock::acquire, BOXED_BOOL, 2, 1, false, false),
                                     { boxInt(1) }));
    thread_lock_cls->giveAttr("release", new BoxedFunction(boxRTFunction((void*)BoxedThreadLock::release, NONE, 1)));
    thread_lock_cls->giveAttr("acquire_lock", thread_lock_cls->getattr(internStringMortal("acquire")));
    thread_lock_cls->giveAttr("release_lock", thread_lock_cls->getattr(internStringMortal("release")));
    thread_lock_cls->giveAttr("__enter__", thread_lock_cls->getattr(internStringMortal("acquire")));
    thread_lock_cls->giveAttr("__exit__", new BoxedFunction(boxRTFunction((void*)BoxedThreadLock::exit, NONE, 4)));
    thread_lock_cls->giveAttr("locked",
                              new BoxedFunction(boxRTFunction((void*)BoxedThreadLock::locked, BOXED_BOOL, 1)));
    thread_lock_cls->giveAttr("locked_lock", thread_lock_cls->getattr(internStringMortal("locked")));
    thread_lock_cls->freeze();

    ThreadError = BoxedHeapClass::create(type_cls, Exception, NULL, Exception->attrs_offset,
                                         Exception->tp_weaklistoffset, Exception->tp_basicsize, false, "error");
    ThreadError->giveAttr("__module__", boxString("thread"));
    ThreadError->freeze();

    thread_module->giveAttr("error", ThreadError);
}
Esempio n. 15
0
extern "C" Box* createClass(std::string *name, BoxedModule *parent_module) {
    BoxedClass* rtn = new BoxedClass(true, NULL);
    rtn->giveAttr("__name__", boxString(*name));

    Box* modname = parent_module->getattr("__name__", NULL, NULL);
    rtn->giveAttr("__module__", modname);

    return rtn;
}
Esempio n. 16
0
Box* getDocString(llvm::ArrayRef<AST_stmt*> body) {
    if (body.size() > 0 && body[0]->type == AST_TYPE::Expr
        && static_cast<AST_Expr*>(body[0])->value->type == AST_TYPE::Str) {
        auto expr = static_cast<AST_Expr*>(body[0]);
        auto str = static_cast<AST_Str*>(expr->value);
        return boxString(str->str_data);
    }

    return incref(Py_None);
}
Esempio n. 17
0
extern "C" BoxedFunction::BoxedFunction(CLFunction *f) : HCBox(&function_flavor, function_cls), f(f) {
    if (f->source) {
        assert(f->source->ast);
        //this->giveAttr("__name__", boxString(&f->source->ast->name));
        this->giveAttr("__name__", boxString(f->source->getName()));

        Box* modname = f->source->parent_module->getattr("__name__", NULL, NULL);
        this->giveAttr("__module__", modname);
    }
}
Esempio n. 18
0
extern "C" Box* chr(Box* arg) {
    if (arg->cls != int_cls) {
        fprintf(stderr, "TypeError: coercing to Unicode: need string of buffer, %s found\n", getTypeName(arg)->c_str());
        raiseExc();
    }
    i64 n = static_cast<BoxedInt*>(arg)->n;
    RELEASE_ASSERT(n >= 0 && n < 256, "");

    return boxString(std::string(1, (char)n));
}
Esempio n. 19
0
void setupSysEnd() {
    std::vector<Box*> builtin_module_names;
    for (int i = 0; PyImport_Inittab[i].name != NULL; i++)
        builtin_module_names.push_back(boxString(PyImport_Inittab[i].name));

    std::sort<decltype(builtin_module_names)::iterator, PyLt>(builtin_module_names.begin(), builtin_module_names.end(),
                                                              PyLt());

    sys_module->giveAttr("builtin_module_names",
                         BoxedTuple::create(builtin_module_names.size(), &builtin_module_names[0]));

    for (Box* b : builtin_module_names)
        Py_DECREF(b);

#ifndef NDEBUG
    for (const auto& p : *sys_modules_dict) {
        assert(PyString_Check(p.first));

        bool found = false;
        for (int i = 0; PyImport_Inittab[i].name != NULL; i++) {
            if (((BoxedString*)p.first)->s() == PyImport_Inittab[i].name) {
                found = true;
            }
        }
        if (!found)
            assert(0 && "found a module which is inside sys.modules but not listed inside PyImport_Inittab!");
    }
#endif

    /* version_info */
    if (VersionInfoType.tp_name == 0)
        PyStructSequence_InitType((PyTypeObject*)&VersionInfoType, &version_info_desc);
    /* prevent user from creating new instances */
    VersionInfoType.tp_init = NULL;
    VersionInfoType.tp_new = NULL;

    SET_SYS_FROM_STRING("version_info", make_version_info());

    /* float_info */
    if (FloatInfoType.tp_name == 0)
        PyStructSequence_InitType((PyTypeObject*)&FloatInfoType, &float_info_desc);
    /* flags */
    if (FlagsType.tp_name == 0)
        PyStructSequence_InitType((PyTypeObject*)&FlagsType, &flags_desc);
    SET_SYS_FROM_STRING("flags", make_flags());
    /* prevent user from creating new instances */
    FlagsType.tp_init = NULL;
    FlagsType.tp_new = NULL;
    /* prevent user from creating new instances */
    FloatInfoType.tp_init = NULL;
    FloatInfoType.tp_new = NULL;

    SET_SYS_FROM_STRING("float_info", PyFloat_GetInfo());
}
Esempio n. 20
0
Box* moduleRepr(BoxedModule* m) {
    assert(m->cls == module_cls);

    std::ostringstream os;
    os << "<module '" << m->name() << "' ";

    if (m->fn == "__builtin__") {
        os << "(built-in)>";
    } else {
        os << "from '" << m->fn << "'>";
    }
    return boxString(os.str());
}
Esempio n. 21
0
Box* tupleRepr(BoxedTuple* t) {
    assert(isSubclass(t->cls, tuple_cls));

    int n;
    std::string O("");
    llvm::raw_string_ostream os(O);

    n = t->size();
    if (n == 0) {
        os << "()";
        return boxString(os.str());
    }

    int status = Py_ReprEnter((PyObject*)t);
    if (status != 0) {
        if (status < 0)
            return boxString(os.str());

        os << "(...)";
        return boxString(os.str());
    }

    os << "(";

    for (int i = 0; i < n; i++) {
        if (i)
            os << ", ";

        BoxedString* elt_repr = static_cast<BoxedString*>(repr(t->elts[i]));
        os << elt_repr->s();
    }
    if (n == 1)
        os << ",";
    os << ")";

    Py_ReprLeave((PyObject*)t);
    return boxString(os.str());
}
Esempio n. 22
0
extern "C" Box* intOct(BoxedInt* self) {
    if (!isSubclass(self->cls, int_cls))
        raiseExcHelper(TypeError, "descriptor '__oct__' requires a 'int' object but received a '%s'",
                       getTypeName(self));

    char buf[80];
    int len = 0;
    bool is_negative = self->n < 0;
    if (is_negative)
        len = snprintf(buf, sizeof(buf), "-%#lo", std::abs(self->n));
    else
        len = snprintf(buf, sizeof(buf), "%#lo", self->n);
    return boxString(llvm::StringRef(buf, len));
}
Esempio n. 23
0
BoxedString* internStringImmortal(llvm::StringRef s) noexcept {
    auto it = interned_strings.find_as(s);
    if (it != interned_strings.end())
        return incref(*it);

    num_interned_strings.log();
    BoxedString* entry = boxString(s);
    // CPython returns mortal but in our current implementation they are inmortal
    entry->interned_state = SSTATE_INTERNED_IMMORTAL;
    interned_strings.insert((BoxedString*)entry);

    Py_INCREF(entry);
    return entry;
}
Esempio n. 24
0
File: set.cpp Progetto: kod3r/pyston
static Box* _setRepr(BoxedSet* self, const char* type_name) {
    std::ostringstream os("");

    os << type_name << "([";
    bool first = true;
    for (Box* elt : self->s) {
        if (!first) {
            os << ", ";
        }
        os << static_cast<BoxedString*>(repr(elt))->s;
        first = false;
    }
    os << "])";
    return boxString(os.str());
}
Esempio n. 25
0
extern "C" void raise0_capi(ExcInfo* frame_exc_info) noexcept {
    updateFrameExcInfoIfNeeded(frame_exc_info);
    assert(frame_exc_info->type);

    // TODO need to clean up when we call normalize, do_raise, etc
    if (frame_exc_info->type == None) {
        frame_exc_info->type = TypeError;
        frame_exc_info->value
            = boxString("exceptions must be old-style classes or derived from BaseException, not NoneType");
        frame_exc_info->traceback = None;
        PyErr_NormalizeException(&frame_exc_info->type, &frame_exc_info->value, &frame_exc_info->traceback);
    }

    startReraise();
    PyErr_Restore(frame_exc_info->type, frame_exc_info->value, frame_exc_info->traceback);
}
Esempio n. 26
0
Box* BoxedCode::varnames(Box* b, void*) noexcept {
    RELEASE_ASSERT(b->cls == code_cls, "");
    BoxedCode* code = static_cast<BoxedCode*>(b);

    auto& param_names = code->param_names;
    if (!param_names.takes_param_names)
        return incref(EmptyTuple);

    std::vector<Box*> elts;
    for (auto sr : param_names.allArgsAsStr())
        elts.push_back(boxString(sr));
    auto rtn = BoxedTuple::create(elts.size(), &elts[0]);
    for (auto e : elts)
        Py_DECREF(e);
    return rtn;
}
Esempio n. 27
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();
}
Esempio n. 28
0
Box* fileReadline1(BoxedFile* self) {
    assert(self->cls == file_cls);

    std::ostringstream os("");

    while (true) {
        char c;
        int nread = fread(&c, 1, 1, self->f);
        if (nread == 0)
            break;
        os << c;

        if (c == '\n')
            break;
    }
    return boxString(os.str());
}
Esempio n. 29
0
Box* moduleRepr(BoxedModule* m) {
    assert(m->cls == module_cls);

    std::ostringstream os;
    os << "<module '";

    Box* name = m->peekattr("__name__");
    if (!name || name->cls != str_cls) {
        os << '?';
    } else {
        BoxedString *sname = static_cast<BoxedString*>(name);
        os << sname->s;
    }

    // TODO not all modules will be built-in
    os << "' (built-in)>";
    return boxString(os.str());
}
Esempio n. 30
0
extern "C" BoxedFunction::BoxedFunction(CLFunction* f, std::initializer_list<Box*> defaults)
    : Box(&function_flavor, function_cls), f(f), ndefaults(0), defaults(NULL) {
    // make sure to initialize defaults first, since the GC behavior is triggered by ndefaults,
    // and a GC can happen within this constructor:
    this->defaults = new (defaults.size()) GCdArray();
    memcpy(this->defaults->elts, defaults.begin(), defaults.size() * sizeof(Box*));
    this->ndefaults = defaults.size();

    if (f->source) {
        assert(f->source->ast);
        // this->giveAttr("__name__", boxString(&f->source->ast->name));
        this->giveAttr("__name__", boxString(f->source->getName()));

        Box* modname = f->source->parent_module->getattr("__name__", NULL, NULL);
        this->giveAttr("__module__", modname);
    }

    assert(f->num_defaults == ndefaults);
}