mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-22 12:30:19 +00:00
...
This commit is contained in:
parent
a71b1a6e90
commit
ca78599049
@ -21,6 +21,7 @@ inline PyObject* VM::_run_top_frame(){
|
|||||||
#endif
|
#endif
|
||||||
try{
|
try{
|
||||||
if(need_raise){ need_raise = false; _raise(); }
|
if(need_raise){ need_raise = false; _raise(); }
|
||||||
|
if(s_data.is_overflow()) StackOverflowError();
|
||||||
/**********************************************************************/
|
/**********************************************************************/
|
||||||
/* NOTE:
|
/* NOTE:
|
||||||
* Be aware of accidental gc!
|
* Be aware of accidental gc!
|
||||||
@ -52,7 +53,7 @@ goto *OP_LABELS[byte.op];
|
|||||||
|
|
||||||
__NEXT_STEP:;
|
__NEXT_STEP:;
|
||||||
#if DEBUG_CEVAL_STEP
|
#if DEBUG_CEVAL_STEP
|
||||||
std::cout << frame->stack_info() << " " << OP_NAMES[byte.op] << std::endl;
|
_log_s_data();
|
||||||
#endif
|
#endif
|
||||||
#if DEBUG_CEVAL_STEP_MIN
|
#if DEBUG_CEVAL_STEP_MIN
|
||||||
std::cout << OP_NAMES[byte.op] << std::endl;
|
std::cout << OP_NAMES[byte.op] << std::endl;
|
||||||
@ -495,7 +496,6 @@ __NEXT_STEP:;
|
|||||||
obj = iter->next();
|
obj = iter->next();
|
||||||
while(obj != nullptr){
|
while(obj != nullptr){
|
||||||
PUSH(obj);
|
PUSH(obj);
|
||||||
// if(s_data.is_overflow()) StackOverflowError();
|
|
||||||
obj = iter->next();
|
obj = iter->next();
|
||||||
}
|
}
|
||||||
} DISPATCH();
|
} DISPATCH();
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
// debug macros
|
// debug macros
|
||||||
#define DEBUG_NO_BUILTIN_MODULES 0
|
#define DEBUG_NO_BUILTIN_MODULES 0
|
||||||
#define DEBUG_EXTRA_CHECK 1
|
#define DEBUG_EXTRA_CHECK 1
|
||||||
#define DEBUG_DIS_EXEC 1
|
#define DEBUG_DIS_EXEC 0
|
||||||
#define DEBUG_CEVAL_STEP 0
|
#define DEBUG_CEVAL_STEP 0
|
||||||
#define DEBUG_CEVAL_STEP_MIN 0
|
#define DEBUG_CEVAL_STEP_MIN 0
|
||||||
#define DEBUG_FULL_EXCEPTION 1
|
#define DEBUG_FULL_EXCEPTION 1
|
||||||
@ -53,8 +53,13 @@
|
|||||||
#define PK_ENABLE_COMPUTED_GOTO 0
|
#define PK_ENABLE_COMPUTED_GOTO 0
|
||||||
#define UNREACHABLE() __assume(0)
|
#define UNREACHABLE() __assume(0)
|
||||||
#else
|
#else
|
||||||
#define PK_ENABLE_COMPUTED_GOTO 0
|
#define PK_ENABLE_COMPUTED_GOTO 1
|
||||||
#define UNREACHABLE() __builtin_unreachable()
|
#define UNREACHABLE() __builtin_unreachable()
|
||||||
|
|
||||||
|
#if DEBUG_CEVAL_STEP || DEBUG_CEVAL_STEP_MIN
|
||||||
|
#undef PK_ENABLE_COMPUTED_GOTO
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__EMSCRIPTEN__) || defined(__arm__) || defined(__i386__)
|
#if defined(__EMSCRIPTEN__) || defined(__arm__) || defined(__i386__)
|
||||||
|
23
src/frame.h
23
src/frame.h
@ -158,15 +158,6 @@ struct ValueStack {
|
|||||||
void clear() { _sp = _begin; }
|
void clear() { _sp = _begin; }
|
||||||
bool is_overflow() const { return _sp >= _begin + MAX_SIZE; }
|
bool is_overflow() const { return _sp >= _begin + MAX_SIZE; }
|
||||||
|
|
||||||
void dup_top_n(int n) {
|
|
||||||
// [a, b, c]
|
|
||||||
// ^p0 ^p1
|
|
||||||
PyObject** p0 = _sp - n;
|
|
||||||
PyObject** p1 = _sp;
|
|
||||||
memcpy(p1, p0, n * sizeof(void*));
|
|
||||||
_sp += n;
|
|
||||||
}
|
|
||||||
|
|
||||||
ValueStack(const ValueStack&) = delete;
|
ValueStack(const ValueStack&) = delete;
|
||||||
ValueStack(ValueStack&&) = delete;
|
ValueStack(ValueStack&&) = delete;
|
||||||
ValueStack& operator=(const ValueStack&) = delete;
|
ValueStack& operator=(const ValueStack&) = delete;
|
||||||
@ -211,22 +202,10 @@ struct Frame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int stack_size() const { return _s->_sp - _sp_base; }
|
int stack_size() const { return _s->_sp - _sp_base; }
|
||||||
|
|
||||||
ArgsView stack_view() const { return ArgsView(_sp_base, _s->_sp); }
|
ArgsView stack_view() const { return ArgsView(_sp_base, _s->_sp); }
|
||||||
|
|
||||||
std::string stack_info(){
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << this << ": [";
|
|
||||||
for(PyObject** t=_sp_base; t<_s->end(); t++){
|
|
||||||
ss << *t;
|
|
||||||
if(t != _s->end()-1) ss << ", ";
|
|
||||||
}
|
|
||||||
ss << "]";
|
|
||||||
return ss.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
void jump_abs(int i){ _next_ip = i; }
|
void jump_abs(int i){ _next_ip = i; }
|
||||||
void jump_rel(int i){ _next_ip += i; }
|
// void jump_rel(int i){ _next_ip += i; }
|
||||||
|
|
||||||
bool jump_to_exception_handler(){
|
bool jump_to_exception_handler(){
|
||||||
// try to find a parent try block
|
// try to find a parent try block
|
||||||
|
38
src/vm.h
38
src/vm.h
@ -323,7 +323,6 @@ public:
|
|||||||
else throw UnhandledException();
|
else throw UnhandledException();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RecursionError() { _error("RecursionError", "maximum recursion depth exceeded"); }
|
|
||||||
void StackOverflowError() { _error("StackOverflowError", ""); }
|
void StackOverflowError() { _error("StackOverflowError", ""); }
|
||||||
void IOError(const Str& msg) { _error("IOError", msg); }
|
void IOError(const Str& msg) { _error("IOError", msg); }
|
||||||
void NotImplementedError(){ _error("NotImplementedError", ""); }
|
void NotImplementedError(){ _error("NotImplementedError", ""); }
|
||||||
@ -363,8 +362,8 @@ public:
|
|||||||
_lazy_modules.clear();
|
_lazy_modules.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _log_s_data(const char* title = nullptr);
|
||||||
PyObject* _vectorcall(int ARGC, int KWARGC=0, bool op_call=false);
|
PyObject* _vectorcall(int ARGC, int KWARGC=0, bool op_call=false);
|
||||||
|
|
||||||
CodeObject_ compile(Str source, Str filename, CompileMode mode, bool unknown_global_scope=false);
|
CodeObject_ compile(Str source, Str filename, CompileMode mode, bool unknown_global_scope=false);
|
||||||
PyObject* num_negated(PyObject* obj);
|
PyObject* num_negated(PyObject* obj);
|
||||||
f64 num_to_float(PyObject* obj);
|
f64 num_to_float(PyObject* obj);
|
||||||
@ -546,9 +545,7 @@ inline bool VM::asBool(PyObject* obj){
|
|||||||
PyObject* self;
|
PyObject* self;
|
||||||
PyObject* len_f = get_unbound_method(obj, __len__, &self, false);
|
PyObject* len_f = get_unbound_method(obj, __len__, &self, false);
|
||||||
if(self != _py_null){
|
if(self != _py_null){
|
||||||
PUSH(len_f);
|
PyObject* ret = call_method(self, len_f);
|
||||||
PUSH(self);
|
|
||||||
PyObject* ret = _vectorcall(0);
|
|
||||||
return CAST(i64, ret) > 0;
|
return CAST(i64, ret) > 0;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -657,6 +654,28 @@ inline Str VM::disassemble(CodeObject_ co){
|
|||||||
return Str(ss.str());
|
return Str(ss.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void VM::_log_s_data(const char* title) {
|
||||||
|
std::stringstream ss;
|
||||||
|
if(title) ss << title << " | ";
|
||||||
|
FrameId frame = top_frame();
|
||||||
|
ss << frame->co->name << ": [";
|
||||||
|
for(PyObject* obj: s_data){
|
||||||
|
if(obj == _py_begin_call) ss << "BEGIN_CALL";
|
||||||
|
else if(obj == _py_null) ss << "NULL";
|
||||||
|
else if(is_int(obj)) ss << CAST(i64, obj);
|
||||||
|
else if(is_float(obj)) ss << CAST(f64, obj);
|
||||||
|
else ss << obj << "(" << obj_type_name(this, obj->type) << ")";
|
||||||
|
ss << ", ";
|
||||||
|
}
|
||||||
|
std::string output = ss.str();
|
||||||
|
if(!s_data.empty()) {
|
||||||
|
output.pop_back(); output.pop_back();
|
||||||
|
}
|
||||||
|
output.push_back(']');
|
||||||
|
Bytecode byte = frame->co->codes[frame->_ip];
|
||||||
|
std::cout << output << " " << OP_NAMES[byte.op] << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
inline void VM::init_builtin_types(){
|
inline void VM::init_builtin_types(){
|
||||||
_all_types.push_back({heap._new<Type>(Type(1), Type(0)), -1, "object"});
|
_all_types.push_back({heap._new<Type>(Type(1), Type(0)), -1, "object"});
|
||||||
_all_types.push_back({heap._new<Type>(Type(1), Type(1)), 0, "type"});
|
_all_types.push_back({heap._new<Type>(Type(1), Type(1)), 0, "type"});
|
||||||
@ -770,8 +789,11 @@ inline PyObject* VM::_vectorcall(int ARGC, int KWARGC, bool op_call){
|
|||||||
PyObject* obj;
|
PyObject* obj;
|
||||||
if(new_f != nullptr){
|
if(new_f != nullptr){
|
||||||
PUSH(new_f);
|
PUSH(new_f);
|
||||||
s_data.dup_top_n(1 + ARGC + KWARGC*2);
|
PUSH(_py_null);
|
||||||
obj = _vectorcall(ARGC, KWARGC, false);
|
for(PyObject* obj: args) PUSH(obj);
|
||||||
|
for(PyObject* obj: kwargs) PUSH(obj);
|
||||||
|
// _log_s_data("L790");
|
||||||
|
obj = _vectorcall(ARGC, KWARGC);
|
||||||
if(!isinstance(obj, OBJ_GET(Type, callable))) return obj;
|
if(!isinstance(obj, OBJ_GET(Type, callable))) return obj;
|
||||||
}else{
|
}else{
|
||||||
obj = heap.gcnew<DummyInstance>(OBJ_GET(Type, callable), {});
|
obj = heap.gcnew<DummyInstance>(OBJ_GET(Type, callable), {});
|
||||||
@ -783,7 +805,7 @@ inline PyObject* VM::_vectorcall(int ARGC, int KWARGC, bool op_call){
|
|||||||
p1[-(ARGC + 2)] = callable;
|
p1[-(ARGC + 2)] = callable;
|
||||||
p1[-(ARGC + 1)] = self;
|
p1[-(ARGC + 1)] = self;
|
||||||
// [init_f, self, args..., kwargs...]
|
// [init_f, self, args..., kwargs...]
|
||||||
_vectorcall(ARGC, KWARGC, false);
|
_vectorcall(ARGC, KWARGC);
|
||||||
// We just discard the return value of `__init__`
|
// We just discard the return value of `__init__`
|
||||||
// in cpython it raises a TypeError if the return value is not None
|
// in cpython it raises a TypeError if the return value is not None
|
||||||
}else{
|
}else{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user