This commit is contained in:
blueloveTH 2023-02-04 00:57:19 +08:00
parent d4e299bce0
commit ef36a1d3a0
3 changed files with 51 additions and 17 deletions

View File

@ -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() {

View File

@ -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);

View File

@ -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){
if(frame->id() < base_id) UNREACHABLE();
try{
if(need_raise){ need_raise = false; _raise(); }
ret = run_frame(frame); 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);