This commit is contained in:
blueloveTH 2023-01-09 01:56:46 +08:00
parent 668d676e0b
commit 85bbdeaf9c
6 changed files with 56 additions and 58 deletions

View File

@ -19,7 +19,7 @@ static const char* OP_NAMES[] = {
struct ByteCode{ struct ByteCode{
uint8_t op; uint8_t op;
int arg; int arg;
uint16_t line; int line;
uint16_t block; // the block id of this bytecode uint16_t block; // the block id of this bytecode
}; };
@ -149,7 +149,8 @@ struct CodeObject {
class Frame { class Frame {
private: private:
std::vector<PyVar> s_data; std::vector<PyVar> s_data;
int ip = 0; int ip = -1;
int next_ip = 0;
public: public:
const _Code code; const _Code code;
PyVar _module; PyVar _module;
@ -167,12 +168,14 @@ public:
: code(code), _module(_module), f_locals(std::move(locals)) { : code(code), _module(_module), f_locals(std::move(locals)) {
} }
inline const ByteCode& readCode() { inline const ByteCode& next_bytecode() {
return code->co_code[ip++]; ip = next_ip;
next_ip = ip + 1;
return code->co_code[ip];
} }
_Str errorSnapshot(){ _Str errorSnapshot(){
int line = code->co_code[ip-1].line; int line = code->co_code[ip].line;
return code->src->snapshot(line); return code->src->snapshot(line);
} }
@ -180,8 +183,8 @@ public:
return s_data.size(); return s_data.size();
} }
inline bool isCodeEnd() const { inline bool has_next_bytecode() const {
return ip >= code->co_code.size(); return next_ip < code->co_code.size();
} }
inline PyVar __pop(){ inline PyVar __pop(){
@ -191,15 +194,18 @@ public:
return v; return v;
} }
inline PyVar __deref_pointer(VM*, PyVar); inline void __deref(VM*, PyVar&);
inline PyVar popValue(VM* vm){ inline PyVar popValue(VM* vm){
return __deref_pointer(vm, __pop()); PyVar value = __pop();
__deref(vm, value);
return value;
} }
inline PyVar topValue(VM* vm){ inline PyVar topValue(VM* vm){
if(s_data.empty()) throw std::runtime_error("s_data.empty() is true"); PyVar value = __top();
return __deref_pointer(vm, s_data.back()); __deref(vm, value);
return value;
} }
inline PyVar& __top(){ inline PyVar& __top(){
@ -208,7 +214,9 @@ public:
} }
inline PyVar __topValueN(VM* vm, int n=-1){ inline PyVar __topValueN(VM* vm, int n=-1){
return __deref_pointer(vm, s_data[s_data.size() + n]); PyVar value = s_data[s_data.size() + n];
__deref(vm, value);
return value;
} }
template<typename T> template<typename T>
@ -217,14 +225,14 @@ public:
} }
inline void jumpAbsolute(int i){ inline void jumpAbsolute(int i){
this->ip = i; next_ip = i;
} }
void jumpAbsoluteSafe(int target){ void jumpAbsoluteSafe(int target){
const ByteCode& prev = code->co_code[this->ip]; const ByteCode& prev = code->co_code[ip];
int i = prev.block; int i = prev.block;
this->ip = target; next_ip = target;
if(isCodeEnd()){ if(next_ip >= code->co_code.size()){
while(i>=0){ while(i>=0){
if(code->co_blocks[i].type == FOR_LOOP) __pop(); if(code->co_blocks[i].type == FOR_LOOP) __pop();
i = code->co_blocks[i].parent; i = code->co_blocks[i].parent;
@ -242,8 +250,14 @@ public:
} }
pkpy::ArgList popNValuesReversed(VM* vm, int n){ pkpy::ArgList popNValuesReversed(VM* vm, int n){
int new_size = s_data.size() - n;
if(new_size < 0) throw std::runtime_error("stackSize() < n");
pkpy::ArgList v(n); pkpy::ArgList v(n);
for(int i=n-1; i>=0; i--) v._index(i) = popValue(vm); for(int i=n-1; i>=0; i--){
v._index(i) = std::move(s_data[new_size + i]);
__deref(vm, v._index(i));
}
s_data.resize(new_size);
return v; return v;
} }

View File

@ -698,7 +698,7 @@ __LISTCOMP:
int emitCode(Opcode opcode, int arg=-1) { int emitCode(Opcode opcode, int arg=-1) {
int line = parser->previous.line; int line = parser->previous.line;
getCode()->co_code.push_back( getCode()->co_code.push_back(
ByteCode{(uint8_t)opcode, arg, (uint16_t)line, (uint16_t)getCode()->_currBlockIndex} ByteCode{(uint8_t)opcode, arg, line, (uint16_t)getCode()->_currBlockIndex}
); );
return getCode()->co_code.size() - 1; return getCode()->co_code.size() - 1;
} }

View File

@ -3,7 +3,7 @@
#include "pocketpy.h" #include "pocketpy.h"
//#define PK_DEBUG_TIME #define PK_DEBUG_TIME
//#define PK_DEBUG_THREADED //#define PK_DEBUG_THREADED
struct Timer{ struct Timer{

View File

@ -19,7 +19,7 @@ enum NameScope {
struct NameRef : BaseRef { struct NameRef : BaseRef {
const std::pair<_Str, NameScope>* pair; const std::pair<_Str, NameScope>* pair;
NameRef(const std::pair<_Str, NameScope>* pair) : pair(pair) {} NameRef(const std::pair<_Str, NameScope>& pair) : pair(&pair) {}
PyVar get(VM* vm, Frame* frame) const; PyVar get(VM* vm, Frame* frame) const;
void set(VM* vm, Frame* frame, PyVar val) const; void set(VM* vm, Frame* frame, PyVar val) const;

View File

@ -37,8 +37,8 @@ protected:
} }
PyVar runFrame(Frame* frame){ PyVar runFrame(Frame* frame){
while(!frame->isCodeEnd()){ while(frame->has_next_bytecode()){
const ByteCode& byte = frame->readCode(); const ByteCode& byte = frame->next_bytecode();
//printf("[%d] %s (%d)\n", frame->stackSize(), OP_NAMES[byte.op], byte.arg); //printf("[%d] %s (%d)\n", frame->stackSize(), OP_NAMES[byte.op], byte.arg);
//printf("%s\n", frame->code->src->getLine(byte.line).c_str()); //printf("%s\n", frame->code->src->getLine(byte.line).c_str());
@ -54,18 +54,16 @@ protected:
frame->push(obj); frame->push(obj);
} break; } break;
case OP_LOAD_NAME_REF: { case OP_LOAD_NAME_REF: {
frame->push(PyRef(NameRef( frame->push(PyRef(NameRef(frame->code->co_names[byte.arg])));
&(frame->code->co_names[byte.arg])
)));
} break; } break;
case OP_STORE_NAME_REF: { case OP_STORE_NAME_REF: {
const auto& p = frame->code->co_names[byte.arg]; const auto& p = frame->code->co_names[byte.arg];
NameRef(&p).set(this, frame, frame->popValue(this)); NameRef(p).set(this, frame, frame->popValue(this));
} break; } break;
case OP_BUILD_ATTR_REF: { case OP_BUILD_ATTR_REF: {
const auto& attr = frame->code->co_names[byte.arg]; const auto& attr = frame->code->co_names[byte.arg];
PyVar obj = frame->popValue(this); PyVar obj = frame->popValue(this);
frame->push(PyRef(AttrRef(obj, NameRef(&attr)))); frame->push(PyRef(AttrRef(obj, NameRef(attr))));
} break; } break;
case OP_BUILD_INDEX_REF: { case OP_BUILD_INDEX_REF: {
PyVar index = frame->popValue(this); PyVar index = frame->popValue(this);
@ -88,10 +86,8 @@ protected:
for(int i=0; i<items.size(); i++){ for(int i=0; i<items.size(); i++){
if(!items[i]->isType(_tp_ref)) { if(!items[i]->isType(_tp_ref)) {
done = true; done = true;
PyVarList values(items.size()); PyVarList values = items.toList();
for(int i=0; i<items.size(); i++){ for(int j=i; j<values.size(); j++) frame->__deref(this, values[j]);
values[i] = frame->__deref_pointer(this, items[i]);
}
frame->push(PyTuple(values)); frame->push(PyTuple(values));
break; break;
} }
@ -151,6 +147,10 @@ protected:
fastCall(BINARY_SPECIAL_METHODS[byte.arg], fastCall(BINARY_SPECIAL_METHODS[byte.arg],
frame->popNValuesReversed(this, 2)) frame->popNValuesReversed(this, 2))
); );
// pkpy::ArgList args(2);
// args._index(1) = frame->popValue(this);
// args._index(0) = frame->topValue(this);
// frame->__top() = fastCall(BINARY_SPECIAL_METHODS[byte.arg], std::move(args));
} break; } break;
case OP_BITWISE_OP: case OP_BITWISE_OP:
{ {
@ -624,7 +624,7 @@ public:
template<typename T> template<typename T>
inline PyVar newObject(PyVar type, T _value) { inline PyVar newObject(PyVar type, T _value) {
__checkType(type, _tp_type); if(!type->isType(_tp_type)) UNREACHABLE();
return pkpy::make_shared<PyObject, Py_<T>>(_value, type); return pkpy::make_shared<PyObject, Py_<T>>(_value, type);
} }
@ -678,30 +678,15 @@ public:
return nullptr; return nullptr;
} }
void setAttr(PyVar& obj, const _Str& name, const PyVar& value) { template<typename T>
if(obj->isType(_tp_super)){ void setAttr(PyObject* obj, const _Str& name, T&& value) {
const PyVar* root = &obj; while(obj->isType(_tp_super)) obj = ((Py_<PyVar>*)obj)->_valueT.get();
while(true){ obj->attribs[name] = value;
root = &UNION_GET(PyVar, *root);
if(!(*root)->isType(_tp_super)) break;
}
(*root)->attribs[name] = value;
}else{
obj->attribs[name] = value;
}
} }
void setAttr(PyVar& obj, const _Str& name, PyVar&& value) { template<typename T>
if(obj->isType(_tp_super)){ inline void setAttr(PyVar& obj, const _Str& name, T&& value) {
const PyVar* root = &obj; setAttr(obj.get(), name, value);
while(true){
root = &UNION_GET(PyVar, *root);
if(!(*root)->isType(_tp_super)) break;
}
(*root)->attribs[name] = std::move(value);
}else{
obj->attribs[name] = std::move(value);
}
} }
void bindMethod(_Str typeName, _Str funcName, _CppFunc fn) { void bindMethod(_Str typeName, _Str funcName, _CppFunc fn) {
@ -1093,9 +1078,8 @@ void TupleRef::del(VM* vm, Frame* frame) const{
} }
/***** Frame's Impl *****/ /***** Frame's Impl *****/
inline PyVar Frame::__deref_pointer(VM* vm, PyVar v){ inline void Frame::__deref(VM* vm, PyVar& v){
if(v->isType(vm->_tp_ref)) return vm->PyRef_AS_C(v)->get(vm, this); if(v->isType(vm->_tp_ref)) v = vm->PyRef_AS_C(v)->get(vm, this);
return v;
} }
/***** Iterators' Impl *****/ /***** Iterators' Impl *****/

View File

@ -1,4 +1,4 @@
g++ -o pocketpy src/main.cpp --std=c++17 -pg -O1 -pthread g++ -o pocketpy src/main.cpp --std=c++17 -pg -O1 -pthread -fno-rtti
./pocketpy tests/1.py ./pocketpy tests/1.py