mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 03:20:18 +00:00
up
This commit is contained in:
parent
d4e299bce0
commit
ef36a1d3a0
@ -175,6 +175,7 @@ private:
|
||||
std::vector<PyVar> s_data;
|
||||
int ip = -1;
|
||||
int next_ip = 0;
|
||||
int m_id;
|
||||
public:
|
||||
const _Code code;
|
||||
PyVar _module;
|
||||
@ -183,8 +184,12 @@ public:
|
||||
inline PyVarDict& f_locals() noexcept { return *_locals; }
|
||||
inline PyVarDict& f_globals() noexcept { return _module->attribs; }
|
||||
|
||||
inline i64 id() const noexcept { return m_id; }
|
||||
|
||||
Frame(const _Code code, PyVar _module, pkpy::shared_ptr<PyVarDict> _locals)
|
||||
: code(code), _module(_module), _locals(_locals) {
|
||||
static thread_local i64 _id = 0;
|
||||
m_id = _id++;
|
||||
}
|
||||
|
||||
inline const Bytecode& next_bytecode() {
|
||||
|
14
src/error.h
14
src/error.h
@ -2,12 +2,18 @@
|
||||
|
||||
#include "safestl.h"
|
||||
|
||||
class NeedMoreLines {
|
||||
public:
|
||||
struct NeedMoreLines {
|
||||
NeedMoreLines(bool isClassDef) : isClassDef(isClassDef) {}
|
||||
bool isClassDef;
|
||||
};
|
||||
|
||||
struct HandledException {};
|
||||
|
||||
struct UnhandledException {
|
||||
PyVar obj;
|
||||
UnhandledException(PyVar obj) : obj(obj) {}
|
||||
};
|
||||
|
||||
enum CompileMode {
|
||||
EXEC_MODE,
|
||||
EVAL_MODE,
|
||||
@ -77,6 +83,10 @@ class _Exception : public std::exception {
|
||||
public:
|
||||
_Exception(_Str type, _Str msg, bool is_runtime_error): type(type), msg(msg), is_runtime_error(is_runtime_error) {}
|
||||
|
||||
bool match_type(const _Str& type) const {
|
||||
return this->type == type;
|
||||
}
|
||||
|
||||
void st_push(_Str snapshot){
|
||||
if(stacktrace.size() >= 8) return;
|
||||
stacktrace.push(snapshot);
|
||||
|
49
src/vm.h
49
src/vm.h
@ -187,10 +187,16 @@ protected:
|
||||
PyVar expr = frame->pop_value(this);
|
||||
if(asBool(expr) != True) _error("AssertionError", "");
|
||||
} break;
|
||||
case OP_EXCEPTION_MATCH: break;
|
||||
case OP_EXCEPTION_MATCH:
|
||||
{
|
||||
const auto& _e = PyException_AS_C(frame->top());
|
||||
_Str name = frame->code->co_names[byte.arg].first;
|
||||
frame->push(PyBool(_e.match_type(name)));
|
||||
} break;
|
||||
case OP_RAISE:
|
||||
{
|
||||
_Str msg = PyStr_AS_C(asStr(frame->pop_value(this)));
|
||||
PyVar obj = frame->pop_value(this);
|
||||
_Str msg = obj == None ? "" : PyStr_AS_C(asStr(obj));
|
||||
_Str type = frame->code->co_names[byte.arg].first;
|
||||
_error(type, msg);
|
||||
} break;
|
||||
@ -549,13 +555,34 @@ public:
|
||||
template<typename ...Args>
|
||||
PyVar _exec(Args&&... args){
|
||||
Frame* frame = __push_new_frame(std::forward<Args>(args)...);
|
||||
Frame* frameBase = frame;
|
||||
i64 base_id = frame->id();
|
||||
PyVar ret = nullptr;
|
||||
bool need_raise = false;
|
||||
|
||||
while(true){
|
||||
ret = run_frame(frame);
|
||||
if(frame->id() < base_id) UNREACHABLE();
|
||||
try{
|
||||
if(need_raise){ need_raise = false; _raise(); }
|
||||
ret = run_frame(frame);
|
||||
}catch(HandledException& e){
|
||||
continue;
|
||||
}catch(UnhandledException& e){
|
||||
_Exception& _e = UNION_GET(_Exception, e.obj);
|
||||
_e.st_push(frame->curr_snapshot());
|
||||
callstack.pop_back();
|
||||
|
||||
if(!callstack.empty()){
|
||||
frame = callstack.back().get();
|
||||
if(frame->id() < base_id) throw e;
|
||||
frame->push(ret);
|
||||
need_raise = true;
|
||||
continue;
|
||||
}
|
||||
throw _e;
|
||||
}
|
||||
|
||||
if(ret != __py2py_call_signal){
|
||||
if(frame == frameBase){ // [ frameBase<- ]
|
||||
if(frame->id() == base_id){ // [ frameBase<- ]
|
||||
break;
|
||||
}else{
|
||||
callstack.pop_back();
|
||||
@ -893,10 +920,7 @@ public:
|
||||
|
||||
/***** Error Reporter *****/
|
||||
private:
|
||||
bool _error_lock = false;
|
||||
|
||||
void _error(const _Str& name, const _Str& msg){
|
||||
if(_error_lock) UNREACHABLE();
|
||||
auto e = _Exception(name, msg, true);
|
||||
top_frame()->push(PyException(e));
|
||||
_raise();
|
||||
@ -904,12 +928,8 @@ private:
|
||||
|
||||
void _raise(){
|
||||
bool ok = top_frame()->jump_to_exception_handler();
|
||||
if(ok) return;
|
||||
// 当前帧里面没有异常处理器了,应推到上一层
|
||||
_error_lock = true;
|
||||
const auto& e = PyException_AS_C(top_frame()->top());
|
||||
_error_lock = false;
|
||||
throw e;
|
||||
if(ok) throw HandledException();
|
||||
throw UnhandledException(top_frame()->top());
|
||||
}
|
||||
|
||||
public:
|
||||
@ -938,7 +958,6 @@ public:
|
||||
};
|
||||
|
||||
/***** Pointers' Impl *****/
|
||||
|
||||
PyVar NameRef::get(VM* vm, Frame* frame) const{
|
||||
PyVar* val;
|
||||
val = frame->f_locals().try_get(pair->first);
|
||||
|
Loading…
x
Reference in New Issue
Block a user