mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-21 20:10:17 +00:00
update gc
This commit is contained in:
parent
6714a3f784
commit
0be3e7ab6c
@ -266,7 +266,7 @@ struct Pointer{
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline T& ref() noexcept { return *reinterpret_cast<T*>(ptr); }
|
||||
T& ref() noexcept { return *reinterpret_cast<T*>(ptr); }
|
||||
|
||||
PyObject* get(VM* vm){
|
||||
if(level > 1) return VAR_T(Pointer, ctype, level-1, ref<char*>());
|
||||
|
@ -62,10 +62,10 @@ struct Type {
|
||||
int index;
|
||||
Type(): index(-1) {}
|
||||
Type(int index): index(index) {}
|
||||
inline bool operator==(Type other) const noexcept {
|
||||
bool operator==(Type other) const noexcept {
|
||||
return this->index == other.index;
|
||||
}
|
||||
inline bool operator!=(Type other) const noexcept {
|
||||
bool operator!=(Type other) const noexcept {
|
||||
return this->index != other.index;
|
||||
}
|
||||
};
|
||||
|
@ -305,7 +305,7 @@ private:
|
||||
parser->set_next_token(TK("@eof"));
|
||||
}
|
||||
|
||||
inline TokenIndex peek() {
|
||||
TokenIndex peek() {
|
||||
return parser->curr.type;
|
||||
}
|
||||
|
||||
|
32
src/frame.h
32
src/frame.h
@ -18,10 +18,10 @@ struct Frame {
|
||||
const uint64_t id;
|
||||
std::vector<std::pair<int, std::vector<PyObject*>>> s_try_block;
|
||||
|
||||
inline NameDict& f_locals() noexcept { return _locals != nullptr ? *_locals : _module->attr(); }
|
||||
inline NameDict& f_globals() noexcept { return _module->attr(); }
|
||||
NameDict& f_locals() noexcept { return _locals != nullptr ? *_locals : _module->attr(); }
|
||||
NameDict& f_globals() noexcept { return _module->attr(); }
|
||||
|
||||
inline PyObject** f_closure_try_get(StrName name) noexcept {
|
||||
PyObject** f_closure_try_get(StrName name) noexcept {
|
||||
if(_closure == nullptr) return nullptr;
|
||||
return _closure->try_get(name);
|
||||
}
|
||||
@ -32,7 +32,7 @@ struct Frame {
|
||||
const NameDict_& _closure=nullptr)
|
||||
: co(co.get()), _module(_module), _locals(_locals), _closure(_closure), id(kFrameGlobalId++) { }
|
||||
|
||||
inline const Bytecode& next_bytecode() {
|
||||
const Bytecode& next_bytecode() {
|
||||
_ip = _next_ip++;
|
||||
return co->codes[_ip];
|
||||
}
|
||||
@ -53,11 +53,11 @@ struct Frame {
|
||||
// return ss.str();
|
||||
// }
|
||||
|
||||
inline bool has_next_bytecode() const {
|
||||
bool has_next_bytecode() const {
|
||||
return _next_ip < co->codes.size();
|
||||
}
|
||||
|
||||
inline PyObject* pop(){
|
||||
PyObject* pop(){
|
||||
#if PK_EXTRA_CHECK
|
||||
if(_data.empty()) throw std::runtime_error("_data.empty() is true");
|
||||
#endif
|
||||
@ -66,7 +66,7 @@ struct Frame {
|
||||
return v;
|
||||
}
|
||||
|
||||
inline void _pop(){
|
||||
void _pop(){
|
||||
#if PK_EXTRA_CHECK
|
||||
if(_data.empty()) throw std::runtime_error("_data.empty() is true");
|
||||
#endif
|
||||
@ -75,26 +75,26 @@ struct Frame {
|
||||
|
||||
void try_deref(VM*, PyObject*&);
|
||||
|
||||
inline PyObject* pop_value(VM* vm){
|
||||
PyObject* pop_value(VM* vm){
|
||||
PyObject* value = pop();
|
||||
try_deref(vm, value);
|
||||
return value;
|
||||
}
|
||||
|
||||
inline PyObject* top_value(VM* vm){
|
||||
PyObject* top_value(VM* vm){
|
||||
PyObject* value = top();
|
||||
try_deref(vm, value);
|
||||
return value;
|
||||
}
|
||||
|
||||
inline PyObject*& top(){
|
||||
PyObject*& top(){
|
||||
#if PK_EXTRA_CHECK
|
||||
if(_data.empty()) throw std::runtime_error("_data.empty() is true");
|
||||
#endif
|
||||
return _data.back();
|
||||
}
|
||||
|
||||
inline PyObject*& top_1(){
|
||||
PyObject*& top_1(){
|
||||
#if PK_EXTRA_CHECK
|
||||
if(_data.size() < 2) throw std::runtime_error("_data.size() < 2");
|
||||
#endif
|
||||
@ -102,16 +102,16 @@ struct Frame {
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void push(T&& obj){ _data.push_back(std::forward<T>(obj)); }
|
||||
void push(T&& obj){ _data.push_back(std::forward<T>(obj)); }
|
||||
|
||||
inline void jump_abs(int i){ _next_ip = i; }
|
||||
inline void jump_rel(int i){ _next_ip += i; }
|
||||
void jump_abs(int i){ _next_ip = i; }
|
||||
void jump_rel(int i){ _next_ip += i; }
|
||||
|
||||
inline void on_try_block_enter(){
|
||||
void on_try_block_enter(){
|
||||
s_try_block.emplace_back(co->codes[_ip].block, _data);
|
||||
}
|
||||
|
||||
inline void on_try_block_exit(){
|
||||
void on_try_block_exit(){
|
||||
s_try_block.pop_back();
|
||||
}
|
||||
|
||||
|
@ -13,7 +13,7 @@ public:
|
||||
this->current = r.start;
|
||||
}
|
||||
|
||||
inline bool _has_next(){
|
||||
bool _has_next(){
|
||||
return r.step > 0 ? current < r.stop : current > r.stop;
|
||||
}
|
||||
|
||||
|
@ -41,7 +41,7 @@ struct DictArrayPool {
|
||||
const std::vector<uint16_t> kHashSeeds = {9629, 43049, 13267, 59509, 39251, 1249, 35803, 54469, 27689, 9719, 34897, 18973, 30661, 19913, 27919, 32143, 3467, 28019, 1051, 39419, 1361, 28547, 48197, 2609, 24317, 22861, 41467, 17623, 52837, 59053, 33589, 32117};
|
||||
static DictArrayPool<32> _dict_pool;
|
||||
|
||||
inline uint16_t find_next_capacity(uint16_t n){
|
||||
inline static uint16_t find_next_capacity(uint16_t n){
|
||||
uint16_t x = 2;
|
||||
while(x < n) x <<= 1;
|
||||
return x;
|
||||
@ -49,7 +49,7 @@ inline uint16_t find_next_capacity(uint16_t n){
|
||||
|
||||
#define _hash(key, mask, hash_seed) ( ( (key).index * (hash_seed) >> 8 ) & (mask) )
|
||||
|
||||
inline uint16_t find_perfect_hash_seed(uint16_t capacity, const std::vector<StrName>& keys){
|
||||
inline static uint16_t find_perfect_hash_seed(uint16_t capacity, const std::vector<StrName>& keys){
|
||||
if(keys.empty()) return kHashSeeds[0];
|
||||
std::set<uint16_t> indices;
|
||||
std::pair<uint16_t, float> best_score = {kHashSeeds[0], 0.0f};
|
||||
@ -73,11 +73,11 @@ struct NameDict {
|
||||
uint16_t _mask;
|
||||
StrName* _keys;
|
||||
|
||||
inline PyObject*& value(uint16_t i){
|
||||
PyObject*& value(uint16_t i){
|
||||
return reinterpret_cast<PyObject**>(_keys + _capacity)[i];
|
||||
}
|
||||
|
||||
inline PyObject* value(uint16_t i) const {
|
||||
PyObject* value(uint16_t i) const {
|
||||
return reinterpret_cast<PyObject**>(_keys + _capacity)[i];
|
||||
}
|
||||
|
||||
@ -175,14 +175,14 @@ while(!_keys[i].empty()) { \
|
||||
_rehash(false); // do not resize
|
||||
}
|
||||
|
||||
inline PyObject** try_get(StrName key){
|
||||
PyObject** try_get(StrName key){
|
||||
bool ok; uint16_t i;
|
||||
HASH_PROBE(key, ok, i);
|
||||
if(!ok) return nullptr;
|
||||
return &value(i);
|
||||
}
|
||||
|
||||
inline bool try_set(StrName key, PyObject* val){
|
||||
bool try_set(StrName key, PyObject* val){
|
||||
bool ok; uint16_t i;
|
||||
HASH_PROBE(key, ok, i);
|
||||
if(!ok) return false;
|
||||
@ -190,7 +190,7 @@ while(!_keys[i].empty()) { \
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool contains(StrName key) const {
|
||||
bool contains(StrName key) const {
|
||||
bool ok; uint16_t i;
|
||||
HASH_PROBE(key, ok, i);
|
||||
return ok;
|
||||
|
10
src/obj.h
10
src/obj.h
@ -22,7 +22,7 @@ struct NativeFunc {
|
||||
bool method;
|
||||
|
||||
NativeFunc(NativeFuncRaw f, int argc, bool method) : f(f), argc(argc), method(method) {}
|
||||
inline PyObject* operator()(VM* vm, Args& args) const;
|
||||
PyObject* operator()(VM* vm, Args& args) const;
|
||||
};
|
||||
|
||||
struct Function {
|
||||
@ -98,9 +98,9 @@ struct PyObject {
|
||||
Type type;
|
||||
NameDict* _attr;
|
||||
|
||||
inline bool is_attr_valid() const noexcept { return _attr != nullptr; }
|
||||
inline NameDict& attr() noexcept { return *_attr; }
|
||||
inline PyObject* attr(StrName name) const noexcept { return (*_attr)[name]; }
|
||||
bool is_attr_valid() const noexcept { return _attr != nullptr; }
|
||||
NameDict& attr() noexcept { return *_attr; }
|
||||
PyObject* attr(StrName name) const noexcept { return (*_attr)[name]; }
|
||||
virtual void* value() = 0;
|
||||
|
||||
virtual void mark() {
|
||||
@ -120,7 +120,7 @@ struct Py_ : PyObject {
|
||||
Py_(Type type, const T& val): PyObject(type), _value(val) { _init(); }
|
||||
Py_(Type type, T&& val): PyObject(type), _value(std::move(val)) { _init(); }
|
||||
|
||||
inline void _init() noexcept {
|
||||
void _init() noexcept {
|
||||
if constexpr (std::is_same_v<T, Type> || std::is_same_v<T, DummyModule>) {
|
||||
_attr = new NameDict(8, kTypeAttrLoadFactor);
|
||||
}else if constexpr(std::is_same_v<T, DummyInstance>){
|
||||
|
@ -120,7 +120,7 @@ struct Parser {
|
||||
return t;
|
||||
}
|
||||
|
||||
inline char peekchar() const{ return *curr_char; }
|
||||
char peekchar() const{ return *curr_char; }
|
||||
|
||||
bool match_n_chars(int n, char c0){
|
||||
const char* c = curr_char;
|
||||
|
@ -14,8 +14,8 @@ struct BaseRef {
|
||||
|
||||
struct NameRef : BaseRef {
|
||||
const std::pair<StrName, NameScope> pair;
|
||||
inline StrName name() const { return pair.first; }
|
||||
inline NameScope scope() const { return pair.second; }
|
||||
StrName name() const { return pair.first; }
|
||||
NameScope scope() const { return pair.second; }
|
||||
NameRef(const std::pair<StrName, NameScope>& pair) : pair(pair) {}
|
||||
|
||||
PyObject* get(VM* vm, Frame* frame) const{
|
||||
|
@ -14,7 +14,7 @@ namespace pkpy {
|
||||
PyObject** _args;
|
||||
int _size;
|
||||
|
||||
inline void _alloc(int n){
|
||||
void _alloc(int n){
|
||||
this->_args = _pool.alloc(n);
|
||||
this->_size = n;
|
||||
}
|
||||
@ -59,7 +59,7 @@ namespace pkpy {
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline int size() const { return _size; }
|
||||
int size() const { return _size; }
|
||||
|
||||
List move_to_list() noexcept {
|
||||
List ret(_size);
|
||||
|
26
src/vm.h
26
src/vm.h
@ -89,7 +89,7 @@ public:
|
||||
return asRepr(obj);
|
||||
}
|
||||
|
||||
inline Frame* top_frame() const {
|
||||
Frame* top_frame() const {
|
||||
#if PK_EXTRA_CHECK
|
||||
if(callstack.empty()) UNREACHABLE();
|
||||
#endif
|
||||
@ -147,23 +147,23 @@ public:
|
||||
return obj;
|
||||
}
|
||||
|
||||
inline PyObject* call(PyObject* callable){
|
||||
PyObject* call(PyObject* callable){
|
||||
return call(callable, no_arg(), no_arg(), false);
|
||||
}
|
||||
|
||||
template<typename ArgT>
|
||||
inline std::enable_if_t<std::is_same_v<std::decay_t<ArgT>, Args>, PyObject*>
|
||||
std::enable_if_t<std::is_same_v<std::decay_t<ArgT>, Args>, PyObject*>
|
||||
call(PyObject* _callable, ArgT&& args){
|
||||
return call(_callable, std::forward<ArgT>(args), no_arg(), false);
|
||||
}
|
||||
|
||||
template<typename ArgT>
|
||||
inline std::enable_if_t<std::is_same_v<std::decay_t<ArgT>, Args>, PyObject*>
|
||||
std::enable_if_t<std::is_same_v<std::decay_t<ArgT>, Args>, PyObject*>
|
||||
call(PyObject* obj, const StrName name, ArgT&& args){
|
||||
return call(getattr(obj, name, true, true), std::forward<ArgT>(args), no_arg(), false);
|
||||
}
|
||||
|
||||
inline PyObject* call(PyObject* obj, StrName name){
|
||||
PyObject* call(PyObject* obj, StrName name){
|
||||
return call(getattr(obj, name, true, true), no_arg(), no_arg(), false);
|
||||
}
|
||||
|
||||
@ -185,7 +185,7 @@ public:
|
||||
}
|
||||
|
||||
template<typename ...Args>
|
||||
inline std::unique_ptr<Frame> _new_frame(Args&&... args){
|
||||
std::unique_ptr<Frame> _new_frame(Args&&... args){
|
||||
if(callstack.size() > recursionlimit){
|
||||
_error("RecursionError", "maximum recursion depth exceeded");
|
||||
}
|
||||
@ -193,7 +193,7 @@ public:
|
||||
}
|
||||
|
||||
template<typename ...Args>
|
||||
inline PyObject* _exec(Args&&... args){
|
||||
PyObject* _exec(Args&&... args){
|
||||
callstack.push(_new_frame(std::forward<Args>(args)...));
|
||||
return _exec();
|
||||
}
|
||||
@ -272,12 +272,12 @@ public:
|
||||
Type tp_super, tp_exception, tp_star_wrapper;
|
||||
|
||||
template<typename P>
|
||||
inline PyObject* PyIter(P&& value) {
|
||||
PyObject* PyIter(P&& value) {
|
||||
static_assert(std::is_base_of_v<BaseIter, std::decay_t<P>>);
|
||||
return gcnew<P>(tp_iterator, std::forward<P>(value));
|
||||
}
|
||||
|
||||
inline BaseIter* PyIter_AS_C(PyObject* obj)
|
||||
BaseIter* PyIter_AS_C(PyObject* obj)
|
||||
{
|
||||
check_type(obj, tp_iterator);
|
||||
return static_cast<BaseIter*>(obj->value());
|
||||
@ -309,16 +309,16 @@ public:
|
||||
|
||||
void AttributeError(Str msg){ _error("AttributeError", msg); }
|
||||
|
||||
inline void check_type(PyObject* obj, Type type){
|
||||
void check_type(PyObject* obj, Type type){
|
||||
if(is_type(obj, type)) return;
|
||||
TypeError("expected " + OBJ_NAME(_t(type)).escape(true) + ", but got " + OBJ_NAME(_t(obj)).escape(true));
|
||||
}
|
||||
|
||||
inline PyObject* _t(Type t){
|
||||
PyObject* _t(Type t){
|
||||
return _all_types[t.index].obj;
|
||||
}
|
||||
|
||||
inline PyObject* _t(PyObject* obj){
|
||||
PyObject* _t(PyObject* obj){
|
||||
if(is_int(obj)) return _t(tp_int);
|
||||
if(is_float(obj)) return _t(tp_float);
|
||||
return _all_types[OBJ_GET(Type, _t(obj->type)).index].obj;
|
||||
@ -358,7 +358,7 @@ public:
|
||||
const BaseRef* PyRef_AS_C(PyObject* obj);
|
||||
};
|
||||
|
||||
PyObject* NativeFunc::operator()(VM* vm, Args& args) const{
|
||||
inline PyObject* NativeFunc::operator()(VM* vm, Args& args) const{
|
||||
int args_size = args.size() - (int)method; // remove self
|
||||
if(argc != -1 && args_size != argc) {
|
||||
vm->TypeError("expected " + std::to_string(argc) + " arguments, but got " + std::to_string(args_size));
|
||||
|
Loading…
x
Reference in New Issue
Block a user