This commit is contained in:
blueloveTH 2023-05-21 14:30:40 +08:00
parent fdfe20ead1
commit 680a678123
9 changed files with 140 additions and 149 deletions

View File

@ -296,7 +296,7 @@ struct C99ReflType final: ReflType{
} }
static void _register(VM* vm, PyObject* mod, PyObject* type){ static void _register(VM* vm, PyObject* mod, PyObject* type){
vm->bind_constructor<-1>(type, CPP_NOT_IMPLEMENTED()); vm->bind_notimplemented_constructor<C99ReflType>(type);
vm->bind_method<0>(type, "__call__", [](VM* vm, ArgsView args){ vm->bind_method<0>(type, "__call__", [](VM* vm, ArgsView args){
C99ReflType& self = _CAST(C99ReflType&, args[0]); C99ReflType& self = _CAST(C99ReflType&, args[0]);

View File

@ -131,7 +131,6 @@ struct Type {
#define THREAD_LOCAL // thread_local #define THREAD_LOCAL // thread_local
#define CPP_LAMBDA(x) ([](VM* vm, ArgsView args) { return x; }) #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 #ifdef POCKETPY_H
#define FATAL_ERROR() throw std::runtime_error( "L" + std::to_string(__LINE__) + " FATAL_ERROR()!"); #define FATAL_ERROR() throw std::runtime_error( "L" + std::to_string(__LINE__) + " FATAL_ERROR()!");

View File

@ -1,71 +1,94 @@
#pragma once #pragma once
#include "ceval.h" #include "cffi.h"
#include "common.h"
#include "frame.h" #include "frame.h"
namespace pkpy{ namespace pkpy{
class RangeIter final: public BaseIter { struct RangeIter{
PY_CLASS(RangeIter, builtins, "_range_iterator")
Range r;
i64 current; i64 current;
Range r; // copy by value, so we don't need to keep ref RangeIter(Range r) : r(r), current(r.start) {}
public:
RangeIter(VM* vm, PyObject* ref) : BaseIter(vm) {
this->r = OBJ_GET(Range, ref);
this->current = r.start;
}
bool _has_next(){ static void _register(VM* vm, PyObject* mod, PyObject* type){
return r.step > 0 ? current < r.stop : current > r.stop; vm->_all_types[OBJ_GET(Type, type)].subclass_enabled = false;
} vm->bind_notimplemented_constructor<RangeIter>(type);
vm->bind__iter__(OBJ_GET(Type, type), [](VM* vm, PyObject* obj){ return obj; });
PyObject* next(){ vm->bind__next__(OBJ_GET(Type, type), [](VM* vm, PyObject* obj){
if(!_has_next()) return vm->StopIteration; RangeIter& self = _CAST(RangeIter&, obj);
current += r.step; bool has_next = self.r.step > 0 ? self.current < self.r.stop : self.current > self.r.stop;
return VAR(current-r.step); if(!has_next) return vm->StopIteration;
self.current += self.r.step;
return VAR(self.current - self.r.step);
});
} }
}; };
template <typename T> struct ArrayIter{
class ArrayIter final: public BaseIter { PY_CLASS(ArrayIter, builtins, "_array_iterator")
PyObject* ref; PyObject* ref;
T* array; PyObject** begin;
int index; PyObject** end;
public: PyObject** current;
ArrayIter(VM* vm, PyObject* ref) : BaseIter(vm), ref(ref) {
array = &OBJ_GET(T, ref);
index = 0;
}
PyObject* next() override{ ArrayIter(PyObject* ref, PyObject** begin, PyObject** end)
if(index >= array->size()) return vm->StopIteration; : ref(ref), begin(begin), end(end), current(begin) {}
return array->operator[](index++);
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<ArrayIter>(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<StringIter>(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{ void _gc_mark() const{
OBJ_MARK(ref); frame._gc_mark();
} for(PyObject* obj: s_backup) OBJ_MARK(obj);
};
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{ PyObject* next(VM* vm){
OBJ_MARK(ref);
}
};
inline PyObject* Generator::next(){
if(state == 2) return vm->StopIteration; if(state == 2) return vm->StopIteration;
// reset frame._sp_base // reset frame._sp_base
frame._sp_base = frame._s->_sp; frame._sp_base = frame._s->_sp;
@ -88,11 +111,21 @@ inline PyObject* Generator::next(){
state = 2; state = 2;
return vm->StopIteration; return vm->StopIteration;
} }
} }
inline void Generator::_gc_mark() const{ static void _register(VM* vm, PyObject* mod, PyObject* type){
frame._gc_mark(); vm->_all_types[OBJ_GET(Type, type)].subclass_enabled = false;
for(PyObject* obj: s_backup) OBJ_MARK(obj); vm->bind_notimplemented_constructor<Generator>(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);
});
}
};
inline PyObject* VM::_py_generator(Frame&& frame, ArgsView buffer){
return VAR_T(Generator, std::move(frame), buffer);
} }
} // namespace pkpy } // namespace pkpy

View File

@ -204,12 +204,6 @@ struct Mat3x3{
} }
/*************** affine transformations ***************/ /*************** 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){ static Mat3x3 rotate(float radian){
float cr = cosf(radian); float cr = cosf(radian);
float sr = sinf(radian); float sr = sinf(radian);
@ -218,12 +212,6 @@ struct Mat3x3{
0.0f, 0.0f, 1.0f); 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){ static Mat3x3 trs(Vec2 t, float radian, Vec2 s){
float cr = cosf(radian); float cr = cosf(radian);
float sr = sinf(radian); float sr = sinf(radian);

View File

@ -246,16 +246,13 @@ inline size_t memory_usage(){
return pool64.allocated_size() + pool128.allocated_size(); return pool64.allocated_size() + pool128.allocated_size();
} }
#define SP_MALLOC(size) pool128.alloc(size)
#define SP_FREE(p) pool128.dealloc(p)
template <typename T> template <typename T>
struct shared_ptr { struct shared_ptr {
int* counter; int* counter;
T* _t() const noexcept { return (T*)(counter + 1); } T* _t() const noexcept { return (T*)(counter + 1); }
void _inc_counter() { if(counter) ++(*counter); } 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: public:
shared_ptr() : counter(nullptr) {} shared_ptr() : counter(nullptr) {}
@ -307,7 +304,7 @@ public:
template <typename T, typename... Args> template <typename T, typename... Args>
shared_ptr<T> make_sp(Args&&... args) { shared_ptr<T> make_sp(Args&&... args) {
int* p = (int*)SP_MALLOC(sizeof(int) + sizeof(T)); int* p = (int*)pool128.alloc(sizeof(int) + sizeof(T));
*p = 1; *p = 1;
new(p+1) T(std::forward<Args>(args)...); new(p+1) T(std::forward<Args>(args)...);
return shared_ptr<T>(p); return shared_ptr<T>(p);

View File

@ -6,7 +6,7 @@
namespace pkpy{ namespace pkpy{
const std::vector<uint16_t> 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) ) #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<StrN
static std::set<uint16_t> indices; static std::set<uint16_t> indices;
indices.clear(); indices.clear();
std::pair<uint16_t, float> best_score = {kHashSeeds[0], 0.0f}; std::pair<uint16_t, float> best_score = {kHashSeeds[0], 0.0f};
for(int i=0; i<kHashSeeds.size(); i++){ const int kHashSeedsSize = sizeof(kHashSeeds) / sizeof(kHashSeeds[0]);
for(int i=0; i<kHashSeedsSize; i++){
indices.clear(); indices.clear();
for(auto key: keys){ for(auto key: keys){
uint16_t index = _hash(key, capacity-1, kHashSeeds[i]); uint16_t index = _hash(key, capacity-1, kHashSeeds[i]);

View File

@ -115,15 +115,6 @@ struct Slice {
Slice(PyObject* start, PyObject* stop, PyObject* step) : start(start), stop(stop), step(step) {} Slice(PyObject* start, PyObject* stop, PyObject* step) : start(start), stop(stop), step(step) {}
}; };
class BaseIter {
protected:
VM* vm;
public:
BaseIter(VM* vm) : vm(vm) {}
virtual PyObject* next() = 0;
virtual ~BaseIter() = default;
};
struct GCHeader { struct GCHeader {
bool enabled; // whether this object is managed by GC bool enabled; // whether this object is managed by GC
bool marked; // whether this object is marked bool marked; // whether this object is marked

View File

@ -223,10 +223,7 @@ inline void init_builtins(VM* _vm) {
return VAR(r); return VAR(r);
}); });
_vm->bind__iter__(_vm->tp_range, [](VM* vm, PyObject* obj) { _vm->bind__iter__(_vm->tp_range, [](VM* vm, PyObject* obj) { return VAR_T(RangeIter, OBJ_GET(Range, obj)); });
return vm->PyIter(RangeIter(vm, obj));
});
_vm->bind__repr__(_vm->_type("NoneType"), [](VM* vm, PyObject* obj) { return VAR("None"); }); _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"); }); _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; return self.index(other) != -1;
}); });
_vm->bind__str__(_vm->tp_str, [](VM* vm, PyObject* obj) { return obj; }); _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) { _vm->bind__repr__(_vm->tp_str, [](VM* vm, PyObject* obj) {
const Str& self = _CAST(Str&, obj); const Str& self = _CAST(Str&, obj);
return VAR(self.escape(true)); return VAR(self.escape(true));
@ -551,7 +548,8 @@ inline void init_builtins(VM* _vm) {
return (i64)_CAST(List&, obj).size(); return (i64)_CAST(List&, obj).size();
}); });
_vm->bind__iter__(_vm->tp_list, [](VM* vm, PyObject* obj) { _vm->bind__iter__(_vm->tp_list, [](VM* vm, PyObject* obj) {
return vm->PyIter(ArrayIter<List>(vm, obj)); List& self = _CAST(List&, obj);
return VAR_T(ArrayIter, obj, self.begin(), self.end());
}); });
_vm->bind__getitem__(_vm->tp_list, PyArrayGetItem<List>); _vm->bind__getitem__(_vm->tp_list, PyArrayGetItem<List>);
_vm->bind__setitem__(_vm->tp_list, [](VM* vm, PyObject* obj, PyObject* index, PyObject* value){ _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; return x;
}); });
_vm->bind__iter__(_vm->tp_tuple, [](VM* vm, PyObject* self) { _vm->bind__iter__(_vm->tp_tuple, [](VM* vm, PyObject* obj) {
return vm->PyIter(ArrayIter<Tuple>(vm, self)); Tuple& self = _CAST(Tuple&, obj);
return VAR_T(ArrayIter, obj, self.begin(), self.end());
}); });
_vm->bind__getitem__(_vm->tp_tuple, PyArrayGetItem<Tuple>); _vm->bind__getitem__(_vm->tp_tuple, PyArrayGetItem<Tuple>);
_vm->bind__len__(_vm->tp_tuple, [](VM* vm, PyObject* self) { _vm->bind__len__(_vm->tp_tuple, [](VM* vm, PyObject* obj) {
const Tuple& tuple = _CAST(Tuple&, self); return (i64)_CAST(Tuple&, obj).size();
return (i64)tuple.size();
}); });
/************ bool ************/ /************ bool ************/
@ -1068,7 +1066,7 @@ struct ReMatch {
ReMatch(i64 start, i64 end, std::cmatch m) : start(start), end(end), m(m) {} ReMatch(i64 start, i64 end, std::cmatch m) : start(start), end(end), m(m) {}
static void _register(VM* vm, PyObject* mod, PyObject* type){ static void _register(VM* vm, PyObject* mod, PyObject* type){
vm->bind_constructor<-1>(type, CPP_NOT_IMPLEMENTED()); vm->bind_notimplemented_constructor<ReMatch>(type);
vm->bind_method<0>(type, "start", CPP_LAMBDA(VAR(_CAST(ReMatch&, args[0]).start))); 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))); vm->bind_method<0>(type, "end", CPP_LAMBDA(VAR(_CAST(ReMatch&, args[0]).end)));

View File

@ -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));} 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{ struct PyTypeInfo{
PyObject* obj; PyObject* obj;
Type base; Type base;
@ -144,7 +131,7 @@ public:
// for quick access // for quick access
Type tp_object, tp_type, tp_int, tp_float, tp_bool, tp_str; Type tp_object, tp_type, tp_int, tp_float, tp_bool, tp_str;
Type tp_list, tp_tuple; 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_slice, tp_range, tp_module;
Type tp_super, tp_exception, tp_bytes, tp_mappingproxy; Type tp_super, tp_exception, tp_bytes, tp_mappingproxy;
Type tp_dict; Type tp_dict;
@ -189,7 +176,6 @@ public:
} }
PyObject* py_iter(PyObject* obj){ PyObject* py_iter(PyObject* obj){
if(is_type(obj, tp_iterator)) return obj;
const PyTypeInfo* ti = _inst_type_info(obj); const PyTypeInfo* ti = _inst_type_info(obj);
if(ti->m__iter__) return ti->m__iter__(this, obj); if(ti->m__iter__) return ti->m__iter__(this, obj);
PyObject* self; PyObject* self;
@ -477,12 +463,20 @@ public:
template<typename T, typename __T> template<typename T, typename __T>
PyObject* bind_default_constructor(__T&& type) { 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]); Type t = OBJ_GET(Type, args[0]);
return vm->heap.gcnew<T>(t, T()); return vm->heap.gcnew<T>(t, T());
}); });
} }
template<typename T, typename __T>
PyObject* bind_notimplemented_constructor(__T&& type) {
return bind_constructor<-1>(std::forward<__T>(type), [](VM* vm, ArgsView args){
vm->NotImplementedError();
return vm->None;
});
}
template<int ARGC> template<int ARGC>
PyObject* bind_builtin_func(Str name, NativeFuncC fn) { PyObject* bind_builtin_func(Str name, NativeFuncC fn) {
return bind_func<ARGC>(builtins, name, fn); return bind_func<ARGC>(builtins, name, fn);
@ -496,17 +490,9 @@ public:
return index; return index;
} }
template<typename P>
PyObject* PyIter(P&& value) {
static_assert(std::is_base_of_v<BaseIter, std::decay_t<P>>);
return heap.gcnew<P>(tp_iterator, std::forward<P>(value));
}
PyObject* PyIterNext(PyObject* obj){ PyObject* PyIterNext(PyObject* obj){
if(is_non_tagged_type(obj, tp_iterator)){ const PyTypeInfo* ti = _inst_type_info(obj);
BaseIter* iter = static_cast<BaseIter*>(obj->value()); if(ti->m__next__) return ti->m__next__(this, obj);
return iter->next();
}
return call_method(obj, __next__); return call_method(obj, __next__);
} }
@ -600,6 +586,7 @@ public:
void _error(Exception); void _error(Exception);
PyObject* _run_top_frame(); PyObject* _run_top_frame();
void post_init(); void post_init();
PyObject* _py_generator(Frame&& frame, ArgsView buffer);
}; };
inline PyObject* NativeFunc::operator()(VM* vm, ArgsView args) const{ 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_module = _new_type_object("module");
tp_function = _new_type_object("function"); tp_function = _new_type_object("function");
tp_native_func = _new_type_object("native_func"); tp_native_func = _new_type_object("native_func");
tp_iterator = _new_type_object("iterator");
tp_bound_method = _new_type_object("bound_method"); tp_bound_method = _new_type_object("bound_method");
tp_super = _new_type_object("super"); tp_super = _new_type_object("super");
tp_exception = _new_type_object("Exception"); 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){ if(co->is_generator){
s_data.reset(p0); s_data.reset(p0);
PyObject* ret = PyIter(Generator( return _py_generator(
this,
Frame(&s_data, nullptr, co, fn._module, callable), Frame(&s_data, nullptr, co, fn._module, callable),
ArgsView(buffer, buffer + co_nlocals) ArgsView(buffer, buffer + co_nlocals)
)); );
return ret;
} }
// copy buffer back to stack // copy buffer back to stack