This commit is contained in:
blueloveTH 2024-06-01 19:32:19 +08:00
parent fc84e657e3
commit 8ef573a800
10 changed files with 40 additions and 22 deletions

View File

@ -1,6 +1,6 @@
--- ---
icon: log icon: log
title: 'Upgrade to v1.5.0' title: 'Upgrade to v2.0.0'
order: 25 order: 25
--- ---
@ -207,7 +207,7 @@ Enabling the profiler has a performance overhead. Only enable it when you need i
+ `vm->is_non_tagged_type` was removed. Use `vm->is_type` instead. + `vm->is_non_tagged_type` was removed. Use `vm->is_type` instead.
+ `vm->check_non_tagged_type` was removed. Use `vm->check_type` instead. + `vm->check_non_tagged_type` was removed. Use `vm->check_type` instead.
## Python Stringify functions ## Python stringify functions
The following functions now return `Str` object instead of `PyVar`: The following functions now return `Str` object instead of `PyVar`:
@ -216,3 +216,7 @@ The following functions now return `Str` object instead of `PyVar`:
+ `vm->py_json` + `vm->py_json`
Also, `vm->bind__str__` and `vm->bind__repr__` were changed to return `Str` object. Also, `vm->bind__str__` and `vm->bind__repr__` were changed to return `Str` object.
## Catching exceptions
Now you need to catch `TopLevelException` instead of `Exception`.

View File

@ -49,7 +49,7 @@ Execute a compiled code object
```cpp ```cpp
try{ try{
vm->_exec(co); // may throw vm->_exec(co); // may throw
}catch(Exception& e){ }catch(TopLevelException e){
std::cerr << e.summary() << std::endl; std::cerr << e.summary() << std::endl;
} }
``` ```

View File

@ -52,7 +52,7 @@ These two methods are provided for this purpose:
try{ try{
CodeObject_ code = vm->compile("a[0]", "main.py", EXEC_MODE, false); CodeObject_ code = vm->compile("a[0]", "main.py", EXEC_MODE, false);
vm->_exec(code, vm->_main); vm->_exec(code, vm->_main);
}catch(Exception& e){ }catch(TopLevelException e){
// use e.summary() to get a summary of the exception // use e.summary() to get a summary of the exception
std::cerr << e.summary() << std::endl; std::cerr << e.summary() << std::endl;
} }

View File

@ -88,4 +88,17 @@ struct Exception {
Str summary() const; Str summary() const;
}; };
struct TopLevelException: std::exception{
Exception* ptr;
TopLevelException(Exception* ptr): ptr(ptr) {}
PyObject* self() const { return ptr->self(); }
Str summary() const { return ptr->summary(); }
const char* what() const noexcept override {
static Str cached_summary(summary());
return cached_summary.c_str();
}
};
} // namespace pkpy } // namespace pkpy

View File

