Commit 54ee4c2e authored by Kevin Modzelewski's avatar Kevin Modzelewski

Gets through sys

parent 353e7876
......@@ -1769,7 +1769,7 @@ static void init_slotdefs() noexcept {
return;
for (int i = 0; i < sizeof(slotdefs) / sizeof(slotdefs[0]); i++) {
slotdefs[i].name_strobj = getStringConstant(slotdefs[i].name.data());
slotdefs[i].name_strobj = getStaticString(slotdefs[i].name.data());
if (i > 0) {
if (!slotdefs[i].name.size())
......@@ -1860,13 +1860,13 @@ static const slotdef* update_one_slot(BoxedClass* type, const slotdef* p) noexce
// there was only one:
assert((p + 1)->offset > p->offset);
static BoxedString* class_str = getStringConstant("__class__");
static BoxedString* class_str = getStaticString("__class__");
if (p->name_strobj == class_str) {
if (descr == object_cls->getattr(class_str))
descr = NULL;
}
static BoxedString* getattribute_str = getStringConstant("__getattribute__");
static BoxedString* getattribute_str = getStaticString("__getattribute__");
if (p->name_strobj == getattribute_str) {
if (descr && descr->cls == wrapperdescr_cls
&& ((BoxedWrapperDescriptor*)descr)->wrapped == PyObject_GenericGetAttr)
......
......@@ -647,6 +647,13 @@ public:
void setattr(BoxedString* attr, Box* val, SetattrRewriteArgs* rewrite_args);
// giveAttr consumes a reference to val and attr
void giveAttr(const char* attr, Box* val) { giveAttr(internStringMortal(attr), val); }
// giveAttrBorrowed consumes a reference only to attr (but it only has the const char* variant
// which creates the reference). should probably switch the names to stay consistent; most functions
// don't steal references.
void giveAttrBorrowed(const char* attr, Box* val) {
Py_INCREF(val);
giveAttr(internStringMortal(attr), val);
}
void giveAttr(BoxedString* attr, Box* val);
// for debugging mostly:
......@@ -657,6 +664,8 @@ public:
template <Rewritable rewritable = REWRITABLE>
Box* getattr(BoxedString* attr, GetattrRewriteArgs* rewrite_args);
Box* getattr(BoxedString* attr) { return getattr<NOT_REWRITABLE>(attr, NULL); }
Box* getattrString(const char* attr);
bool hasattr(BoxedString* attr) { return getattr(attr) != NULL; }
void delattr(BoxedString* attr, DelattrRewriteArgs* rewrite_args);
......
......@@ -230,10 +230,11 @@ public:
BoxedSysFlags() {
auto zero = boxInt(0);
assert(zero);
division_warning = zero;
bytes_warning = zero;
no_user_site = zero;
optimize = zero;
division_warning = incref(zero);
bytes_warning = incref(zero);
no_user_site = incref(zero);
optimize = incref(zero);
Py_DECREF(zero);
}
DEFAULT_CLASS(sys_flags_cls);
......@@ -252,6 +253,13 @@ public:
static Box* __new__(Box* cls, Box* args, Box* kwargs) {
raiseExcHelper(TypeError, "cannot create 'sys.flags' instances");
}
static void dealloc(BoxedSysFlags* self) {
Py_DECREF(self->division_warning);
Py_DECREF(self->bytes_warning);
Py_DECREF(self->no_user_site);
Py_DECREF(self->optimize);
}
};
static std::string generateVersionString() {
......@@ -627,26 +635,34 @@ Return the current value of the recursion limit, the maximum depth\n\
of the Python interpreter stack. This limit prevents infinite\n\
recursion from causing an overflow of the C stack and crashing Python.");
static int _check_and_flush(FILE* stream) {
int prev_fail = ferror(stream);
return fflush(stream) || prev_fail ? EOF : 0;
}
void setupSys() {
sys_modules_dict = new BoxedDict();
constants.push_back(sys_modules_dict);
gc::registerPermanentRoot(sys_modules_dict);
// This is ok to call here because we've already created the sys_modules_dict
sys_module = createModule(boxString("sys"));
constants.push_back(sys_module);
sys_module->giveAttr("modules", sys_modules_dict);
sys_module->giveAttrBorrowed("modules", sys_modules_dict);
BoxedList* sys_path = new BoxedList();
sys_module->giveAttr("path", sys_path);
constants.push_back(sys_path);
sys_module->giveAttrBorrowed("path", sys_path);
sys_module->giveAttr("argv", new BoxedList());
sys_module->giveAttr("stdout", new BoxedFile(stdout, "<stdout>", "w"));
sys_module->giveAttr("stdin", new BoxedFile(stdin, "<stdin>", "r"));
sys_module->giveAttr("stderr", new BoxedFile(stderr, "<stderr>", "w"));
sys_module->giveAttr("__stdout__", sys_module->getattr(internStringMortal("stdout")));
sys_module->giveAttr("__stdin__", sys_module->getattr(internStringMortal("stdin")));
sys_module->giveAttr("__stderr__", sys_module->getattr(internStringMortal("stderr")));
sys_module->giveAttr("stdout", new BoxedFile(stdout, "<stdout>", "w", NULL));
sys_module->giveAttr("stdin", new BoxedFile(stdin, "<stdin>", "r", _check_and_flush));
sys_module->giveAttr("stderr", new BoxedFile(stderr, "<stderr>", "w", _check_and_flush));
sys_module->giveAttrBorrowed("__stdout__", sys_module->getattr(autoDecref(internStringMortal("stdout"))));
sys_module->giveAttrBorrowed("__stdin__", sys_module->getattr(autoDecref(internStringMortal("stdin"))));
sys_module->giveAttrBorrowed("__stderr__", sys_module->getattr(autoDecref(internStringMortal("stderr"))));
sys_module->giveAttr("exc_info",
new BoxedBuiltinFunctionOrMethod(FunctionMetadata::create((void*)sysExcInfo, BOXED_TUPLE, 0),
......@@ -659,7 +675,7 @@ void setupSys() {
"exit", { None }, NULL, exit_doc));
sys_module->giveAttr("warnoptions", new BoxedList());
sys_module->giveAttr("py3kwarning", False);
sys_module->giveAttrBorrowed("py3kwarning", False);
sys_module->giveAttr("byteorder", boxString(isLittleEndian() ? "little" : "big"));
sys_module->giveAttr("platform", boxString(Py_GetPlatform()));
......@@ -686,7 +702,7 @@ void setupSys() {
sys_module->giveAttr("path_importer_cache", new BoxedDict());
// As we don't support compile() etc yet force 'dont_write_bytecode' to true.
sys_module->giveAttr("dont_write_bytecode", True);
sys_module->giveAttrBorrowed("dont_write_bytecode", True);
sys_module->giveAttr("prefix", boxString(Py_GetPrefix()));
sys_module->giveAttr("exec_prefix", boxString(Py_GetExecPrefix()));
......@@ -700,7 +716,8 @@ void setupSys() {
sys_module->giveAttr("version", boxString(generateVersionString()));
sys_module->giveAttr("hexversion", boxInt(PY_VERSION_HEX));
sys_module->giveAttr("subversion", BoxedTuple::create({ boxString("Pyston"), boxString(""), boxString("") }));
sys_module->giveAttr("subversion", BoxedTuple::create({ autoDecref(boxString("Pyston")), autoDecref(boxString("")),
autoDecref(boxString("")) }));
sys_module->giveAttr("maxint", boxInt(PYSTON_INT_MAX));
sys_module->giveAttr("maxsize", boxInt(PY_SSIZE_T_MAX));
......@@ -708,6 +725,7 @@ void setupSys() {
BoxedClass(object_cls, BoxedSysFlags::gcHandler, 0, 0, sizeof(BoxedSysFlags), false, "flags");
sys_flags_cls->giveAttr(
"__new__", new BoxedFunction(FunctionMetadata::create((void*)BoxedSysFlags::__new__, UNKNOWN, 1, true, true)));
sys_flags_cls->tp_dealloc = (destructor)BoxedSysFlags::dealloc;
#define ADD(name) \
sys_flags_cls->giveAttr(STRINGIFY(name), \
new BoxedMemberDescriptor(BoxedMemberDescriptor::OBJECT, offsetof(BoxedSysFlags, name)))
......@@ -728,7 +746,7 @@ void setupSys() {
sys_module->giveAttr(md.ml_name, new BoxedCApiFunction(&md, sys_module));
}
sys_module->giveAttr("__displayhook__", sys_module->getattr(internStringMortal("displayhook")));
sys_module->giveAttrBorrowed("__displayhook__", sys_module->getattr(autoDecref(internStringMortal("displayhook"))));
sys_module->giveAttr("flags", new BoxedSysFlags());
}
......
......@@ -287,7 +287,7 @@ BoxedFile::BoxedFile(FILE* f, std::string fname, const char* fmode, int (*close)
f_bufptr(0),
f_setbuf(0),
unlocked_count(0) {
static BoxedString* not_yet_string = internStringImmortal("<uninitialized file>");
static BoxedString* not_yet_string = getStaticString("<uninitialized file>");
Py_INCREF(not_yet_string);
this->f_name = not_yet_string;
Py_INCREF(not_yet_string);
......@@ -297,7 +297,9 @@ BoxedFile::BoxedFile(FILE* f, std::string fname, const char* fmode, int (*close)
Py_INCREF(None);
this->f_errors = None;
Box* r = fill_file_fields(this, f, boxString(fname), fmode, close);
Box* fname_s = boxString(fname);
Box* r = fill_file_fields(this, f, fname_s, fmode, close);
Py_DECREF(fname_s);
checkAndThrowCAPIException();
assert(r == this);
}
......@@ -1838,13 +1840,19 @@ static PyGetSetDef file_getsetlist[] = {
{ "closed", (getter)get_closed, NULL, "True if the file is closed", NULL },
};
void fileDestructor(Box* b) {
void file_dealloc(Box* b) noexcept {
assert(isSubclass(b->cls, file_cls));
BoxedFile* self = static_cast<BoxedFile*>(b);
BoxedFile* f = static_cast<BoxedFile*>(b);
if (f->f_fp && f->f_close)
f->f_close(f->f_fp);
f->f_fp = NULL;
if (self->f_fp && self->f_close)
self->f_close(self->f_fp);
self->f_fp = NULL;
Py_DECREF(f->f_name);
Py_DECREF(f->f_mode);
Py_DECREF(f->f_encoding);
Py_DECREF(f->f_errors);
PyMem_Free(f->f_setbuf);
}
void BoxedFile::gcHandler(GCVisitor* v, Box* b) {
......@@ -1861,7 +1869,6 @@ void BoxedFile::gcHandler(GCVisitor* v, Box* b) {
}
void setupFile() {
file_cls->tp_dealloc = fileDestructor;
file_cls->has_safe_tp_dealloc = true;
file_cls->giveAttr(
......@@ -1881,7 +1888,7 @@ void setupFile() {
new BoxedFunction(FunctionMetadata::create((void*)fileEnter, typeFromClass(file_cls), 1)));
file_cls->giveAttr("__exit__", new BoxedFunction(FunctionMetadata::create((void*)fileExit, UNKNOWN, 4)));
file_cls->giveAttr("__iter__", file_cls->getattr(internStringMortal("__enter__")));
file_cls->giveAttr("__iter__", file_cls->getattr(getStaticString("__enter__")));
file_cls->giveAttr("__hasnext__",
new BoxedFunction(FunctionMetadata::create((void*)fileIterHasNext, BOXED_BOOL, 1)));
file_cls->giveAttr("next", new BoxedFunction(FunctionMetadata::create((void*)fileIterNext, STR, 1)));
......
......@@ -439,8 +439,7 @@ extern "C" BoxedFunctionBase::BoxedFunctionBase(FunctionMetadata* md, std::initi
this->doc = md->source->getDocString();
} else {
this->modname = PyString_InternFromString("__builtin__");
Py_INCREF(None);
this->doc = None;
this->doc = incref(None);
}
}
......@@ -455,6 +454,7 @@ BoxedFunction::BoxedFunction(FunctionMetadata* md, std::initializer_list<Box*> d
// some builtin functions that are BoxedFunctions but really ought to be a type that
// we don't have yet.
if (md->source) {
assert(!this->name);
this->name = static_cast<BoxedString*>(md->source->getName());
}
}
......@@ -489,6 +489,7 @@ void BoxedFunction::gcHandler(GCVisitor* v, Box* b) {
BoxedBuiltinFunctionOrMethod::BoxedBuiltinFunctionOrMethod(FunctionMetadata* md, const char* name, const char* doc)
: BoxedBuiltinFunctionOrMethod(md, name, {}) {
Py_DECREF(this->doc);
this->doc = doc ? boxString(doc) : None;
}
......@@ -498,8 +499,10 @@ BoxedBuiltinFunctionOrMethod::BoxedBuiltinFunctionOrMethod(FunctionMetadata* md,
: BoxedFunctionBase(md, defaults, closure) {
assert(name);
assert(!this->name);
this->name = static_cast<BoxedString*>(boxString(name));
this->doc = doc ? boxString(doc) : None;
Py_DECREF(this->doc);
this->doc = doc ? boxString(doc) : incref(None);
}
static void functionDtor(Box* b) {
......@@ -3763,6 +3766,7 @@ void setupRuntime() {
dict_cls->tp_flags |= Py_TPFLAGS_DICT_SUBCLASS;
file_cls = new (0) BoxedClass(object_cls, &BoxedFile::gcHandler, 0, offsetof(BoxedFile, weakreflist),
sizeof(BoxedFile), false, "file");
file_cls->tp_dealloc = file_dealloc;
int_cls = new (0) BoxedClass(object_cls, NULL, 0, 0, sizeof(BoxedInt), false, "int");
int_cls->tp_flags |= Py_TPFLAGS_INT_SUBCLASS;
bool_cls = new (0) BoxedClass(int_cls, NULL, 0, 0, sizeof(BoxedBool), false, "bool");
......@@ -3856,12 +3860,20 @@ void setupRuntime() {
for (auto b : interned_ints)
constants.push_back(b);
// sys is the first module that needs to be set up, due to modules
// being tracked in sys.modules:
setupSys();
// XXX
_Py_ReleaseInternedStrings();
for (auto b : classes)
b->clearAttrs();
for (auto b : constants)
for (auto b : constants) {
b->clearAttrs();
Py_DECREF(b);
}
for (auto b : classes) {
if (b->tp_mro) {
Py_DECREF(b->tp_mro);
......@@ -3872,13 +3884,6 @@ void setupRuntime() {
exit(0);
// XXX
// sys is the first module that needs to be set up, due to modules
// being tracked in sys.modules:
setupSys();
// Weakrefs are used for tp_subclasses:
init_weakref();
......
......@@ -176,6 +176,7 @@ void setCAPIException(const ExcInfo& e);
// Finalizer-related
void default_free(void*);
void dealloc_null(Box* box);
void file_dealloc(Box*) noexcept;
// In Pyston, this is the same type as CPython's PyTypeObject (they are interchangeable, but we
// use BoxedClass in Pyston wherever possible as a convention).
......@@ -352,6 +353,33 @@ static_assert(offsetof(pyston::BoxedHeapClass, as_sequence) == offsetof(PyHeapTy
static_assert(offsetof(pyston::BoxedHeapClass, as_buffer) == offsetof(PyHeapTypeObject, as_buffer), "");
static_assert(sizeof(pyston::BoxedHeapClass) == sizeof(PyHeapTypeObject), "");
template <typename B, bool Nullable = false> struct DecrefHandle {
private:
B* b;
public:
DecrefHandle(B* b) : b(b) {}
~DecrefHandle() {
if (Nullable)
Py_XDECREF(b);
else
Py_DECREF(b);
}
operator B*() { return b; }
};
template <typename B, bool Nullable = false> DecrefHandle<B, Nullable> autoDecref(B* b) {
return DecrefHandle<B, Nullable>(b);
}
template <typename B> B* incref(B* b) {
Py_INCREF(b);
return b;
}
template <typename B> B* xincref(B* b) {
Py_XINCREF(b);
return b;
}
class BoxedInt : public Box {
public:
int64_t n;
......@@ -1198,11 +1226,25 @@ inline Box*& getArg(int idx, Box*& arg1, Box*& arg2, Box*& arg3, Box** args) {
return args[idx - 3];
}
inline BoxedString* getStringConstant(llvm::StringRef s) {
inline BoxedString* getStaticString(llvm::StringRef s) {
BoxedString* r = internStringImmortal(s);
constants.push_back(r);
return r;
}
inline Box* Box::getattrString(const char* attr) {
// XXX need to auto-decref
BoxedString* s = internStringMortal(attr);
try {
Box* r = getattr<NOT_REWRITABLE>(s, NULL);
Py_DECREF(s);
return r;
} catch (ExcInfo e) {
Py_DECREF(s);
throw e;
}
}
} // namespace pyston
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment