Commit d51a1c9f authored by Kevin Modzelewski's avatar Kevin Modzelewski

Merge branch 'selfhost'

parents 8628cdc9 0f43471c
......@@ -26,6 +26,12 @@ namespace pyston {
#ifndef NDEBUG
int AST::next_lineno = 100000;
AST::AST(AST_TYPE::AST_TYPE type) : type(type), lineno(++next_lineno) {
// if (lineno == 100644)
// raise(SIGTRAP);
}
#endif
llvm::StringRef getOpSymbol(int op_type) {
......
......@@ -149,12 +149,12 @@ public:
#ifndef NDEBUG
private:
// In debug mode, initialize lineno to something unique, so that if we see something ridiculous
// appear in the traceback, we can isolate the allocation which created it.
static int next_lineno;
public:
// In debug mode, initialize lineno to something unique, so that if we see something ridiculous
// appear in the traceback, we can isolate the allocation which created it.
AST(AST_TYPE::AST_TYPE type) : type(type), lineno(++next_lineno) {}
AST(AST_TYPE::AST_TYPE type);
#else
AST(AST_TYPE::AST_TYPE type) : type(type) {}
#endif
......
......@@ -473,7 +473,11 @@ public:
struct ExcInfo {
Box* type, *value, *traceback;
#ifndef NDEBUG
ExcInfo(Box* type, Box* value, Box* traceback);
#else
ExcInfo(Box* type, Box* value, Box* traceback) : type(type), value(value), traceback(traceback) {}
#endif
bool matches(BoxedClass* cls) const;
};
......
......@@ -979,6 +979,8 @@ void setupBuiltins() {
builtins_module->giveAttr("None", None);
builtins_module->giveAttr("__debug__", False);
builtins_module->giveAttr("print", new BoxedFunction(boxRTFunction((void*)print, NONE, 0, 0, true, true)));
notimplemented_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(Box), false);
......
......@@ -45,9 +45,40 @@ Box* startNewThread(Box* target, Box* args) {
return boxInt(thread_id ^ 0x12345678901L);
}
static BoxedClass* thread_lock_cls;
class BoxedThreadLock : public Box {
public:
BoxedThreadLock() {}
DEFAULT_CLASS(thread_lock_cls);
};
Box* allocateLock() {
return new BoxedThreadLock();
}
Box* getIdent() {
return boxInt(pthread_self());
}
void setupThread() {
thread_module = createModule("thread", "__builtin__");
thread_module->giveAttr("start_new_thread", new BoxedFunction(boxRTFunction((void*)startNewThread, BOXED_INT, 2)));
thread_module->giveAttr("allocate_lock", new BoxedFunction(boxRTFunction((void*)allocateLock, UNKNOWN, 0)));
thread_module->giveAttr("get_ident", new BoxedFunction(boxRTFunction((void*)getIdent, BOXED_INT, 0)));
thread_lock_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(BoxedThreadLock), false);
thread_lock_cls->giveAttr("__name__", boxStrConstant("lock"));
thread_lock_cls->giveAttr("__module__", boxStrConstant("thread"));
thread_lock_cls->freeze();
BoxedClass* ThreadError
= new BoxedHeapClass(Exception, NULL, Exception->attrs_offset, Exception->tp_basicsize, false);
ThreadError->giveAttr("__name__", boxStrConstant("error"));
ThreadError->giveAttr("__module__", boxStrConstant("thread"));
ThreadError->freeze();
thread_module->giveAttr("error", ThreadError);
}
}
......@@ -25,7 +25,10 @@ static Box* memberGet(BoxedMemberDescriptor* self, Box* inst, Box* owner) {
return self;
if (self->type == BoxedMemberDescriptor::OBJECT) {
return *(Box**)(((char*)inst) + self->offset);
Box* rtn = *(Box**)(((char*)inst) + self->offset);
if (!rtn)
rtn = None;
return rtn;
}
Py_FatalError("unimplemented");
......@@ -83,6 +86,43 @@ static Box* propertySet(Box* self, Box* obj, Box* val) {
return None;
}
static Box* propertyDel(Box* self, Box* obj) {
return propertySet(self, obj, NULL);
}
static Box* property_copy(BoxedProperty* old, Box* get, Box* set, Box* del) {
// In CPython, I think this can take a subclass of property, and will call the subclass's
// constructor... for now just enforce that it's a property object and inline the constructor:
RELEASE_ASSERT(old->cls == property_cls, "");
if (!get)
get = old->prop_get;
if (!set)
set = old->prop_set;
if (!del)
del = old->prop_del;
return new BoxedProperty(get, set, del, old->prop_doc);
}
static Box* propertyGetter(Box* self, Box* obj) {
RELEASE_ASSERT(self->cls == property_cls, "");
BoxedProperty* prop = static_cast<BoxedProperty*>(self);
return property_copy(prop, obj, NULL, NULL);
}
static Box* propertySetter(Box* self, Box* obj) {
RELEASE_ASSERT(self->cls == property_cls, "");
BoxedProperty* prop = static_cast<BoxedProperty*>(self);
return property_copy(prop, NULL, obj, NULL);
}
static Box* propertyDeleter(Box* self, Box* obj) {
RELEASE_ASSERT(self->cls == property_cls, "");
BoxedProperty* prop = static_cast<BoxedProperty*>(self);
return property_copy(prop, NULL, NULL, obj);
}
static Box* staticmethodInit(Box* _self, Box* f) {
RELEASE_ASSERT(_self->cls == staticmethod_cls, "");
BoxedStaticmethod* self = static_cast<BoxedStaticmethod*>(_self);
......@@ -135,11 +175,13 @@ void setupDescr() {
property_cls->giveAttr("__name__", boxStrConstant("property"));
property_cls->giveAttr(
"__init__",
new BoxedFunction(boxRTFunction((void*)propertyInit, UNKNOWN, 5, 4, false, false), { None, None, None, None }));
property_cls->giveAttr("__get__",
new BoxedFunction(boxRTFunction((void*)propertyGet, UNKNOWN, 3, 0, false, false)));
property_cls->giveAttr("__set__",
new BoxedFunction(boxRTFunction((void*)propertySet, UNKNOWN, 3, 0, false, false)));
new BoxedFunction(boxRTFunction((void*)propertyInit, UNKNOWN, 5, 4, false, false), { NULL, NULL, NULL, NULL }));
property_cls->giveAttr("__get__", new BoxedFunction(boxRTFunction((void*)propertyGet, UNKNOWN, 3)));
property_cls->giveAttr("__set__", new BoxedFunction(boxRTFunction((void*)propertySet, UNKNOWN, 3)));
property_cls->giveAttr("__delete__", new BoxedFunction(boxRTFunction((void*)propertyDel, UNKNOWN, 2)));
property_cls->giveAttr("getter", new BoxedFunction(boxRTFunction((void*)propertyGetter, UNKNOWN, 2)));
property_cls->giveAttr("setter", new BoxedFunction(boxRTFunction((void*)propertySetter, UNKNOWN, 2)));
property_cls->giveAttr("deleter", new BoxedFunction(boxRTFunction((void*)propertyDeleter, UNKNOWN, 2)));
property_cls->giveAttr("fget",
new BoxedMemberDescriptor(BoxedMemberDescriptor::OBJECT, offsetof(BoxedProperty, prop_get)));
property_cls->giveAttr("fset",
......
......@@ -1455,6 +1455,16 @@ extern "C" Box* getattr(Box* obj, const char* attr) {
static StatCounter slowpath_getattr("slowpath_getattr");
slowpath_getattr.log();
bool is_dunder = (attr[0] == '_' && attr[1] == '_');
if (is_dunder) {
if (strcmp(attr, "__dict__") == 0) {
// TODO this is wrong, should be added at the class level as a getset
if (obj->cls->instancesHaveHCAttrs())
return makeAttrWrapper(obj);
}
}
if (VERBOSITY() >= 2) {
#if !DISABLE_STATS
std::string per_name_stat_name = "getattr__" + std::string(attr);
......@@ -1500,13 +1510,7 @@ extern "C" Box* getattr(Box* obj, const char* attr) {
return val;
}
if (attr[0] == '_' && attr[1] == '_') {
if (strcmp(attr, "__dict__") == 0) {
// TODO this is wrong, should be added at the class level as a getset
if (obj->cls->instancesHaveHCAttrs())
return makeAttrWrapper(obj);
}
if (is_dunder) {
// There's more to it than this:
if (strcmp(attr, "__class__") == 0) {
assert(obj->cls != instance_cls); // I think in this case __class__ is supposed to be the classobj?
......
......@@ -229,37 +229,45 @@ void raise0() {
raiseRaw(*exc_info);
}
#ifndef NDEBUG
ExcInfo::ExcInfo(Box* type, Box* value, Box* traceback) : type(type), value(value), traceback(traceback) {
if (this->type && this->type != None)
RELEASE_ASSERT(isSubclass(this->type->cls, type_cls), "throwing old-style objects not supported yet (%s)",
getTypeName(this->type)->c_str());
}
#endif
bool ExcInfo::matches(BoxedClass* cls) const {
RELEASE_ASSERT(isSubclass(this->type->cls, type_cls), "throwing old-style objects not supported yet");
assert(this->type);
RELEASE_ASSERT(isSubclass(this->type->cls, type_cls), "throwing old-style objects not supported yet (%s)",
getTypeName(this->type)->c_str());
return isSubclass(static_cast<BoxedClass*>(this->type), cls);
}
void raise3(Box* arg0, Box* arg1, Box* arg2) {
RELEASE_ASSERT(arg2 == None, "unsupported");
// TODO switch this to PyErr_Normalize
if (isSubclass(arg0->cls, type_cls)) {
BoxedClass* c = static_cast<BoxedClass*>(arg0);
if (isSubclass(c, Exception)) {
if (isSubclass(c, BaseException)) {
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());
raiseRaw(ExcInfo(c, exc_obj, arg2));
}
}
if (arg1 != None)
raiseExcHelper(TypeError, "instance exception may not have a separate value");
if (isSubclass(arg0->cls, BaseException)) {
if (arg1 != None)
raiseExcHelper(TypeError, "instance exception may not have a separate value");
raiseRaw(ExcInfo(arg0->cls, arg0, arg2));
}
// TODO: should only allow throwing of old-style classes or things derived
// from BaseException:
raiseExc(arg0);
raiseExcHelper(TypeError, "exceptions must be old-style classes or derived from BaseException, not %s",
getTypeName(arg0)->c_str());
}
void raiseExcHelper(BoxedClass* cls, const char* msg, ...) {
......
......@@ -899,6 +899,14 @@ public:
}
return rtn;
}
static Box* len(Box* _self) {
RELEASE_ASSERT(_self->cls == attrwrapper_cls, "");
AttrWrapper* self = static_cast<AttrWrapper*>(_self);
HCAttrs* attrs = self->b->getHCAttrsPtr();
return boxInt(attrs->hcls->attr_offsets.size());
}
};
Box* makeAttrWrapper(Box* b) {
......@@ -1141,6 +1149,7 @@ void setupRuntime() {
attrwrapper_cls->giveAttr("keys", new BoxedFunction(boxRTFunction((void*)AttrWrapper::keys, LIST, 1)));
attrwrapper_cls->giveAttr("values", new BoxedFunction(boxRTFunction((void*)AttrWrapper::values, LIST, 1)));
attrwrapper_cls->giveAttr("items", new BoxedFunction(boxRTFunction((void*)AttrWrapper::items, LIST, 1)));
attrwrapper_cls->giveAttr("__len__", new BoxedFunction(boxRTFunction((void*)AttrWrapper::len, BOXED_INT, 1)));
attrwrapper_cls->freeze();
// sys is the first module that needs to be set up, due to modules
......
# expected: fail
# - working on it
import sys
def compact(s):
......@@ -13,7 +10,7 @@ def compact(s):
return s
# TODO This should be a subclass of Exception not object:
class NotPossible(object):
class NotPossible(Exception):
pass
P = 1000000007
......
# Regression test: __dict__ should be accessible from __getattr__
class C(object):
def __getattr__(self, attr):
print len(self.__dict__)
return 5
print C().a
# fail-if: '-x' in EXTRA_JIT_ARGS
# I think pypa has an issue parsing decorator expressions if they aren't simple names
# https://github.com/vinzenz/libpypa/issues/15
class C(object):
def fget(self):
return 5
......@@ -13,3 +17,50 @@ print C.x.__get__(c, C)
print type(C.x.__get__(None, C))
c.x = 7
print c.x
class C2(object):
@property
def x(self):
print "x1"
return 2
x1 = x
@x.setter
def x(self, value):
print "x2"
return 3
x2 = x
@x.deleter
def x(self):
print "x3"
c = C2()
print "These should all succeed:"
print c.x1
print c.x2
print c.x
try:
# This will fail since x1 is a copy that didn't have the setter set:
c.x1 = 1
except AttributeError, e:
print e
c.x2 = 1
c.x = 1
try:
# This will fail since x1 is a copy that didn't have the deleter set:
del c.x1
except AttributeError, e:
print e
try:
# This will fail since x1 is a copy that didn't have the deleter set:
del c.x2
except AttributeError, e:
print e
c.x = 1
from thread import start_new_thread
from thread import start_new_thread, allocate_lock
import time
print type(allocate_lock())
done = 0
def run(arg):
global done
......
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