@ -1,5 +1,4 @@
#include "pocketpy/ceval.h" #include "pocketpy/ceval.h"
#include "pocketpy/codeobject.h"
namespace pkpy{ namespace pkpy{
@ -1052,15 +1051,16 @@ __NEXT_STEP:
}catch(InternalException internal){ }catch(InternalException internal){
__internal_exception = internal; __internal_exception = internal;
if(internal.type == InternalExceptionType::Unhandled){ if(internal.type == InternalExceptionType::Unhandled){
PyVar e_obj = POPX(); __last_exception = POPX().get();
Exception& _e = PK_OBJ_GET(Exception, e_obj); Exception& _e = __last_exception->as<Exception>();
bool is_base_frame_to_be_popped = frame == base_frame; bool is_base_frame_to_be_popped = frame == base_frame;
__pop_frame(); __pop_frame();
if(callstack.empty()){ if(callstack.empty()){
throw std::move(_e); // propagate to the top level // propagate to the top level
throw TopLevelException(&_e);
} }
frame = &callstack.top(); frame = &callstack.top();
PUSH(e_obj); PUSH(__last_exception);
if(is_base_frame_to_be_popped){ if(is_base_frame_to_be_popped){
throw InternalException(InternalExceptionType::ToBeRaised); throw InternalException(InternalExceptionType::ToBeRaised);
} }

View File

@ -1376,10 +1376,10 @@ __EAT_DOTS_END:
// TODO: refactor this // TODO: refactor this
void Lexer::throw_err(StrName type, Str msg, int lineno, const char* cursor){ void Lexer::throw_err(StrName type, Str msg, int lineno, const char* cursor){
PyVar e_obj = vm->call(vm->builtins->attr(type), VAR(msg)); vm->__last_exception = vm->call(vm->builtins->attr(type), VAR(msg)).get();
Exception& e = PK_OBJ_GET(Exception, e_obj); Exception& e = vm->__last_exception->as<Exception>();
e.st_push(src, lineno, cursor, ""); e.st_push(src, lineno, cursor, "");
throw std::move(e); throw TopLevelException(&e);
} }
std::string_view TokenDeserializer::read_string(char c){ std::string_view TokenDeserializer::read_string(char c){

View File

@ -199,14 +199,14 @@ void add_module_traceback(VM* vm){
PyObject* mod = vm->new_module("traceback"); PyObject* mod = vm->new_module("traceback");
vm->bind_func(mod, "print_exc", 0, [](VM* vm, ArgsView args) { vm->bind_func(mod, "print_exc", 0, [](VM* vm, ArgsView args) {
if(vm->__last_exception == nullptr) vm->ValueError("no exception"); if(vm->__last_exception == nullptr) vm->ValueError("no exception");
Exception& e = _CAST(Exception&, vm->__last_exception); Exception& e = vm->__last_exception->as<Exception>();
vm->stdout_write(e.summary()); vm->stdout_write(e.summary());
return vm->None; return vm->None;
}); });
vm->bind_func(mod, "format_exc", 0, [](VM* vm, ArgsView args) { vm->bind_func(mod, "format_exc", 0, [](VM* vm, ArgsView args) {
if(vm->__last_exception == nullptr) vm->ValueError("no exception"); if(vm->__last_exception == nullptr) vm->ValueError("no exception");
Exception& e = _CAST(Exception&, vm->__last_exception); Exception& e = vm->__last_exception->as<Exception>();
return VAR(e.summary()); return VAR(e.summary());
}); });
} }

View File

@ -1649,7 +1649,7 @@ void VM::__post_init_builtin_types(){
this->_exec(code, this->builtins); this->_exec(code, this->builtins);
code = compile(kPythonLibs__set, "<set>", EXEC_MODE); code = compile(kPythonLibs__set, "<set>", EXEC_MODE);
this->_exec(code, this->builtins); this->_exec(code, this->builtins);
}catch(const Exception& e){ }catch(TopLevelException e){
std::cerr << e.summary() << std::endl; std::cerr << e.summary() << std::endl;
std::cerr << "failed to load builtins module!!" << std::endl; std::cerr << "failed to load builtins module!!" << std::endl;
exit(1); exit(1);
@ -1679,7 +1679,7 @@ CodeObject_ VM::compile(std::string_view source, const Str& filename, CompileMod
Compiler compiler(this, source, filename, mode, unknown_global_scope); Compiler compiler(this, source, filename, mode, unknown_global_scope);
try{ try{
return compiler.compile(); return compiler.compile();
}catch(const Exception& e){ }catch(TopLevelException e){
_error(e.self()); _error(e.self());
return nullptr; return nullptr;
} }
@ -1689,7 +1689,7 @@ Str VM::precompile(std::string_view source, const Str& filename, CompileMode mod
Compiler compiler(this, source, filename, mode, false); Compiler compiler(this, source, filename, mode, false);
try{ try{
return compiler.precompile(); return compiler.precompile();
}catch(const Exception& e){ }catch(TopLevelException e){
_error(e.self()); _error(e.self());
return nullptr; return nullptr;
} }

View File

@ -44,7 +44,7 @@ static PyVar stack_item(VM* vm, int index){
#define PK_PROTECTED(__B) \ #define PK_PROTECTED(__B) \
try{ __B } \ try{ __B } \
catch(const Exception& e ) { \ catch(TopLevelException e) { \
vm->__c.error = e.self(); \ vm->__c.error = e.self(); \
return false; \ return false; \
} catch(const std::exception& re){ \ } catch(const std::exception& re){ \

View File

@ -1383,7 +1383,7 @@ PyObject* VM::bind(PyObject* obj, const char* sig, const char* docstring, Native
try{ try{
// fn(a, b, *c, d=1) -> None // fn(a, b, *c, d=1) -> None
co = compile(_S("def ", sig, " : pass"), "<bind>", EXEC_MODE); co = compile(_S("def ", sig, " : pass"), "<bind>", EXEC_MODE);
}catch(const Exception&){ }catch(TopLevelException){
throw std::runtime_error("invalid signature: " + std::string(sig)); throw std::runtime_error("invalid signature: " + std::string(sig));
} }
if(co->func_decls.size() != 1){ if(co->func_decls.size() != 1){
@ -1442,7 +1442,8 @@ void VM::_error(PyVar e_obj){
Exception& e = PK_OBJ_GET(Exception, e_obj); Exception& e = PK_OBJ_GET(Exception, e_obj);
if(callstack.empty()){ if(callstack.empty()){
e.is_re = false; e.is_re = false;
throw std::move(e); __last_exception = e_obj.get();
throw TopLevelException(&e);
} }
PUSH(e_obj); PUSH(e_obj);
__raise_exc(); __raise_exc();