From 6b25aae3f71a221a4924e0b92402bc5e7b40cce1 Mon Sep 17 00:00:00 2001 From: blueloveTH Date: Thu, 4 May 2023 16:38:33 +0800 Subject: [PATCH] ... --- src/ceval.h | 5 ++++- src/main.cpp | 2 +- src/pocketpy.h | 16 +++++----------- src/repl.h | 8 ++++---- src/vm.h | 37 +++++++++++-------------------------- 5 files changed, 25 insertions(+), 43 deletions(-) diff --git a/src/ceval.h b/src/ceval.h index 7b1d08e0..bd91df6d 100644 --- a/src/ceval.h +++ b/src/ceval.h @@ -67,7 +67,10 @@ __NEXT_STEP:; TARGET(DUP_TOP) PUSH(TOP()); DISPATCH(); TARGET(ROT_TWO) std::swap(TOP(), SECOND()); DISPATCH(); TARGET(PRINT_EXPR) - if(TOP() != None) *_stdout << CAST(Str&, asRepr(TOP())) << '\n'; + if(TOP() != None){ + _stdout(this, CAST(Str&, asRepr(TOP()))); + _stdout(this, "\n"); + } POP(); DISPATCH(); /*****************************************/ diff --git a/src/main.cpp b/src/main.cpp index 282d4522..891008b5 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -14,7 +14,7 @@ int main(int argc, char** argv){ pkpy::REPL* repl = pkpy_new_repl(vm); bool need_more_lines = false; while(true){ - (*vm->_stdout) << (need_more_lines ? "... " : ">>> "); + vm->_stdout(vm, need_more_lines ? "... " : ">>> "); bool eof = false; std::string line = pkpy::getline(&eof); if(eof) break; diff --git a/src/pocketpy.h b/src/pocketpy.h index a8a9b5ab..70c0451e 100644 --- a/src/pocketpy.h +++ b/src/pocketpy.h @@ -770,12 +770,12 @@ inline void add_module_sys(VM* vm){ vm->setattr(mod, "stderr", stderr_); vm->bind_func<1>(stdout_, "write", [](VM* vm, ArgsView args) { - (*vm->_stdout) << CAST(Str&, args[0]).sv(); + vm->_stdout(vm, CAST(Str&, args[0])); return vm->None; }); vm->bind_func<1>(stderr_, "write", [](VM* vm, ArgsView args) { - (*vm->_stderr) << CAST(Str&, args[0]).sv(); + vm->_stderr(vm, CAST(Str&, args[0])); return vm->None; }); } @@ -828,7 +828,7 @@ inline void add_module_dis(VM* vm){ PyObject* f = args[0]; if(is_type(f, vm->tp_bound_method)) f = CAST(BoundMethod, args[0]).func; CodeObject_ code = CAST(Function&, f).decl->code; - (*vm->_stdout) << vm->disassemble(code); + vm->_stdout(vm, vm->disassemble(code)); return vm->None; }); } @@ -1105,15 +1105,9 @@ extern "C" { } __EXPORT - pkpy::VM* pkpy_new_vm(bool use_stdio=true, bool enable_os=true){ - pkpy::VM* p = new pkpy::VM(use_stdio, enable_os); + pkpy::VM* pkpy_new_vm(bool enable_os=true){ + pkpy::VM* p = new pkpy::VM(enable_os); _pk_deleter_map[p] = [](void* p){ delete (pkpy::VM*)p; }; return p; } - - __EXPORT - char* pkpy_vm_read_output(pkpy::VM* vm){ - std::string json = vm->read_output(); - return strdup(json.c_str()); - } } \ No newline at end of file diff --git a/src/repl.h b/src/repl.h index f766257a..3932755f 100644 --- a/src/repl.h +++ b/src/repl.h @@ -49,10 +49,10 @@ protected: VM* vm; public: REPL(VM* vm) : vm(vm){ - (*vm->_stdout) << ("pocketpy " PK_VERSION " (" __DATE__ ", " __TIME__ ") "); - (*vm->_stdout) << "[" << std::to_string(sizeof(void*) * 8) << " bit]" "\n"; - (*vm->_stdout) << ("https://github.com/blueloveTH/pocketpy" "\n"); - (*vm->_stdout) << ("Type \"exit()\" to exit." "\n"); + vm->_stdout(vm, "pocketpy " PK_VERSION " (" __DATE__ ", " __TIME__ ") "); + vm->_stdout(vm, fmt("[", sizeof(void*)*8, " bit]" "\n")); + vm->_stdout(vm, "https://github.com/blueloveTH/pocketpy" "\n"); + vm->_stdout(vm, "Type \"exit()\" to exit." "\n"); } bool input(std::string line){ diff --git a/src/vm.h b/src/vm.h index 1bac852e..ead7b57b 100644 --- a/src/vm.h +++ b/src/vm.h @@ -73,6 +73,8 @@ struct FrameId{ Frame* operator->() const { return &data->operator[](index); } }; +typedef void(*PrintFunc)(VM*, const Str&); + class VM { VM* vm; // self reference for simplify code public: @@ -93,10 +95,8 @@ public: PyObject* StopIteration; PyObject* _main; // __main__ module - std::stringstream _stdout_buffer; - std::stringstream _stderr_buffer; - std::ostream* _stdout; - std::ostream* _stderr; + PrintFunc _stdout; + PrintFunc _stderr; bool _initialized; @@ -109,31 +109,16 @@ public: const bool enable_os; - VM(bool use_stdio=true, bool enable_os=true) : heap(this), enable_os(enable_os) { + VM(bool enable_os=true) : heap(this), enable_os(enable_os) { this->vm = this; - this->_stdout = use_stdio ? &std::cout : &_stdout_buffer; - this->_stderr = use_stdio ? &std::cerr : &_stderr_buffer; + _stdout = [](VM* vm, const Str& s) { std::cout << s; }; + _stderr = [](VM* vm, const Str& s) { std::cerr << s; }; callstack.reserve(8); _initialized = false; init_builtin_types(); _initialized = true; } - bool is_stdio_used() const { return _stdout == &std::cout; } - - std::string read_output(){ - if(is_stdio_used()) UNREACHABLE(); - std::stringstream* s_out = (std::stringstream*)(vm->_stdout); - std::stringstream* s_err = (std::stringstream*)(vm->_stderr); - pkpy::Str _stdout = s_out->str(); - pkpy::Str _stderr = s_err->str(); - std::stringstream ss; - ss << '{' << "\"stdout\": " << _stdout.escape(false); - ss << ", " << "\"stderr\": " << _stderr.escape(false) << '}'; - s_out->str(""); s_err->str(""); - return ss.str(); - } - FrameId top_frame() { #if DEBUG_EXTRA_CHECK if(callstack.empty()) FATAL_ERROR(); @@ -195,13 +180,13 @@ public: #endif return _exec(code, _module); }catch (const Exception& e){ - *_stderr << e.summary() << '\n'; - + _stderr(this, e.summary() + "\n"); } #if !DEBUG_FULL_EXCEPTION catch (const std::exception& e) { - *_stderr << "An std::exception occurred! It could be a bug.\n"; - *_stderr << e.what() << '\n'; + _stderr(this, "An std::exception occurred! It could be a bug.\n"); + _stderr(this, e.what()); + _stderr(this, "\n"); } #endif callstack.clear();