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