Пример #1
0
void raise3(Box* arg0, Box* arg1, Box* arg2) {
    // TODO switch this to PyErr_Normalize

    if (arg2 == None)
        arg2 = getTraceback();

    if (isSubclass(arg0->cls, type_cls)) {
        BoxedClass* c = static_cast<BoxedClass*>(arg0);
        if (isSubclass(c, BaseException)) {
            Box* exc_obj;

            if (isSubclass(arg1->cls, BaseException)) {
                exc_obj = arg1;
                c = exc_obj->cls;
            } else if (arg1 != None) {
                exc_obj = runtimeCall(c, ArgPassSpec(1), arg1, NULL, NULL, NULL, NULL);
            } else {
                exc_obj = runtimeCall(c, ArgPassSpec(0), NULL, NULL, NULL, NULL, NULL);
            }

            raiseRaw(ExcInfo(c, exc_obj, arg2));
        }
    }

    if (isSubclass(arg0->cls, BaseException)) {
        if (arg1 != None)
            raiseExcHelper(TypeError, "instance exception may not have a separate value");
        raiseRaw(ExcInfo(arg0->cls, arg0, arg2));
    }

    raiseExcHelper(TypeError, "exceptions must be old-style classes or derived from BaseException, not %s",
                   getTypeName(arg0));
}
Пример #2
0
void raise3(Box* arg0, Box* arg1, Box* arg2) {
    RELEASE_ASSERT(arg2 == None, "unsupported");

    if (isSubclass(arg0->cls, type_cls)) {
        BoxedClass* c = static_cast<BoxedClass*>(arg0);
        if (isSubclass(c, Exception)) {
            Box* exc_obj;
            if (arg1 != None)
                exc_obj = exceptionNew2(c, arg1);
            else
                exc_obj = exceptionNew1(c);
            raiseExc(exc_obj);
        } else {
            raiseExcHelper(TypeError, "exceptions must be old-style classes or derived from BaseException, not %s",
                           getTypeName(arg0)->c_str());
        }
    }

    if (arg1 != None)
        raiseExcHelper(TypeError, "instance exception may not have a separate value");

    // TODO: should only allow throwing of old-style classes or things derived
    // from BaseException:
    raiseExc(arg0);
}
Пример #3
0
void raise3(Box* arg0, Box* arg1, Box* arg2) {
    // TODO switch this to PyErr_Normalize

    if (isSubclass(arg0->cls, type_cls)) {
        BoxedClass* c = static_cast<BoxedClass*>(arg0);
        if (isSubclass(c, BaseException)) {
            Box* exc_obj;
            if (arg1 != None)
                exc_obj = exceptionNew2(c, arg1);
            else
                exc_obj = exceptionNew1(c);

            raiseRaw(ExcInfo(c, exc_obj, arg2));
        }
    }

    if (isSubclass(arg0->cls, BaseException)) {
        if (arg1 != None)
            raiseExcHelper(TypeError, "instance exception may not have a separate value");
        raiseRaw(ExcInfo(arg0->cls, arg0, arg2));
    }

    raiseExcHelper(TypeError, "exceptions must be old-style classes or derived from BaseException, not %s",
                   getTypeName(arg0)->c_str());
}
Пример #4
0
extern "C" Box* listPop(BoxedList* self, Box* idx) {
    LOCK_REGION(self->lock.asWrite());

    if (idx == None) {
        if (self->size == 0) {
            raiseExcHelper(IndexError, "pop from empty list");
        }

        self->size--;
        Box* rtn = self->elts->elts[self->size];
        return rtn;
    }

    if (idx->cls != int_cls) {
        raiseExcHelper(TypeError, "an integer is required");
    }

    int64_t n = static_cast<BoxedInt*>(idx)->n;
    if (n < 0)
        n = self->size + n;

    if (n < 0 || n >= self->size) {
        if (self->size == 0)
            fprintf(stderr, "IndexError: pop from empty list\n");
        else
            fprintf(stderr, "IndexError: pop index out of range\n");
        raiseExcHelper(IndexError, "");
    }

    Box* rtn = self->elts->elts[n];
    memmove(self->elts->elts + n, self->elts->elts + n + 1, (self->size - n - 1) * sizeof(Box*));
    self->size--;

    return rtn;
}
Пример #5
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());
}
Пример #6
0
Box* setRemove(BoxedSet* self, Box* key) {
    RELEASE_ASSERT(isSubclass(self->cls, set_cls), "");

    if (PySet_Check(key)) {
        try {
            bool existed = _setRemove(self, key);
            if (existed)
                return incref(None);
        } catch (ExcInfo e) {
            if (!e.matches(TypeError))
                throw e;

            e.clear();

            BoxedSet* tmpKey = makeNewSet(frozenset_cls, key);
            AUTO_DECREF(tmpKey);
            bool existed = _setRemove(self, tmpKey);
            if (existed)
                return incref(None);
        }
        raiseExcHelper(KeyError, key);
    }

    bool existed = _setRemove(self, key);
    if (existed)
        return incref(None);
    raiseExcHelper(KeyError, key);
}
Пример #7
0
Box* complexNew(Box* _cls, Box* real, Box* imag) {
    RELEASE_ASSERT(_cls == complex_cls, "");

    double real_f;
    if (real->cls == int_cls) {
        real_f = static_cast<BoxedInt*>(real)->n;
    } else if (real->cls == float_cls) {
        real_f = static_cast<BoxedFloat*>(real)->d;
    } else {
        // TODO: implement taking a string argument
        raiseExcHelper(TypeError, "complex() argument must be a string or number");
    }

    double imag_f;
    if (imag->cls == int_cls) {
        imag_f = static_cast<BoxedInt*>(imag)->n;
    } else if (imag->cls == float_cls) {
        imag_f = static_cast<BoxedFloat*>(imag)->d;
    } else if (imag->cls == str_cls) {
        raiseExcHelper(TypeError, "complex() second arg can't be a string");
    } else {
        raiseExcHelper(TypeError, "complex() argument must be a string or number");
    }

    return new BoxedComplex(real_f, imag_f);
}
Пример #8
0
static Box* _intNew(Box* val, Box* base) {
    if (isSubclass(val->cls, int_cls)) {
        RELEASE_ASSERT(!base, "");
        BoxedInt* n = static_cast<BoxedInt*>(val);
        if (val->cls == int_cls)
            return n;
        return new BoxedInt(n->n);
    } else if (isSubclass(val->cls, str_cls)) {
        int base_n;
        if (!base)
            base_n = 10;
        else {
            RELEASE_ASSERT(base->cls == int_cls, "");
            base_n = static_cast<BoxedInt*>(base)->n;
        }

        BoxedString* s = static_cast<BoxedString*>(val);

        RELEASE_ASSERT(s->size() == strlen(s->data()), "");
        Box* r = PyInt_FromString(s->data(), NULL, base_n);
        if (!r)
            throwCAPIException();
        return r;
    } else if (isSubclass(val->cls, unicode_cls)) {
        int base_n;
        if (!base)
            base_n = 10;
        else {
            RELEASE_ASSERT(base->cls == int_cls, "");
            base_n = static_cast<BoxedInt*>(base)->n;
        }

        Box* r = PyInt_FromUnicode(PyUnicode_AS_UNICODE(val), PyUnicode_GET_SIZE(val), base_n);
        if (!r)
            throwCAPIException();
        return r;
    } else if (val->cls == float_cls) {
        RELEASE_ASSERT(!base, "");
        double d = static_cast<BoxedFloat*>(val)->d;
        return new BoxedInt(d);
    } else {
        RELEASE_ASSERT(!base, "");
        static const std::string int_str("__int__");
        Box* r = callattr(val, &int_str, CallattrFlags({.cls_only = true, .null_on_nonexistent = true }),
                          ArgPassSpec(0), NULL, NULL, NULL, NULL, NULL);

        if (!r) {
            fprintf(stderr, "TypeError: int() argument must be a string or a number, not '%s'\n", getTypeName(val));
            raiseExcHelper(TypeError, "");
        }

        if (!isSubclass(r->cls, int_cls) && !isSubclass(r->cls, long_cls)) {
            raiseExcHelper(TypeError, "__int__ returned non-int (type %s)", r->cls->tp_name);
        }
        return r;
    }
Пример #9
0
static uint64_t asUnsignedLong(BoxedLong* self) {
    assert(self->cls == long_cls);

    if (mpz_sgn(self->n) == -1)
        raiseExcHelper(OverflowError, "can't convert negative value to unsigned long");

    if (!mpz_fits_ulong_p(self->n))
        raiseExcHelper(OverflowError, "long int too large to convert");
    return mpz_get_ui(self->n);
}
Пример #10
0
// takes the three arguments of a `raise' and produces the ExcInfo to throw
ExcInfo excInfoForRaise(Box* type, Box* value, Box* tb) {
    assert(type && value && tb); // use None for default behavior, not nullptr
    // TODO switch this to PyErr_Normalize

    if (tb == None) {
        tb = NULL;
    } else if (tb != NULL && !PyTraceBack_Check(tb)) {
        raiseExcHelper(TypeError, "raise: arg 3 must be a traceback or None");
    }


    /* Next, repeatedly, replace a tuple exception with its first item */
    while (PyTuple_Check(type) && PyTuple_Size(type) > 0) {
        PyObject* tmp = type;
        type = PyTuple_GET_ITEM(type, 0);
        Py_INCREF(type);
        Py_DECREF(tmp);
    }

    if (PyExceptionClass_Check(type)) {
        PyErr_NormalizeException(&type, &value, &tb);

        if (!PyExceptionInstance_Check(value)) {
            raiseExcHelper(TypeError, "calling %s() should have returned an instance of "
                                      "BaseException, not '%s'",
                           ((PyTypeObject*)type)->tp_name, Py_TYPE(value)->tp_name);
        }
    } else if (PyExceptionInstance_Check(type)) {
        /* Raising an instance.  The value should be a dummy. */
        if (value != Py_None) {
            raiseExcHelper(TypeError, "instance exception may not have a separate value");
        } else {
            /* Normalize to raise <class>, <instance> */
            Py_DECREF(value);
            value = type;
            type = PyExceptionInstance_Class(type);
            Py_INCREF(type);
        }
    } else {
        /* Not something you can raise.  You get an exception
           anyway, just not what you specified :-) */
        raiseExcHelper(TypeError, "exceptions must be old-style classes or "
                                  "derived from BaseException, not %s",
                       type->cls->tp_name);
    }

    assert(PyExceptionClass_Check(type));

    if (tb == NULL) {
        tb = None;
    }

    return ExcInfo(type, value, tb);
}
Пример #11
0
// called from both generatorHasNext and generatorSend/generatorNext (but only if generatorHasNext hasn't been called)
static void generatorSendInternal(BoxedGenerator* self, Box* v) {
    STAT_TIMER(t0, "us_timer_generator_switching", 0);

    if (self->running)
        raiseExcHelper(ValueError, "generator already executing");

    // check if the generator already exited
    if (self->entryExited) {
        freeGeneratorStack(self);
        raiseExcHelper(StopIteration, (const char*)nullptr);
    }

    self->returnValue = v;
    self->running = true;

#if STAT_TIMERS
    if (!self->prev_stack)
        self->prev_stack = StatTimer::createStack(self->my_timer);
    else
        self->prev_stack = StatTimer::swapStack(self->prev_stack);
#endif

    swapContext(&self->returnContext, self->context, (intptr_t)self);

#if STAT_TIMERS
    self->prev_stack = StatTimer::swapStack(self->prev_stack);
    if (self->entryExited) {
        assert(self->prev_stack == &self->my_timer);
        assert(self->my_timer.isPaused());
    }
#endif

    self->running = false;

    // propagate exception to the caller
    if (self->exception.type) {
        assert(self->entryExited);
        freeGeneratorStack(self);
        // don't raise StopIteration exceptions because those are handled specially.
        if (!self->exception.matches(StopIteration))
            throw self->exception;
        return;
    }

    if (self->entryExited) {
        freeGeneratorStack(self);
        // Reset the current exception.
        // We could directly create the StopIteration exception but we delay creating it because often the caller is not
        // interested in the exception (=generatorHasnext). If we really need it we will create it inside generatorSend.
        self->exception = ExcInfo(NULL, NULL, NULL);
        return;
    }
}
Пример #12
0
extern "C" Box* tupleNew(Box* _cls, BoxedTuple* args, BoxedDict* kwargs) {
    if (!PyType_Check(_cls))
        raiseExcHelper(TypeError, "tuple.__new__(X): X is not a type object (%s)", getTypeName(_cls));

    BoxedClass* cls = static_cast<BoxedClass*>(_cls);
    if (!isSubclass(cls, tuple_cls))
        raiseExcHelper(TypeError, "tuple.__new__(%s): %s is not a subtype of tuple", getNameOfClass(cls),
                       getNameOfClass(cls));

    int args_sz = args->size();
    int kwargs_sz = kwargs ? kwargs->d.size() : 0;

    if (args_sz + kwargs_sz > 1)
        raiseExcHelper(TypeError, "tuple() takes at most 1 argument (%d given)", args_sz + kwargs_sz);

    if (args_sz || kwargs_sz) {
        Box* elements;
        // if initializing from iterable argument, check common case positional args first
        if (args_sz) {
            elements = args->elts[0];
        } else {
            assert(kwargs_sz);
            auto const seq = *(kwargs->d.begin());
            auto const kw = static_cast<BoxedString*>(seq.first.value);

            if (kw->s() == "sequence")
                elements = seq.second;
            else
                raiseExcHelper(TypeError, "'%s' is an invalid keyword argument for this function", kw->data());
        }

        if (cls == tuple_cls) {
            // Call PySequence_Tuple since it has some perf special-cases
            // that can make it quite a bit faster than the generic pyElements iteration:
            Box* r = PySequence_Tuple(elements);
            if (!r)
                throwCAPIException();
            return r;
        }

        std::vector<Box*, StlCompatAllocator<Box*>> elts;
        for (auto e : elements->pyElements())
            elts.push_back(e);

        return BoxedTuple::create(elts.size(), &elts[0], cls);
    } else {
        if (cls == tuple_cls)
            return EmptyTuple;
        return BoxedTuple::create(0, cls);
    }
}
Пример #13
0
BoxedLong* _longNew(Box* val, Box* _base) {
    BoxedLong* rtn = new BoxedLong();
    if (_base) {
        if (!isSubclass(_base->cls, int_cls))
            raiseExcHelper(TypeError, "an integer is required");
        int base = static_cast<BoxedInt*>(_base)->n;

        if (!isSubclass(val->cls, str_cls))
            raiseExcHelper(TypeError, "long() can't convert non-string with explicit base");
        BoxedString* s = static_cast<BoxedString*>(val);

        rtn = (BoxedLong*)PyLong_FromString(s->data(), NULL, base);
        checkAndThrowCAPIException();
    } else {
        if (isSubclass(val->cls, long_cls)) {
            BoxedLong* l = static_cast<BoxedLong*>(val);
            if (val->cls == long_cls)
                return l;
            BoxedLong* rtn = new BoxedLong();
            mpz_init_set(rtn->n, l->n);
            return rtn;
        } else if (isSubclass(val->cls, int_cls)) {
            mpz_init_set_si(rtn->n, static_cast<BoxedInt*>(val)->n);
        } else if (val->cls == str_cls) {
            llvm::StringRef s = static_cast<BoxedString*>(val)->s();
            assert(s.data()[s.size()] == '\0');
            int r = mpz_init_set_str(rtn->n, s.data(), 10);
            RELEASE_ASSERT(r == 0, "");
        } else if (val->cls == float_cls) {
            mpz_init_set_si(rtn->n, static_cast<BoxedFloat*>(val)->d);
        } else {
            static BoxedString* long_str = static_cast<BoxedString*>(PyString_InternFromString("__long__"));
            Box* r = callattr(val, long_str, CallattrFlags({.cls_only = true, .null_on_nonexistent = true }),
                              ArgPassSpec(0), NULL, NULL, NULL, NULL, NULL);

            if (!r) {
                fprintf(stderr, "TypeError: long() argument must be a string or a number, not '%s'\n",
                        getTypeName(val));
                raiseExcHelper(TypeError, "");
            }

            if (isSubclass(r->cls, int_cls)) {
                mpz_init_set_si(rtn->n, static_cast<BoxedInt*>(r)->n);
            } else if (!isSubclass(r->cls, long_cls)) {
                raiseExcHelper(TypeError, "__long__ returned non-long (type %s)", r->cls->tp_name);
            } else {
                return static_cast<BoxedLong*>(r);
            }
        }
    }
Пример #14
0
Box* sysGetFrame(Box* val) {
    int depth = 0;
    if (val) {
        if (!PyInt_Check(val)) {
            raiseExcHelper(TypeError, "TypeError: an integer is required");
        }
        depth = static_cast<BoxedInt*>(val)->n;
    }

    Box* frame = getFrame(depth);
    if (!frame) {
        raiseExcHelper(ValueError, "call stack is not deep enough");
    }
    return incref(frame);
}
Пример #15
0
Box* sysGetFrame(Box* val) {
    int depth = 0;
    if (val) {
        if (!isSubclass(val->cls, int_cls)) {
            raiseExcHelper(TypeError, "TypeError: an integer is required");
        }
        depth = static_cast<BoxedInt*>(val)->n;
    }

    Box* frame = getFrame(depth);
    if (!frame) {
        raiseExcHelper(ValueError, "call stack is not deep enough");
    }
    return frame;
}
Пример #16
0
static Box* importSub(const std::string* name, Box* parent_module) {
    BoxedList* path_list;
    if (parent_module == NULL) {
        path_list = getSysPath();
        if (path_list == NULL || path_list->cls != list_cls) {
            raiseExcHelper(RuntimeError, "sys.path must be a list of directory names");
        }
    } else {
        path_list = static_cast<BoxedList*>(parent_module->getattr("__path__", NULL));
        if (path_list == NULL || path_list->cls != list_cls) {
            raiseExcHelper(ImportError, "No module named %s", name->c_str());
        }
    }

    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 + ".py");
        std::string fn(joined_path.str());

        if (VERBOSITY() >= 2)
            printf("Searching for %s at %s...\n", name->c_str(), fn.c_str());

        bool exists;
        llvm::error_code code = llvm::sys::fs::exists(joined_path.str(), exists);
        assert(LLVM_SYS_FS_EXISTS_CODE_OKAY(code));

        if (!exists)
            continue;

        if (VERBOSITY() >= 1)
            printf("Importing %s from %s\n", name->c_str(), fn.c_str());

        BoxedModule* module = createAndRunModule(*name, fn);
        return module;
    }

    if (*name == "test") {
        return importTestExtension();
    }

    raiseExcHelper(ImportError, "No module named %s", name->c_str());
}
Пример #17
0
extern "C" Box* intTrunc(BoxedInt* self) {
    if (!isSubclass(self->cls, int_cls))
        raiseExcHelper(TypeError, "descriptor '__trunc__' requires a 'int' object but received a '%s'",
                       getTypeName(self));

    return self;
}
Пример #18
0
extern "C" Box* intNonzero(BoxedInt* v) {
    if (!isSubclass(v->cls, int_cls))
        raiseExcHelper(TypeError, "descriptor '__nonzero__' requires a 'int' object but received a '%s'",
                       getTypeName(v));

    return boxBool(v->n != 0);
}
Пример #19
0
extern "C" Box* intInvert(BoxedInt* v) {
    if (!isSubclass(v->cls, int_cls))
        raiseExcHelper(TypeError, "descriptor '__invert__' requires a 'int' object but received a '%s'",
                       getTypeName(v));

    return boxInt(~v->n);
}
Пример #20
0
Box* dictClear(BoxedDict* self) {
    if (!isSubclass(self->cls, dict_cls))
        raiseExcHelper(TypeError, "descriptor 'clear' requires a 'dict' object but received a '%s'", getTypeName(self));

    self->d.clear();
    return None;
}
Пример #21
0
extern "C" Box* listInsert(BoxedList* self, Box* idx, Box* v) {
    if (idx->cls != int_cls) {
        raiseExcHelper(TypeError, "an integer is required");
    }

    LOCK_REGION(self->lock.asWrite());

    int64_t n = static_cast<BoxedInt*>(idx)->n;
    if (n < 0)
        n = self->size + n;

    if (n >= self->size) {
        listAppendInternal(self, v);
    } else {
        if (n < 0)
            n = 0;
        assert(0 <= n && n < self->size);

        self->ensure(1);
        memmove(self->elts->elts + n + 1, self->elts->elts + n, (self->size - n) * sizeof(Box*));

        self->size++;
        self->elts->elts[n] = v;
    }

    return None;
}
Пример #22
0
Box* timeSleep(Box* arg) {
    double secs;
    if (arg->cls == int_cls)
        secs = static_cast<BoxedInt*>(arg)->n;
    else if (arg->cls == float_cls)
        secs = static_cast<BoxedFloat*>(arg)->d;
    else {
        raiseExcHelper(TypeError, "a float is required");
    }

    double fullsecs;
    double nanosecs = modf(secs, &fullsecs);

    struct timespec req;
    req.tv_sec = (int)(fullsecs + 0.01);
    req.tv_nsec = (int)(nanosecs * 1000000000);

    {
        threading::GLAllowThreadsReadRegion _allow_threads;
        int code = nanosleep(&req, NULL);

        if (code)
            err(1, NULL);
    }

    return None;
}
Пример #23
0
Box* setGe(BoxedSet* self, BoxedSet* rhs) {
    RELEASE_ASSERT(PyAnySet_Check(self), "");
    if (!PyAnySet_Check(rhs))
        raiseExcHelper(TypeError, "can only compare to a set");

    return setIssuperset(self, rhs);
}
Пример #24
0
template <ExceptionStyle S> Box* generatorClose(Box* s) noexcept(S == CAPI) {
    assert(s->cls == generator_cls);
    BoxedGenerator* self = static_cast<BoxedGenerator*>(s);

    // check if the generator already exited
    if (self->entryExited)
        return incref(Py_None);

    if (S == CAPI) {
        Box* rtn = generatorThrow<S>(self, GeneratorExit, nullptr, nullptr);
        if (rtn) {
            PyErr_SetString(RuntimeError, "generator ignored GeneratorExit");
            return NULL;
        }
        if (PyErr_ExceptionMatches(PyExc_StopIteration) || PyErr_ExceptionMatches(PyExc_GeneratorExit)) {
            PyErr_Clear();
            return incref(Py_None);
        }
        return NULL;
    } else {
        try {
            autoDecref(generatorThrow<S>(self, GeneratorExit, nullptr, nullptr));
            raiseExcHelper(RuntimeError, "generator ignored GeneratorExit");
        } catch (ExcInfo e) {
            if (e.matches(StopIteration) || e.matches(GeneratorExit)) {
                e.clear();
                return incref(Py_None);
            }
            throw e;
        }
    }
    assert(0); // unreachable
}
Пример #25
0
Box* generatorThrow(Box* s, BoxedClass* exc_cls, Box* exc_val = nullptr, Box** args = nullptr) noexcept(S == CAPI) {
    assert(s->cls == generator_cls);
    BoxedGenerator* self = static_cast<BoxedGenerator*>(s);

    if (self->iterated_from__hasnext__ && !self->entryExited)
        Py_FatalError(".throw called on generator last advanced with __hasnext__");

    Box* exc_tb = args ? args[0] : nullptr;
    if (exc_tb && exc_tb != Py_None && !PyTraceBack_Check(exc_tb)) {
        if (S == CAPI) {
            PyErr_SetString(TypeError, "throw() third argument must be a traceback object");
            return NULL;
        }
        raiseExcHelper(TypeError, "throw() third argument must be a traceback object");
    }
    if (!exc_val)
        exc_val = Py_None;
    if (!exc_tb)
        exc_tb = Py_None;

    ExcInfo exc_info = excInfoForRaise(incref(exc_cls), incref(exc_val), incref(exc_tb));
    if (self->entryExited) {
        if (S == CAPI) {
            setCAPIException(exc_info);
            return NULL;
        }
        throw exc_info;
    }

    self->exception = exc_info;
    return generatorSend<S>(self, Py_None);
}
Пример #26
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;
}
Пример #27
0
Box* generatorSend(Box* s, Box* v) {
    assert(s->cls == generator_cls);
    BoxedGenerator* self = static_cast<BoxedGenerator*>(s);

    if (self->iterated_from__hasnext__)
        Py_FatalError(".throw called on generator last advanced with __hasnext__");

    generatorSendInternal(self, v);

    // throw StopIteration if the generator exited
    if (self->entryExited) {
        // But we can't just create a new exc because the generator may have exited because of an explicit
        // 'raise StopIterationSubClass, "test"' statement and we can't replace it with the generic StopIteration
        // exception.
        // That's why we set inside 'generatorSendInternal()' 'self->exception' to the raised StopIteration exception or
        // create a new one if the generator exited implicit.
        // CPython raises the custom exception just once, on the next generator 'next' it will we a normal StopIteration
        // exc.
        assert(self->exception.type == NULL || self->exception.matches(StopIteration));
        ExcInfo old_exc = self->exception;
        // Clear the exception for GC purposes:
        self->exception = ExcInfo(nullptr, nullptr, nullptr);
        if (old_exc.type == NULL)
            raiseExcHelper(StopIteration, (const char*)nullptr);
        throw old_exc;
    }

    return self->returnValue;
}
Пример #28
0
Box* dictLen(BoxedDict* self) {
    if (!isSubclass(self->cls, dict_cls))
        raiseExcHelper(TypeError, "descriptor '__len__' requires a 'dict' object but received a '%s'",
                       getTypeName(self));

    return boxInt(self->d.size());
}
Пример #29
0
Box* mathSqrt(Box* b) {
    double d = _extractFloat(b);
    if (d < 0) {
        raiseExcHelper(ValueError, "math domain error");
    }
    return boxFloat(sqrt(d));
}
Пример #30
0
Box* tupleMul(BoxedTuple* self, Box* rhs) {
    Py_ssize_t n;
    if (PyIndex_Check(rhs)) {
        n = PyNumber_AsSsize_t(rhs, PyExc_OverflowError);
        if (n == -1 && PyErr_Occurred())
            throwCAPIException();
    } else {
        raiseExcHelper(TypeError, "can't multiply sequence by non-int of type '%s'", getTypeName(rhs));
    }

    int s = self->size();

    if (n < 0)
        n = 0;

    if ((s == 0 || n == 1) && PyTuple_CheckExact(self)) {
        return self;
    } else {
        BoxedTuple* rtn = BoxedTuple::create(n * s);
        int rtn_i = 0;
        for (int i = 0; i < n; ++i) {
            memmove(&rtn->elts[rtn_i], &self->elts[0], sizeof(Box*) * s);
            rtn_i += s;
        }
        return rtn;
    }
}