mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 11:30:18 +00:00
up
This commit is contained in:
parent
668d676e0b
commit
85bbdeaf9c
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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{
|
||||||
|
@ -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;
|
||||||
|
58
src/vm.h
58
src/vm.h
@ -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 *****/
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user