From 6714a3f7843afe512ccf8903720d12901bce1551 Mon Sep 17 00:00:00 2001 From: blueloveTH Date: Tue, 28 Mar 2023 17:46:49 +0800 Subject: [PATCH] update gc --- preprocess.py | 2 +- src/ceval.h | 2 +- src/cffi.h | 10 ++-- src/codeobject.h | 4 +- src/compiler.h | 2 +- src/frame.h | 2 +- src/gc.h | 5 +- src/io.h | 6 +-- src/iter.h | 2 +- src/namedict.h | 8 ++-- src/obj.h | 6 +-- src/pocketpy.h | 33 +++++++------- src/ref.h | 4 +- src/str.h | 6 +-- src/tuplelist.h | 14 +++--- src/vm.h | 116 +++++++++++++++++++++++++---------------------- 16 files changed, 113 insertions(+), 109 deletions(-) diff --git a/preprocess.py b/preprocess.py index deffcff7..23ac599e 100644 --- a/preprocess.py +++ b/preprocess.py @@ -20,7 +20,7 @@ def generate_python_sources(): #include namespace pkpy{ - std::map kPythonLibs = { + inline static std::map kPythonLibs = { ''' for key, value in sources.items(): header += ' '*8 + '{"' + key + '", "' + value + '"},' diff --git a/src/ceval.h b/src/ceval.h index 643d5042..0ef326a7 100644 --- a/src/ceval.h +++ b/src/ceval.h @@ -7,7 +7,7 @@ namespace pkpy{ Str _read_file_cwd(const Str& name, bool* ok); -PyObject* VM::run_frame(Frame* frame){ +inline PyObject* VM::run_frame(Frame* frame){ while(frame->has_next_bytecode()){ const Bytecode& byte = frame->next_bytecode(); switch (byte.op) diff --git a/src/cffi.h b/src/cffi.h index 3039ce9a..0bc6e8a8 100644 --- a/src/cffi.h +++ b/src/cffi.h @@ -152,7 +152,7 @@ struct TypeDB{ static TypeDB _type_db; -auto _ = [](){ +inline static auto ___x = [](){ #define REGISTER_BASIC_TYPE(T) _type_db.register_type(#T, {}); _type_db.register_type("void", {}); REGISTER_BASIC_TYPE(char); @@ -403,9 +403,9 @@ struct CType{ } }; -void add_module_c(VM* vm){ +inline void add_module_c(VM* vm){ PyObject* mod = vm->new_module("c"); - PyObject* ptr_t = Pointer::register_class(vm, mod); + Pointer::register_class(vm, mod); Value::register_class(vm, mod); CType::register_class(vm, mod); @@ -462,11 +462,11 @@ void add_module_c(VM* vm){ }); } -PyObject* py_var(VM* vm, void* p){ +inline PyObject* py_var(VM* vm, void* p){ return VAR_T(Pointer, _type_db.get(), (char*)p); } -PyObject* py_var(VM* vm, char* p){ +inline PyObject* py_var(VM* vm, char* p){ return VAR_T(Pointer, _type_db.get(), (char*)p); } diff --git a/src/codeobject.h b/src/codeobject.h index 27981b72..4778955c 100644 --- a/src/codeobject.h +++ b/src/codeobject.h @@ -18,7 +18,7 @@ enum Opcode { #undef OPCODE }; -static const char* OP_NAMES[] = { +inline const char* OP_NAMES[] = { #define OPCODE(name) #name, #include "opcodes.h" #undef OPCODE @@ -31,7 +31,7 @@ struct Bytecode{ uint16_t block; }; -Str pad(const Str& s, const int n){ +inline Str pad(const Str& s, const int n){ if(s.size() >= n) return s.substr(0, n); return s + std::string(n - s.size(), ' '); } diff --git a/src/compiler.h b/src/compiler.h index 0e6a5bb8..320e0aee 100644 --- a/src/compiler.h +++ b/src/compiler.h @@ -766,7 +766,7 @@ private: // from a import b as c, d as e void compile_from_import() { - Token tkmodule = _compile_import(); + _compile_import(); consume(TK("import")); if (match(TK("*"))) { if(name_scope() != NAME_GLOBAL) SyntaxError("import * can only be used in global scope"); diff --git a/src/frame.h b/src/frame.h index 850cc6f8..b4a0d18d 100644 --- a/src/frame.h +++ b/src/frame.h @@ -73,7 +73,7 @@ struct Frame { _data.pop_back(); } - inline void try_deref(VM*, PyObject*&); + void try_deref(VM*, PyObject*&); inline PyObject* pop_value(VM* vm){ PyObject* value = pop(); diff --git a/src/gc.h b/src/gc.h index ce85395e..bb1e2f36 100644 --- a/src/gc.h +++ b/src/gc.h @@ -6,12 +6,9 @@ namespace pkpy { struct ManagedHeap{ std::vector heap; - template - PyObject* gcnew(Type type, T&& val){ - PyObject* obj = new Py_>(type, std::forward(val)); + void _add(PyObject* obj){ obj->gc.enabled = true; heap.push_back(obj); - return obj; } void sweep(){ diff --git a/src/io.h b/src/io.h index 6ee42756..b5ea9f43 100644 --- a/src/io.h +++ b/src/io.h @@ -10,7 +10,7 @@ namespace pkpy{ -Str _read_file_cwd(const Str& name, bool* ok){ +inline Str _read_file_cwd(const Str& name, bool* ok){ std::filesystem::path path(name.c_str()); bool exists = std::filesystem::exists(path); if(!exists){ @@ -78,7 +78,7 @@ struct FileIO { } }; -void add_module_io(VM* vm){ +inline void add_module_io(VM* vm){ PyObject* mod = vm->new_module("io"); PyObject* type = FileIO::register_class(vm, mod); vm->bind_builtin_func<2>("open", [type](VM* vm, const Args& args){ @@ -86,7 +86,7 @@ void add_module_io(VM* vm){ }); } -void add_module_os(VM* vm){ +inline void add_module_os(VM* vm){ PyObject* mod = vm->new_module("os"); // Working directory is shared by all VMs!! vm->bind_func<0>(mod, "getcwd", [](VM* vm, const Args& args){ diff --git a/src/iter.h b/src/iter.h index 1ebdbdb6..71cd9a70 100644 --- a/src/iter.h +++ b/src/iter.h @@ -50,7 +50,7 @@ public: } }; -PyObject* Generator::next(){ +inline PyObject* Generator::next(){ if(state == 2) return nullptr; vm->callstack.push(std::move(frame)); PyObject* ret = vm->_exec(); diff --git a/src/namedict.h b/src/namedict.h index 22d6b783..2534a90d 100644 --- a/src/namedict.h +++ b/src/namedict.h @@ -6,7 +6,7 @@ namespace pkpy{ -const int kNameDictNodeSize = sizeof(StrName) + sizeof(PyObject*); +const int kNameDictNodeSize = sizeof(StrName) + sizeof(void*); template struct DictArrayPool { @@ -41,7 +41,7 @@ struct DictArrayPool { const std::vector 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; -uint16_t find_next_capacity(uint16_t n){ +inline uint16_t find_next_capacity(uint16_t n){ uint16_t x = 2; while(x < n) x <<= 1; return x; @@ -49,7 +49,7 @@ uint16_t find_next_capacity(uint16_t n){ #define _hash(key, mask, hash_seed) ( ( (key).index * (hash_seed) >> 8 ) & (mask) ) -uint16_t find_perfect_hash_seed(uint16_t capacity, const std::vector& keys){ +inline uint16_t find_perfect_hash_seed(uint16_t capacity, const std::vector& keys){ if(keys.empty()) return kHashSeeds[0]; std::set indices; std::pair best_score = {kHashSeeds[0], 0.0f}; @@ -207,7 +207,7 @@ while(!_keys[i].empty()) { \ bool ok; uint16_t i; HASH_PROBE(key, ok, i); if(!ok) throw std::out_of_range("NameDict key not found: " + key.str()); - _keys[i] = StrName(); value(i).reset(); + _keys[i] = StrName(); value(i) = nullptr; _size--; } diff --git a/src/obj.h b/src/obj.h index 80bfa100..9b094403 100644 --- a/src/obj.h +++ b/src/obj.h @@ -147,8 +147,8 @@ const int kTpFloatIndex = 3; inline bool is_type(PyObject* obj, Type type) noexcept { switch(type.index){ - case kTpIntIndex: return is_tag_01(obj); - case kTpFloatIndex: return is_tag_10(obj); + case kTpIntIndex: return is_int(obj); + case kTpFloatIndex: return is_float(obj); default: return !is_tagged(obj) && obj->type == type; } } @@ -216,7 +216,7 @@ __T _py_cast(VM* vm, PyObject* obj) { } #define VAR(x) py_var(vm, x) -#define VAR_T(T, ...) vm->heap.gcnew(T::_type(vm), T(__VA_ARGS__)) +#define VAR_T(T, ...) vm->gcnew(T::_type(vm), T(__VA_ARGS__)) #define CAST(T, x) py_cast(vm, x) #define _CAST(T, x) _py_cast(vm, x) diff --git a/src/pocketpy.h b/src/pocketpy.h index 6bf8bb66..ac5fd710 100644 --- a/src/pocketpy.h +++ b/src/pocketpy.h @@ -10,7 +10,7 @@ namespace pkpy { -CodeObject_ VM::compile(Str source, Str filename, CompileMode mode) { +inline CodeObject_ VM::compile(Str source, Str filename, CompileMode mode) { Compiler compiler(this, source.c_str(), filename, mode); try{ return compiler.compile(); @@ -42,7 +42,7 @@ CodeObject_ VM::compile(Str source, Str filename, CompileMode mode) { }); -void init_builtins(VM* _vm) { +inline void init_builtins(VM* _vm) { BIND_NUM_ARITH_OPT(__add__, +) BIND_NUM_ARITH_OPT(__sub__, -) BIND_NUM_ARITH_OPT(__mul__, *) @@ -69,7 +69,7 @@ void init_builtins(VM* _vm) { vm->TypeError("super(type, obj): obj must be an instance or subtype of type"); } Type base = vm->_all_types[type.index].base; - return vm->heap.gcnew(vm->tp_super, Super(args[1], base)); + return vm->gcnew(vm->tp_super, Super(args[1], base)); }); _vm->bind_builtin_func<2>("isinstance", [](VM* vm, Args& args) { @@ -88,7 +88,8 @@ void init_builtins(VM* _vm) { i64 lhs = CAST(i64, args[0]); i64 rhs = CAST(i64, args[1]); if(rhs == 0) vm->ZeroDivisionError(); - return VAR(Tuple{VAR(lhs/rhs), VAR(lhs%rhs)}); + Tuple t = Tuple{VAR(lhs/rhs), VAR(lhs%rhs)}; + return VAR(std::move(t)); }); _vm->bind_builtin_func<1>("eval", [](VM* vm, Args& args) { @@ -574,7 +575,7 @@ void init_builtins(VM* _vm) { #define __EXPORT #endif -void add_module_time(VM* vm){ +inline void add_module_time(VM* vm){ PyObject* mod = vm->new_module("time"); vm->bind_func<0>(mod, "time", [](VM* vm, Args& args) { auto now = std::chrono::high_resolution_clock::now(); @@ -582,20 +583,17 @@ void add_module_time(VM* vm){ }); } -void add_module_sys(VM* vm){ +inline void add_module_sys(VM* vm){ PyObject* mod = vm->new_module("sys"); vm->setattr(mod, "version", VAR(PK_VERSION)); - - vm->bind_func<1>(mod, "getrefcount", CPP_LAMBDA(VAR(args[0].use_count()))); vm->bind_func<0>(mod, "getrecursionlimit", CPP_LAMBDA(VAR(vm->recursionlimit))); - vm->bind_func<1>(mod, "setrecursionlimit", [](VM* vm, Args& args) { vm->recursionlimit = CAST(int, args[0]); return vm->None; }); } -void add_module_json(VM* vm){ +inline void add_module_json(VM* vm){ PyObject* mod = vm->new_module("json"); vm->bind_func<1>(mod, "loads", [](VM* vm, Args& args) { const Str& expr = CAST(Str&, args[0]); @@ -606,7 +604,7 @@ void add_module_json(VM* vm){ vm->bind_func<1>(mod, "dumps", CPP_LAMBDA(vm->call(args[0], __json__))); } -void add_module_math(VM* vm){ +inline void add_module_math(VM* vm){ PyObject* mod = vm->new_module("math"); vm->setattr(mod, "pi", VAR(3.1415926535897932384)); vm->setattr(mod, "e" , VAR(2.7182818284590452354)); @@ -625,7 +623,7 @@ void add_module_math(VM* vm){ vm->bind_func<1>(mod, "sqrt", CPP_LAMBDA(VAR(std::sqrt(vm->num_to_float(args[0]))))); } -void add_module_dis(VM* vm){ +inline void add_module_dis(VM* vm){ PyObject* mod = vm->new_module("dis"); vm->bind_func<1>(mod, "dis", [](VM* vm, Args& args) { PyObject* f = args[0]; @@ -651,7 +649,8 @@ struct ReMatch { vm->bind_method<0>(type, "span", [](VM* vm, Args& args) { auto& self = CAST(ReMatch&, args[0]); - return VAR(Tuple{VAR(self.start), VAR(self.end)}); + Tuple t = Tuple{VAR(self.start), VAR(self.end)}; + return VAR(std::move(t)); }); vm->bind_method<1>(type, "group", [](VM* vm, Args& args) { @@ -663,7 +662,7 @@ struct ReMatch { } }; -PyObject* _regex_search(const Str& pattern, const Str& string, bool fromStart, VM* vm){ +inline PyObject* _regex_search(const Str& pattern, const Str& string, bool fromStart, VM* vm){ std::regex re(pattern); std::smatch m; if(std::regex_search(string, m, re)){ @@ -675,7 +674,7 @@ PyObject* _regex_search(const Str& pattern, const Str& string, bool fromStart, V return vm->None; }; -void add_module_re(VM* vm){ +inline void add_module_re(VM* vm){ PyObject* mod = vm->new_module("re"); ReMatch::register_class(vm, mod); @@ -749,14 +748,14 @@ struct Random{ } }; -void add_module_random(VM* vm){ +inline void add_module_random(VM* vm){ PyObject* mod = vm->new_module("random"); Random::register_class(vm, mod); CodeObject_ code = vm->compile(kPythonLibs["random"], "random.py", EXEC_MODE); vm->_exec(code, mod); } -void VM::post_init(){ +inline void VM::post_init(){ init_builtins(this); add_module_sys(this); add_module_time(this); diff --git a/src/ref.h b/src/ref.h index 88d3e58a..f08c4956 100644 --- a/src/ref.h +++ b/src/ref.h @@ -154,10 +154,10 @@ struct TupleRef : BaseRef { template PyObject* VM::PyRef(P&& value) { static_assert(std::is_base_of_v>); - return heap.gcnew

