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
title: 'Upgrade to v1.5.0'
title: 'Upgrade to v2.0.0'
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->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`:
@ -216,3 +216,7 @@ The following functions now return `Str` object instead of `PyVar`:
+ `vm->py_json`
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
try{
vm->_exec(co); // may throw
}catch(Exception& e){
}catch(TopLevelException e){
std::cerr << e.summary() << std::endl;
}
```

View File

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

View File

@ -88,4 +88,17 @@ struct Exception {
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

View File

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

View File

@ -1376,10 +1376,10 @@ __EAT_DOTS_END:
// TODO: refactor this
void Lexer::throw_err(StrName type, Str msg, int lineno, const char* cursor){
PyVar e_obj = vm->call(vm->builtins->attr(type), VAR(msg));
Exception& e = PK_OBJ_GET(Exception, e_obj);
vm->__last_exception = vm->call(vm->builtins->attr(type), VAR(msg)).get();
Exception& e = vm->__last_exception->as<Exception>();
e.st_push(src, lineno, cursor, "");
throw std::move(e);
throw TopLevelException(&e);
}
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");
vm->bind_func(mod, "print_exc", 0, [](VM* vm, ArgsView args) {
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());
return vm->None;
});
vm->bind_func(mod, "format_exc", 0, [](VM* vm, ArgsView args) {
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());
});
}

View File

@ -1649,7 +1649,7 @@ void VM::__post_init_builtin_types(){
this->_exec(code, this->builtins);
code = compile(kPythonLibs__set, "<set>", EXEC_MODE);
this->_exec(code, this->builtins);
}catch(const Exception& e){
}catch(TopLevelException e){
std::cerr << e.summary() << std::endl;
std::cerr << "failed to load builtins module!!" << std::endl;
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);
try{
return compiler.compile();
}catch(const Exception& e){
}catch(TopLevelException e){
_error(e.self());
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);
try{
return compiler.precompile();
}catch(const Exception& e){
}catch(TopLevelException e){
_error(e.self());
return nullptr;
}

View File

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

View File

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