From 680a67812372e0c7744ea15558573bfe6396e525 Mon Sep 17 00:00:00 2001 From: blueloveTH Date: Sun, 21 May 2023 14:30:40 +0800 Subject: [PATCH] ... --- src/cffi.h | 2 +- src/common.h | 1 - src/iter.h | 185 +++++++++++++++++++++++++++++-------------------- src/linalg.h | 12 ---- src/memory.h | 7 +- src/namedict.h | 5 +- src/obj.h | 9 --- src/pocketpy.h | 22 +++--- src/vm.h | 46 ++++-------- 9 files changed, 140 insertions(+), 149 deletions(-) diff --git a/src/cffi.h b/src/cffi.h index 479b72a5..0f2b510b 100644 --- a/src/cffi.h +++ b/src/cffi.h @@ -296,7 +296,7 @@ struct C99ReflType final: ReflType{ } static void _register(VM* vm, PyObject* mod, PyObject* type){ - vm->bind_constructor<-1>(type, CPP_NOT_IMPLEMENTED()); + vm->bind_notimplemented_constructor(type); vm->bind_method<0>(type, "__call__", [](VM* vm, ArgsView args){ C99ReflType& self = _CAST(C99ReflType&, args[0]); diff --git a/src/common.h b/src/common.h index bef0fafa..d95cc98b 100644 --- a/src/common.h +++ b/src/common.h @@ -131,7 +131,6 @@ struct Type { #define THREAD_LOCAL // thread_local #define CPP_LAMBDA(x) ([](VM* vm, ArgsView args) { return x; }) -#define CPP_NOT_IMPLEMENTED() ([](VM* vm, ArgsView args) { vm->NotImplementedError(); return vm->None; }) #ifdef POCKETPY_H #define FATAL_ERROR() throw std::runtime_error( "L" + std::to_string(__LINE__) + " FATAL_ERROR()!"); diff --git a/src/iter.h b/src/iter.h index efa642a1..42ed993d 100644 --- a/src/iter.h +++ b/src/iter.h @@ -1,98 +1,131 @@ #pragma once -#include "ceval.h" +#include "cffi.h" +#include "common.h" #include "frame.h" namespace pkpy{ -class RangeIter final: public BaseIter { +struct RangeIter{ + PY_CLASS(RangeIter, builtins, "_range_iterator") + Range r; i64 current; - Range r; // copy by value, so we don't need to keep ref -public: - RangeIter(VM* vm, PyObject* ref) : BaseIter(vm) { - this->r = OBJ_GET(Range, ref); - this->current = r.start; - } + RangeIter(Range r) : r(r), current(r.start) {} - bool _has_next(){ - return r.step > 0 ? current < r.stop : current > r.stop; - } - - PyObject* next(){ - if(!_has_next()) return vm->StopIteration; - current += r.step; - return VAR(current-r.step); + static void _register(VM* vm, PyObject* mod, PyObject* type){ + vm->_all_types[OBJ_GET(Type, type)].subclass_enabled = false; + vm->bind_notimplemented_constructor(type); + vm->bind__iter__(OBJ_GET(Type, type), [](VM* vm, PyObject* obj){ return obj; }); + vm->bind__next__(OBJ_GET(Type, type), [](VM* vm, PyObject* obj){ + RangeIter& self = _CAST(RangeIter&, obj); + bool has_next = self.r.step > 0 ? self.current < self.r.stop : self.current > self.r.stop; + if(!has_next) return vm->StopIteration; + self.current += self.r.step; + return VAR(self.current - self.r.step); + }); } }; -template -class ArrayIter final: public BaseIter { +struct ArrayIter{ + PY_CLASS(ArrayIter, builtins, "_array_iterator") PyObject* ref; - T* array; - int index; -public: - ArrayIter(VM* vm, PyObject* ref) : BaseIter(vm), ref(ref) { - array = &OBJ_GET(T, ref); - index = 0; - } + PyObject** begin; + PyObject** end; + PyObject** current; - PyObject* next() override{ - if(index >= array->size()) return vm->StopIteration; - return array->operator[](index++); + ArrayIter(PyObject* ref, PyObject** begin, PyObject** end) + : ref(ref), begin(begin), end(end), current(begin) {} + + void _gc_mark() const{ OBJ_MARK(ref); } + + static void _register(VM* vm, PyObject* mod, PyObject* type){ + vm->_all_types[OBJ_GET(Type, type)].subclass_enabled = false; + vm->bind_notimplemented_constructor(type); + vm->bind__iter__(OBJ_GET(Type, type), [](VM* vm, PyObject* obj){ return obj; }); + vm->bind__next__(OBJ_GET(Type, type), [](VM* vm, PyObject* obj){ + ArrayIter& self = _CAST(ArrayIter&, obj); + if(self.current == self.end) return vm->StopIteration; + return *self.current++; + }); + } +}; + +struct StringIter{ + PY_CLASS(StringIter, builtins, "_string_iterator") + PyObject* ref; + Str* str; + int index; + + StringIter(PyObject* ref) : ref(ref), str(&OBJ_GET(Str, ref)), index(0) {} + + void _gc_mark() const{ OBJ_MARK(ref); } + + static void _register(VM* vm, PyObject* mod, PyObject* type){ + vm->_all_types[OBJ_GET(Type, type)].subclass_enabled = false; + vm->bind_notimplemented_constructor(type); + vm->bind__iter__(OBJ_GET(Type, type), [](VM* vm, PyObject* obj){ return obj; }); + vm->bind__next__(OBJ_GET(Type, type), [](VM* vm, PyObject* obj){ + StringIter& self = _CAST(StringIter&, obj); + // TODO: optimize this... operator[] is of O(n) complexity + if(self.index == self.str->u8_length()) return vm->StopIteration; + return VAR(self.str->u8_getitem(self.index++)); + }); + } +}; + +struct Generator{ + PY_CLASS(Generator, builtins, "_generator") + Frame frame; + int state; // 0,1,2 + List s_backup; + + Generator(Frame&& frame, ArgsView buffer): frame(std::move(frame)), state(0) { + for(PyObject* obj: buffer) s_backup.push_back(obj); } void _gc_mark() const{ - OBJ_MARK(ref); + frame._gc_mark(); + for(PyObject* obj: s_backup) OBJ_MARK(obj); + } + + PyObject* next(VM* vm){ + if(state == 2) return vm->StopIteration; + // reset frame._sp_base + frame._sp_base = frame._s->_sp; + frame._locals.a = frame._s->_sp; + // restore the context + for(PyObject* obj: s_backup) frame._s->push(obj); + s_backup.clear(); + vm->callstack.push(std::move(frame)); + PyObject* ret = vm->_run_top_frame(); + if(ret == PY_OP_YIELD){ + // backup the context + frame = std::move(vm->callstack.top()); + PyObject* ret = frame._s->popx(); + for(PyObject* obj: frame.stack_view()) s_backup.push_back(obj); + vm->_pop_frame(); + state = 1; + if(ret == vm->StopIteration) state = 2; + return ret; + }else{ + state = 2; + return vm->StopIteration; + } + } + + static void _register(VM* vm, PyObject* mod, PyObject* type){ + vm->_all_types[OBJ_GET(Type, type)].subclass_enabled = false; + vm->bind_notimplemented_constructor(type); + vm->bind__iter__(OBJ_GET(Type, type), [](VM* vm, PyObject* obj){ return obj; }); + vm->bind__next__(OBJ_GET(Type, type), [](VM* vm, PyObject* obj){ + Generator& self = _CAST(Generator&, obj); + return self.next(vm); + }); } }; -class StringIter final: public BaseIter { - PyObject* ref; - int index; -public: - StringIter(VM* vm, PyObject* ref) : BaseIter(vm), ref(ref), index(0) {} - - PyObject* next() override{ - // TODO: optimize this to use iterator - // operator[] is O(n) complexity - Str* str = &OBJ_GET(Str, ref); - if(index == str->u8_length()) return vm->StopIteration; - return VAR(str->u8_getitem(index++)); - } - - void _gc_mark() const{ - OBJ_MARK(ref); - } -}; - -inline PyObject* Generator::next(){ - if(state == 2) return vm->StopIteration; - // reset frame._sp_base - frame._sp_base = frame._s->_sp; - frame._locals.a = frame._s->_sp; - // restore the context - for(PyObject* obj: s_backup) frame._s->push(obj); - s_backup.clear(); - vm->callstack.push(std::move(frame)); - PyObject* ret = vm->_run_top_frame(); - if(ret == PY_OP_YIELD){ - // backup the context - frame = std::move(vm->callstack.top()); - PyObject* ret = frame._s->popx(); - for(PyObject* obj: frame.stack_view()) s_backup.push_back(obj); - vm->_pop_frame(); - state = 1; - if(ret == vm->StopIteration) state = 2; - return ret; - }else{ - state = 2; - return vm->StopIteration; - } -} - -inline void Generator::_gc_mark() const{ - frame._gc_mark(); - for(PyObject* obj: s_backup) OBJ_MARK(obj); +inline PyObject* VM::_py_generator(Frame&& frame, ArgsView buffer){ + return VAR_T(Generator, std::move(frame), buffer); } } // namespace pkpy \ No newline at end of file diff --git a/src/linalg.h b/src/linalg.h index 364a960f..a2fe1b3c 100644 --- a/src/linalg.h +++ b/src/linalg.h @@ -204,12 +204,6 @@ struct Mat3x3{ } /*************** affine transformations ***************/ - static Mat3x3 translate(Vec2 v){ - return Mat3x3(1.0f, 0.0f, v.x, - 0.0f, 1.0f, v.y, - 0.0f, 0.0f, 1.0f); - } - static Mat3x3 rotate(float radian){ float cr = cosf(radian); float sr = sinf(radian); @@ -218,12 +212,6 @@ struct Mat3x3{ 0.0f, 0.0f, 1.0f); } - static Mat3x3 scale(Vec2 s){ - return Mat3x3(s.x, 0.0f, 0.0f, - 0.0f, s.y, 0.0f, - 0.0f, 0.0f, 1.0f); - } - static Mat3x3 trs(Vec2 t, float radian, Vec2 s){ float cr = cosf(radian); float sr = sinf(radian); diff --git a/src/memory.h b/src/memory.h index 3c3d8166..9b087cd4 100644 --- a/src/memory.h +++ b/src/memory.h @@ -246,16 +246,13 @@ inline size_t memory_usage(){ return pool64.allocated_size() + pool128.allocated_size(); } -#define SP_MALLOC(size) pool128.alloc(size) -#define SP_FREE(p) pool128.dealloc(p) - template struct shared_ptr { int* counter; T* _t() const noexcept { return (T*)(counter + 1); } void _inc_counter() { if(counter) ++(*counter); } - void _dec_counter() { if(counter && --(*counter) == 0) {((T*)(counter + 1))->~T(); SP_FREE(counter);} } + void _dec_counter() { if(counter && --(*counter) == 0) {((T*)(counter + 1))->~T(); pool128.dealloc(counter);} } public: shared_ptr() : counter(nullptr) {} @@ -307,7 +304,7 @@ public: template shared_ptr make_sp(Args&&... args) { - int* p = (int*)SP_MALLOC(sizeof(int) + sizeof(T)); + int* p = (int*)pool128.alloc(sizeof(int) + sizeof(T)); *p = 1; new(p+1) T(std::forward(args)...); return shared_ptr(p); diff --git a/src/namedict.h b/src/namedict.h index b7e644f5..d78581ef 100644 --- a/src/namedict.h +++ b/src/namedict.h @@ -6,7 +6,7 @@ namespace pkpy{ -const std::vector kHashSeeds = {9629, 43049, 13267, 59509, 39251, 1249, 27689, 9719, 19913}; +const uint16_t kHashSeeds[] = {9629, 43049, 13267, 59509, 39251, 1249, 27689, 9719, 19913}; #define _hash(key, mask, hash_seed) ( ( (key).index * (hash_seed) >> 8 ) & (mask) ) @@ -15,7 +15,8 @@ inline uint16_t find_perfect_hash_seed(uint16_t capacity, const std::vector indices; indices.clear(); std::pair best_score = {kHashSeeds[0], 0.0f}; - for(int i=0; ibind__iter__(_vm->tp_range, [](VM* vm, PyObject* obj) { - return vm->PyIter(RangeIter(vm, obj)); - }); - + _vm->bind__iter__(_vm->tp_range, [](VM* vm, PyObject* obj) { return VAR_T(RangeIter, OBJ_GET(Range, obj)); }); _vm->bind__repr__(_vm->_type("NoneType"), [](VM* vm, PyObject* obj) { return VAR("None"); }); _vm->bind__json__(_vm->_type("NoneType"), [](VM* vm, PyObject* obj) { return VAR("null"); }); @@ -373,7 +370,7 @@ inline void init_builtins(VM* _vm) { return self.index(other) != -1; }); _vm->bind__str__(_vm->tp_str, [](VM* vm, PyObject* obj) { return obj; }); - _vm->bind__iter__(_vm->tp_str, [](VM* vm, PyObject* obj) { return vm->PyIter(StringIter(vm, obj)); }); + _vm->bind__iter__(_vm->tp_str, [](VM* vm, PyObject* obj) { return VAR_T(StringIter, obj); }); _vm->bind__repr__(_vm->tp_str, [](VM* vm, PyObject* obj) { const Str& self = _CAST(Str&, obj); return VAR(self.escape(true)); @@ -551,7 +548,8 @@ inline void init_builtins(VM* _vm) { return (i64)_CAST(List&, obj).size(); }); _vm->bind__iter__(_vm->tp_list, [](VM* vm, PyObject* obj) { - return vm->PyIter(ArrayIter(vm, obj)); + List& self = _CAST(List&, obj); + return VAR_T(ArrayIter, obj, self.begin(), self.end()); }); _vm->bind__getitem__(_vm->tp_list, PyArrayGetItem); _vm->bind__setitem__(_vm->tp_list, [](VM* vm, PyObject* obj, PyObject* index, PyObject* value){ @@ -584,13 +582,13 @@ inline void init_builtins(VM* _vm) { return x; }); - _vm->bind__iter__(_vm->tp_tuple, [](VM* vm, PyObject* self) { - return vm->PyIter(ArrayIter(vm, self)); + _vm->bind__iter__(_vm->tp_tuple, [](VM* vm, PyObject* obj) { + Tuple& self = _CAST(Tuple&, obj); + return VAR_T(ArrayIter, obj, self.begin(), self.end()); }); _vm->bind__getitem__(_vm->tp_tuple, PyArrayGetItem); - _vm->bind__len__(_vm->tp_tuple, [](VM* vm, PyObject* self) { - const Tuple& tuple = _CAST(Tuple&, self); - return (i64)tuple.size(); + _vm->bind__len__(_vm->tp_tuple, [](VM* vm, PyObject* obj) { + return (i64)_CAST(Tuple&, obj).size(); }); /************ bool ************/ @@ -1068,7 +1066,7 @@ struct ReMatch { ReMatch(i64 start, i64 end, std::cmatch m) : start(start), end(end), m(m) {} static void _register(VM* vm, PyObject* mod, PyObject* type){ - vm->bind_constructor<-1>(type, CPP_NOT_IMPLEMENTED()); + vm->bind_notimplemented_constructor(type); vm->bind_method<0>(type, "start", CPP_LAMBDA(VAR(_CAST(ReMatch&, args[0]).start))); vm->bind_method<0>(type, "end", CPP_LAMBDA(VAR(_CAST(ReMatch&, args[0]).end))); diff --git a/src/vm.h b/src/vm.h index a2a8cdc5..e48d71d8 100644 --- a/src/vm.h +++ b/src/vm.h @@ -48,19 +48,6 @@ inline int set_read_file_cwd(ReadFileCwdFunc func) { _read_file_cwd = func; retu inline PyObject* py_var(VM* vm, ctype&& value) { return vm->heap.gcnew(vm->ptype, std::move(value));} -class Generator final: public BaseIter { - Frame frame; - int state; // 0,1,2 - List s_backup; -public: - Generator(VM* vm, Frame&& frame, ArgsView buffer): BaseIter(vm), frame(std::move(frame)), state(0) { - for(PyObject* obj: buffer) s_backup.push_back(obj); - } - - PyObject* next() override; - void _gc_mark() const; -}; - struct PyTypeInfo{ PyObject* obj; Type base; @@ -144,7 +131,7 @@ public: // for quick access Type tp_object, tp_type, tp_int, tp_float, tp_bool, tp_str; Type tp_list, tp_tuple; - Type tp_function, tp_native_func, tp_iterator, tp_bound_method; + Type tp_function, tp_native_func, tp_bound_method; Type tp_slice, tp_range, tp_module; Type tp_super, tp_exception, tp_bytes, tp_mappingproxy; Type tp_dict; @@ -189,7 +176,6 @@ public: } PyObject* py_iter(PyObject* obj){ - if(is_type(obj, tp_iterator)) return obj; const PyTypeInfo* ti = _inst_type_info(obj); if(ti->m__iter__) return ti->m__iter__(this, obj); PyObject* self; @@ -477,12 +463,20 @@ public: template PyObject* bind_default_constructor(__T&& type) { - return bind_constructor<-1>(std::forward<__T>(type), [](VM* vm, ArgsView args){ + return bind_constructor<1>(std::forward<__T>(type), [](VM* vm, ArgsView args){ Type t = OBJ_GET(Type, args[0]); return vm->heap.gcnew(t, T()); }); } + template + PyObject* bind_notimplemented_constructor(__T&& type) { + return bind_constructor<-1>(std::forward<__T>(type), [](VM* vm, ArgsView args){ + vm->NotImplementedError(); + return vm->None; + }); + } + template PyObject* bind_builtin_func(Str name, NativeFuncC fn) { return bind_func(builtins, name, fn); @@ -496,17 +490,9 @@ public: return index; } - template - PyObject* PyIter(P&& value) { - static_assert(std::is_base_of_v>); - return heap.gcnew

(tp_iterator, std::forward

(value)); - } - PyObject* PyIterNext(PyObject* obj){ - if(is_non_tagged_type(obj, tp_iterator)){ - BaseIter* iter = static_cast(obj->value()); - return iter->next(); - } + const PyTypeInfo* ti = _inst_type_info(obj); + if(ti->m__next__) return ti->m__next__(this, obj); return call_method(obj, __next__); } @@ -600,6 +586,7 @@ public: void _error(Exception); PyObject* _run_top_frame(); void post_init(); + PyObject* _py_generator(Frame&& frame, ArgsView buffer); }; inline PyObject* NativeFunc::operator()(VM* vm, ArgsView args) const{ @@ -1049,7 +1036,6 @@ inline void VM::init_builtin_types(){ tp_module = _new_type_object("module"); tp_function = _new_type_object("function"); tp_native_func = _new_type_object("native_func"); - tp_iterator = _new_type_object("iterator"); tp_bound_method = _new_type_object("bound_method"); tp_super = _new_type_object("super"); tp_exception = _new_type_object("Exception"); @@ -1255,12 +1241,10 @@ inline PyObject* VM::_py_call(PyObject** p0, PyObject* callable, ArgsView args, if(co->is_generator){ s_data.reset(p0); - PyObject* ret = PyIter(Generator( - this, + return _py_generator( Frame(&s_data, nullptr, co, fn._module, callable), ArgsView(buffer, buffer + co_nlocals) - )); - return ret; + ); } // copy buffer back to stack