void raiseExcHelper(BoxedClass* cls, const char* msg, ...) { auto entries = getTracebackEntries(); last_tb = std::move(entries); if (msg != NULL) { va_list ap; va_start(ap, msg); // printf("Raising: "); // vprintf(msg, ap); // printf("\n"); // va_start(ap, msg); char buf[1024]; vsnprintf(buf, sizeof(buf), msg, ap); va_end(ap); BoxedString* message = boxStrConstant(buf); Box* exc_obj = exceptionNew2(cls, message); raiseExc(exc_obj); } else { Box* exc_obj = exceptionNew1(cls); raiseExc(exc_obj); } }
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); }
Box* getattr2(Box* obj, Box* _str) { if (_str->cls != str_cls) { fprintf(stderr, "TypeError: getattr(): attribute name must be string\n"); raiseExc(); } BoxedString* str = static_cast<BoxedString*>(_str); Box* rtn = getattr_internal(obj, str->s.c_str(), true, true, NULL, NULL); if (!rtn) { fprintf(stderr, "AttributeError: '%s' object has no attribute '%s'\n", getTypeName(obj)->c_str(), str->s.c_str()); raiseExc(); } return rtn; }
static inline void raiseDivZeroExcIfZero(T var) { if (var == 0) { fprintf(stderr, "float divide by zero\n"); raiseExc(); } }
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()); }
Box* fileRead2(BoxedFile* self, Box* size) { assert(self->cls == file_cls); if (size->cls != int_cls) { fprintf(stderr, "TypeError: an integer is required\n"); raiseExc(); } return _fileRead(self, static_cast<BoxedInt*>(size)->n); }
static Box* sysExit(Box* arg) { assert(arg); Box* exc = runtimeCall(SystemExit, ArgPassSpec(1), arg, NULL, NULL, NULL, NULL); // TODO this should be handled by the SystemExit constructor exc->giveAttr("code", arg); raiseExc(exc); }
extern "C" Box* open2(Box* arg1, Box* arg2) { if (arg1->cls != str_cls) { fprintf(stderr, "TypeError: coercing to Unicode: need string of buffer, %s found\n", getTypeName(arg1)->c_str()); raiseExc(); } if (arg2->cls != str_cls) { fprintf(stderr, "TypeError: coercing to Unicode: need string of buffer, %s found\n", getTypeName(arg2)->c_str()); raiseExc(); } const std::string &fn = static_cast<BoxedString*>(arg1)->s; const std::string &mode = static_cast<BoxedString*>(arg2)->s; FILE* f = fopen(fn.c_str(), mode.c_str()); RELEASE_ASSERT(f, ""); return new BoxedFile(f); }
extern "C" Box* intDivFloat(BoxedInt* lhs, BoxedFloat *rhs) { assert(lhs->cls == int_cls); assert(rhs->cls == float_cls); if (rhs->d == 0) { fprintf(stderr, "float divide by zero\n"); raiseExc(); } return boxFloat(lhs->n / rhs->d); }
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)); }
Box* dictGetitem(BoxedDict* self, Box* k) { Box* &pos = self->d[k]; if (pos == NULL) { BoxedString *s = repr(k); fprintf(stderr, "KeyError: %s\n", s->s.c_str()); raiseExc(); } return pos; }
Box* fileClose(BoxedFile* self) { assert(self->cls == file_cls); if (self->closed) { fprintf(stderr, "IOError: file is closed\n"); raiseExc(); } fclose(self->f); self->closed = true; return None; }
Box* fileWrite(BoxedFile* self, Box* val) { assert(self->cls == file_cls); if (self->closed) { fprintf(stderr, "IOError: file is closed\n"); raiseExc(); } if (val->cls == str_cls) { const std::string &s = static_cast<BoxedString*>(val)->s; size_t size = s.size(); size_t written = 0; while (written < size) { //const int BUF_SIZE = 1024; //char buf[BUF_SIZE]; //int to_write = std::min(BUF_SIZE, size - written); //memcpy(buf, s.c_str() + written, to_write); //size_t new_written = fwrite(buf, 1, to_write, self->f); size_t new_written = fwrite(s.c_str() + written, 1, size - written, self->f); if (!new_written) { int error = ferror(self->f); fprintf(stderr, "IOError %d\n", error); raiseExc(); } written += new_written; } return None; } else { fprintf(stderr, "str expected\n"); raiseExc(); } }
void raiseExcHelper(BoxedClass* cls, const char* msg, ...) { if (msg != NULL) { va_list ap; va_start(ap, msg); // printf("Raising: "); // vprintf(msg, ap); // printf("\n"); // va_start(ap, msg); char buf[1024]; vsnprintf(buf, sizeof(buf), msg, ap); va_end(ap); BoxedString* message = boxStrConstant(buf); Box* exc_obj = runtimeCall(cls, ArgPassSpec(1), message, NULL, NULL, NULL, NULL); raiseExc(exc_obj); } else { Box* exc_obj = runtimeCall(cls, ArgPassSpec(0), NULL, NULL, NULL, NULL, NULL); raiseExc(exc_obj); } }
Box* getattr3(Box* obj, Box* _str, Box* default_value) { if (_str->cls != str_cls) { fprintf(stderr, "TypeError: getattr(): attribute name must be string\n"); raiseExc(); } BoxedString* str = static_cast<BoxedString*>(_str); Box* rtn = getattr_internal(obj, str->s.c_str(), true, true, NULL, NULL); if (!rtn) { return default_value; } return rtn; }
static Box* sysExit(Box* arg) { assert(arg); Box* exc = runtimeCall(SystemExit, ArgPassSpec(1), arg, NULL, NULL, NULL, NULL); raiseExc(exc); }
void raiseExcHelper(BoxedClass* cls, Box* arg) { Box* exc_obj = runtimeCall(cls, ArgPassSpec(1), arg, NULL, NULL, NULL, NULL); raiseExc(exc_obj); }