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){
vm->bind_constructor<-1>(type, CPP_NOT_IMPLEMENTED());
vm->bind_notimplemented_constructor<C99ReflType>(type);
vm->bind_method<0>(type, "__call__", [](VM* vm, ArgsView args){
C99ReflType& self = _CAST(C99ReflType&, args[0]);

View File

@ -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()!");

View File

@ -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<RangeIter>(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 <typename T>
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<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{
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<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);
});
}
};
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

View File

@ -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);

View File

@ -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 <typename T>
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 <typename T, typename... 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;
new(p+1) T(std::forward<Args>(args)...);
return shared_ptr<T>(p);

View File

@ -6,7 +6,7 @@
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) )
@ -15,7 +15,8 @@ inline uint16_t find_perfect_hash_seed(uint16_t capacity, const std::vector<StrN
static std::set<uint16_t> indices;
indices.clear();
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();
for(auto key: keys){
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) {}
};
class BaseIter {
protected:
VM* vm;
public:
BaseIter(VM* vm) : vm(vm) {}
virtual PyObject* next() = 0;
virtual ~BaseIter() = default;
};
struct GCHeader {
bool enabled; // whether this object is managed by GC
bool marked; // whether this object is marked

View File

@ -223,10 +223,7 @@ inline void init_builtins(VM* _vm) {
return VAR(r);
});
_vm->bind__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<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__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<Tuple>(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<Tuple>);
_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<ReMatch>(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)));

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));}
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<typename T, typename __T>
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, 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>
PyObject* bind_builtin_func(Str name, NativeFuncC fn) {
return bind_func<ARGC>(builtins, name, fn);
@ -496,17 +490,9 @@ public:
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){
if(is_non_tagged_type(obj, tp_iterator)){
BaseIter* iter = static_cast<BaseIter*>(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