Commit 0dc84225 authored by Marius Wachtler's avatar Marius Wachtler

Add basic support for setting member descriptors.

In addition fixed a bug:
The rewriter generated a 64bit mem comparison for the 32bit offset value,
thus comparing partially undefined memory.
parent a8af1ea6
......@@ -293,7 +293,7 @@ ASM_SRCS := $(wildcard src/runtime/*.S)
STDMODULE_SRCS := errnomodule.c shamodule.c sha256module.c sha512module.c _math.c mathmodule.c md5.c md5module.c _randommodule.c _sre.c operator.c binascii.c pwdmodule.c posixmodule.c _struct.c datetimemodule.c _functoolsmodule.c _collectionsmodule.c itertoolsmodule.c resource.c signalmodule.c selectmodule.c fcntlmodule.c timemodule.c arraymodule.c zlibmodule.c _codecsmodule.c socketmodule.c unicodedata.c _weakref.c $(EXTRA_STDMODULE_SRCS)
STDOBJECT_SRCS := structseq.c capsule.c stringobject.c exceptions.c unicodeobject.c unicodectype.c bytearrayobject.c bytes_methods.c weakrefobject.c $(EXTRA_STDOBJECT_SRCS)
STDPYTHON_SRCS := pyctype.c getargs.c formatter_string.c pystrtod.c dtoa.c formatter_unicode.c $(EXTRA_STDPYTHON_SRCS)
STDPYTHON_SRCS := pyctype.c getargs.c formatter_string.c pystrtod.c dtoa.c formatter_unicode.c structmember.c $(EXTRA_STDPYTHON_SRCS)
FROM_CPYTHON_SRCS := $(addprefix from_cpython/Modules/,$(STDMODULE_SRCS)) $(addprefix from_cpython/Objects/,$(STDOBJECT_SRCS)) $(addprefix from_cpython/Python/,$(STDPYTHON_SRCS))
# The stdlib objects have slightly longer dependency chains,
......
......@@ -21,7 +21,7 @@ file(GLOB_RECURSE STDMODULE_SRCS Modules errnomodule.c shamodule.c sha256module.
file(GLOB_RECURSE STDOBJECT_SRCS Objects structseq.c capsule.c stringobject.c exceptions.c unicodeobject.c unicodectype.c bytearrayobject.c bytes_methods.c weakrefobject.c)
# compile specified files in from_cpython/Python
file(GLOB_RECURSE STDPYTHON_SRCS Python getargs.c pyctype.c formatter_string.c pystrtod.c dtoa.c formatter_unicode.c)
file(GLOB_RECURSE STDPYTHON_SRCS Python getargs.c pyctype.c formatter_string.c pystrtod.c dtoa.c formatter_unicode.c structmember.c)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-missing-field-initializers -Wno-tautological-compare -Wno-type-limits")
add_library(FROM_CPYTHON OBJECT ${STDMODULE_SRCS} ${STDOBJECT_SRCS} ${STDPYTHON_SRCS})
This diff is collapsed.
......@@ -1471,6 +1471,10 @@ extern "C" PyObject* PyBuffer_FromMemory(void* ptr, Py_ssize_t size) noexcept {
Py_FatalError("unimplemented");
}
extern "C" int PyEval_GetRestricted(void) noexcept {
return 0; // We don't support restricted mode
}
BoxedModule* importTestExtension(const std::string& name) {
std::string pathname_name = "test/test_extension/" + name + ".pyston.so";
const char* pathname = pathname_name.c_str();
......
......@@ -1098,7 +1098,7 @@ void setupFile() {
file_cls->giveAttr("next", new BoxedFunction(boxRTFunction((void*)fileIterNext, STR, 1)));
file_cls->giveAttr("softspace",
new BoxedMemberDescriptor(BoxedMemberDescriptor::INT, offsetof(BoxedFile, f_softspace)));
new BoxedMemberDescriptor(BoxedMemberDescriptor::INT, offsetof(BoxedFile, f_softspace), false));
file_cls->giveAttr("__new__", new BoxedFunction(boxRTFunction((void*)fileNew, UNKNOWN, 3, 1, false, false),
{ boxStrConstant("r") }));
......
......@@ -853,9 +853,12 @@ Box* dataDescriptorInstanceSpecialCases(GetattrRewriteArgs* rewrite_args, const
if (rewrite_args) {
// TODO we could use offset as the index in the assembly lookup rather than hardcoding
// the value in the assembly and guarding on it be the same.
r_descr->addAttrGuard(offsetof(BoxedMemberDescriptor, offset), member_desc->offset);
// This could be optimized if addAttrGuard supported things < 64 bits
static_assert(sizeof(member_desc->offset) == 4, "assumed by assembly instruction below");
r_descr->getAttr(offsetof(BoxedMemberDescriptor, offset), Location::any(), assembler::MovType::ZLQ)
->addGuard(member_desc->offset);
static_assert(sizeof(member_desc->type) == 4, "assumed by assembly instruction below");
r_descr->getAttr(offsetof(BoxedMemberDescriptor, type), Location::any(), assembler::MovType::ZLQ)
->addGuard(member_desc->type);
......@@ -940,7 +943,6 @@ Box* dataDescriptorInstanceSpecialCases(GetattrRewriteArgs* rewrite_args, const
CASE_INTEGER_TYPE(LONGLONG, long long, PyLong_FromLongLong, long long)
CASE_INTEGER_TYPE(ULONGLONG, unsigned long long, PyLong_FromUnsignedLongLong, unsigned long long)
CASE_INTEGER_TYPE(PYSSIZET, Py_ssize_t, boxInt, Py_ssize_t)
case BoxedMemberDescriptor::STRING: {
if (rewrite_args) {
RewriterVar* r_interm = rewrite_args->obj->getAttr(member_desc->offset, rewrite_args->destination);
......@@ -1565,6 +1567,17 @@ bool dataDescriptorSetSpecialCases(Box* obj, Box* val, Box* descr, SetattrRewrit
getset_descr->set(obj, val, getset_descr->closure);
return true;
} else if (descr->cls == member_cls) {
BoxedMemberDescriptor* member_desc = static_cast<BoxedMemberDescriptor*>(descr);
PyMemberDef member_def;
memset(&member_def, 0, sizeof(member_def));
member_def.offset = member_desc->offset;
member_def.type = member_desc->type;
if (member_desc->readonly)
member_def.flags |= READONLY;
PyMember_SetOne((char*)obj, &member_def, val);
checkAndThrowCAPIException();
return true;
}
......@@ -1636,6 +1649,8 @@ void setattrInternal(Box* obj, const std::string& attr, Box* val, SetattrRewrite
// We don't need to to the invalidation stuff in this case.
return;
} else {
if (!obj->cls->instancesHaveHCAttrs() && !obj->cls->instancesHaveDictAttrs())
raiseAttributeError(obj, attr.c_str());
obj->setattr(attr, val, rewrite_args);
}
......@@ -1670,10 +1685,6 @@ extern "C" void setattr(Box* obj, const char* attr, Box* attr_val) {
static StatCounter slowpath_setattr("slowpath_setattr");
slowpath_setattr.log();
if (!obj->cls->instancesHaveHCAttrs() && !obj->cls->instancesHaveDictAttrs()) {
raiseAttributeError(obj, attr);
}
if (obj->cls == type_cls) {
BoxedClass* cobj = static_cast<BoxedClass*>(obj);
if (!isUserDefined(cobj)) {
......
......@@ -1379,8 +1379,8 @@ void setupRuntime() {
function_cls->giveAttr("__name__", new (pyston_getset_cls) BoxedGetsetDescriptor(funcName, funcSetName, NULL));
function_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)functionRepr, STR, 1)));
function_cls->giveAttr("__module__",
new BoxedMemberDescriptor(BoxedMemberDescriptor::OBJECT, offsetof(BoxedFunction, modname)));
function_cls->giveAttr("__module__", new BoxedMemberDescriptor(BoxedMemberDescriptor::OBJECT,
offsetof(BoxedFunction, modname), false));
function_cls->giveAttr("__get__", new BoxedFunction(boxRTFunction((void*)functionGet, UNKNOWN, 3)));
function_cls->giveAttr("__call__",
new BoxedFunction(boxRTFunction((void*)functionCall, UNKNOWN, 1, 0, true, true)));
......
......@@ -495,9 +495,12 @@ public:
} type;
int offset;
bool readonly;
BoxedMemberDescriptor(MemberType type, int offset) : type(type), offset(offset) {}
BoxedMemberDescriptor(PyMemberDef* member) : type((MemberType)member->type), offset(member->offset) {}
BoxedMemberDescriptor(MemberType type, int offset, bool readonly = true)
: type(type), offset(offset), readonly(readonly) {}
BoxedMemberDescriptor(PyMemberDef* member)
: type((MemberType)member->type), offset(member->offset), readonly(member->flags & READONLY) {}
DEFAULT_CLASS_SIMPLE(member_cls);
};
......
......@@ -17,3 +17,8 @@ print (0.5j + 1.5).real
print (0.5j + 1.5).imag
print complex(1, 1.0) / 2.0
try:
complex(1, 1.0).real = 1
except TypeError, e:
print e
......@@ -50,5 +50,6 @@ except IOError as e:
f = open("/dev/null", "w")
print f.write("hello world")
f.softspace = 0
print f.flush()
print f.close()
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