(tp_ref, std::forward

(value)); + return gcnew

(tp_ref, std::forward

(value)); } -const BaseRef* VM::PyRef_AS_C(PyObject* obj) +inline const BaseRef* VM::PyRef_AS_C(PyObject* obj) { if(!is_type(obj, tp_ref)) TypeError("expected an l-value"); return static_cast(obj->value()); diff --git a/src/str.h b/src/str.h index 7c7ccd88..d5119619 100644 --- a/src/str.h +++ b/src/str.h @@ -127,7 +127,7 @@ public: const uint32_t kLoRangeA[] = {170,186,443,448,660,1488,1519,1568,1601,1646,1649,1749,1774,1786,1791,1808,1810,1869,1969,1994,2048,2112,2144,2208,2230,2308,2365,2384,2392,2418,2437,2447,2451,2474,2482,2486,2493,2510,2524,2527,2544,2556,2565,2575,2579,2602,2610,2613,2616,2649,2654,2674,2693,2703,2707,2730,2738,2741,2749,2768,2784,2809,2821,2831,2835,2858,2866,2869,2877,2908,2911,2929,2947,2949,2958,2962,2969,2972,2974,2979,2984,2990,3024,3077,3086,3090,3114,3133,3160,3168,3200,3205,3214,3218,3242,3253,3261,3294,3296,3313,3333,3342,3346,3389,3406,3412,3423,3450,3461,3482,3507,3517,3520,3585,3634,3648,3713,3716,3718,3724,3749,3751,3762,3773,3776,3804,3840,3904,3913,3976,4096,4159,4176,4186,4193,4197,4206,4213,4238,4352,4682,4688,4696,4698,4704,4746,4752,4786,4792,4800,4802,4808,4824,4882,4888,4992,5121,5743,5761,5792,5873,5888,5902,5920,5952,5984,5998,6016,6108,6176,6212,6272,6279,6314,6320,6400,6480,6512,6528,6576,6656,6688,6917,6981,7043,7086,7098,7168,7245,7258,7401,7406,7413,7418,8501,11568,11648,11680,11688,11696,11704,11712,11720,11728,11736,12294,12348,12353,12447,12449,12543,12549,12593,12704,12784,13312,19968,40960,40982,42192,42240,42512,42538,42606,42656,42895,42999,43003,43011,43015,43020,43072,43138,43250,43259,43261,43274,43312,43360,43396,43488,43495,43514,43520,43584,43588,43616,43633,43642,43646,43697,43701,43705,43712,43714,43739,43744,43762,43777,43785,43793,43808,43816,43968,44032,55216,55243,63744,64112,64285,64287,64298,64312,64318,64320,64323,64326,64467,64848,64914,65008,65136,65142,65382,65393,65440,65474,65482,65490,65498,65536,65549,65576,65596,65599,65616,65664,66176,66208,66304,66349,66370,66384,66432,66464,66504,66640,66816,66864,67072,67392,67424,67584,67592,67594,67639,67644,67647,67680,67712,67808,67828,67840,67872,67968,68030,68096,68112,68117,68121,68192,68224,68288,68297,68352,68416,68448,68480,68608,68864,69376,69415,69424,69600,69635,69763,69840,69891,69956,69968,70006,70019,70081,70106,70108,70144,70163,70272,70280,70282,70287,70303,70320,70405,70415,70419,70442,70450,70453,70461,70480,70493,70656,70727,70751,70784,70852,70855,71040,71128,71168,71236,71296,71352,71424,71680,71935,72096,72106,72161,72163,72192,72203,72250,72272,72284,72349,72384,72704,72714,72768,72818,72960,72968,72971,73030,73056,73063,73066,73112,73440,73728,74880,77824,82944,92160,92736,92880,92928,93027,93053,93952,94032,94208,100352,110592,110928,110948,110960,113664,113776,113792,113808,123136,123214,123584,124928,126464,126469,126497,126500,126503,126505,126516,126521,126523,126530,126535,126537,126539,126541,126545,126548,126551,126553,126555,126557,126559,126561,126564,126567,126572,126580,126585,126590,126592,126603,126625,126629,126635,131072,173824,177984,178208,183984,194560}; const uint32_t kLoRangeB[] = {170,186,443,451,660,1514,1522,1599,1610,1647,1747,1749,1775,1788,1791,1808,1839,1957,1969,2026,2069,2136,2154,2228,2237,2361,2365,2384,2401,2432,2444,2448,2472,2480,2482,2489,2493,2510,2525,2529,2545,2556,2570,2576,2600,2608,2611,2614,2617,2652,2654,2676,2701,2705,2728,2736,2739,2745,2749,2768,2785,2809,2828,2832,2856,2864,2867,2873,2877,2909,2913,2929,2947,2954,2960,2965,2970,2972,2975,2980,2986,3001,3024,3084,3088,3112,3129,3133,3162,3169,3200,3212,3216,3240,3251,3257,3261,3294,3297,3314,3340,3344,3386,3389,3406,3414,3425,3455,3478,3505,3515,3517,3526,3632,3635,3653,3714,3716,3722,3747,3749,3760,3763,3773,3780,3807,3840,3911,3948,3980,4138,4159,4181,4189,4193,4198,4208,4225,4238,4680,4685,4694,4696,4701,4744,4749,4784,4789,4798,4800,4805,4822,4880,4885,4954,5007,5740,5759,5786,5866,5880,5900,5905,5937,5969,5996,6000,6067,6108,6210,6264,6276,6312,6314,6389,6430,6509,6516,6571,6601,6678,6740,6963,6987,7072,7087,7141,7203,7247,7287,7404,7411,7414,7418,8504,11623,11670,11686,11694,11702,11710,11718,11726,11734,11742,12294,12348,12438,12447,12538,12543,12591,12686,12730,12799,19893,40943,40980,42124,42231,42507,42527,42539,42606,42725,42895,42999,43009,43013,43018,43042,43123,43187,43255,43259,43262,43301,43334,43388,43442,43492,43503,43518,43560,43586,43595,43631,43638,43642,43695,43697,43702,43709,43712,43714,43740,43754,43762,43782,43790,43798,43814,43822,44002,55203,55238,55291,64109,64217,64285,64296,64310,64316,64318,64321,64324,64433,64829,64911,64967,65019,65140,65276,65391,65437,65470,65479,65487,65495,65500,65547,65574,65594,65597,65613,65629,65786,66204,66256,66335,66368,66377,66421,66461,66499,66511,66717,66855,66915,67382,67413,67431,67589,67592,67637,67640,67644,67669,67702,67742,67826,67829,67861,67897,68023,68031,68096,68115,68119,68149,68220,68252,68295,68324,68405,68437,68466,68497,68680,68899,69404,69415,69445,69622,69687,69807,69864,69926,69956,70002,70006,70066,70084,70106,70108,70161,70187,70278,70280,70285,70301,70312,70366,70412,70416,70440,70448,70451,70457,70461,70480,70497,70708,70730,70751,70831,70853,70855,71086,71131,71215,71236,71338,71352,71450,71723,71935,72103,72144,72161,72163,72192,72242,72250,72272,72329,72349,72440,72712,72750,72768,72847,72966,72969,73008,73030,73061,73064,73097,73112,73458,74649,75075,78894,83526,92728,92766,92909,92975,93047,93071,94026,94032,100343,101106,110878,110930,110951,111355,113770,113788,113800,113817,123180,123214,123627,125124,126467,126495,126498,126500,126503,126514,126519,126521,126523,126530,126535,126537,126539,126543,126546,126548,126551,126553,126555,126557,126559,126562,126564,126570,126578,126583,126588,126590,126601,126619,126627,126633,126651,173782,177972,178205,183969,191456,195101}; -bool is_unicode_Lo_char(uint32_t c) { +inline bool is_unicode_Lo_char(uint32_t c) { auto index = std::lower_bound(kLoRangeA, kLoRangeA + 476, c) - kLoRangeA; if(c == kLoRangeA[index]) return true; index -= 1; @@ -184,8 +184,8 @@ struct StrName { } }; -std::map> StrName::_interned; -std::vector StrName::_r_interned; +inline std::map> StrName::_interned; +inline std::vector StrName::_r_interned; const StrName __class__ = StrName::get("__class__"); const StrName __base__ = StrName::get("__base__"); diff --git a/src/tuplelist.h b/src/tuplelist.h index 97710de4..c9eca86e 100644 --- a/src/tuplelist.h +++ b/src/tuplelist.h @@ -41,8 +41,8 @@ namespace pkpy { static pkpy::Args from_list(List&& other) noexcept { Args ret(other.size()); - memcpy((void*)ret._args, (void*)other.data(), sizeof(PyObject*)*ret.size()); - memset((void*)other.data(), 0, sizeof(PyObject*)*ret.size()); + memcpy((void*)ret._args, (void*)other.data(), sizeof(void*)*ret.size()); + memset((void*)other.data(), 0, sizeof(void*)*ret.size()); other.clear(); return ret; } @@ -63,8 +63,8 @@ namespace pkpy { List move_to_list() noexcept { List ret(_size); - memcpy((void*)ret.data(), (void*)_args, sizeof(PyObject*)*_size); - memset((void*)_args, 0, sizeof(PyObject*)*_size); + memcpy((void*)ret.data(), (void*)_args, sizeof(void*)*_size); + memset((void*)_args, 0, sizeof(void*)*_size); return ret; } @@ -75,8 +75,8 @@ namespace pkpy { _args[0] = self; if(old_size == 0) return; - memcpy((void*)(_args+1), (void*)old_args, sizeof(PyObject*)*old_size); - memset((void*)old_args, 0, sizeof(PyObject*)*old_size); + memcpy((void*)(_args+1), (void*)old_args, sizeof(void*)*old_size); + memset((void*)old_args, 0, sizeof(void*)*old_size); _pool.dealloc(old_args, old_size); } @@ -89,5 +89,5 @@ namespace pkpy { } typedef Args Tuple; - THREAD_LOCAL SmallArrayPool Args::_pool; + inline THREAD_LOCAL SmallArrayPool Args::_pool; } // namespace pkpy \ No newline at end of file diff --git a/src/vm.h b/src/vm.h index bde67257..df534c8a 100644 --- a/src/vm.h +++ b/src/vm.h @@ -8,22 +8,22 @@ namespace pkpy{ #define DEF_NATIVE_2(ctype, ptype) \ - template<> ctype py_cast(VM* vm, PyObject* obj) { \ + template<> inline ctype py_cast(VM* vm, PyObject* obj) { \ vm->check_type(obj, vm->ptype); \ return OBJ_GET(ctype, obj); \ } \ - template<> ctype _py_cast(VM* vm, PyObject* obj) { \ + template<> inline ctype _py_cast(VM* vm, PyObject* obj) { \ return OBJ_GET(ctype, obj); \ } \ - template<> ctype& py_cast(VM* vm, PyObject* obj) { \ + template<> inline ctype& py_cast(VM* vm, PyObject* obj) { \ vm->check_type(obj, vm->ptype); \ return OBJ_GET(ctype, obj); \ } \ - template<> ctype& _py_cast(VM* vm, PyObject* obj) { \ + template<> inline ctype& _py_cast(VM* vm, PyObject* obj) { \ return OBJ_GET(ctype, obj); \ } \ - PyObject* py_var(VM* vm, const ctype& value) { return vm->heap.gcnew(vm->ptype, value);} \ - PyObject* py_var(VM* vm, ctype&& value) { return vm->heap.gcnew(vm->ptype, std::move(value));} + inline PyObject* py_var(VM* vm, const ctype& value) { return vm->gcnew(vm->ptype, value);} \ + inline PyObject* py_var(VM* vm, ctype&& value) { return vm->gcnew(vm->ptype, std::move(value));} class Generator: public BaseIter { std::unique_ptr frame; @@ -134,14 +134,21 @@ public: } PyObject* fast_call(StrName name, Args&& args){ - PyObject** val = find_name_in_mro(_t(args[0]).get(), name); + PyObject** val = find_name_in_mro(_t(args[0]), name); if(val != nullptr) return call(*val, std::move(args)); AttributeError(args[0], name); return nullptr; } - inline PyObject* call(PyObject* _callable){ - return call(_callable, no_arg(), no_arg(), false); + template + PyObject* gcnew(Type type, T&& val){ + PyObject* obj = new Py_>(type, std::forward(val)); + heap._add(obj); + return obj; + } + + inline PyObject* call(PyObject* callable){ + return call(callable, no_arg(), no_arg(), false); } template @@ -193,7 +200,7 @@ public: PyObject* property(NativeFuncRaw fget){ PyObject* p = builtins->attr("property"); - PyObject* method = heap.gcnew(tp_native_function, NativeFunc(fget, 1, false)); + PyObject* method = gcnew(tp_native_function, NativeFunc(fget, 1, false)); return call(p, Args{method}); } @@ -267,7 +274,7 @@ public: template inline PyObject* PyIter(P&& value) { static_assert(std::is_base_of_v>); - return heap.gcnew

(tp_iterator, std::forward

(value)); + return gcnew

(tp_iterator, std::forward

(value)); } inline BaseIter* PyIter_AS_C(PyObject* obj) @@ -359,7 +366,7 @@ PyObject* NativeFunc::operator()(VM* vm, Args& args) const{ return f(vm, args); } -void CodeObject::optimize(VM* vm){ +inline void CodeObject::optimize(VM* vm){ std::vector keys; for(auto& p: names) if(p.second == NAME_LOCAL) keys.push_back(p.first); uint32_t base_n = (uint32_t)(keys.size() / kLocalsLoadFactor + 0.5); @@ -411,13 +418,13 @@ DEF_NATIVE_2(Slice, tp_slice) DEF_NATIVE_2(Exception, tp_exception) DEF_NATIVE_2(StarWrapper, tp_star_wrapper) -#define PY_CAST_INT(T) \ -template<> T py_cast(VM* vm, PyObject* obj){ \ - vm->check_type(obj, vm->tp_int); \ - return (T)(obj.bits >> 2); \ -} \ -template<> T _py_cast(VM* vm, PyObject* obj){ \ - return (T)(obj.bits >> 2); \ +#define PY_CAST_INT(T) \ +template<> inline T py_cast(VM* vm, PyObject* obj){ \ + vm->check_type(obj, vm->tp_int); \ + return (T)(BITS(obj) >> 2); \ +} \ +template<> inline T _py_cast(VM* vm, PyObject* obj){ \ + return (T)(BITS(obj) >> 2); \ } PY_CAST_INT(char) @@ -432,32 +439,32 @@ PY_CAST_INT(unsigned long) PY_CAST_INT(unsigned long long) -template<> float py_cast(VM* vm, PyObject* obj){ +template<> inline float py_cast(VM* vm, PyObject* obj){ vm->check_type(obj, vm->tp_float); - i64 bits = obj.bits; + i64 bits = BITS(obj); bits = (bits >> 2) << 2; return BitsCvt(bits)._float; } -template<> float _py_cast(VM* vm, PyObject* obj){ - i64 bits = obj.bits; +template<> inline float _py_cast(VM* vm, PyObject* obj){ + i64 bits = BITS(obj); bits = (bits >> 2) << 2; return BitsCvt(bits)._float; } -template<> double py_cast(VM* vm, PyObject* obj){ +template<> inline double py_cast(VM* vm, PyObject* obj){ vm->check_type(obj, vm->tp_float); - i64 bits = obj.bits; + i64 bits = BITS(obj); bits = (bits >> 2) << 2; return BitsCvt(bits)._float; } -template<> double _py_cast(VM* vm, PyObject* obj){ - i64 bits = obj.bits; +template<> inline double _py_cast(VM* vm, PyObject* obj){ + i64 bits = BITS(obj); bits = (bits >> 2) << 2; return BitsCvt(bits)._float; } #define PY_VAR_INT(T) \ - PyObject* py_var(VM* vm, T _val){ \ + inline PyObject* py_var(VM* vm, T _val){ \ i64 val = static_cast(_val); \ if(((val << 2) >> 2) != val){ \ vm->_error("OverflowError", std::to_string(val) + " is out of range"); \ @@ -478,7 +485,7 @@ PY_VAR_INT(unsigned long) PY_VAR_INT(unsigned long long) #define PY_VAR_FLOAT(T) \ - PyObject* py_var(VM* vm, T _val){ \ + inline PyObject* py_var(VM* vm, T _val){ \ f64 val = static_cast(_val); \ i64 bits = BitsCvt(val)._int; \ bits = (bits >> 2) << 2; \ @@ -489,23 +496,23 @@ PY_VAR_INT(unsigned long long) PY_VAR_FLOAT(float) PY_VAR_FLOAT(double) -PyObject* py_var(VM* vm, bool val){ +inline PyObject* py_var(VM* vm, bool val){ return val ? vm->True : vm->False; } -template<> bool py_cast(VM* vm, PyObject* obj){ +template<> inline bool py_cast(VM* vm, PyObject* obj){ vm->check_type(obj, vm->tp_bool); return obj == vm->True; } -template<> bool _py_cast(VM* vm, PyObject* obj){ +template<> inline bool _py_cast(VM* vm, PyObject* obj){ return obj == vm->True; } -PyObject* py_var(VM* vm, const char val[]){ +inline PyObject* py_var(VM* vm, const char val[]){ return VAR(Str(val)); } -PyObject* py_var(VM* vm, std::string val){ +inline PyObject* py_var(VM* vm, std::string val){ return VAR(Str(std::move(val))); } @@ -514,7 +521,7 @@ void _check_py_class(VM* vm, PyObject* obj){ vm->check_type(obj, T::_type(vm)); } -PyObject* VM::num_negated(PyObject* obj){ +inline PyObject* VM::num_negated(PyObject* obj){ if (is_int(obj)){ return VAR(-CAST(i64, obj)); }else if(is_float(obj)){ @@ -524,7 +531,7 @@ PyObject* VM::num_negated(PyObject* obj){ return nullptr; } -f64 VM::num_to_float(PyObject* obj){ +inline f64 VM::num_to_float(PyObject* obj){ if(is_float(obj)){ return CAST(f64, obj); } else if (is_int(obj)){ @@ -534,7 +541,7 @@ f64 VM::num_to_float(PyObject* obj){ return 0; } -PyObject* VM::asBool(PyObject* obj){ +inline PyObject* VM::asBool(PyObject* obj){ if(is_type(obj, tp_bool)) return obj; if(obj == None) return False; if(is_type(obj, tp_int)) return VAR(CAST(i64, obj) != 0); @@ -547,7 +554,7 @@ PyObject* VM::asBool(PyObject* obj){ return True; } -i64 VM::hash(PyObject* obj){ +inline i64 VM::hash(PyObject* obj){ if (is_type(obj, tp_str)) return CAST(Str&, obj).hash(); if (is_int(obj)) return CAST(i64, obj); if (is_type(obj, tp_tuple)) { @@ -555,11 +562,12 @@ i64 VM::hash(PyObject* obj){ const Tuple& items = CAST(Tuple&, obj); for (int i=0; i> 2)); // recommended by Github Copilot + // recommended by Github Copilot + x = x ^ (y + 0x9e3779b9 + (x << 6) + (x >> 2)); } return x; } - if (is_type(obj, tp_type)) return obj.bits; + if (is_type(obj, tp_type)) return BITS(obj); if (is_type(obj, tp_bool)) return _CAST(bool, obj) ? 1 : 0; if (is_float(obj)){ f64 val = CAST(f64, obj); @@ -569,11 +577,11 @@ i64 VM::hash(PyObject* obj){ return 0; } -PyObject* VM::asRepr(PyObject* obj){ +inline PyObject* VM::asRepr(PyObject* obj){ return call(obj, __repr__); } -PyObject* VM::new_module(StrName name) { +inline PyObject* VM::new_module(StrName name) { PyObject* obj = new Py_(tp_module, DummyModule()); obj->attr().set(__name__, VAR(name.str())); // we do not allow override in order to avoid memory leak @@ -583,7 +591,7 @@ PyObject* VM::new_module(StrName name) { return obj; } -Str VM::disassemble(CodeObject_ co){ +inline Str VM::disassemble(CodeObject_ co){ std::vector jumpTargets; for(auto byte : co->codes){ if(byte.op == OP_JUMP_ABSOLUTE || byte.op == OP_SAFE_JUMP_ABSOLUTE || byte.op == OP_POP_JUMP_IF_FALSE){ @@ -652,7 +660,7 @@ Str VM::disassemble(CodeObject_ co){ return Str(ss.str()); } -void VM::init_builtin_types(){ +inline void VM::init_builtin_types(){ PyObject* _tp_object = new Py_(Type(1), Type(0)); PyObject* _tp_type = new Py_(Type(1), Type(1)); // PyTypeObject is managed by _all_types @@ -711,14 +719,14 @@ void VM::init_builtin_types(){ for(auto [k, v]: _modules.items()) v->attr()._try_perfect_rehash(); } -PyObject* VM::call(PyObject* callable, Args args, const Args& kwargs, bool opCall){ +inline PyObject* VM::call(PyObject* callable, Args args, const Args& kwargs, bool opCall){ if(is_type(callable, tp_type)){ PyObject** new_f = callable->attr().try_get(__new__); PyObject* obj; if(new_f != nullptr){ obj = call(*new_f, std::move(args), kwargs, false); }else{ - obj = heap.gcnew(_callable, {}); + obj = gcnew(OBJ_GET(Type, callable), {}); PyObject* init_f = getattr(obj, __init__, false, true); if (init_f != nullptr) call(init_f, std::move(args), kwargs, false); } @@ -784,15 +792,15 @@ PyObject* VM::call(PyObject* callable, Args args, const Args& kwargs, bool opCal return _exec(); } - PyObject* call_f = getattr(_callable, __call__, false, true); + PyObject* call_f = getattr(callable, __call__, false, true); if(call_f != nullptr){ return call(call_f, std::move(args), kwargs, false); } - TypeError(OBJ_NAME(_t(*callable)).escape(true) + " object is not callable"); + TypeError(OBJ_NAME(_t(callable)).escape(true) + " object is not callable"); return None; } -void VM::unpack_args(Args& args){ +inline void VM::unpack_args(Args& args){ List unpacked; for(int i=0; i; // https://docs.python.org/3/howto/descriptor.html#invocation-from-an-instance -PyObject* VM::getattr(PyObject* obj, StrName name, bool throw_err, bool class_only){ +inline PyObject* VM::getattr(PyObject* obj, StrName name, bool throw_err, bool class_only){ PyObject* objtype = _t(obj); // handle super() proxy if(is_type(obj, tp_super)){ @@ -842,12 +850,12 @@ PyObject* VM::getattr(PyObject* obj, StrName name, bool throw_err, bool class_on } template -void VM::setattr(PyObject* obj, StrName name, T&& value){ +inline void VM::setattr(PyObject* obj, StrName name, T&& value){ static_assert(std::is_same_v, PyObject*>); PyObject* objtype = _t(obj); // handle super() proxy if(is_type(obj, tp_super)){ - Super& super = OBJ_GET(Super, *obj); + Super& super = OBJ_GET(Super, obj); obj = super.first; objtype = _t(super.second); } @@ -881,7 +889,7 @@ void VM::bind_func(PyObject* obj, Str name, NativeFuncRaw fn) { obj->attr().set(name, VAR(NativeFunc(fn, ARGC, false))); } -void VM::_error(Exception e){ +inline void VM::_error(Exception e){ if(callstack.empty()){ e.is_re = false; throw e; @@ -890,7 +898,7 @@ void VM::_error(Exception e){ _raise(); } -PyObject* VM::_exec(){ +inline PyObject* VM::_exec(){ Frame* frame = top_frame(); i64 base_id = frame->id; PyObject* ret = nullptr;