diff --git a/include/pocketpy/cffi.h b/include/pocketpy/cffi.h index f4adfb9f..1aade54c 100644 --- a/include/pocketpy/cffi.h +++ b/include/pocketpy/cffi.h @@ -8,9 +8,8 @@ namespace pkpy { #define PY_CLASS(T, mod, name) \ static Type _type(VM* vm) { \ - static const StrName __x0(#mod); \ - static const StrName __x1(#name); \ - return PK_OBJ_GET(Type, vm->_modules[__x0]->attr(__x1)); \ + PK_LOCAL_STATIC const std::pair _path(#mod, #name); \ + return PK_OBJ_GET(Type, vm->_modules[_path.first]->attr()[_path.second]); \ } \ static void _check_type(VM* vm, PyObject* val){ \ if(!vm->isinstance(val, T::_type(vm))){ \ diff --git a/include/pocketpy/common.h b/include/pocketpy/common.h index 5ce4cc74..a58b987b 100644 --- a/include/pocketpy/common.h +++ b/include/pocketpy/common.h @@ -59,6 +59,8 @@ struct GIL { #define PK_UNUSED(x) (void)(x) +#define PK_LOCAL_STATIC static + namespace pkpy{ namespace std = ::std; diff --git a/include/pocketpy/config.h b/include/pocketpy/config.h index 3ad233c6..7c1b25c9 100644 --- a/include/pocketpy/config.h +++ b/include/pocketpy/config.h @@ -48,7 +48,7 @@ // This is the maximum number of arguments in a function declaration // including positional arguments, keyword-only arguments, and varargs // (not recommended to change this) -#define PK_MAX_CO_VARNAMES 255 +#define PK_MAX_CO_VARNAMES 32 namespace pkpy{ // Hash table load factor (smaller ones mean less collision but more memory) diff --git a/include/pocketpy/linalg.h b/include/pocketpy/linalg.h index fc079b6a..48125d93 100644 --- a/include/pocketpy/linalg.h +++ b/include/pocketpy/linalg.h @@ -102,18 +102,15 @@ struct Mat3x3{ void set_identity(){ set_zeros(); _11 = _22 = _33 = 1.0f; } static Mat3x3 zeros(){ - static Mat3x3 ret(0, 0, 0, 0, 0, 0, 0, 0, 0); - return ret; + return Mat3x3(0, 0, 0, 0, 0, 0, 0, 0, 0); } static Mat3x3 ones(){ - static Mat3x3 ret(1, 1, 1, 1, 1, 1, 1, 1, 1); - return ret; + return Mat3x3(1, 1, 1, 1, 1, 1, 1, 1, 1); } static Mat3x3 identity(){ - static Mat3x3 ret(1, 0, 0, 0, 1, 0, 0, 0, 1); - return ret; + return Mat3x3(1, 0, 0, 0, 1, 0, 0, 0, 1); } Mat3x3 operator+(const Mat3x3& other) const{ diff --git a/include/pocketpy/obj.h b/include/pocketpy/obj.h index db2f21ed..094da466 100644 --- a/include/pocketpy/obj.h +++ b/include/pocketpy/obj.h @@ -165,7 +165,6 @@ Str obj_type_name(VM* vm, Type type); #if PK_DEBUG_NO_BUILTINS #define OBJ_NAME(obj) Str("") #else -DEF_SNAME(__name__); #define OBJ_NAME(obj) PK_OBJ_GET(Str, vm->getattr(obj, __name__)) #endif diff --git a/include/pocketpy/pocketpy.h b/include/pocketpy/pocketpy.h index 14ac1464..62038860 100644 --- a/include/pocketpy/pocketpy.h +++ b/include/pocketpy/pocketpy.h @@ -59,7 +59,7 @@ struct PyREPL{ vm->bind_method<1>(type, "input", [](VM* vm, ArgsView args){ PyREPL& self = _CAST(PyREPL&, args[0]); const Str& s = CAST(Str&, args[1]); - static std::stringstream ss_out; + PK_LOCAL_STATIC std::stringstream ss_out; ss_out.str(""); TempOut _(vm, [](VM* vm, const Str& s){ ss_out << s; }); bool ok = self.repl->input(s.str()); diff --git a/include/pocketpy/str.h b/include/pocketpy/str.h index 430e0582..c8f7b316 100644 --- a/include/pocketpy/str.h +++ b/include/pocketpy/str.h @@ -174,6 +174,19 @@ const StrName __getitem__ = StrName::get("__getitem__"); const StrName __setitem__ = StrName::get("__setitem__"); const StrName __delitem__ = StrName::get("__delitem__"); +// specials +const StrName __new__ = StrName::get("__new__"); +const StrName __init__ = StrName::get("__init__"); +const StrName __call__ = StrName::get("__call__"); +const StrName __divmod__ = StrName::get("__divmod__"); +const StrName __enter__ = StrName::get("__enter__"); +const StrName __exit__ = StrName::get("__exit__"); +const StrName __name__ = StrName::get("__name__"); + +const StrName pk_id_add = StrName::get("add"); +const StrName pk_id_set = StrName::get("set"); +const StrName pk_id_eval = StrName::get("eval"); + #define DEF_SNAME(name) const static StrName name(#name) } // namespace pkpy \ No newline at end of file diff --git a/src/ceval.cpp b/src/ceval.cpp index 9fce2eb3..9c2a1633 100644 --- a/src/ceval.cpp +++ b/src/ceval.cpp @@ -3,11 +3,6 @@ namespace pkpy{ PyObject* VM::_run_top_frame(){ - DEF_SNAME(add); - DEF_SNAME(set); - DEF_SNAME(__enter__); - DEF_SNAME(__exit__); - FrameId frame = top_frame(); const int base_id = frame.index; bool need_raise = false; @@ -242,7 +237,7 @@ __NEXT_STEP:; DISPATCH(); /*****************************************/ TARGET(BUILD_LONG) { - const static StrName m_long("long"); + PK_LOCAL_STATIC const StrName m_long("long"); _0 = builtins->attr().try_get(m_long); if(_0 == nullptr) AttributeError(builtins, m_long); TOP() = call(_0, TOP()); @@ -275,7 +270,7 @@ __NEXT_STEP:; DISPATCH(); TARGET(BUILD_SET) _0 = VAR(STACK_VIEW(byte.arg).to_list()); - _0 = call(builtins->attr(set), _0); + _0 = call(builtins->attr(pk_id_set), _0); STACK_SHRINK(byte.arg); PUSH(_0); DISPATCH(); @@ -323,7 +318,7 @@ __NEXT_STEP:; _unpack_as_list(STACK_VIEW(byte.arg), list); STACK_SHRINK(byte.arg); _0 = VAR(std::move(list)); - _0 = call(builtins->attr(set), _0); + _0 = call(builtins->attr(pk_id_set), _0); PUSH(_0); } DISPATCH(); /*****************************************/ @@ -499,11 +494,10 @@ __NEXT_STEP:; frame->jump_abs_break(index); } DISPATCH(); /*****************************************/ - TARGET(EVAL){ - DEF_SNAME(eval); - _0 = builtins->attr(eval); + TARGET(EVAL) + _0 = builtins->attr(pk_id_eval); TOP() = call(_0, TOP()); - } DISPATCH(); + DISPATCH(); TARGET(CALL) _0 = vectorcall( byte.arg & 0xFFFF, // ARGC @@ -565,7 +559,7 @@ __NEXT_STEP:; } DISPATCH(); TARGET(SET_ADD) _0 = POPX(); - call_method(SECOND(), add, _0); + call_method(SECOND(), pk_id_add, _0); DISPATCH(); /*****************************************/ TARGET(UNARY_NEGATIVE) diff --git a/src/expr.cpp b/src/expr.cpp index 301a1658..fe514f1c 100644 --- a/src/expr.cpp +++ b/src/expr.cpp @@ -365,7 +365,7 @@ namespace pkpy{ void FStringExpr::emit(CodeEmitContext* ctx){ VM* vm = ctx->vm; - static const std::regex pattern(R"(\{(.*?)\})"); + PK_LOCAL_STATIC const std::regex pattern(R"(\{(.*?)\})"); std::cregex_iterator begin(src.begin(), src.end(), pattern); std::cregex_iterator end; int size = 0; diff --git a/src/io.cpp b/src/io.cpp index c6a080d4..63329f8a 100644 --- a/src/io.cpp +++ b/src/io.cpp @@ -89,8 +89,8 @@ void add_module_io(VM* vm){ PyObject* mod = vm->new_module("io"); FileIO::register_class(vm, mod); vm->bind_builtin_func<2>("open", [](VM* vm, ArgsView args){ - static StrName m_io("io"); - static StrName m_FileIO("FileIO"); + PK_LOCAL_STATIC StrName m_io("io"); + PK_LOCAL_STATIC StrName m_FileIO("FileIO"); return vm->call(vm->_modules[m_io]->attr(m_FileIO), args[0], args[1]); }); #endif diff --git a/src/lexer.cpp b/src/lexer.cpp index 75a88601..78a7f5c9 100644 --- a/src/lexer.cpp +++ b/src/lexer.cpp @@ -260,7 +260,7 @@ static bool is_unicode_Lo_char(uint32_t c) { } void Lexer::eat_number() { - static const std::regex pattern("^(0x)?[0-9a-fA-F]+(\\.[0-9]+)?(L)?"); + PK_LOCAL_STATIC const std::regex pattern("^(0x)?[0-9a-fA-F]+(\\.[0-9]+)?(L)?"); std::smatch m; const char* i = token_start; diff --git a/src/pocketpy.cpp b/src/pocketpy.cpp index 91214b5f..e4055904 100644 --- a/src/pocketpy.cpp +++ b/src/pocketpy.cpp @@ -132,7 +132,7 @@ void init_builtins(VM* _vm) { vm->ValueError("pow(): rhs should be positive"); } - static const auto _mul = [](i64 a, i64 b, i64 c){ + PK_LOCAL_STATIC const auto _mul = [](i64 a, i64 b, i64 c){ if(c < 16384) return (a%c) * (b%c) % c; i64 res = 0; while(b > 0){ @@ -192,7 +192,6 @@ void init_builtins(VM* _vm) { auto res = std::div(lhs, rhs); return VAR(Tuple({VAR(res.quot), VAR(res.rem)})); }else{ - DEF_SNAME(__divmod__); return vm->call_method(args[0], __divmod__, args[1]); } }); @@ -853,7 +852,7 @@ void init_builtins(VM* _vm) { return VAR(val ? "true" : "false"); }); - const static auto f_bool_add = [](VM* vm, PyObject* lhs, PyObject* rhs) -> PyObject* { + const PK_LOCAL_STATIC auto f_bool_add = [](VM* vm, PyObject* lhs, PyObject* rhs) -> PyObject* { int x = (int)_CAST(bool, lhs); if(is_int(rhs)) return VAR(x + _CAST(int, rhs)); if(rhs == vm->True) return VAR(x + 1); @@ -861,7 +860,7 @@ void init_builtins(VM* _vm) { return vm->NotImplemented; }; - const static auto f_bool_mul = [](VM* vm, PyObject* lhs, PyObject* rhs) -> PyObject* { + const PK_LOCAL_STATIC auto f_bool_mul = [](VM* vm, PyObject* lhs, PyObject* rhs) -> PyObject* { int x = (int)_CAST(bool, lhs); if(is_int(rhs)) return VAR(x * _CAST(int, rhs)); if(rhs == vm->True) return VAR(x); diff --git a/src/vm.cpp b/src/vm.cpp index 136ab7c9..0803e647 100644 --- a/src/vm.cpp +++ b/src/vm.cpp @@ -743,7 +743,7 @@ PyObject* VM::vectorcall(int ARGC, int KWARGC, bool op_call){ ArgsView args(p1 - ARGC - int(method_call), p1); ArgsView kwargs(p1, s_data._sp); - static PK_THREAD_LOCAL PyObject* buffer[PK_MAX_CO_VARNAMES]; + PyObject* buffer[PK_MAX_CO_VARNAMES]; if(is_non_tagged_type(callable, tp_native_func)){ const auto& f = PK_OBJ_GET(NativeFunc, callable); @@ -796,8 +796,6 @@ PyObject* VM::vectorcall(int ARGC, int KWARGC, bool op_call){ if(is_non_tagged_type(callable, tp_type)){ if(method_call) FATAL_ERROR(); // [type, NULL, args..., kwargs...] - - DEF_SNAME(__new__); PyObject* new_f = find_name_in_mro(callable, __new__); PyObject* obj; #if PK_DEBUG_EXTRA_CHECK @@ -819,7 +817,6 @@ PyObject* VM::vectorcall(int ARGC, int KWARGC, bool op_call){ // __init__ PyObject* self; - DEF_SNAME(__init__); callable = get_unbound_method(obj, __init__, &self, false); if (self != PY_NULL) { // replace `NULL` with `self` @@ -838,7 +835,6 @@ PyObject* VM::vectorcall(int ARGC, int KWARGC, bool op_call){ // handle `__call__` overload PyObject* self; - DEF_SNAME(__call__); PyObject* call_f = get_unbound_method(callable, __call__, &self, false); if(self != PY_NULL){ p1[-(ARGC + 2)] = call_f;