Commit 56f6fbea authored by Kevin Modzelewski's avatar Kevin Modzelewski

Merge branch 'merge'

parents da9f8db9 0d932768
...@@ -135,6 +135,7 @@ link_directories(${CMAKE_BINARY_DIR}/libunwind/lib) ...@@ -135,6 +135,7 @@ link_directories(${CMAKE_BINARY_DIR}/libunwind/lib)
link_directories(${LLVM_LIBRARY_DIRS}) link_directories(${LLVM_LIBRARY_DIRS})
add_subdirectory(lib_python) add_subdirectory(lib_python)
add_subdirectory(lib_pyston)
add_subdirectory(src) add_subdirectory(src)
add_subdirectory(test/test_extension) add_subdirectory(test/test_extension)
add_subdirectory(test/unittests) add_subdirectory(test/unittests)
......
...@@ -749,10 +749,10 @@ $(call link,_release,$(OPT_OBJS),$(LDFLAGS_RELEASE),$(LLVM_RELEASE_DEPS)) ...@@ -749,10 +749,10 @@ $(call link,_release,$(OPT_OBJS),$(LDFLAGS_RELEASE),$(LLVM_RELEASE_DEPS))
else else
.PHONY: pyston_dbg pyston_release .PHONY: pyston_dbg pyston_release
pyston_dbg: pyston_dbg:
$(NINJA) -C $(HOME)/pyston-build-dbg pyston $(NINJAFLAGS) $(NINJA) -C $(HOME)/pyston-build-dbg pyston copy_stdlib copy_libpyston $(NINJAFLAGS)
ln -sf $(HOME)/pyston-build-dbg/pyston pyston_dbg ln -sf $(HOME)/pyston-build-dbg/pyston pyston_dbg
pyston_release: pyston_release:
$(NINJA) -C $(HOME)/pyston-build-release pyston $(NINJAFLAGS) $(NINJA) -C $(HOME)/pyston-build-release pyston copy_stdlib copy_libpyston $(NINJAFLAGS)
ln -sf $(HOME)/pyston-build-release/pyston pyston_release ln -sf $(HOME)/pyston-build-release/pyston pyston_release
endif endif
......
# Copy any changed lib_pyston sources:
file(GLOB_RECURSE LIBPYSTON_SRCS . "*.py")
SET(LIBPYSTON_TARGETS "")
foreach(STDLIB_FILE ${LIBPYSTON_SRCS})
file(RELATIVE_PATH FN_REL ${CMAKE_SOURCE_DIR} ${STDLIB_FILE})
set(TARGET ${CMAKE_BINARY_DIR}/${FN_REL})
add_custom_command(OUTPUT ${TARGET} COMMAND
${CMAKE_COMMAND} -E copy_if_different ${STDLIB_FILE} ${TARGET}
DEPENDS ${STDLIB_FILE}
COMMENT "Copying ${FN_REL}"
)
set(LIBPYSTON_TARGETS ${LIBPYSTON_TARGETS} ${TARGET})
endforeach(STDLIB_FILE)
add_custom_target(copy_libpyston ALL DEPENDS ${LIBPYSTON_TARGETS})
# TODO: we will have to figure out a better way of generating this file
build_time_vars = {}
# Copy any changed stdlib files to the destination:
file(GLOB_RECURSE STDLIB_SRCS 2.7/ "*.py")
SET(STDLIB_TARGETS "")
foreach(STDLIB_FILE ${STDLIB_SRCS})
file(RELATIVE_PATH FN_REL ${CMAKE_SOURCE_DIR} ${STDLIB_FILE})
set(TARGET ${CMAKE_BINARY_DIR}/${FN_REL})
add_custom_command(OUTPUT ${TARGET} COMMAND
${CMAKE_COMMAND} -E copy_if_different ${STDLIB_FILE} ${TARGET}
DEPENDS ${STDLIB_FILE}
COMMENT "Copying ${FN_REL}"
)
set(STDLIB_TARGETS ${STDLIB_TARGETS} ${TARGET})
endforeach(STDLIB_FILE)
add_custom_target(copy_stdlib ALL DEPENDS ${STDLIB_TARGETS})
# compile specified files in lib_python/2.7_Modules # compile specified files in lib_python/2.7_Modules
file(GLOB_RECURSE STDMODULE_SRCS 2.7_Modules 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) file(GLOB_RECURSE STDMODULE_SRCS 2.7_Modules 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)
......
...@@ -123,6 +123,12 @@ int main(int argc, char** argv) { ...@@ -123,6 +123,12 @@ int main(int argc, char** argv) {
llvm::sys::path::append(stdlib_dir, "2.7"); llvm::sys::path::append(stdlib_dir, "2.7");
appendToSysPath(stdlib_dir.c_str()); appendToSysPath(stdlib_dir.c_str());
// go from ./lib_python/2.7 to ./lib_pyston
llvm::sys::path::remove_filename(stdlib_dir);
llvm::sys::path::remove_filename(stdlib_dir);
llvm::sys::path::append(stdlib_dir, "lib_pyston");
appendToSysPath(stdlib_dir.c_str());
// end of argument parsing // end of argument parsing
_t.split("to run"); _t.split("to run");
......
...@@ -84,18 +84,23 @@ void prependToSysPath(const std::string& path) { ...@@ -84,18 +84,23 @@ void prependToSysPath(const std::string& path) {
static BoxedClass* sys_flags_cls; static BoxedClass* sys_flags_cls;
class BoxedSysFlags : public Box { class BoxedSysFlags : public Box {
public: public:
Box* division_warning, *bytes_warning; Box* division_warning, *bytes_warning, *no_user_site;
BoxedSysFlags() : Box(sys_flags_cls) { BoxedSysFlags() : Box(sys_flags_cls) {
auto zero = boxInt(0); auto zero = boxInt(0);
division_warning = zero; division_warning = zero;
bytes_warning = zero; bytes_warning = zero;
no_user_site = zero;
} }
static void gcHandler(GCVisitor* v, Box* b) { static void gcHandler(GCVisitor* v, Box* _b) {
assert(b->cls == sys_flags_cls); assert(_b->cls == sys_flags_cls);
boxGCHandler(v, _b);
boxGCHandler(v, b); BoxedSysFlags* self = static_cast<BoxedSysFlags*>(_b);
v->visit(self->division_warning);
v->visit(self->bytes_warning);
v->visit(self->no_user_site);
} }
static Box* __new__(Box* cls, Box* args, Box* kwargs) { static Box* __new__(Box* cls, Box* args, Box* kwargs) {
...@@ -164,6 +169,7 @@ void setupSys() { ...@@ -164,6 +169,7 @@ void setupSys() {
new BoxedMemberDescriptor(BoxedMemberDescriptor::OBJECT, offsetof(BoxedSysFlags, name))) new BoxedMemberDescriptor(BoxedMemberDescriptor::OBJECT, offsetof(BoxedSysFlags, name)))
ADD(division_warning); ADD(division_warning);
ADD(bytes_warning); ADD(bytes_warning);
ADD(no_user_site);
#undef ADD #undef ADD
sys_flags_cls->freeze(); sys_flags_cls->freeze();
......
...@@ -305,43 +305,82 @@ extern "C" Box* dictNew(Box* _cls, BoxedTuple* args, BoxedDict* kwargs) { ...@@ -305,43 +305,82 @@ extern "C" Box* dictNew(Box* _cls, BoxedTuple* args, BoxedDict* kwargs) {
return new BoxedDict(); return new BoxedDict();
} }
extern "C" Box* dictInit(BoxedDict* self, BoxedTuple* args, BoxedDict* kwargs) { void dictMerge(BoxedDict* self, Box* other) {
int args_sz = args->elts.size(); if (other->cls == dict_cls) {
int kwargs_sz = kwargs->d.size(); for (const auto& p : static_cast<BoxedDict*>(other)->d)
self->d[p.first] = p.second;
return;
}
// CPython accepts a single positional and keyword arguments, in any combination static const std::string keys_str("keys");
if (args_sz > 1) Box* keys = callattr(other, &keys_str, CallattrFlags({.cls_only = false, .null_on_nonexistent = true }),
raiseExcHelper(TypeError, "dict expected at most 1 arguments, got %d", args_sz); ArgPassSpec(0), NULL, NULL, NULL, NULL, NULL);
assert(keys);
// handle positional argument first as iterable for (Box* k : keys->pyElements()) {
if (args_sz == 1) { self->d[k] = getitem(other, k);
int idx = 0; }
}
void dictMergeFromSeq2(BoxedDict* self, Box* other) {
int idx = 0;
// raises if not iterable // raises if not iterable
for (const auto& element : args->elts[0]->pyElements()) { for (const auto& element : other->pyElements()) {
// should this check subclasses? anyway to check if something is iterable... // should this check subclasses? anyway to check if something is iterable...
if (element->cls == list_cls) { if (element->cls == list_cls) {
BoxedList* list = static_cast<BoxedList*>(element); BoxedList* list = static_cast<BoxedList*>(element);
if (list->size != 2) if (list->size != 2)
raiseExcHelper(ValueError, "dictionary update sequence element #%d has length %d; 2 is required", raiseExcHelper(ValueError, "dictionary update sequence element #%d has length %d; 2 is required", idx,
idx, list->size); list->size);
self->d[list->elts->elts[0]] = list->elts->elts[1]; self->d[list->elts->elts[0]] = list->elts->elts[1];
} else if (element->cls == tuple_cls) { } else if (element->cls == tuple_cls) {
BoxedTuple* tuple = static_cast<BoxedTuple*>(element); BoxedTuple* tuple = static_cast<BoxedTuple*>(element);
if (tuple->elts.size() != 2) if (tuple->elts.size() != 2)
raiseExcHelper(ValueError, "dictionary update sequence element #%d has length %d; 2 is required", raiseExcHelper(ValueError, "dictionary update sequence element #%d has length %d; 2 is required", idx,
idx, tuple->elts.size()); tuple->elts.size());
self->d[tuple->elts[0]] = tuple->elts[1]; self->d[tuple->elts[0]] = tuple->elts[1];
} else } else
raiseExcHelper(TypeError, "cannot convert dictionary update sequence element #%d to a sequence", idx); raiseExcHelper(TypeError, "cannot convert dictionary update sequence element #%d to a sequence", idx);
idx++;
}
}
Box* dictUpdate(BoxedDict* self, BoxedTuple* args, BoxedDict* kwargs) {
assert(args->cls == tuple_cls);
assert(kwargs);
assert(kwargs->cls == dict_cls);
idx++; RELEASE_ASSERT(args->elts.size() <= 1, ""); // should throw a TypeError
if (args->elts.size()) {
Box* arg = args->elts[0];
if (getattrInternal(arg, "keys", NULL)) {
dictMerge(self, arg);
} else {
dictMergeFromSeq2(self, arg);
} }
} }
if (kwargs->d.size())
dictMerge(self, kwargs);
return None;
}
extern "C" Box* dictInit(BoxedDict* self, BoxedTuple* args, BoxedDict* kwargs) {
int args_sz = args->elts.size();
int kwargs_sz = kwargs->d.size();
// CPython accepts a single positional and keyword arguments, in any combination
if (args_sz > 1)
raiseExcHelper(TypeError, "dict expected at most 1 arguments, got %d", args_sz);
dictUpdate(self, args, kwargs);
// handle keyword arguments by merging (possibly over positional entries per CPy) // handle keyword arguments by merging (possibly over positional entries per CPy)
assert(kwargs->cls == dict_cls); assert(kwargs->cls == dict_cls);
...@@ -396,6 +435,8 @@ void setupDict() { ...@@ -396,6 +435,8 @@ void setupDict() {
dict_cls->giveAttr("__iter__", dict_cls->giveAttr("__iter__",
new BoxedFunction(boxRTFunction((void*)dictIterKeys, typeFromClass(dict_iterator_cls), 1))); new BoxedFunction(boxRTFunction((void*)dictIterKeys, typeFromClass(dict_iterator_cls), 1)));
dict_cls->giveAttr("update", new BoxedFunction(boxRTFunction((void*)dictUpdate, NONE, 1, 0, true, true)));
dict_cls->giveAttr("clear", new BoxedFunction(boxRTFunction((void*)dictClear, NONE, 1))); dict_cls->giveAttr("clear", new BoxedFunction(boxRTFunction((void*)dictClear, NONE, 1)));
dict_cls->giveAttr("copy", new BoxedFunction(boxRTFunction((void*)dictCopy, DICT, 1))); dict_cls->giveAttr("copy", new BoxedFunction(boxRTFunction((void*)dictCopy, DICT, 1)));
......
...@@ -1841,6 +1841,10 @@ extern "C" void dump(void* p) { ...@@ -1841,6 +1841,10 @@ extern "C" void dump(void* p) {
printf("Int value: %ld\n", static_cast<BoxedInt*>(b)->n); printf("Int value: %ld\n", static_cast<BoxedInt*>(b)->n);
} }
if (isSubclass(b->cls, list_cls)) {
printf("%ld elements\n", static_cast<BoxedList*>(b)->size);
}
return; return;
} }
......
...@@ -285,6 +285,8 @@ extern "C" void typeGCHandler(GCVisitor* v, Box* b) { ...@@ -285,6 +285,8 @@ extern "C" void typeGCHandler(GCVisitor* v, Box* b) {
if (cls->base) if (cls->base)
v->visit(cls->base); v->visit(cls->base);
if (cls->tp_dict)
v->visit(cls->tp_dict);
} }
extern "C" void instancemethodGCHandler(GCVisitor* v, Box* b) { extern "C" void instancemethodGCHandler(GCVisitor* v, Box* b) {
......
...@@ -163,3 +163,34 @@ try: ...@@ -163,3 +163,34 @@ try:
assert 0 assert 0
except KeyError, e: except KeyError, e:
print 'ok' print 'ok'
d = {}
d.update({1:2, 3:4})
print sorted(d.items())
print sorted(dict(d).items())
class CustomMapping(object):
def __init__(self):
self.n = 0
def keys(self):
print "keys()"
return [1, 3, 7]
def __getitem__(self, key):
print key
self.n += 1
return self.n
print sorted(dict(CustomMapping()).items())
cm = CustomMapping()
def custom_keys():
print "custom_keys()"
return [2, 4, 2]
cm.keys = custom_keys
print sorted(dict(cm).items())
d = {}
d.update({'c':3}, a=1, b=2)
print sorted(d.items())
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