This commit is contained in:
blueloveTH 2022-12-06 22:19:39 +08:00
parent 41123fc4ec
commit 94bfc2336a
4 changed files with 80 additions and 58 deletions

View File

@ -40,3 +40,4 @@ jobs:
run: | run: |
bash build_cpp.sh bash build_cpp.sh
python3 scripts/run_tests.py python3 scripts/run_tests.py
./pocketpy tests/1.py

View File

@ -5,90 +5,97 @@
namespace pkpy{ namespace pkpy{
template <typename T> template <typename T>
class shared_ptr { class shared_ptr {
int* count; int* counter = nullptr;
T* ptr;
inline void _delete(){ #define _t() ((T*)(counter + 1))
delete count; #define _inc_counter() if(counter) ++(*counter)
delete ptr; #define _dec_counter() if(counter && --(*counter) == 0){ _t()->~T(); free(counter); }
}
public: public:
shared_ptr() : count(nullptr), ptr(nullptr) {} shared_ptr() {}
shared_ptr(T* ptr) : count(new int(1)), ptr(ptr) {} shared_ptr(int* block) : counter(block) {}
shared_ptr(const shared_ptr& other) : count(other.count), ptr(other.ptr) { shared_ptr(const shared_ptr& other) : counter(other.counter) {
if(count) (*count)++; _inc_counter();
} }
shared_ptr(shared_ptr&& other) : count(other.count), ptr(other.ptr) { shared_ptr(shared_ptr&& other) : counter(other.counter) {
other.count = nullptr; other.counter = nullptr;
other.ptr = nullptr;
} }
~shared_ptr() { ~shared_ptr() {
if (count && --(*count) == 0) _delete(); _dec_counter();
} }
bool operator==(const shared_ptr& other) const { bool operator==(const shared_ptr& other) const {
return ptr == other.ptr; return counter == other.counter;
} }
bool operator!=(const shared_ptr& other) const { bool operator!=(const shared_ptr& other) const {
return ptr != other.ptr; return counter != other.counter;
} }
bool operator==(std::nullptr_t) const { bool operator==(std::nullptr_t) const {
return ptr == nullptr; return counter == nullptr;
} }
bool operator!=(std::nullptr_t) const { bool operator!=(std::nullptr_t) const {
return ptr != nullptr; return counter != nullptr;
} }
shared_ptr& operator=(const shared_ptr& other) { shared_ptr& operator=(const shared_ptr& other) {
if (this != &other) { if (this != &other) {
if (count && --(*count) == 0) _delete(); _dec_counter();
count = other.count; counter = other.counter;
ptr = other.ptr; _inc_counter();
if (count) ++(*count);
} }
return *this; return *this;
} }
shared_ptr& operator=(shared_ptr&& other) { shared_ptr& operator=(shared_ptr&& other) {
if (this != &other) { if (this != &other) {
if (count && --(*count) == 0) _delete(); _dec_counter();
count = other.count; counter = other.counter;
ptr = other.ptr; other.counter = nullptr;
other.count = nullptr;
other.ptr = nullptr;
} }
return *this; return *this;
} }
T& operator*() const { T& operator*() const {
return *ptr; return *_t();
} }
T* operator->() const { T* operator->() const {
return ptr; return _t();
} }
T* get() const { T* get() const {
return ptr; return _t();
} }
int use_count() const { int use_count() const {
return count ? *count : 0; return counter ? *counter : 0;
} }
void reset(){ void reset(){
if (count && --(*count) == 0) _delete(); _dec_counter();
count = nullptr; counter = nullptr;
ptr = nullptr;
} }
}; };
template <typename T, typename... Args> #undef _t
#undef _inc_counter
#undef _dec_counter
template <typename T, typename U, typename... Args>
shared_ptr<T> make_shared(Args&&... args) { shared_ptr<T> make_shared(Args&&... args) {
return shared_ptr<T>(new T(std::forward<Args>(args)...)); static_assert(std::is_base_of<T, U>::value, "U must be derived from T");
int* p = (int*)malloc(sizeof(int) + sizeof(U));
*p = 1;
new(p+1) U(std::forward<Args>(args)...);
return shared_ptr<T>(p);
} }
template <typename T, typename... Args>
shared_ptr<T> make_shared(Args&&... args) {
int* p = (int*)malloc(sizeof(int) + sizeof(T));
*p = 1;
new(p+1) T(std::forward<Args>(args)...);
return shared_ptr<T>(p);
}
template <typename T> template <typename T>
class unique_ptr { class unique_ptr {

View File

@ -148,8 +148,9 @@ void __initializeBuiltinFunctions(VM* _vm) {
_vm->bindMethod("range", "__iter__", [](VM* vm, const pkpy::ArgList& args) { _vm->bindMethod("range", "__iter__", [](VM* vm, const pkpy::ArgList& args) {
vm->__checkType(args[0], vm->_tp_range); vm->__checkType(args[0], vm->_tp_range);
_Iterator* iter = new RangeIterator(vm, args[0]); return vm->PyIter(
return vm->PyIter(pkpy::shared_ptr<_Iterator>(iter)); pkpy::make_shared<_Iterator, RangeIterator>(vm, args[0])
);
}); });
_vm->bindMethod("NoneType", "__repr__", [](VM* vm, const pkpy::ArgList& args) { _vm->bindMethod("NoneType", "__repr__", [](VM* vm, const pkpy::ArgList& args) {
@ -313,8 +314,9 @@ void __initializeBuiltinFunctions(VM* _vm) {
}); });
_vm->bindMethod("str", "__iter__", [](VM* vm, const pkpy::ArgList& args) { _vm->bindMethod("str", "__iter__", [](VM* vm, const pkpy::ArgList& args) {
_Iterator* iter = new StringIterator(vm, args[0]); return vm->PyIter(
return vm->PyIter(pkpy::shared_ptr<_Iterator>(iter)); pkpy::make_shared<_Iterator, StringIterator>(vm, args[0])
);
}); });
_vm->bindMethod("str", "__repr__", [](VM* vm, const pkpy::ArgList& args) { _vm->bindMethod("str", "__repr__", [](VM* vm, const pkpy::ArgList& args) {
@ -426,8 +428,9 @@ void __initializeBuiltinFunctions(VM* _vm) {
/************ PyList ************/ /************ PyList ************/
_vm->bindMethod("list", "__iter__", [](VM* vm, const pkpy::ArgList& args) { _vm->bindMethod("list", "__iter__", [](VM* vm, const pkpy::ArgList& args) {
vm->__checkType(args[0], vm->_tp_list); vm->__checkType(args[0], vm->_tp_list);
_Iterator* iter = new VectorIterator(vm, args[0]); return vm->PyIter(
return vm->PyIter(pkpy::shared_ptr<_Iterator>(iter)); pkpy::make_shared<_Iterator, VectorIterator>(vm, args[0])
);
}); });
_vm->bindMethod("list", "append", [](VM* vm, const pkpy::ArgList& args) { _vm->bindMethod("list", "append", [](VM* vm, const pkpy::ArgList& args) {
@ -523,8 +526,9 @@ void __initializeBuiltinFunctions(VM* _vm) {
_vm->bindMethod("tuple", "__iter__", [](VM* vm, const pkpy::ArgList& args) { _vm->bindMethod("tuple", "__iter__", [](VM* vm, const pkpy::ArgList& args) {
vm->__checkType(args[0], vm->_tp_tuple); vm->__checkType(args[0], vm->_tp_tuple);
_Iterator* iter = new VectorIterator(vm, args[0]); return vm->PyIter(
return vm->PyIter(pkpy::shared_ptr<_Iterator>(iter)); pkpy::make_shared<_Iterator, VectorIterator>(vm, args[0])
);
}); });
_vm->bindMethod("tuple", "__len__", [](VM* vm, const pkpy::ArgList& args) { _vm->bindMethod("tuple", "__len__", [](VM* vm, const pkpy::ArgList& args) {

View File

@ -55,8 +55,9 @@ protected:
frame->push(obj); frame->push(obj);
} break; } break;
case OP_LOAD_NAME_PTR: { case OP_LOAD_NAME_PTR: {
const BasePointer* p = new NamePointer(frame->code->co_names[byte.arg]); frame->push(PyPointer(
frame->push(PyPointer(_Pointer(p))); pkpy::make_shared<const BasePointer, NamePointer>(frame->code->co_names[byte.arg])
));
} break; } break;
case OP_STORE_NAME_PTR: { case OP_STORE_NAME_PTR: {
const auto& p = frame->code->co_names[byte.arg]; const auto& p = frame->code->co_names[byte.arg];
@ -65,20 +66,25 @@ protected:
case OP_BUILD_ATTR_PTR: { case OP_BUILD_ATTR_PTR: {
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);
const BasePointer* p = new AttrPointer(obj, &attr); frame->push(PyPointer(
frame->push(PyPointer(_Pointer(p))); pkpy::make_shared<const BasePointer, AttrPointer>(obj, &attr)
));
} break; } break;
case OP_BUILD_ATTR_PTR_PTR: { case OP_BUILD_ATTR_PTR_PTR: {
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);
__checkType(obj, _tp_user_pointer); __checkType(obj, _tp_user_pointer);
const _Pointer& p = std::get<_Pointer>(obj->_native); const _Pointer& p = std::get<_Pointer>(obj->_native);
frame->push(PyPointer(_Pointer(new AttrPointer(p->get(this, frame), &attr)))); frame->push(PyPointer(
pkpy::make_shared<const BasePointer, AttrPointer>(p->get(this, frame), &attr)
));
} break; } break;
case OP_BUILD_INDEX_PTR: { case OP_BUILD_INDEX_PTR: {
PyVar index = frame->popValue(this); PyVar index = frame->popValue(this);
PyVar obj = frame->popValue(this); PyVar obj = frame->popValue(this);
frame->push(PyPointer(_Pointer(new IndexPointer(obj, index)))); frame->push(PyPointer(
pkpy::make_shared<const BasePointer, IndexPointer>(obj, index)
));
} break; } break;
case OP_STORE_PTR: { case OP_STORE_PTR: {
PyVar obj = frame->popValue(this); PyVar obj = frame->popValue(this);
@ -108,7 +114,9 @@ protected:
std::vector<_Pointer> pointers(items.size()); std::vector<_Pointer> pointers(items.size());
for(int i=0; i<items.size(); i++) for(int i=0; i<items.size(); i++)
pointers[i] = PyPointer_AS_C(items[i]); pointers[i] = PyPointer_AS_C(items[i]);
frame->push(PyPointer(_Pointer(new CompoundPointer(pointers)))); frame->push(PyPointer(
pkpy::make_shared<const BasePointer, CompoundPointer>(std::move(pointers))
));
} break; } break;
case OP_BUILD_STRING: case OP_BUILD_STRING:
{ {
@ -205,8 +213,10 @@ protected:
{ {
// _pointer to pointer // _pointer to pointer
const _Pointer p = PyPointer_AS_C(frame->__pop()); const _Pointer p = PyPointer_AS_C(frame->__pop());
_Pointer up(new UserPointer(p, frame->id)); frame->push(newObject(
frame->push(newObject(_tp_user_pointer, std::move(up))); _tp_user_pointer,
pkpy::make_shared<const BasePointer, UserPointer>(p, frame->id)
));
} break; } break;
case OP_UNARY_DEREF: case OP_UNARY_DEREF:
{ {
@ -660,7 +670,7 @@ public:
return nullptr; return nullptr;
} }
inline void setAttr(PyVar& obj, const _Str& name, const PyVar& value) { void setAttr(PyVar& obj, const _Str& name, const PyVar& value) {
if(obj->isType(_tp_super)){ if(obj->isType(_tp_super)){
const PyVar* root = &obj; const PyVar* root = &obj;
while(true){ while(true){
@ -673,7 +683,7 @@ public:
} }
} }
inline void setAttr(PyVar& obj, const _Str& name, PyVar&& value) { void setAttr(PyVar& obj, const _Str& name, PyVar&& value) {
if(obj->isType(_tp_super)){ if(obj->isType(_tp_super)){
const PyVar* root = &obj; const PyVar* root = &obj;
while(true){ while(true){
@ -728,7 +738,7 @@ public:
return isIntOrFloat(obj1) && isIntOrFloat(obj2); return isIntOrFloat(obj1) && isIntOrFloat(obj2);
} }
_Float numToFloat(const PyVar& obj){ inline _Float numToFloat(const PyVar& obj){
if (obj->isType(_tp_int)){ if (obj->isType(_tp_int)){
return (_Float)PyInt_AS_C(obj); return (_Float)PyInt_AS_C(obj);
}else if(obj->isType(_tp_float)){ }else if(obj->isType(_tp_float)){