Commit e993a28b authored by Kevin Modzelewski's avatar Kevin Modzelewski

Fix the behavior of the default print destination

Ie if you override sys.stdout, prints without an explicit destination
will go to the new location.

Also sneak in a couple other bugfixes.
parent 4f9e7751
...@@ -194,6 +194,7 @@ LDFLAGS_RELEASE := $(LLVM_RELEASE_LDFLAGS) $(COMMON_LDFLAGS) ...@@ -194,6 +194,7 @@ LDFLAGS_RELEASE := $(LLVM_RELEASE_LDFLAGS) $(COMMON_LDFLAGS)
BUILD_SYSTEM_DEPS := Makefile Makefile.local $(wildcard build_system/*) BUILD_SYSTEM_DEPS := Makefile Makefile.local $(wildcard build_system/*)
CLANG_DEPS := $(CLANGPP_EXE) $(abspath $(dir $(CLANGPP_EXE))/../../built_release) CLANG_DEPS := $(CLANGPP_EXE) $(abspath $(dir $(CLANGPP_EXE))/../../built_release)
$(CLANGPP_EXE) $(CLANG_EXE): $(abspath $(dir $(CLANGPP_EXE))/../../built_release)
# settings to make clang and ccache play nicely: # settings to make clang and ccache play nicely:
CLANG_CCACHE_FLAGS := -Qunused-arguments CLANG_CCACHE_FLAGS := -Qunused-arguments
......
...@@ -70,6 +70,7 @@ public: ...@@ -70,6 +70,7 @@ public:
virtual llvm::Function* getIntrinsic(llvm::Intrinsic::ID) = 0; virtual llvm::Function* getIntrinsic(llvm::Intrinsic::ID) = 0;
virtual llvm::Value* createCall(ExcInfo exc_info, llvm::Value* callee, const std::vector<llvm::Value*>& args) = 0; virtual llvm::Value* createCall(ExcInfo exc_info, llvm::Value* callee, const std::vector<llvm::Value*>& args) = 0;
virtual llvm::Value* createCall(ExcInfo exc_info, llvm::Value* callee) = 0;
virtual llvm::Value* createCall(ExcInfo exc_info, llvm::Value* callee, llvm::Value* arg1) = 0; virtual llvm::Value* createCall(ExcInfo exc_info, llvm::Value* callee, llvm::Value* arg1) = 0;
virtual llvm::Value* createCall2(ExcInfo exc_info, llvm::Value* callee, llvm::Value* arg1, llvm::Value* arg2) = 0; virtual llvm::Value* createCall2(ExcInfo exc_info, llvm::Value* callee, llvm::Value* arg1, llvm::Value* arg2) = 0;
virtual llvm::Value* createCall3(ExcInfo exc_info, llvm::Value* callee, llvm::Value* arg1, llvm::Value* arg2, virtual llvm::Value* createCall3(ExcInfo exc_info, llvm::Value* callee, llvm::Value* arg1, llvm::Value* arg2,
......
...@@ -206,6 +206,10 @@ public: ...@@ -206,6 +206,10 @@ public:
} }
} }
llvm::Value* createCall(ExcInfo exc_info, llvm::Value* callee) override {
return createCall(exc_info, callee, std::vector<llvm::Value*>());
}
llvm::Value* createCall(ExcInfo exc_info, llvm::Value* callee, llvm::Value* arg1) override { llvm::Value* createCall(ExcInfo exc_info, llvm::Value* callee, llvm::Value* arg1) override {
return createCall(exc_info, callee, std::vector<llvm::Value*>({ arg1 })); return createCall(exc_info, callee, std::vector<llvm::Value*>({ arg1 }));
} }
...@@ -1720,8 +1724,9 @@ private: ...@@ -1720,8 +1724,9 @@ private:
dest = d->makeConverted(emitter, d->getConcreteType()); dest = d->makeConverted(emitter, d->getConcreteType());
d->decvref(emitter); d->decvref(emitter);
} else { } else {
dest = new ConcreteCompilerVariable(typeFromClass(file_cls), llvm::Value* sys_stdout_val = emitter.createCall(exc_info, g.funcs.getSysStdout);
embedConstantPtr(getSysStdout(), g.llvm_value_type_ptr), true); dest = new ConcreteCompilerVariable(UNKNOWN, sys_stdout_val, true);
// TODO: speculate that sys.stdout is a file?
} }
assert(dest); assert(dest);
......
...@@ -208,6 +208,7 @@ void initGlobalFuncs(GlobalState& g) { ...@@ -208,6 +208,7 @@ void initGlobalFuncs(GlobalState& g) {
GET(printFloat); GET(printFloat);
GET(listAppendInternal); GET(listAppendInternal);
GET(getSysStdout);
g.funcs.runtimeCall = getFunc((void*)runtimeCall, "runtimeCall"); g.funcs.runtimeCall = getFunc((void*)runtimeCall, "runtimeCall");
g.funcs.runtimeCall0 = addFunc((void*)runtimeCall, g.llvm_value_type_ptr, g.llvm_value_type_ptr, g.i32); g.funcs.runtimeCall0 = addFunc((void*)runtimeCall, g.llvm_value_type_ptr, g.llvm_value_type_ptr, g.i32);
......
...@@ -41,7 +41,7 @@ struct GlobalFuncs { ...@@ -41,7 +41,7 @@ struct GlobalFuncs {
llvm::Value* unpackIntoArray, *raiseAttributeError, *raiseAttributeErrorStr, *raiseNotIterableError, llvm::Value* unpackIntoArray, *raiseAttributeError, *raiseAttributeErrorStr, *raiseNotIterableError,
*assertNameDefined, *assertFail; *assertNameDefined, *assertFail;
llvm::Value* printFloat, *listAppendInternal; llvm::Value* printFloat, *listAppendInternal, *getSysStdout;
llvm::Value* runtimeCall0, *runtimeCall1, *runtimeCall2, *runtimeCall3, *runtimeCall, *runtimeCallN; llvm::Value* runtimeCall0, *runtimeCall1, *runtimeCall2, *runtimeCall3, *runtimeCall, *runtimeCallN;
llvm::Value* callattr0, *callattr1, *callattr2, *callattr3, *callattr, *callattrN; llvm::Value* callattr0, *callattr1, *callattr2, *callattr3, *callattr, *callattrN;
llvm::Value* reoptCompiledFunc, *compilePartialFunc; llvm::Value* reoptCompiledFunc, *compilePartialFunc;
......
...@@ -410,10 +410,10 @@ BoxedModule* getCurrentModule() { ...@@ -410,10 +410,10 @@ BoxedModule* getCurrentModule() {
} }
BoxedDict* getLocals(bool only_user_visible) { BoxedDict* getLocals(bool only_user_visible) {
BoxedDict* d = new BoxedDict();
for (PythonFrameIterator& frame_info : unwindPythonFrames()) { for (PythonFrameIterator& frame_info : unwindPythonFrames()) {
if (frame_info.getId().type == PythonFrameId::COMPILED) { if (frame_info.getId().type == PythonFrameId::COMPILED) {
BoxedDict* d = new BoxedDict();
CompiledFunction* cf = frame_info.getCF(); CompiledFunction* cf = frame_info.getCF();
uint64_t ip = frame_info.getId().ip; uint64_t ip = frame_info.getId().ip;
...@@ -464,14 +464,15 @@ BoxedDict* getLocals(bool only_user_visible) { ...@@ -464,14 +464,15 @@ BoxedDict* getLocals(bool only_user_visible) {
} }
} }
} }
return d;
} else if (frame_info.getId().type == PythonFrameId::INTERPRETED) { } else if (frame_info.getId().type == PythonFrameId::INTERPRETED) {
return localsForInterpretedFrame((void*)frame_info.getId().bp, only_user_visible); return localsForInterpretedFrame((void*)frame_info.getId().bp, only_user_visible);
} else { } else {
abort(); abort();
} }
} }
RELEASE_ASSERT(0, "Internal error: unable to find any python frames");
return d;
} }
......
...@@ -101,6 +101,7 @@ void force() { ...@@ -101,6 +101,7 @@ void force() {
FORCE(printFloat); FORCE(printFloat);
FORCE(listAppendInternal); FORCE(listAppendInternal);
FORCE(getSysStdout);
FORCE(runtimeCall); FORCE(runtimeCall);
FORCE(callattr); FORCE(callattr);
......
...@@ -1860,6 +1860,10 @@ extern "C" void dump(void* p) { ...@@ -1860,6 +1860,10 @@ extern "C" void dump(void* p) {
printf("%ld elements\n", static_cast<BoxedTuple*>(b)->elts.size()); printf("%ld elements\n", static_cast<BoxedTuple*>(b)->elts.size());
} }
if (isSubclass(b->cls, int_cls)) {
printf("Int value: %ld\n", static_cast<BoxedInt*>(b)->n);
}
return; return;
} }
......
...@@ -75,7 +75,7 @@ void setupSysEnd(); ...@@ -75,7 +75,7 @@ void setupSysEnd();
BoxedDict* getSysModulesDict(); BoxedDict* getSysModulesDict();
BoxedList* getSysPath(); BoxedList* getSysPath();
Box* getSysStdout(); extern "C" Box* getSysStdout();
extern "C" { extern "C" {
extern BoxedClass* object_cls, *type_cls, *bool_cls, *int_cls, *long_cls, *float_cls, *str_cls, *function_cls, extern BoxedClass* object_cls, *type_cls, *bool_cls, *int_cls, *long_cls, *float_cls, *str_cls, *function_cls,
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
# but calling an attribute is such a common case that we special case it as a callattr(), # but calling an attribute is such a common case that we special case it as a callattr(),
# which avoids the allocation/immediate deallocation of the instancemethod object. # which avoids the allocation/immediate deallocation of the instancemethod object.
# statcheck: noninit_count('num_instancemethods') <= 10 # statcheck: noninit_count('num_instancemethods') <= 10
# statcheck: stats['slowpath_callattr'] <= 20 # statcheck: noninit_count('slowpath_callattr') <= 100
class C(object): class C(object):
def foo(self, a0, a1, a2, a3, a4, a5, a6, a7): def foo(self, a0, a1, a2, a3, a4, a5, a6, a7):
print "foo", a0, a1, a2, a3, a4, a5, a6, a7 print "foo", a0, a1, a2, a3, a4, a5, a6, a7
......
# expected: fail
# prints without an explicit destination should go to sys.stdout, not to the real stdout, # prints without an explicit destination should go to sys.stdout, not to the real stdout,
# in case sys.stdout gets changed: # in case sys.stdout gets changed:
......
...@@ -252,6 +252,12 @@ def run_test(fn, check_stats, run_memcheck): ...@@ -252,6 +252,12 @@ def run_test(fn, check_stats, run_memcheck):
if m: if m:
statname = m.group(1) statname = m.group(1)
raise Exception((l, statname, stats[statname])) raise Exception((l, statname, stats[statname]))
m = re.match("""noninit_count\(['"]([\w_]+)['"]\)""", l)
if m:
statname = m.group(1)
raise Exception((l, statname, noninit_count(statname)))
raise Exception((l, stats)) raise Exception((l, stats))
else: else:
# only can get here if all statchecks passed # only can get here if all statchecks passed
......
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