mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 11:30:18 +00:00
remove _Pointer
This commit is contained in:
parent
b3a1cee0b7
commit
a7751461c9
22
src/obj.h
22
src/obj.h
@ -10,7 +10,6 @@ struct BasePointer;
|
||||
class VM;
|
||||
class Frame;
|
||||
|
||||
typedef pkpy::shared_ptr<const BasePointer> _Pointer;
|
||||
typedef PyVar (*_CppFunc)(VM*, const pkpy::ArgList&);
|
||||
typedef pkpy::shared_ptr<CodeObject> _Code;
|
||||
|
||||
@ -60,7 +59,7 @@ protected:
|
||||
public:
|
||||
virtual PyVar next() = 0;
|
||||
virtual bool hasNext() = 0;
|
||||
_Pointer var;
|
||||
VarRef var;
|
||||
BaseIterator(VM* vm, PyVar _ref) : vm(vm), _ref(_ref) {}
|
||||
virtual ~BaseIterator() = default;
|
||||
};
|
||||
@ -69,10 +68,14 @@ typedef pkpy::shared_ptr<Function> _Func;
|
||||
typedef pkpy::shared_ptr<BaseIterator> _Iterator;
|
||||
|
||||
struct PyObject {
|
||||
PyVarDict attribs;
|
||||
protected:
|
||||
void* _value;
|
||||
public:
|
||||
PyVar _type;
|
||||
PyVarDict attribs;
|
||||
|
||||
inline bool isType(const PyVar& type){ return this->_type == type; }
|
||||
inline void* value(){ return _value; }
|
||||
|
||||
// currently __name__ is only used for 'type'
|
||||
PyVar _typeName(){ return _type->attribs[__name__]; }
|
||||
@ -80,17 +83,14 @@ struct PyObject {
|
||||
|
||||
template <typename T>
|
||||
struct Py_ : PyObject {
|
||||
T _value;
|
||||
T _valueT;
|
||||
|
||||
Py_(const T& val, const PyVar& type) {
|
||||
_value = val;
|
||||
_type = type;
|
||||
}
|
||||
Py_(T&& val, const PyVar& type) {
|
||||
_value = std::move(val);
|
||||
Py_(T val, const PyVar& type) {
|
||||
_valueT = val;
|
||||
_value = &_valueT;
|
||||
_type = type;
|
||||
}
|
||||
};
|
||||
|
||||
#define UNION_GET(T, obj) (((Py_<T>*)((obj).get()))->_value)
|
||||
#define UNION_GET(T, obj) (((Py_<T>*)((obj).get()))->_valueT)
|
||||
#define UNION_TP_NAME(obj) UNION_GET(_Str, (obj)->_typeName())
|
@ -18,9 +18,10 @@ enum NameScope {
|
||||
};
|
||||
|
||||
struct NamePointer : BasePointer {
|
||||
const _Str name;
|
||||
const NameScope scope;
|
||||
NamePointer(const _Str& name, NameScope scope) : name(name), scope(scope) {}
|
||||
_Str name;
|
||||
NameScope scope;
|
||||
NamePointer(_Str name, NameScope scope) : name(name), scope(scope) {}
|
||||
NamePointer(){}
|
||||
|
||||
bool operator==(const NamePointer& other) const {
|
||||
return name == other.name && scope == other.scope;
|
||||
@ -35,6 +36,7 @@ struct AttrPointer : BasePointer {
|
||||
mutable PyVar obj;
|
||||
const NamePointer* attr;
|
||||
AttrPointer(PyVar obj, const NamePointer* attr) : obj(obj), attr(attr) {}
|
||||
AttrPointer(){}
|
||||
|
||||
PyVar get(VM* vm, Frame* frame) const;
|
||||
void set(VM* vm, Frame* frame, PyVar val) const;
|
||||
@ -43,8 +45,9 @@ struct AttrPointer : BasePointer {
|
||||
|
||||
struct IndexPointer : BasePointer {
|
||||
mutable PyVar obj;
|
||||
const PyVar index;
|
||||
PyVar index;
|
||||
IndexPointer(PyVar obj, PyVar index) : obj(obj), index(index) {}
|
||||
IndexPointer(){}
|
||||
|
||||
PyVar get(VM* vm, Frame* frame) const;
|
||||
void set(VM* vm, Frame* frame, PyVar val) const;
|
||||
@ -52,9 +55,10 @@ struct IndexPointer : BasePointer {
|
||||
};
|
||||
|
||||
struct CompoundPointer : BasePointer {
|
||||
const std::vector<_Pointer> pointers;
|
||||
CompoundPointer(const std::vector<_Pointer>& pointers) : pointers(pointers) {}
|
||||
CompoundPointer(std::vector<_Pointer>&& pointers) : pointers(pointers) {}
|
||||
PyVarList varRefs;
|
||||
CompoundPointer(const PyVarList& varRefs) : varRefs(varRefs) {}
|
||||
CompoundPointer(PyVarList&& varRefs) : varRefs(std::move(varRefs)) {}
|
||||
CompoundPointer(){}
|
||||
|
||||
PyVar get(VM* vm, Frame* frame) const;
|
||||
void set(VM* vm, Frame* frame, PyVar val) const;
|
||||
@ -62,9 +66,10 @@ struct CompoundPointer : BasePointer {
|
||||
};
|
||||
|
||||
struct UserPointer : BasePointer {
|
||||
const _Pointer p;
|
||||
VarRef p;
|
||||
uint64_t f_id;
|
||||
UserPointer(_Pointer p, uint64_t f_id) : p(p), f_id(f_id) {}
|
||||
UserPointer(VarRef p, uint64_t f_id) : p(p), f_id(f_id) {}
|
||||
UserPointer() {}
|
||||
|
||||
PyVar get(VM* vm, Frame* frame) const;
|
||||
void set(VM* vm, Frame* frame, PyVar val) const;
|
||||
|
@ -7,6 +7,7 @@
|
||||
struct PyObject;
|
||||
typedef pkpy::shared_ptr<PyObject> PyVar;
|
||||
typedef PyVar PyVarOrNull;
|
||||
typedef PyVar VarRef;
|
||||
|
||||
class PyVarList: public std::vector<PyVar> {
|
||||
PyVar& at(size_t) = delete;
|
||||
|
75
src/vm.h
75
src/vm.h
@ -19,7 +19,6 @@
|
||||
__DEF_PY(type, ctype, ptype) \
|
||||
__DEF_PY_AS_C(type, ctype, ptype)
|
||||
|
||||
typedef void(*PrintFn)(const VM*, const char*);
|
||||
|
||||
class VM {
|
||||
std::atomic<bool> _stopFlag = false;
|
||||
@ -55,9 +54,7 @@ protected:
|
||||
frame->push(obj);
|
||||
} break;
|
||||
case OP_LOAD_NAME_PTR: {
|
||||
frame->push(PyPointer(
|
||||
pkpy::make_shared<const BasePointer, NamePointer>(frame->code->co_names[byte.arg])
|
||||
));
|
||||
frame->push(PyPointer(NamePointer(frame->code->co_names[byte.arg])));
|
||||
} break;
|
||||
case OP_STORE_NAME_PTR: {
|
||||
const auto& p = frame->code->co_names[byte.arg];
|
||||
@ -66,33 +63,28 @@ protected:
|
||||
case OP_BUILD_ATTR_PTR: {
|
||||
const auto& attr = frame->code->co_names[byte.arg];
|
||||
PyVar obj = frame->popValue(this);
|
||||
frame->push(PyPointer(
|
||||
pkpy::make_shared<const BasePointer, AttrPointer>(obj, &attr)
|
||||
));
|
||||
frame->push(PyPointer(AttrPointer(obj, &attr)));
|
||||
} break;
|
||||
case OP_BUILD_ATTR_PTR_PTR: {
|
||||
const auto& attr = frame->code->co_names[byte.arg];
|
||||
PyVar obj = frame->popValue(this);
|
||||
__checkType(obj, _tp_user_pointer);
|
||||
const _Pointer& p = UNION_GET(_Pointer, obj);
|
||||
frame->push(PyPointer(
|
||||
pkpy::make_shared<const BasePointer, AttrPointer>(p->get(this, frame), &attr)
|
||||
));
|
||||
const VarRef& var = UNION_GET(VarRef, obj);
|
||||
auto p = PyPointer_AS_C(var);
|
||||
frame->push(PyPointer(AttrPointer(p->get(this, frame), &attr)));
|
||||
} break;
|
||||
case OP_BUILD_INDEX_PTR: {
|
||||
PyVar index = frame->popValue(this);
|
||||
PyVar obj = frame->popValue(this);
|
||||
frame->push(PyPointer(
|
||||
pkpy::make_shared<const BasePointer, IndexPointer>(obj, index)
|
||||
));
|
||||
frame->push(PyPointer(IndexPointer(obj, index)));
|
||||
} break;
|
||||
case OP_STORE_PTR: {
|
||||
PyVar obj = frame->popValue(this);
|
||||
const _Pointer p = PyPointer_AS_C(frame->__pop());
|
||||
auto p = PyPointer_AS_C(frame->__pop());
|
||||
p->set(this, frame, std::move(obj));
|
||||
} break;
|
||||
case OP_DELETE_PTR: {
|
||||
const _Pointer p = PyPointer_AS_C(frame->__pop());
|
||||
auto p = PyPointer_AS_C(frame->__pop());
|
||||
p->del(this, frame);
|
||||
} break;
|
||||
case OP_BUILD_SMART_TUPLE:
|
||||
@ -111,12 +103,7 @@ protected:
|
||||
}
|
||||
}
|
||||
if(done) break;
|
||||
std::vector<_Pointer> pointers(items.size());
|
||||
for(int i=0; i<items.size(); i++)
|
||||
pointers[i] = PyPointer_AS_C(items[i]);
|
||||
frame->push(PyPointer(
|
||||
pkpy::make_shared<const BasePointer, CompoundPointer>(std::move(pointers))
|
||||
));
|
||||
frame->push(PyPointer(CompoundPointer(items.toList())));
|
||||
} break;
|
||||
case OP_BUILD_STRING:
|
||||
{
|
||||
@ -212,10 +199,11 @@ protected:
|
||||
case OP_UNARY_REF:
|
||||
{
|
||||
// _pointer to pointer
|
||||
const _Pointer p = PyPointer_AS_C(frame->__pop());
|
||||
VarRef obj = frame->__pop();
|
||||
__checkType(obj, _tp_pointer);
|
||||
frame->push(newObject(
|
||||
_tp_user_pointer,
|
||||
pkpy::make_shared<const BasePointer, UserPointer>(p, frame->id)
|
||||
PyPointer(UserPointer(obj, frame->id))
|
||||
));
|
||||
} break;
|
||||
case OP_UNARY_DEREF:
|
||||
@ -223,7 +211,7 @@ protected:
|
||||
// pointer to _pointer
|
||||
PyVar obj = frame->popValue(this);
|
||||
__checkType(obj, _tp_user_pointer);
|
||||
frame->push(PyPointer(UNION_GET(_Pointer, obj)));
|
||||
frame->push(UNION_GET(VarRef, obj));
|
||||
} break;
|
||||
case OP_POP_JUMP_IF_FALSE:
|
||||
if(!PyBool_AS_C(asBool(frame->popValue(this)))) frame->jump(byte.arg);
|
||||
@ -283,7 +271,9 @@ protected:
|
||||
PyVarOrNull iter_fn = getAttr(obj, __iter__, false);
|
||||
if(iter_fn != nullptr){
|
||||
PyVar tmp = call(iter_fn, {obj});
|
||||
PyIter_AS_C(tmp)->var = std::move(PyPointer_AS_C(frame->__pop()));
|
||||
VarRef var = frame->__pop();
|
||||
__checkType(var, _tp_pointer);
|
||||
PyIter_AS_C(tmp)->var = var;
|
||||
frame->push(std::move(tmp));
|
||||
}else{
|
||||
typeError("'" + UNION_TP_NAME(obj) + "' object is not iterable");
|
||||
@ -295,7 +285,7 @@ protected:
|
||||
// __top() must be PyIter, so no need to __deref()
|
||||
auto& it = PyIter_AS_C(frame->__top());
|
||||
if(it->hasNext()){
|
||||
it->var->set(this, frame, it->next());
|
||||
PyPointer_AS_C(it->var)->set(this, frame, it->next());
|
||||
}
|
||||
else{
|
||||
frame->safeJump(byte.arg);
|
||||
@ -768,11 +758,16 @@ public:
|
||||
PyVar _tp_slice, _tp_range, _tp_module, _tp_pointer;
|
||||
PyVar _tp_user_pointer, _tp_super;
|
||||
|
||||
__DEF_PY(Pointer, _Pointer, _tp_pointer)
|
||||
inline _Pointer& PyPointer_AS_C(const PyVar& obj)
|
||||
template<typename P>
|
||||
inline VarRef PyPointer(P value) {
|
||||
static_assert(std::is_base_of<BasePointer, P>::value, "P should derive from BasePointer");
|
||||
return newObject(_tp_pointer, value);
|
||||
}
|
||||
|
||||
inline const BasePointer* PyPointer_AS_C(const PyVar& obj)
|
||||
{
|
||||
if(!obj->isType(_tp_pointer)) typeError("expected an l-value");
|
||||
return UNION_GET(_Pointer, obj);
|
||||
return (const BasePointer*)(obj->value());
|
||||
}
|
||||
|
||||
__DEF_PY_AS_C(Int, _Int, _tp_int)
|
||||
@ -1021,9 +1016,9 @@ void IndexPointer::del(VM* vm, Frame* frame) const{
|
||||
}
|
||||
|
||||
PyVar CompoundPointer::get(VM* vm, Frame* frame) const{
|
||||
PyVarList args(pointers.size());
|
||||
for (int i = 0; i < pointers.size(); i++) {
|
||||
args[i] = pointers[i]->get(vm, frame);
|
||||
PyVarList args(varRefs.size());
|
||||
for (int i = 0; i < varRefs.size(); i++) {
|
||||
args[i] = vm->PyPointer_AS_C(varRefs[i])->get(vm, frame);
|
||||
}
|
||||
return vm->PyTuple(args);
|
||||
}
|
||||
@ -1033,27 +1028,27 @@ void CompoundPointer::set(VM* vm, Frame* frame, PyVar val) const{
|
||||
vm->typeError("only tuple or list can be unpacked");
|
||||
}
|
||||
const PyVarList& args = UNION_GET(PyVarList, val);
|
||||
if(args.size() > pointers.size()) vm->valueError("too many values to unpack");
|
||||
if(args.size() < pointers.size()) vm->valueError("not enough values to unpack");
|
||||
for (int i = 0; i < pointers.size(); i++) {
|
||||
pointers[i]->set(vm, frame, args[i]);
|
||||
if(args.size() > varRefs.size()) vm->valueError("too many values to unpack");
|
||||
if(args.size() < varRefs.size()) vm->valueError("not enough values to unpack");
|
||||
for (int i = 0; i < varRefs.size(); i++) {
|
||||
vm->PyPointer_AS_C(varRefs[i])->set(vm, frame, args[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void CompoundPointer::del(VM* vm, Frame* frame) const{
|
||||
for (auto& ptr : pointers) ptr->del(vm, frame);
|
||||
for (auto& r : varRefs) vm->PyPointer_AS_C(r)->del(vm, frame);
|
||||
}
|
||||
|
||||
PyVar UserPointer::get(VM* vm, Frame* frame) const{
|
||||
frame = vm->__findFrame(f_id);
|
||||
if(frame == nullptr) vm->nullPointerError();
|
||||
return p->get(vm, frame);
|
||||
return vm->PyPointer_AS_C(p)->get(vm, frame);
|
||||
}
|
||||
|
||||
void UserPointer::set(VM* vm, Frame* frame, PyVar val) const{
|
||||
frame = vm->__findFrame(f_id);
|
||||
if(frame == nullptr) vm->nullPointerError();
|
||||
p->set(vm, frame, val);
|
||||
vm->PyPointer_AS_C(p)->set(vm, frame, val);
|
||||
}
|
||||
|
||||
void UserPointer::del(VM* vm, Frame* frame) const{
|
||||
|
Loading…
x
Reference in New Issue
Block a user