From 2dfb6ed07a85d3f89806f38bf5fdad6b326ca8c5 Mon Sep 17 00:00:00 2001 From: blueloveTH Date: Sun, 2 Jun 2024 16:53:51 +0800 Subject: [PATCH] major refactor --- 3rd/cjson/include/cJSONw.hpp | 2 +- 3rd/lua_bridge/src/lua_bridge.cpp | 4 +- CMakeLists.txt | 2 +- build_g.sh | 2 + include/pocketpy.h | 2 +- include/pocketpy.hpp | 3 + include/pocketpy/common.h | 240 ------------------ .../{_generated.h => common/_generated.hpp} | 0 include/pocketpy/{any.h => common/any.hpp} | 9 +- include/pocketpy/common/gil.hpp | 17 ++ .../{memory.h => common/memorypool.hpp} | 4 +- .../{namedict.h => common/namedict.hpp} | 21 +- include/pocketpy/{str.h => common/str.hpp} | 9 +- include/pocketpy/common/traits.hpp | 36 +++ include/pocketpy/common/types.hpp | 28 ++ include/pocketpy/common/utils.hpp | 28 ++ .../pocketpy/{vector.h => common/vector.hpp} | 25 +- include/pocketpy/common/version.hpp | 6 + .../{compiler.h => compiler/compiler.hpp} | 5 +- .../pocketpy/{expr.h => compiler/expr.hpp} | 7 +- .../pocketpy/{lexer.h => compiler/lexer.hpp} | 8 +- .../{bindings.h => interpreter/bindings.hpp} | 13 +- .../{ceval.h => interpreter/ceval.hpp} | 2 +- .../pocketpy/{cffi.h => interpreter/cffi.hpp} | 3 +- .../{frame.h => interpreter/frame.hpp} | 34 +-- include/pocketpy/{gc.h => interpreter/gc.hpp} | 7 +- .../pocketpy/{iter.h => interpreter/iter.hpp} | 4 +- .../{profiler.h => interpreter/profiler.hpp} | 2 +- include/pocketpy/{vm.h => interpreter/vm.hpp} | 24 +- .../{array2d.h => modules/array2d.hpp} | 2 +- .../pocketpy/{base64.h => modules/base64.hpp} | 2 +- include/pocketpy/{csv.h => modules/csv.hpp} | 2 +- .../dataclasses.hpp} | 2 +- .../pocketpy/{easing.h => modules/easing.hpp} | 2 +- include/pocketpy/{io.h => modules/io.hpp} | 2 +- .../pocketpy/{linalg.h => modules/linalg.hpp} | 5 +- .../{modules.h => modules/modules.hpp} | 2 +- .../pocketpy/{random.h => modules/random.hpp} | 2 +- include/pocketpy/objects/base.hpp | 100 ++++++++ .../pocketpy/{obj.h => objects/builtins.hpp} | 87 +------ .../{codeobject.h => objects/codeobject.hpp} | 25 +- include/pocketpy/{dict.h => objects/dict.hpp} | 6 +- .../pocketpy/{error.h => objects/error.hpp} | 34 +-- include/pocketpy/objects/object.hpp | 63 +++++ include/pocketpy/objects/sourcedata.hpp | 35 +++ include/pocketpy/objects/stackmemory.hpp | 17 ++ .../{tuplelist.h => objects/tuplelist.hpp} | 6 +- include/pocketpy/pocketpy.h | 18 -- include/pocketpy/pocketpy.hpp | 8 + include/pocketpy/{repl.h => tools/repl.hpp} | 2 +- prebuild.py | 6 +- src/{ => common}/_generated.cpp | 2 +- src/{ => common}/any.cpp | 10 +- src/{memory.cpp => common/memorypool.cpp} | 19 +- src/{ => common}/str.cpp | 12 +- src/{ => compiler}/compiler.cpp | 24 +- src/{ => compiler}/expr.cpp | 20 +- src/{ => compiler}/lexer.cpp | 7 +- src/{ => interpreter}/ceval.cpp | 14 +- src/{ => interpreter}/cffi.cpp | 2 +- src/{ => interpreter}/frame.cpp | 30 ++- src/{ => interpreter}/gc.cpp | 4 +- src/{ => interpreter}/iter.cpp | 2 +- src/{ => interpreter}/profiler.cpp | 6 +- src/{ => interpreter}/vm.cpp | 31 ++- src/{ => modules}/array2d.cpp | 11 +- src/{ => modules}/base64.cpp | 3 +- src/{ => modules}/csv.cpp | 3 +- src/{ => modules}/dataclasses.cpp | 3 +- src/{ => modules}/easing.cpp | 5 +- src/{ => modules}/io.cpp | 5 +- src/{ => modules}/linalg.cpp | 5 +- src/{ => modules}/modules.cpp | 10 +- src/{ => modules}/random.cpp | 5 +- src/namedict.cpp | 4 - src/objects/builtins.cpp | 6 + src/{ => objects}/codeobject.cpp | 5 +- src/{ => objects}/dict.cpp | 6 +- src/objects/error.cpp | 20 ++ src/{obj.cpp => objects/object.cpp} | 2 +- src/{error.cpp => objects/sourcedata.cpp} | 20 +- src/{ => objects}/tuplelist.cpp | 2 +- src/pocketpy.cpp | 19 +- src/pocketpy_c.cpp | 8 +- src/{ => tools}/repl.cpp | 5 +- 85 files changed, 665 insertions(+), 640 deletions(-) create mode 100644 include/pocketpy.hpp delete mode 100644 include/pocketpy/common.h rename include/pocketpy/{_generated.h => common/_generated.hpp} (100%) rename include/pocketpy/{any.h => common/any.hpp} (95%) create mode 100644 include/pocketpy/common/gil.hpp rename include/pocketpy/{memory.h => common/memorypool.hpp} (89%) rename include/pocketpy/{namedict.h => common/namedict.hpp} (92%) rename include/pocketpy/{str.h => common/str.hpp} (97%) create mode 100644 include/pocketpy/common/traits.hpp create mode 100644 include/pocketpy/common/types.hpp create mode 100644 include/pocketpy/common/utils.hpp rename include/pocketpy/{vector.h => common/vector.hpp} (96%) create mode 100644 include/pocketpy/common/version.hpp rename include/pocketpy/{compiler.h => compiler/compiler.hpp} (98%) rename include/pocketpy/{expr.h => compiler/expr.hpp} (99%) rename include/pocketpy/{lexer.h => compiler/lexer.hpp} (97%) rename include/pocketpy/{bindings.h => interpreter/bindings.hpp} (96%) rename include/pocketpy/{ceval.h => interpreter/ceval.hpp} (52%) rename include/pocketpy/{cffi.h => interpreter/cffi.hpp} (98%) rename include/pocketpy/{frame.h => interpreter/frame.hpp} (88%) rename include/pocketpy/{gc.h => interpreter/gc.hpp} (92%) rename include/pocketpy/{iter.h => interpreter/iter.hpp} (96%) rename include/pocketpy/{profiler.h => interpreter/profiler.hpp} (93%) rename include/pocketpy/{vm.h => interpreter/vm.hpp} (98%) rename include/pocketpy/{array2d.h => modules/array2d.hpp} (69%) rename include/pocketpy/{base64.h => modules/base64.hpp} (69%) rename include/pocketpy/{csv.h => modules/csv.hpp} (68%) rename include/pocketpy/{dataclasses.h => modules/dataclasses.hpp} (70%) rename include/pocketpy/{easing.h => modules/easing.hpp} (69%) rename include/pocketpy/{io.h => modules/io.hpp} (81%) rename include/pocketpy/{linalg.h => modules/linalg.hpp} (98%) rename include/pocketpy/{modules.h => modules/modules.hpp} (90%) rename include/pocketpy/{random.h => modules/random.hpp} (69%) create mode 100644 include/pocketpy/objects/base.hpp rename include/pocketpy/{obj.h => objects/builtins.hpp} (50%) rename include/pocketpy/{codeobject.h => objects/codeobject.hpp} (89%) rename include/pocketpy/{dict.h => objects/dict.hpp} (94%) rename include/pocketpy/{error.h => objects/error.hpp} (70%) create mode 100644 include/pocketpy/objects/object.hpp create mode 100644 include/pocketpy/objects/sourcedata.hpp create mode 100644 include/pocketpy/objects/stackmemory.hpp rename include/pocketpy/{tuplelist.h => objects/tuplelist.hpp} (95%) delete mode 100644 include/pocketpy/pocketpy.h create mode 100644 include/pocketpy/pocketpy.hpp rename include/pocketpy/{repl.h => tools/repl.hpp} (84%) rename src/{ => common}/_generated.cpp (99%) rename src/{ => common}/any.cpp (65%) rename src/{memory.cpp => common/memorypool.cpp} (94%) rename src/{ => common}/str.cpp (98%) rename src/{ => compiler}/compiler.cpp (98%) rename src/{ => compiler}/expr.cpp (98%) rename src/{ => compiler}/lexer.cpp (99%) rename src/{ => interpreter}/ceval.cpp (99%) rename src/{ => interpreter}/cffi.cpp (99%) rename src/{ => interpreter}/frame.cpp (82%) rename src/{ => interpreter}/gc.cpp (94%) rename src/{ => interpreter}/iter.cpp (99%) rename src/{ => interpreter}/profiler.cpp (97%) rename src/{ => interpreter}/vm.cpp (98%) rename src/{ => modules}/array2d.cpp (98%) rename src/{ => modules}/base64.cpp (98%) rename src/{ => modules}/csv.cpp (97%) rename src/{ => modules}/dataclasses.cpp (97%) rename src/{ => modules}/easing.cpp (98%) rename src/{ => modules}/io.cpp (98%) rename src/{ => modules}/linalg.cpp (99%) rename src/{ => modules}/modules.cpp (98%) rename src/{ => modules}/random.cpp (98%) delete mode 100644 src/namedict.cpp create mode 100644 src/objects/builtins.cpp rename src/{ => objects}/codeobject.cpp (64%) rename src/{ => objects}/dict.cpp (97%) create mode 100644 src/objects/error.cpp rename src/{obj.cpp => objects/object.cpp} (69%) rename src/{error.cpp => objects/sourcedata.cpp} (81%) rename src/{ => objects}/tuplelist.cpp (96%) rename src/{ => tools}/repl.cpp (92%) diff --git a/3rd/cjson/include/cJSONw.hpp b/3rd/cjson/include/cJSONw.hpp index 856165be..228c399b 100644 --- a/3rd/cjson/include/cJSONw.hpp +++ b/3rd/cjson/include/cJSONw.hpp @@ -1,5 +1,5 @@ #include "cJSON.h" -#include "pocketpy/pocketpy.h" +#include "pocketpy/pocketpy.hpp" namespace pkpy { diff --git a/3rd/lua_bridge/src/lua_bridge.cpp b/3rd/lua_bridge/src/lua_bridge.cpp index 16791862..62f7affe 100644 --- a/3rd/lua_bridge/src/lua_bridge.cpp +++ b/3rd/lua_bridge/src/lua_bridge.cpp @@ -8,7 +8,7 @@ static PyVar lua_popx_to_python(VM*); template static void table_apply(VM* vm, T f){ - PK_ASSERT(lua_istable(_L, -1)); + assert(lua_istable(_L, -1)); lua_pushnil(_L); // [key] while(lua_next(_L, -2) != 0){ // [key, val] lua_pushvalue(_L, -2); // [key, val, key] @@ -191,7 +191,7 @@ static PyVar lua_popx_multi_to_python(VM* vm, int count){ } return VAR(std::move(ret)); } - PK_FATAL_ERROR() + assert(false); } struct PyLuaFunction: PyLuaObject{ diff --git a/CMakeLists.txt b/CMakeLists.txt index 9af1a254..44360dbe 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,7 +17,7 @@ else() endif() include_directories(${CMAKE_CURRENT_LIST_DIR}/include) -aux_source_directory(${CMAKE_CURRENT_LIST_DIR}/src POCKETPY_SRC) +file(GLOB_RECURSE POCKETPY_SRC ${CMAKE_CURRENT_LIST_DIR}/src/*.cpp) option(PK_USE_CJSON "" OFF) if(PK_USE_CJSON) diff --git a/build_g.sh b/build_g.sh index d22c5975..bc8d17be 100644 --- a/build_g.sh +++ b/build_g.sh @@ -1,3 +1,5 @@ +python prebuild.py + SRC=$(find src/ -name "*.cpp") FLAGS="-std=c++17 -Og -stdlib=libc++ -Iinclude -frtti -Wfatal-errors -g" diff --git a/include/pocketpy.h b/include/pocketpy.h index 18ce7049..f56efe16 100644 --- a/include/pocketpy.h +++ b/include/pocketpy.h @@ -1,3 +1,3 @@ #pragma once -#include "pocketpy/pocketpy.h" \ No newline at end of file +#include "pocketpy/pocketpy.hpp" \ No newline at end of file diff --git a/include/pocketpy.hpp b/include/pocketpy.hpp new file mode 100644 index 00000000..f56efe16 --- /dev/null +++ b/include/pocketpy.hpp @@ -0,0 +1,3 @@ +#pragma once + +#include "pocketpy/pocketpy.hpp" \ No newline at end of file diff --git a/include/pocketpy/common.h b/include/pocketpy/common.h deleted file mode 100644 index 66400d99..00000000 --- a/include/pocketpy/common.h +++ /dev/null @@ -1,240 +0,0 @@ -#pragma once - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define PK_VERSION "2.0.0" -#define PK_VERSION_MAJOR 2 -#define PK_VERSION_MINOR 0 -#define PK_VERSION_PATCH 0 - -#include "config.h" -#include "export.h" - -#include "_generated.h" - -#ifdef min -#undef min -#endif - -#ifdef max -#undef max -#endif - -/*******************************************************************************/ - -#if PK_ENABLE_THREAD -#define PK_THREAD_LOCAL thread_local -#include - -struct GIL { - inline static std::mutex _mutex; - explicit GIL() { _mutex.lock(); } - ~GIL() { _mutex.unlock(); } -}; -#define PK_GLOBAL_SCOPE_LOCK() GIL _lock; - -#else -#define PK_THREAD_LOCAL -#define PK_GLOBAL_SCOPE_LOCK() -#endif - -/*******************************************************************************/ -namespace pkpy{ - -namespace std = ::std; - -using i64 = int64_t; // always 64-bit -using f64 = double; // always 64-bit - -static_assert(sizeof(i64) == 8); -static_assert(sizeof(f64) == 8); - -struct DummyInstance { }; -struct DummyModule { }; -struct NoReturn { }; -struct Discarded { }; - -struct Type { - int16_t index; - constexpr Type(): index(0) {} - explicit constexpr Type(int index): index(index) {} - bool operator==(Type other) const { return this->index == other.index; } - bool operator!=(Type other) const { return this->index != other.index; } - constexpr operator int() const { return index; } -}; - -#define PK_LAMBDA(x) ([](VM* vm, ArgsView args) -> PyVar { return x; }) -#define PK_VAR_LAMBDA(x) ([](VM* vm, ArgsView args) -> PyVar { return VAR(x); }) -#define PK_ACTION(x) ([](VM* vm, ArgsView args) -> PyVar { x; return vm->None; }) - -#define PK_REGION(name) 1 - -#ifdef POCKETPY_H -#define PK_FATAL_ERROR() throw std::runtime_error( "L" + std::to_string(__LINE__) + " FATAL_ERROR()!"); -#else -#define PK_FATAL_ERROR() throw std::runtime_error( __FILE__ + std::string(":") + std::to_string(__LINE__) + " FATAL_ERROR()!"); -#endif - -#define PK_ASSERT(x) if(!(x)) PK_FATAL_ERROR(); - -#if PK_DEBUG_EXTRA_CHECK -#define PK_DEBUG_ASSERT(x) if(!(x)) PK_FATAL_ERROR(); -#else -#define PK_DEBUG_ASSERT(x) -#endif - -// is_pod_v<> for c++17 and c++20 -template -inline constexpr bool is_pod_v = std::is_trivially_copyable_v && std::is_standard_layout_v; - -#define PK_ALWAYS_PASS_BY_POINTER(T) \ - T(const T&) = delete; \ - T& operator=(const T&) = delete; \ - T(T&&) = delete; \ - T& operator=(T&&) = delete; - -inline const char* kPlatformStrings[] = { - "win32", // 0 - "emscripten", // 1 - "ios", // 2 - "darwin", // 3 - "android", // 4 - "linux", // 5 - "unknown" // 6 -}; - -#define PK_SLICE_LOOP(i, start, stop, step) for(int i=start; step>0?istop; i+=step) - -template -inline constexpr bool is_integral_v = std::is_same_v - || std::is_same_v - || std::is_same_v - || std::is_same_v - || std::is_same_v - || std::is_same_v - || std::is_same_v - || std::is_same_v - || std::is_same_v - || std::is_same_v - || std::is_same_v; // for imgui - -template -inline constexpr bool is_floating_point_v = std::is_same_v || std::is_same_v; - -inline const char* PK_HEX_TABLE = "0123456789abcdef"; - -struct PyObject; -struct Frame; -class VM; - -// by default, only `int` and `float` enable SSO -// users can specialize this template to enable SSO for other types -// SSO types cannot have instance dict -template -inline constexpr bool is_sso_v = is_integral_v || is_floating_point_v; - -// make a obj_get_t for a given type T, if is_sso_v is true, return T, else return T& -template -using obj_get_t = std::conditional_t, T, T&>; - -struct const_sso_var {}; - -struct PyVar final{ - Type type; - bool is_ptr; - uint8_t flags; - // 12 bytes SSO - int _0; i64 _1; - - // uninitialized - PyVar() = default; - - // implict conversion - PyVar(PyObject* p); - - /* We must initialize all members to allow == operator to work correctly */ - // constexpr initialized - constexpr PyVar(const const_sso_var&, Type type, int value): type(type), is_ptr(false), flags(0), _0(value), _1(0) {} - // zero initialized - constexpr PyVar(std::nullptr_t): type(0), is_ptr(false), flags(0), _0(0), _1(0) {} - // PyObject* initialized (is_sso = false) - PyVar(Type type, PyObject* p): type(type), is_ptr(true), flags(0), _0(0), _1(reinterpret_cast(p)) {} - // SSO initialized (is_sso = true) - template - PyVar(Type type, T value): type(type), is_ptr(false), flags(0), _0(0), _1(0) { - static_assert(sizeof(T) <= 12, "SSO size exceeded"); - as() = value; - } - - template - T& as(){ - static_assert(!std::is_reference_v); - if constexpr(sizeof(T) <= 8){ - return reinterpret_cast(_1); - }else{ - return reinterpret_cast(_0); - } - } - - explicit operator bool() const { return (bool)type; } - - void set_null() { _qword(0) = 0; _qword(1) = 0; } - - i64 _qword(int i) const { return ((const i64*)this)[i]; } - i64& _qword(int i) { return ((i64*)this)[i]; } - - bool operator==(const PyVar& other) const { - return _qword(0) == other._qword(0) && _qword(1) == other._qword(1); - } - - bool operator!=(const PyVar& other) const { - return _qword(0) != other._qword(0) || _qword(1) != other._qword(1); - } - - bool operator==(std::nullptr_t) const { return !(bool)type; } - bool operator!=(std::nullptr_t) const { return (bool)type; } - - PyObject* get() const { - PK_DEBUG_ASSERT(is_ptr) - return reinterpret_cast(_1); - } - - PyObject* operator->() const { - PK_DEBUG_ASSERT(is_ptr) - return reinterpret_cast(_1); - } - - i64 hash() const { return _0 + _1; } - - template - obj_get_t obj_get(); -}; - -static_assert(sizeof(PyVar) == 16 && is_pod_v); - -} // namespace pkpy - - -// specialize std::less for PyVar -namespace std { - template<> - struct less { - bool operator()(const pkpy::PyVar& lhs, const pkpy::PyVar& rhs) const { - return memcmp(&lhs, &rhs, sizeof(pkpy::PyVar)) < 0; - } - }; -} \ No newline at end of file diff --git a/include/pocketpy/_generated.h b/include/pocketpy/common/_generated.hpp similarity index 100% rename from include/pocketpy/_generated.h rename to include/pocketpy/common/_generated.hpp diff --git a/include/pocketpy/any.h b/include/pocketpy/common/any.hpp similarity index 95% rename from include/pocketpy/any.h rename to include/pocketpy/common/any.hpp index 317d2830..68f02b60 100644 --- a/include/pocketpy/any.h +++ b/include/pocketpy/common/any.hpp @@ -1,7 +1,10 @@ #pragma once -#include "common.h" -#include "str.h" +#include "pocketpy/common/traits.hpp" + +#include +#include +#include namespace pkpy { @@ -98,7 +101,7 @@ struct function{ } Ret operator()(Params... params) const{ - if(!_wrapper) throw std::runtime_error("empty function"); + assert(_wrapper); return _wrapper(_impl, std::forward(params)...); } }; diff --git a/include/pocketpy/common/gil.hpp b/include/pocketpy/common/gil.hpp new file mode 100644 index 00000000..d3970097 --- /dev/null +++ b/include/pocketpy/common/gil.hpp @@ -0,0 +1,17 @@ +#pragma once + +#if PK_ENABLE_THREAD +#define PK_THREAD_LOCAL thread_local +#include + +struct GIL { + inline static std::mutex _mutex; + explicit GIL() { _mutex.lock(); } + ~GIL() { _mutex.unlock(); } +}; +#define PK_GLOBAL_SCOPE_LOCK() GIL _lock; + +#else +#define PK_THREAD_LOCAL +#define PK_GLOBAL_SCOPE_LOCK() +#endif diff --git a/include/pocketpy/memory.h b/include/pocketpy/common/memorypool.hpp similarity index 89% rename from include/pocketpy/memory.h rename to include/pocketpy/common/memorypool.hpp index 0b1c3c74..25a0cd79 100644 --- a/include/pocketpy/memory.h +++ b/include/pocketpy/common/memorypool.hpp @@ -1,11 +1,13 @@ #pragma once -#include "common.h" +#include +#include namespace pkpy{ void* pool128_alloc(size_t) noexcept; void pool128_dealloc(void*) noexcept; + template void* pool128_alloc() noexcept{ return pool128_alloc(sizeof(T)); diff --git a/include/pocketpy/namedict.h b/include/pocketpy/common/namedict.hpp similarity index 92% rename from include/pocketpy/namedict.h rename to include/pocketpy/common/namedict.hpp index 3f4548ad..cf72c158 100644 --- a/include/pocketpy/namedict.h +++ b/include/pocketpy/common/namedict.hpp @@ -1,16 +1,16 @@ #pragma once -#include "common.h" -#include "memory.h" -#include "str.h" +#include "pocketpy/common/utils.hpp" +#include "pocketpy/common/str.hpp" + +#include "pocketpy/config.h" namespace pkpy{ template constexpr T default_invalid_value(){ - if constexpr(std::is_same_v) return nullptr; - else if constexpr(std::is_same_v) return -1; - else return Discarded(); + if constexpr(std::is_same_v) return -1; + else return nullptr; } template @@ -80,7 +80,7 @@ while(!_items[i].first.empty()) { \ if(old_items[i].first.empty()) continue; bool ok; uint16_t j; HASH_PROBE_1(old_items[i].first, ok, j); - if(ok) PK_FATAL_ERROR(); + assert(!ok); _items[j] = old_items[i]; } free(old_items); @@ -190,11 +190,4 @@ while(!_items[i].first.empty()) { \ #undef HASH_PROBE_1 }; - -using NameDict = NameDictImpl; -using NameDict_ = std::shared_ptr; -using NameDictInt = NameDictImpl; - -static_assert(sizeof(NameDict) <= 128); - } // namespace pkpy \ No newline at end of file diff --git a/include/pocketpy/str.h b/include/pocketpy/common/str.hpp similarity index 97% rename from include/pocketpy/str.h rename to include/pocketpy/common/str.hpp index f161d0a1..5b4808a9 100644 --- a/include/pocketpy/str.h +++ b/include/pocketpy/common/str.hpp @@ -1,8 +1,11 @@ #pragma once -#include "common.h" -#include "memory.h" -#include "vector.h" +#include "pocketpy/common/utils.hpp" +#include "pocketpy/common/memorypool.hpp" +#include "pocketpy/common/vector.hpp" + +#include +#include namespace pkpy { diff --git a/include/pocketpy/common/traits.hpp b/include/pocketpy/common/traits.hpp new file mode 100644 index 00000000..dd286aaa --- /dev/null +++ b/include/pocketpy/common/traits.hpp @@ -0,0 +1,36 @@ +#pragma once + +#include + +namespace pkpy{ + +// is_pod_v<> for c++17 and c++20 +template +inline constexpr bool is_pod_v = std::is_trivially_copyable_v && std::is_standard_layout_v; + +// https://en.cppreference.com/w/cpp/types/is_integral +template +inline constexpr bool is_integral_v = !std::is_same_v && std::is_integral_v; + +template +inline constexpr bool is_floating_point_v = std::is_same_v || std::is_same_v; + +// by default, only `int` and `float` enable SSO +// users can specialize this template to enable SSO for other types +// SSO types cannot have instance dict +template +inline constexpr bool is_sso_v = is_integral_v || is_floating_point_v; + +// if is_sso_v is true, return T, else return T& +template +using obj_get_t = std::conditional_t, T, T&>; + +template +constexpr inline bool is_trivially_relocatable_v = std::is_trivially_copyable_v && std::is_trivially_destructible_v; + +template struct has_gc_marker : std::false_type {}; +template struct has_gc_marker> : std::true_type {}; + +template +inline constexpr int py_sizeof = 16 + sizeof(T); +} // namespace pkpy \ No newline at end of file diff --git a/include/pocketpy/common/types.hpp b/include/pocketpy/common/types.hpp new file mode 100644 index 00000000..45d712ad --- /dev/null +++ b/include/pocketpy/common/types.hpp @@ -0,0 +1,28 @@ +#pragma once + +#include + +namespace pkpy{ + +using i64 = int64_t; // always 64-bit +using f64 = double; // always 64-bit + +static_assert(sizeof(i64) == 8); +static_assert(sizeof(f64) == 8); + +// Explicitly allow copying if copy constructor is deleted +struct explicit_copy_t { + explicit explicit_copy_t() = default; +}; + +// Dummy types +struct DummyInstance { }; +struct DummyModule { }; +struct NoReturn { }; + +// Forward declarations +struct PyObject; +struct Frame; +class VM; + +}; // namespace pkpy \ No newline at end of file diff --git a/include/pocketpy/common/utils.hpp b/include/pocketpy/common/utils.hpp new file mode 100644 index 00000000..45a663ae --- /dev/null +++ b/include/pocketpy/common/utils.hpp @@ -0,0 +1,28 @@ +#pragma once + +#define PK_REGION(name) 1 + +#define PK_ALWAYS_PASS_BY_POINTER(T) \ + T(const T&) = delete; \ + T& operator=(const T&) = delete; \ + T(T&&) = delete; \ + T& operator=(T&&) = delete; + +#define PK_SLICE_LOOP(i, start, stop, step) for(int i=start; step>0?istop; i+=step) + +namespace pkpy{ + +// global constants +inline const char* PK_HEX_TABLE = "0123456789abcdef"; + +inline const char* kPlatformStrings[] = { + "win32", // 0 + "emscripten", // 1 + "ios", // 2 + "darwin", // 3 + "android", // 4 + "linux", // 5 + "unknown" // 6 +}; + +} // namespace pkpy diff --git a/include/pocketpy/vector.h b/include/pocketpy/common/vector.hpp similarity index 96% rename from include/pocketpy/vector.h rename to include/pocketpy/common/vector.hpp index bf11ecf0..9c841ac0 100644 --- a/include/pocketpy/vector.h +++ b/include/pocketpy/common/vector.hpp @@ -1,17 +1,14 @@ #pragma once -#include "common.h" -#include "memory.h" +#include "pocketpy/common/traits.hpp" +#include "pocketpy/common/types.hpp" + +#include +#include +#include namespace pkpy{ -struct explicit_copy_t { - explicit explicit_copy_t() = default; -}; - -template -constexpr inline bool is_trivially_relocatable_v = std::is_trivially_copyable_v && std::is_trivially_destructible_v; - template struct array{ T* _data; @@ -48,12 +45,12 @@ struct array{ array& operator=(const array& other) = delete; T& operator[](int i) { - PK_DEBUG_ASSERT(i>=0 && i<_size); + assert(i >= 0 && i < _size); return _data[i]; } const T& operator[](int i) const { - PK_DEBUG_ASSERT(i>=0 && i<_size); + assert(i >= 0 && i < _size); return _data[i]; } @@ -192,7 +189,7 @@ struct vector{ } void pop_back(){ - PK_DEBUG_ASSERT(_size > 0); + assert(_size > 0); _size--; if constexpr(!std::is_trivially_destructible_v){ _data[_size].~T(); @@ -315,7 +312,7 @@ namespace pkpy { { if constexpr (std::is_trivially_copyable_v) { - std::memcpy(dest, src, sizeof(T) * n); + memcpy(dest, src, sizeof(T) * n); } else { @@ -330,7 +327,7 @@ namespace pkpy { { if constexpr (is_trivially_relocatable_v) { - std::memcpy(dest, src, sizeof(T) * n); + memcpy(dest, src, sizeof(T) * n); } else { diff --git a/include/pocketpy/common/version.hpp b/include/pocketpy/common/version.hpp new file mode 100644 index 00000000..308598fb --- /dev/null +++ b/include/pocketpy/common/version.hpp @@ -0,0 +1,6 @@ +#pragma once + +#define PK_VERSION "2.0.0" +#define PK_VERSION_MAJOR 2 +#define PK_VERSION_MINOR 0 +#define PK_VERSION_PATCH 0 diff --git a/include/pocketpy/compiler.h b/include/pocketpy/compiler/compiler.hpp similarity index 98% rename from include/pocketpy/compiler.h rename to include/pocketpy/compiler/compiler.hpp index 09ad3209..ab1f7eac 100644 --- a/include/pocketpy/compiler.h +++ b/include/pocketpy/compiler/compiler.hpp @@ -1,9 +1,6 @@ #pragma once -#include "codeobject.h" -#include "common.h" -#include "expr.h" -#include "obj.h" +#include "pocketpy/compiler/expr.hpp" namespace pkpy{ diff --git a/include/pocketpy/expr.h b/include/pocketpy/compiler/expr.hpp similarity index 99% rename from include/pocketpy/expr.h rename to include/pocketpy/compiler/expr.hpp index 97eaaf44..c6134e61 100644 --- a/include/pocketpy/expr.h +++ b/include/pocketpy/compiler/expr.hpp @@ -1,10 +1,7 @@ #pragma once -#include "codeobject.h" -#include "common.h" -#include "lexer.h" -#include "error.h" -#include "vm.h" +#include "pocketpy/objects/codeobject.hpp" +#include "pocketpy/compiler/lexer.hpp" namespace pkpy{ diff --git a/include/pocketpy/lexer.h b/include/pocketpy/compiler/lexer.hpp similarity index 97% rename from include/pocketpy/lexer.h rename to include/pocketpy/compiler/lexer.hpp index e208c2a3..b3f2c2ba 100644 --- a/include/pocketpy/lexer.h +++ b/include/pocketpy/compiler/lexer.hpp @@ -1,9 +1,9 @@ #pragma once -#include "common.h" -#include "error.h" -#include "str.h" -#include "obj.h" +#include "pocketpy/objects/sourcedata.hpp" +#include "pocketpy/objects/error.hpp" + +#include namespace pkpy{ diff --git a/include/pocketpy/bindings.h b/include/pocketpy/interpreter/bindings.hpp similarity index 96% rename from include/pocketpy/bindings.h rename to include/pocketpy/interpreter/bindings.hpp index f91acea4..62da2dcb 100644 --- a/include/pocketpy/bindings.h +++ b/include/pocketpy/interpreter/bindings.hpp @@ -1,7 +1,6 @@ #pragma once -#include "cffi.h" -#include "vm.h" +#include "pocketpy/interpreter/cffi.hpp" namespace pkpy{ struct NativeProxyFuncCBase { @@ -16,7 +15,7 @@ struct NativeProxyFuncC final: NativeProxyFuncCBase { NativeProxyFuncC(_Fp func) : func(func) {} PyVar operator()(VM* vm, ArgsView args) override { - PK_DEBUG_ASSERT(args.size() == N); + assert(args.size() == N); return call(vm, args, std::make_index_sequence()); } @@ -40,7 +39,7 @@ struct NativeProxyMethodC final: NativeProxyFuncCBase { NativeProxyMethodC(_Fp func) : func(func) {} PyVar operator()(VM* vm, ArgsView args) override { - PK_DEBUG_ASSERT(args.size() == N+1); + assert(args.size() == N+1); return call(vm, args, std::make_index_sequence()); } @@ -89,7 +88,7 @@ PyObject* VM::bind(PyObject* obj, const char* sig, const char* docstring, Ret(T: template PyObject* VM::bind_field(PyObject* obj, const char* name, F T::*field){ static_assert(!std::is_reference_v); - PK_ASSERT(is_type(obj, tp_type)); + assert(is_type(obj, tp_type)); std::string_view name_sv(name); int pos = name_sv.find(':'); if(pos > 0) name_sv = name_sv.substr(0, pos); auto fget = [](VM* vm, ArgsView args) -> PyVar{ @@ -201,4 +200,8 @@ PyObject* VM::bind_field(PyObject* obj, const char* name, F T::*field){ tgt[i] = CAST(T, _2); \ }); \ +#define PK_LAMBDA(x) ([](VM* vm, ArgsView args) -> PyVar { return x; }) +#define PK_VAR_LAMBDA(x) ([](VM* vm, ArgsView args) -> PyVar { return VAR(x); }) +#define PK_ACTION(x) ([](VM* vm, ArgsView args) -> PyVar { x; return vm->None; }) + } // namespace pkpy \ No newline at end of file diff --git a/include/pocketpy/ceval.h b/include/pocketpy/interpreter/ceval.hpp similarity index 52% rename from include/pocketpy/ceval.h rename to include/pocketpy/interpreter/ceval.hpp index d7a10dce..a1dc7d1d 100644 --- a/include/pocketpy/ceval.h +++ b/include/pocketpy/interpreter/ceval.hpp @@ -1,4 +1,4 @@ #pragma once -#include "vm.h" +#include "pocketpy/interpreter/vm.hpp" // dummy header for ceval.cpp \ No newline at end of file diff --git a/include/pocketpy/cffi.h b/include/pocketpy/interpreter/cffi.hpp similarity index 98% rename from include/pocketpy/cffi.h rename to include/pocketpy/interpreter/cffi.hpp index 5fec58d5..d122b178 100644 --- a/include/pocketpy/cffi.h +++ b/include/pocketpy/interpreter/cffi.hpp @@ -1,7 +1,6 @@ #pragma once -#include "common.h" -#include "vm.h" +#include "pocketpy/interpreter/vm.hpp" namespace pkpy { diff --git a/include/pocketpy/frame.h b/include/pocketpy/interpreter/frame.hpp similarity index 88% rename from include/pocketpy/frame.h rename to include/pocketpy/interpreter/frame.hpp index 4e3a2e5e..7e9d7666 100644 --- a/include/pocketpy/frame.h +++ b/include/pocketpy/interpreter/frame.hpp @@ -1,10 +1,6 @@ #pragma once -#include "codeobject.h" -#include "common.h" -#include "memory.h" -#include "obj.h" -#include "vector.h" +#include "pocketpy/objects/codeobject.hpp" namespace pkpy{ @@ -155,32 +151,12 @@ struct CallStack{ ++_size; } - void pop(){ - PK_DEBUG_ASSERT(!empty()) - LinkedFrame* p = _tail; - _tail = p->f_back; - p->~LinkedFrame(); - pool128_dealloc(p); - --_size; - } - - LinkedFrame* popx(){ - PK_DEBUG_ASSERT(!empty()) - LinkedFrame* p = _tail; - _tail = p->f_back; - --_size; - p->f_back = nullptr; // unlink - return p; - } - - void pushx(LinkedFrame* p){ - p->f_back = _tail; - _tail = p; - ++_size; - } + void pop(); + LinkedFrame* popx(); + void pushx(LinkedFrame* p); Frame& top() const { - PK_DEBUG_ASSERT(!empty()) + assert(!empty()); return _tail->frame; } diff --git a/include/pocketpy/gc.h b/include/pocketpy/interpreter/gc.hpp similarity index 92% rename from include/pocketpy/gc.h rename to include/pocketpy/interpreter/gc.hpp index c3831238..30a62c4d 100644 --- a/include/pocketpy/gc.h +++ b/include/pocketpy/interpreter/gc.hpp @@ -1,8 +1,9 @@ #pragma once -#include "common.h" -#include "memory.h" -#include "obj.h" +#include "pocketpy/config.h" +#include "pocketpy/common/vector.hpp" +#include "pocketpy/common/utils.hpp" +#include "pocketpy/objects/object.hpp" namespace pkpy { struct ManagedHeap{ diff --git a/include/pocketpy/iter.h b/include/pocketpy/interpreter/iter.hpp similarity index 96% rename from include/pocketpy/iter.h rename to include/pocketpy/interpreter/iter.hpp index 49510f77..fa673a78 100644 --- a/include/pocketpy/iter.h +++ b/include/pocketpy/interpreter/iter.hpp @@ -1,8 +1,6 @@ #pragma once -#include "cffi.h" -#include "common.h" -#include "frame.h" +#include "pocketpy/interpreter/bindings.hpp" namespace pkpy{ diff --git a/include/pocketpy/profiler.h b/include/pocketpy/interpreter/profiler.hpp similarity index 93% rename from include/pocketpy/profiler.h rename to include/pocketpy/interpreter/profiler.hpp index 02c2e647..74aa259d 100644 --- a/include/pocketpy/profiler.h +++ b/include/pocketpy/interpreter/profiler.hpp @@ -1,6 +1,6 @@ #pragma once -#include "frame.h" +#include "pocketpy/interpreter/frame.hpp" namespace pkpy { diff --git a/include/pocketpy/vm.h b/include/pocketpy/interpreter/vm.hpp similarity index 98% rename from include/pocketpy/vm.h rename to include/pocketpy/interpreter/vm.hpp index 7d72aff1..7a4a5768 100644 --- a/include/pocketpy/vm.h +++ b/include/pocketpy/interpreter/vm.hpp @@ -1,17 +1,12 @@ #pragma once -#include "codeobject.h" -#include "common.h" -#include "frame.h" -#include "error.h" -#include "gc.h" -#include "memory.h" -#include "obj.h" -#include "str.h" -#include "tuplelist.h" -#include "dict.h" -#include "profiler.h" - +#include "pocketpy/objects/object.hpp" +#include "pocketpy/objects/dict.hpp" +#include "pocketpy/objects/error.hpp" +#include "pocketpy/objects/stackmemory.hpp" +#include "pocketpy/objects/builtins.hpp" +#include "pocketpy/interpreter/gc.hpp" +#include "pocketpy/interpreter/frame.hpp" namespace pkpy{ @@ -654,7 +649,10 @@ PyObject* VM::register_user_class(PyObject* mod, StrName name, RegisterFunc _reg return vm->new_object(cls_t); }); }else{ - bind_func(type, __new__, -1, PK_ACTION(vm->NotImplementedError())); + bind_func(type, __new__, -1, [](VM* vm, ArgsView args){ + vm->NotImplementedError(); + return vm->None; + }); } } return type; diff --git a/include/pocketpy/array2d.h b/include/pocketpy/modules/array2d.hpp similarity index 69% rename from include/pocketpy/array2d.h rename to include/pocketpy/modules/array2d.hpp index f79cbc45..b121251d 100644 --- a/include/pocketpy/array2d.h +++ b/include/pocketpy/modules/array2d.hpp @@ -1,6 +1,6 @@ #pragma once -#include "bindings.h" +#include "pocketpy/common/types.hpp" namespace pkpy { diff --git a/include/pocketpy/base64.h b/include/pocketpy/modules/base64.hpp similarity index 69% rename from include/pocketpy/base64.h rename to include/pocketpy/modules/base64.hpp index 0bbf6b17..6db26650 100644 --- a/include/pocketpy/base64.h +++ b/include/pocketpy/modules/base64.hpp @@ -1,6 +1,6 @@ #pragma once -#include "bindings.h" +#include "pocketpy/common/types.hpp" namespace pkpy { diff --git a/include/pocketpy/csv.h b/include/pocketpy/modules/csv.hpp similarity index 68% rename from include/pocketpy/csv.h rename to include/pocketpy/modules/csv.hpp index 87d816c8..80107efa 100644 --- a/include/pocketpy/csv.h +++ b/include/pocketpy/modules/csv.hpp @@ -1,6 +1,6 @@ #pragma once -#include "bindings.h" +#include "pocketpy/common/types.hpp" namespace pkpy { diff --git a/include/pocketpy/dataclasses.h b/include/pocketpy/modules/dataclasses.hpp similarity index 70% rename from include/pocketpy/dataclasses.h rename to include/pocketpy/modules/dataclasses.hpp index fe3fcb5f..6f5fd03a 100644 --- a/include/pocketpy/dataclasses.h +++ b/include/pocketpy/modules/dataclasses.hpp @@ -1,6 +1,6 @@ #pragma once -#include "bindings.h" +#include "pocketpy/common/types.hpp" namespace pkpy{ diff --git a/include/pocketpy/easing.h b/include/pocketpy/modules/easing.hpp similarity index 69% rename from include/pocketpy/easing.h rename to include/pocketpy/modules/easing.hpp index 1c69f8a1..7cd72b38 100644 --- a/include/pocketpy/easing.h +++ b/include/pocketpy/modules/easing.hpp @@ -1,6 +1,6 @@ #pragma once -#include "bindings.h" +#include "pocketpy/common/types.hpp" namespace pkpy{ diff --git a/include/pocketpy/io.h b/include/pocketpy/modules/io.hpp similarity index 81% rename from include/pocketpy/io.h rename to include/pocketpy/modules/io.hpp index 675c6cbc..ed954b26 100644 --- a/include/pocketpy/io.h +++ b/include/pocketpy/modules/io.hpp @@ -1,6 +1,6 @@ #pragma once -#include "bindings.h" +#include "pocketpy/common/types.hpp" namespace pkpy{ unsigned char* _default_import_handler(const char*, int*); diff --git a/include/pocketpy/linalg.h b/include/pocketpy/modules/linalg.hpp similarity index 98% rename from include/pocketpy/linalg.h rename to include/pocketpy/modules/linalg.hpp index 008035be..9973fd17 100644 --- a/include/pocketpy/linalg.h +++ b/include/pocketpy/modules/linalg.hpp @@ -1,6 +1,9 @@ #pragma once -#include "bindings.h" +#include "pocketpy/common/types.hpp" +#include "pocketpy/common/traits.hpp" + +#include namespace pkpy{ diff --git a/include/pocketpy/modules.h b/include/pocketpy/modules/modules.hpp similarity index 90% rename from include/pocketpy/modules.h rename to include/pocketpy/modules/modules.hpp index 342aa006..aa9f7ed2 100644 --- a/include/pocketpy/modules.h +++ b/include/pocketpy/modules/modules.hpp @@ -1,6 +1,6 @@ #pragma once -#include "bindings.h" +#include "pocketpy/common/types.hpp" namespace pkpy{ diff --git a/include/pocketpy/random.h b/include/pocketpy/modules/random.hpp similarity index 69% rename from include/pocketpy/random.h rename to include/pocketpy/modules/random.hpp index 4d16f39c..a811b08a 100644 --- a/include/pocketpy/random.h +++ b/include/pocketpy/modules/random.hpp @@ -1,6 +1,6 @@ #pragma once -#include "bindings.h" +#include "pocketpy/common/types.hpp" namespace pkpy{ diff --git a/include/pocketpy/objects/base.hpp b/include/pocketpy/objects/base.hpp new file mode 100644 index 00000000..ca3a8b04 --- /dev/null +++ b/include/pocketpy/objects/base.hpp @@ -0,0 +1,100 @@ +#pragma once + +#include "pocketpy/common/types.hpp" +#include "pocketpy/common/traits.hpp" + +#include +#include +#include + +namespace pkpy{ + +struct Type { + int16_t index; + constexpr Type(): index(0) {} + explicit constexpr Type(int index): index(index) {} + bool operator==(Type other) const { return this->index == other.index; } + bool operator!=(Type other) const { return this->index != other.index; } + constexpr operator int() const { return index; } +}; + +struct const_sso_var {}; + +struct PyVar final{ + Type type; + bool is_ptr; + uint8_t flags; + // 12 bytes SSO + int _0; i64 _1; + + // uninitialized + PyVar() = default; + + // implict conversion + PyVar(PyObject* p); + + /* We must initialize all members to allow == operator to work correctly */ + // constexpr initialized + constexpr PyVar(const const_sso_var&, Type type, int value): type(type), is_ptr(false), flags(0), _0(value), _1(0) {} + // zero initialized + constexpr PyVar(std::nullptr_t): type(0), is_ptr(false), flags(0), _0(0), _1(0) {} + // PyObject* initialized (is_sso = false) + PyVar(Type type, PyObject* p): type(type), is_ptr(true), flags(0), _0(0), _1(reinterpret_cast(p)) {} + // SSO initialized (is_sso = true) + template + PyVar(Type type, T value): type(type), is_ptr(false), flags(0), _0(0), _1(0) { + static_assert(sizeof(T) <= 12, "SSO size exceeded"); + as() = value; + } + + template + T& as(){ + static_assert(!std::is_reference_v); + if constexpr(sizeof(T) <= 8){ + return reinterpret_cast(_1); + }else{ + return reinterpret_cast(_0); + } + } + + explicit operator bool() const { return (bool)type; } + + void set_null() { _qword(0) = 0; _qword(1) = 0; } + + i64 _qword(int i) const { return ((const i64*)this)[i]; } + i64& _qword(int i) { return ((i64*)this)[i]; } + + bool operator==(const PyVar& other) const { + return _qword(0) == other._qword(0) && _qword(1) == other._qword(1); + } + + bool operator!=(const PyVar& other) const { + return _qword(0) != other._qword(0) || _qword(1) != other._qword(1); + } + + bool operator==(std::nullptr_t) const { return !(bool)type; } + bool operator!=(std::nullptr_t) const { return (bool)type; } + + PyObject* get() const { + assert(is_ptr); + return reinterpret_cast(_1); + } + + PyObject* operator->() const { + assert(is_ptr); + return reinterpret_cast(_1); + } + + i64 hash() const { return _0 + _1; } + + template + obj_get_t obj_get(); + + // for std::map<> + bool operator<(const PyVar& other) const { + return memcmp(this, &other, sizeof(PyVar)) < 0; + } +}; + +static_assert(sizeof(PyVar) == 16 && is_pod_v); +} // namespace pkpy \ No newline at end of file diff --git a/include/pocketpy/obj.h b/include/pocketpy/objects/builtins.hpp similarity index 50% rename from include/pocketpy/obj.h rename to include/pocketpy/objects/builtins.hpp index 0ac82915..361631e5 100644 --- a/include/pocketpy/obj.h +++ b/include/pocketpy/objects/builtins.hpp @@ -1,22 +1,9 @@ #pragma once -#include "common.h" -#include "namedict.h" -#include "tuplelist.h" +#include "pocketpy/common/vector.hpp" +#include "pocketpy/objects/object.hpp" -namespace pkpy { - -#if PK_ENABLE_STD_FUNCTION -using NativeFuncC = function; -#else -typedef PyVar (*NativeFuncC)(VM*, ArgsView); -#endif - -enum class BindType{ - DEFAULT, - STATICMETHOD, - CLASSMETHOD, -}; +namespace pkpy{ struct BoundMethod { PyVar self; @@ -50,13 +37,6 @@ struct Range { i64 step = 1; }; -struct StackMemory{ - int count; - StackMemory(int count) : count(count) {} -}; - -template<> -inline bool constexpr is_sso_v = true; struct StarWrapper{ int level; // either 1 or 2 @@ -82,76 +62,19 @@ struct Slice { void _gc_mark(VM*) const; }; -struct PyObject final{ - static constexpr int FIXED_SIZE = 16; - - bool gc_marked; // whether this object is marked - Type type; // we have a duplicated type here for convenience - NameDict* _attr; // gc will delete this on destruction - - bool is_attr_valid() const noexcept { return _attr != nullptr; } - void* _value_ptr() noexcept { return (char*)this + FIXED_SIZE; } - - template T& as() noexcept { - static_assert(std::is_same_v>); - return *reinterpret_cast(_value_ptr()); - } - - NameDict& attr() { - PK_DEBUG_ASSERT(is_attr_valid()) - return *_attr; - } - - PyVar attr(StrName name) const { - PK_DEBUG_ASSERT(is_attr_valid()) - return (*_attr)[name]; - } - - PyObject(Type type) : gc_marked(false), type(type), _attr(nullptr) {} - - template - void placement_new(Args&&... args){ - static_assert(std::is_same_v>); - new(_value_ptr()) T(std::forward(args)...); - - // backdoor for important builtin types - if constexpr(std::is_same_v){ - _enable_instance_dict(); - }else if constexpr(std::is_same_v){ - _enable_instance_dict(PK_TYPE_ATTR_LOAD_FACTOR); - }else if constexpr(std::is_same_v){ - _enable_instance_dict(PK_TYPE_ATTR_LOAD_FACTOR); - } - } - - void _enable_instance_dict() { - _attr = new(pool128_alloc()) NameDict(); - } - void _enable_instance_dict(float lf){ - _attr = new(pool128_alloc()) NameDict(lf); - } -}; - -static_assert(sizeof(PyObject) <= PyObject::FIXED_SIZE); -template -inline constexpr int py_sizeof = PyObject::FIXED_SIZE + sizeof(T); inline const int kTpIntIndex = 3; inline const int kTpFloatIndex = 4; -inline const int kTpStackMemoryIndex = 27; inline bool is_tagged(PyVar p) noexcept { return !p.is_ptr; } inline bool is_float(PyVar p) noexcept { return p.type.index == kTpFloatIndex; } inline bool is_int(PyVar p) noexcept { return p.type.index == kTpIntIndex; } inline bool is_type(PyVar obj, Type type) { - PK_DEBUG_ASSERT(obj != nullptr) + assert(obj != nullptr); return obj.type == type; } -template struct has_gc_marker : std::false_type {}; -template struct has_gc_marker> : std::true_type {}; - struct MappingProxy{ PyObject* obj; MappingProxy(PyObject* obj) : obj(obj) {} @@ -169,7 +92,7 @@ obj_get_t PyVar::obj_get(){ if constexpr(is_sso_v){ return as(); }else{ - PK_DEBUG_ASSERT(is_ptr) + assert(is_ptr); void* v = ((PyObject*)_1)->_value_ptr(); return *reinterpret_cast(v); } diff --git a/include/pocketpy/codeobject.h b/include/pocketpy/objects/codeobject.hpp similarity index 89% rename from include/pocketpy/codeobject.h rename to include/pocketpy/objects/codeobject.hpp index d6bf1c4c..736417ae 100644 --- a/include/pocketpy/codeobject.h +++ b/include/pocketpy/objects/codeobject.hpp @@ -1,16 +1,29 @@ #pragma once -#include "obj.h" -#include "error.h" -#include "any.h" +#include "pocketpy/common/any.hpp" +#include "pocketpy/objects/tuplelist.hpp" +#include "pocketpy/objects/object.hpp" +#include "pocketpy/objects/sourcedata.hpp" namespace pkpy{ +#if PK_ENABLE_STD_FUNCTION +using NativeFuncC = function; +#else +typedef PyVar (*NativeFuncC)(VM*, ArgsView); +#endif + +enum class BindType{ + DEFAULT, + STATICMETHOD, + CLASSMETHOD, +}; + enum NameScope { NAME_LOCAL, NAME_GLOBAL, NAME_GLOBAL_UNKNOWN }; enum Opcode: uint8_t { #define OPCODE(name) OP_##name, - #include "opcodes.h" + #include "pocketpy/opcodes.h" #undef OPCODE }; @@ -158,8 +171,8 @@ struct Function{ template T& lambda_get_userdata(PyVar* p){ static_assert(std::is_same_v>); - int offset = p[-1] != PY_NULL ? -1 : -2; - return PK_OBJ_GET(NativeFunc, p[offset])._userdata.cast(); + int offset = p[-1] != nullptr ? -1 : -2; + return p[offset].obj_get()._userdata.cast(); } } // namespace pkpy \ No newline at end of file diff --git a/include/pocketpy/dict.h b/include/pocketpy/objects/dict.hpp similarity index 94% rename from include/pocketpy/dict.h rename to include/pocketpy/objects/dict.hpp index b946cea9..4a1b0548 100644 --- a/include/pocketpy/dict.h +++ b/include/pocketpy/objects/dict.hpp @@ -1,9 +1,7 @@ #pragma once -#include "obj.h" -#include "common.h" -#include "memory.h" -#include "str.h" +#include "pocketpy/objects/base.hpp" +#include "pocketpy/objects/tuplelist.hpp" namespace pkpy{ diff --git a/include/pocketpy/error.h b/include/pocketpy/objects/error.hpp similarity index 70% rename from include/pocketpy/error.h rename to include/pocketpy/objects/error.hpp index 40c86a04..17e2fd9c 100644 --- a/include/pocketpy/error.h +++ b/include/pocketpy/objects/error.hpp @@ -1,8 +1,7 @@ #pragma once -#include "namedict.h" -#include "str.h" -#include "tuplelist.h" +#include "pocketpy/common/str.hpp" +#include "pocketpy/objects/sourcedata.hpp" namespace pkpy{ @@ -22,33 +21,6 @@ struct InternalException final{ InternalException(InternalExceptionType type, int arg=-1): type(type), arg(arg) {} }; -enum CompileMode { - EXEC_MODE, - EVAL_MODE, - REPL_MODE, - JSON_MODE, - CELL_MODE -}; - -struct SourceData { - PK_ALWAYS_PASS_BY_POINTER(SourceData) - - Str filename; - CompileMode mode; - - Str source; - vector line_starts; - - bool is_precompiled; - vector _precompiled_tokens; - - SourceData(std::string_view source, const Str& filename, CompileMode mode); - SourceData(const Str& filename, CompileMode mode); - std::pair _get_line(int lineno) const; - std::string_view get_line(int lineno) const; - Str snapshot(int lineno, const char* cursor, std::string_view name) const; -}; - struct Exception { StrName type; Str msg; @@ -75,7 +47,7 @@ struct Exception { Exception(StrName type): type(type), is_re(true), _ip_on_error(-1), _code_on_error(nullptr), _self(nullptr) {} PyObject* self() const{ - PK_ASSERT(_self != nullptr); + assert(_self != nullptr); return _self; } diff --git a/include/pocketpy/objects/object.hpp b/include/pocketpy/objects/object.hpp new file mode 100644 index 00000000..63987a04 --- /dev/null +++ b/include/pocketpy/objects/object.hpp @@ -0,0 +1,63 @@ +#pragma once + +#include "pocketpy/common/namedict.hpp" +#include "pocketpy/objects/base.hpp" + +namespace pkpy{ +using NameDict = NameDictImpl; +using NameDict_ = std::shared_ptr; +using NameDictInt = NameDictImpl; + +static_assert(sizeof(NameDict) <= 128); + +struct PyObject final{ + bool gc_marked; // whether this object is marked + Type type; // we have a duplicated type here for convenience + NameDict* _attr; // gc will delete this on destruction + + bool is_attr_valid() const noexcept { return _attr != nullptr; } + void* _value_ptr() noexcept { return (char*)this + 16; } + + template T& as() noexcept { + static_assert(std::is_same_v>); + return *reinterpret_cast(_value_ptr()); + } + + NameDict& attr() { + assert(is_attr_valid()); + return *_attr; + } + + PyVar attr(StrName name) const { + assert(is_attr_valid()); + return (*_attr)[name]; + } + + PyObject(Type type) : gc_marked(false), type(type), _attr(nullptr) {} + + template + void placement_new(Args&&... args){ + static_assert(std::is_same_v>); + new(_value_ptr()) T(std::forward(args)...); + + // backdoor for important builtin types + if constexpr(std::is_same_v){ + _enable_instance_dict(); + }else if constexpr(std::is_same_v){ + _enable_instance_dict(PK_TYPE_ATTR_LOAD_FACTOR); + }else if constexpr(std::is_same_v){ + _enable_instance_dict(PK_TYPE_ATTR_LOAD_FACTOR); + } + } + + void _enable_instance_dict() { + _attr = new(pool128_alloc()) NameDict(); + } + void _enable_instance_dict(float lf){ + _attr = new(pool128_alloc()) NameDict(lf); + } +}; + +static_assert(sizeof(PyObject) <= 16); + +} // namespace pkpy \ No newline at end of file diff --git a/include/pocketpy/objects/sourcedata.hpp b/include/pocketpy/objects/sourcedata.hpp new file mode 100644 index 00000000..3d9fe3c4 --- /dev/null +++ b/include/pocketpy/objects/sourcedata.hpp @@ -0,0 +1,35 @@ +#pragma once + +#include "pocketpy/common/utils.hpp" +#include "pocketpy/common/str.hpp" + +namespace pkpy{ + +enum CompileMode { + EXEC_MODE, + EVAL_MODE, + REPL_MODE, + JSON_MODE, + CELL_MODE +}; + +struct SourceData { + PK_ALWAYS_PASS_BY_POINTER(SourceData) + + Str filename; + CompileMode mode; + + Str source; + vector line_starts; + + bool is_precompiled; + vector _precompiled_tokens; + + SourceData(std::string_view source, const Str& filename, CompileMode mode); + SourceData(const Str& filename, CompileMode mode); + std::pair _get_line(int lineno) const; + std::string_view get_line(int lineno) const; + Str snapshot(int lineno, const char* cursor, std::string_view name) const; +}; + +} // namespace pkpy \ No newline at end of file diff --git a/include/pocketpy/objects/stackmemory.hpp b/include/pocketpy/objects/stackmemory.hpp new file mode 100644 index 00000000..7cf01292 --- /dev/null +++ b/include/pocketpy/objects/stackmemory.hpp @@ -0,0 +1,17 @@ +#pragma once + +#include "pocketpy/common/traits.hpp" + +namespace pkpy{ + +struct StackMemory{ + int count; + StackMemory(int count) : count(count) {} +}; + +template<> +inline bool constexpr is_sso_v = true; + +inline const int kTpStackMemoryIndex = 27; + +} // namespace pkpy \ No newline at end of file diff --git a/include/pocketpy/tuplelist.h b/include/pocketpy/objects/tuplelist.hpp similarity index 95% rename from include/pocketpy/tuplelist.h rename to include/pocketpy/objects/tuplelist.hpp index fa1cc50c..716945db 100644 --- a/include/pocketpy/tuplelist.h +++ b/include/pocketpy/objects/tuplelist.hpp @@ -1,9 +1,7 @@ #pragma once -#include "common.h" -#include "memory.h" -#include "str.h" -#include "vector.h" +#include "pocketpy/common/vector.hpp" +#include "pocketpy/objects/base.hpp" namespace pkpy { diff --git a/include/pocketpy/pocketpy.h b/include/pocketpy/pocketpy.h deleted file mode 100644 index 53d31630..00000000 --- a/include/pocketpy/pocketpy.h +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include "compiler.h" -#include "obj.h" -#include "repl.h" -#include "iter.h" -#include "base64.h" -#include "cffi.h" -#include "linalg.h" -#include "easing.h" -#include "io.h" -#include "vm.h" -#include "random.h" -#include "bindings.h" -#include "csv.h" -#include "dataclasses.h" -#include "array2d.h" -#include "modules.h" diff --git a/include/pocketpy/pocketpy.hpp b/include/pocketpy/pocketpy.hpp new file mode 100644 index 00000000..13f937dd --- /dev/null +++ b/include/pocketpy/pocketpy.hpp @@ -0,0 +1,8 @@ +#pragma once + +#include "pocketpy/objects/builtins.hpp" +#include "pocketpy/interpreter/vm.hpp" +#include "pocketpy/interpreter/iter.hpp" +#include "pocketpy/interpreter/bindings.hpp" +#include "pocketpy/compiler/compiler.hpp" +#include "pocketpy/tools/repl.hpp" diff --git a/include/pocketpy/repl.h b/include/pocketpy/tools/repl.hpp similarity index 84% rename from include/pocketpy/repl.h rename to include/pocketpy/tools/repl.hpp index 5118d013..51014ab3 100644 --- a/include/pocketpy/repl.h +++ b/include/pocketpy/tools/repl.hpp @@ -1,6 +1,6 @@ #pragma once -#include "vm.h" +#include "pocketpy/interpreter/vm.hpp" namespace pkpy{ diff --git a/prebuild.py b/prebuild.py index b7c7ec58..e2f44721 100644 --- a/prebuild.py +++ b/prebuild.py @@ -23,7 +23,7 @@ def get_sources(): sources = get_sources() # use LF line endings instead of CRLF -with open("include/pocketpy/_generated.h", "wt", encoding='utf-8', newline='\n') as f: +with open("include/pocketpy/common/_generated.hpp", "wt", encoding='utf-8', newline='\n') as f: data = '''#pragma once // generated by prebuild.py @@ -35,9 +35,9 @@ namespace pkpy{ data += '} // namespace pkpy\n' f.write(data) -with open("src/_generated.cpp", "wt", encoding='utf-8', newline='\n') as f: +with open("src/common/_generated.cpp", "wt", encoding='utf-8', newline='\n') as f: data = '''// generated by prebuild.py -#include "pocketpy/_generated.h" +#include "pocketpy/common/_generated.hpp" namespace pkpy{ ''' diff --git a/src/_generated.cpp b/src/common/_generated.cpp similarity index 99% rename from src/_generated.cpp rename to src/common/_generated.cpp index 8cf7cebd..3a856096 100644 --- a/src/_generated.cpp +++ b/src/common/_generated.cpp @@ -1,5 +1,5 @@ // generated by prebuild.py -#include "pocketpy/_generated.h" +#include "pocketpy/common/_generated.hpp" namespace pkpy{ const char kPythonLibs__enum[] = "class Enum:\n def __init__(self, name, value):\n self.name = name\n self.value = value\n\n def __str__(self):\n return f'{type(self).__name__}.{self.name}'\n \n def __repr__(self):\n return f'<{str(self)}: {self.value!r}>'\n \n"; diff --git a/src/any.cpp b/src/common/any.cpp similarity index 65% rename from src/any.cpp rename to src/common/any.cpp index ca36fae9..0a687e5c 100644 --- a/src/any.cpp +++ b/src/common/any.cpp @@ -1,10 +1,14 @@ -#include "pocketpy/any.h" +#include "pocketpy/common/any.hpp" + +#include +#include namespace pkpy{ void any::__bad_any_cast(const std::type_index expected, const std::type_index actual){ - Str error = _S("bad_any_cast: expected ", expected.name(), ", got ", actual.name()); - throw std::runtime_error(error.c_str()); + char error[256]; + snprintf(error, sizeof(error), "bad_any_cast: expected %s, got %s", expected.name(), actual.name()); + throw std::runtime_error(error); } any::any(any&& other) noexcept: data(other.data), _vt(other._vt){ diff --git a/src/memory.cpp b/src/common/memorypool.cpp similarity index 94% rename from src/memory.cpp rename to src/common/memorypool.cpp index 55ba8357..1844836b 100644 --- a/src/memory.cpp +++ b/src/common/memorypool.cpp @@ -1,4 +1,8 @@ -#include "pocketpy/memory.h" +#include "pocketpy/common/memorypool.hpp" +#include "pocketpy/common/gil.hpp" +#include "pocketpy/config.h" + +#include namespace pkpy{ @@ -84,18 +88,6 @@ struct DoubleLinkedList{ _size--; } - // void move_all_back(DoubleLinkedList& other){ - // if(other.empty()) return; - // other.tail.prev->next = &tail; - // tail.prev->next = other.head.next; - // other.head.next->prev = tail.prev; - // tail.prev = other.tail.prev; - // _size += other._size; - // other.head.next = &other.tail; - // other.tail.prev = &other.head; - // other._size = 0; - // } - bool empty() const { #if PK_DEBUG_MEMORY_POOL if(size() == 0){ @@ -269,7 +261,6 @@ struct MemoryPool{ static MemoryPool<128> pool128; - void* pool128_alloc(size_t size) noexcept { return pool128.alloc(size); } void pool128_dealloc(void* p) noexcept { pool128.dealloc(p); } diff --git a/src/str.cpp b/src/common/str.cpp similarity index 98% rename from src/str.cpp rename to src/common/str.cpp index 7672c66c..66a614d6 100644 --- a/src/str.cpp +++ b/src/common/str.cpp @@ -1,4 +1,10 @@ -#include "pocketpy/str.h" +#include "pocketpy/common/str.hpp" + +#include +#include +#include +#include +#include namespace pkpy { @@ -60,7 +66,7 @@ int utf8len(unsigned char c, bool suppress){ for(int i=0; isecond); _interned()[s] = index; _pesudo_random_index = index; diff --git a/src/compiler.cpp b/src/compiler/compiler.cpp similarity index 98% rename from src/compiler.cpp rename to src/compiler/compiler.cpp index b9db88b6..83f35d4d 100644 --- a/src/compiler.cpp +++ b/src/compiler/compiler.cpp @@ -1,4 +1,6 @@ -#include "pocketpy/compiler.h" +#include "pocketpy/compiler/compiler.hpp" +#include "pocketpy/common/version.hpp" +#include "pocketpy/interpreter/vm.hpp" namespace pkpy{ PrattRule Compiler::rules[kTokenCount]; @@ -92,7 +94,7 @@ namespace pkpy{ else func->type = FuncType::NORMAL; } - PK_ASSERT(func->type != FuncType::UNSET); + assert(func->type != FuncType::UNSET); } contexts.pop(); } @@ -322,7 +324,7 @@ namespace pkpy{ case TK("**"): ctx()->s_expr.push(make_expr(2, ctx()->s_expr.popx())); break; - default: PK_FATAL_ERROR(); + default: assert(false); } } @@ -640,7 +642,7 @@ __EAT_DOTS_END: TokenIndex op = curr().type; advance(); PrattCallback infix = rules[op].infix; - PK_ASSERT(infix != nullptr); + assert(infix != nullptr); (this->*infix)(); } } @@ -1015,7 +1017,7 @@ __EAT_DOTS_END: ctx()->emit_(OP_POP_TOP, BC_NOARG, BC_KEEPLINE); } }else{ - PK_ASSERT(ctx()->s_expr.size() == 1) + assert(ctx()->s_expr.size() == 1); ctx()->s_expr.pop(); } } @@ -1185,7 +1187,7 @@ __EAT_DOTS_END: if(std::holds_alternative(value)){ obj = VAR(std::get(value)); } - PK_ASSERT(obj != nullptr) + assert(obj != nullptr); return obj; } @@ -1239,7 +1241,7 @@ __EAT_DOTS_END: if(it == token_indices.end()){ token_indices[token.sv()] = 0; // assert no '\n' in token.sv() - for(char c: token.sv()) if(c=='\n') PK_FATAL_ERROR(); + for(char c: token.sv()) assert(c!='\n'); } } } @@ -1336,7 +1338,7 @@ __EAT_DOTS_END: } CodeObject_ Compiler::compile(){ - PK_ASSERT(i == 0) // make sure it is the first time to compile + assert(i == 0); // make sure it is the first time to compile if(lexer.src->is_precompiled){ from_precompiled(lexer.src->source.c_str()); @@ -1397,11 +1399,11 @@ __EAT_DOTS_END: char c = 0; if(s[i]>='0' && s[i]<='9') c += s[i]-'0'; else if(s[i]>='a' && s[i]<='f') c += s[i]-'a'+10; - else PK_FATAL_ERROR(); + else assert(false); c <<= 4; if(s[i+1]>='0' && s[i+1]<='9') c += s[i+1]-'0'; else if(s[i+1]>='a' && s[i+1]<='f') c += s[i+1]-'a'+10; - else PK_FATAL_ERROR(); + else assert(false); buffer[i/2] = c; } buffer[s.size()/2] = 0; @@ -1409,7 +1411,7 @@ __EAT_DOTS_END: } int TokenDeserializer::read_count(){ - PK_ASSERT(*curr == '=') + assert(*curr == '='); curr++; return read_uint('\n'); } diff --git a/src/expr.cpp b/src/compiler/expr.cpp similarity index 98% rename from src/expr.cpp rename to src/compiler/expr.cpp index 5ebe6c0e..1bd3c8b1 100644 --- a/src/expr.cpp +++ b/src/compiler/expr.cpp @@ -1,4 +1,5 @@ -#include "pocketpy/expr.h" +#include "pocketpy/compiler/expr.hpp" +#include "pocketpy/interpreter/vm.hpp" namespace pkpy{ @@ -33,8 +34,7 @@ namespace pkpy{ auto curr_type = co->blocks[curr_iblock].type; co->blocks[curr_iblock].end = co->codes.size(); curr_iblock = co->blocks[curr_iblock].parent; - if(curr_iblock < 0) PK_FATAL_ERROR(); - + assert(curr_iblock >= 0); if(curr_type == CodeBlockType::FOR_LOOP){ // add a no op here to make block check work emit_(OP_NO_OP, BC_NOARG, BC_KEEPLINE, true); @@ -127,7 +127,7 @@ namespace pkpy{ } int CodeEmitContext::add_const(PyVar v){ - PK_ASSERT(!is_type(v, VM::tp_str)) + assert(!is_type(v, VM::tp_str)); // non-string deduplication auto it = _co_consts_nonstring_dedup_map.find(v); if(it != _co_consts_nonstring_dedup_map.end()){ @@ -156,7 +156,7 @@ namespace pkpy{ case NAME_GLOBAL_UNKNOWN: emit_(OP_STORE_NAME, StrName(name).index, line); break; - default: PK_FATAL_ERROR(); break; + default: assert(false); break; } } @@ -191,7 +191,7 @@ namespace pkpy{ case NAME_GLOBAL_UNKNOWN: ctx->emit_(OP_DELETE_NAME, StrName(name).index, line); break; - default: PK_FATAL_ERROR(); break; + default: assert(false); break; } return true; } @@ -246,7 +246,7 @@ namespace pkpy{ case TK("True"): ctx->emit_(OP_LOAD_TRUE, BC_NOARG, line); break; case TK("False"): ctx->emit_(OP_LOAD_FALSE, BC_NOARG, line); break; case TK("..."): ctx->emit_(OP_LOAD_ELLIPSIS, BC_NOARG, line); break; - default: PK_FATAL_ERROR(); + default: assert(false); } } @@ -330,7 +330,7 @@ namespace pkpy{ void DictItemExpr::emit_(CodeEmitContext* ctx) { if(is_starred()){ - PK_ASSERT(key == nullptr); + assert(key == nullptr); value->emit_(ctx); }else{ value->emit_(ctx); @@ -647,7 +647,7 @@ namespace pkpy{ if(!kwargs.empty()){ for(auto& item: kwargs){ if(item.second->is_starred()){ - PK_ASSERT(item.second->star_level() == 2) + assert(item.second->star_level() == 2); item.second->emit_(ctx); }else{ // k=v @@ -752,7 +752,7 @@ namespace pkpy{ case TK("^"): ctx->emit_(OP_BITWISE_XOR, BC_NOARG, line); break; case TK("@"): ctx->emit_(OP_BINARY_MATMUL, BC_NOARG, line); break; - default: PK_FATAL_ERROR(); + default: assert(false); } for(int i: jmps) ctx->patch_jump(i); diff --git a/src/lexer.cpp b/src/compiler/lexer.cpp similarity index 99% rename from src/lexer.cpp rename to src/compiler/lexer.cpp index 405a52f9..9edde5ad 100644 --- a/src/lexer.cpp +++ b/src/compiler/lexer.cpp @@ -1,8 +1,7 @@ -#include "pocketpy/lexer.h" +#include "pocketpy/compiler/lexer.hpp" namespace pkpy{ - static 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}; static 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}; @@ -452,7 +451,7 @@ static bool is_unicode_Lo_char(uint32_t c) { case 2: SyntaxError("invalid utf8 sequence: " + std::string(1, c)); break; case 3: SyntaxError("@id contains invalid char"); break; case 4: SyntaxError("invalid JSON token"); break; - default: PK_FATAL_ERROR(); + default: assert(false); } return true; } @@ -487,7 +486,7 @@ static bool is_unicode_Lo_char(uint32_t c) { } vector Lexer::run() { - PK_ASSERT(curr_char == src->source.c_str()); + assert(curr_char == src->source.c_str()); while (lex_one_token()); return std::move(nexts); } diff --git a/src/ceval.cpp b/src/interpreter/ceval.cpp similarity index 99% rename from src/ceval.cpp rename to src/interpreter/ceval.cpp index 58293a43..3f3bc987 100644 --- a/src/ceval.cpp +++ b/src/interpreter/ceval.cpp @@ -1,4 +1,4 @@ -#include "pocketpy/ceval.h" +#include "pocketpy/interpreter/ceval.hpp" namespace pkpy{ @@ -224,7 +224,7 @@ __NEXT_STEP: TOP() = getattr(TOP(), StrName(byte.arg)); } DISPATCH() case OP_LOAD_CLASS_GLOBAL:{ - PK_ASSERT(__curr_class != nullptr); + assert(__curr_class != nullptr); StrName _name(byte.arg); PyVar _0 = getattr(__curr_class, _name, false); if(_0 != nullptr) { PUSH(_0); DISPATCH() } @@ -284,7 +284,7 @@ __NEXT_STEP: }else{ Function& func = frame->_callable->as(); if(func.decl == __dynamic_func_decl){ - PK_DEBUG_ASSERT(func._closure != nullptr); + assert(func._closure != nullptr); func._closure->set(_name, _0); }else{ vm->NameError(_name); @@ -340,7 +340,7 @@ __NEXT_STEP: }else{ Function& func = frame->_callable->as(); if(func.decl == __dynamic_func_decl){ - PK_DEBUG_ASSERT(func._closure != nullptr); + assert(func._closure != nullptr); bool ok = func._closure->del(_name); if(!ok) vm->NameError(_name); }else{ @@ -941,7 +941,7 @@ __NEXT_STEP: __curr_class = new_type_object(frame->_module, _name, PK_OBJ_GET(Type, _0), true); } DISPATCH() case OP_END_CLASS: { - PK_ASSERT(__curr_class != nullptr); + assert(__curr_class != nullptr); StrName _name(byte.arg); frame->_module->attr().set(_name, __curr_class); // call on_end_subclass @@ -953,7 +953,7 @@ __NEXT_STEP: __curr_class = nullptr; } DISPATCH() case OP_STORE_CLASS_ATTR:{ - PK_ASSERT(__curr_class != nullptr); + assert(__curr_class != nullptr); StrName _name(byte.arg); PyVar _0 = POPX(); if(is_type(_0, tp_function)){ @@ -968,7 +968,7 @@ __NEXT_STEP: __curr_class = POPX().get(); } DISPATCH() case OP_ADD_CLASS_ANNOTATION: { - PK_ASSERT(__curr_class != nullptr); + assert(__curr_class != nullptr); StrName _name(byte.arg); Type type = __curr_class->as(); _all_types[type].annotated_fields.push_back(_name); diff --git a/src/cffi.cpp b/src/interpreter/cffi.cpp similarity index 99% rename from src/cffi.cpp rename to src/interpreter/cffi.cpp index fa9cbadd..5e8296d1 100644 --- a/src/cffi.cpp +++ b/src/interpreter/cffi.cpp @@ -1,4 +1,4 @@ -#include "pocketpy/cffi.h" +#include "pocketpy/interpreter/cffi.hpp" namespace pkpy{ diff --git a/src/frame.cpp b/src/interpreter/frame.cpp similarity index 82% rename from src/frame.cpp rename to src/interpreter/frame.cpp index 752624fd..d8ae089c 100644 --- a/src/frame.cpp +++ b/src/interpreter/frame.cpp @@ -1,4 +1,5 @@ -#include "pocketpy/frame.h" +#include "pocketpy/objects/stackmemory.hpp" +#include "pocketpy/interpreter/frame.hpp" namespace pkpy{ PyVar* FastLocals::try_get_name(StrName name){ @@ -11,7 +12,7 @@ namespace pkpy{ NameDict_ dict = std::make_shared(); co->varnames_inv.apply([&](StrName name, int index){ PyVar value = a[index]; - if(value != PY_NULL) dict->set(name, value); + if(value) dict->set(name, value); }); return dict; } @@ -45,7 +46,7 @@ namespace pkpy{ // pop possible stack memory slots if(_s->top().type == kTpStackMemoryIndex){ int count = _s->top().as().count; - PK_DEBUG_ASSERT(count < 0); + assert(count < 0); _s->_sp += count; _s->_sp -= 2; // pop header and tail } @@ -99,4 +100,27 @@ namespace pkpy{ } } + void CallStack::pop(){ + assert(!empty()); + LinkedFrame* p = _tail; + _tail = p->f_back; + p->~LinkedFrame(); + pool128_dealloc(p); + --_size; + } + + LinkedFrame* CallStack::popx(){ + assert(!empty()); + LinkedFrame* p = _tail; + _tail = p->f_back; + --_size; + p->f_back = nullptr; // unlink + return p; + } + + void CallStack::pushx(LinkedFrame* p){ + p->f_back = _tail; + _tail = p; + ++_size; + } } // namespace pkpy \ No newline at end of file diff --git a/src/gc.cpp b/src/interpreter/gc.cpp similarity index 94% rename from src/gc.cpp rename to src/interpreter/gc.cpp index ec8daa23..6eed0d77 100644 --- a/src/gc.cpp +++ b/src/interpreter/gc.cpp @@ -1,4 +1,4 @@ -#include "pocketpy/gc.h" +#include "pocketpy/interpreter/gc.hpp" namespace pkpy{ @@ -48,7 +48,7 @@ namespace pkpy{ } int ManagedHeap::collect(){ - PK_ASSERT(_gc_lock_counter == 0) + assert(_gc_lock_counter == 0); mark(); int freed = sweep(); return freed; diff --git a/src/iter.cpp b/src/interpreter/iter.cpp similarity index 99% rename from src/iter.cpp rename to src/interpreter/iter.cpp index 55964d49..1ff7826e 100644 --- a/src/iter.cpp +++ b/src/interpreter/iter.cpp @@ -1,4 +1,4 @@ -#include "pocketpy/iter.h" +#include "pocketpy/interpreter/iter.hpp" namespace pkpy{ diff --git a/src/profiler.cpp b/src/interpreter/profiler.cpp similarity index 97% rename from src/profiler.cpp rename to src/interpreter/profiler.cpp index af73b8c2..5052dd69 100644 --- a/src/profiler.cpp +++ b/src/interpreter/profiler.cpp @@ -1,4 +1,4 @@ -#include "pocketpy/profiler.h" +#include "pocketpy/interpreter/profiler.hpp" namespace pkpy{ @@ -49,7 +49,7 @@ void LineProfiler::_step_end(int callstack_size, Frame* frame, int line){ _LineRecord* prev_record = top_frame_record.prev_record; int id_delta = callstack_size - top_frame_record.callstack_size; - PK_ASSERT(abs(id_delta) <= 1) + assert(abs(id_delta) <= 1); // current line is about to change if(prev_record->line != line){ @@ -77,7 +77,7 @@ void LineProfiler::end(){ prev_record->time += delta; frames.pop(); - PK_ASSERT(frames.empty()); + assert(frames.empty()); } Str LineProfiler::stats(){ diff --git a/src/vm.cpp b/src/interpreter/vm.cpp similarity index 98% rename from src/vm.cpp rename to src/interpreter/vm.cpp index 90002289..466428c5 100644 --- a/src/vm.cpp +++ b/src/interpreter/vm.cpp @@ -1,4 +1,7 @@ -#include "pocketpy/vm.h" +#include "pocketpy/interpreter/vm.hpp" + +#include +#include static const char* OP_NAMES[] = { #define OPCODE(name) #name, @@ -358,7 +361,7 @@ namespace pkpy{ path = f_join(cpnts); } - PK_ASSERT(path.begin()[0] != '.' && path.end()[-1] != '.'); + assert(path.begin()[0] != '.' && path.end()[-1] != '.'); // check existing module StrName name(path); @@ -388,7 +391,7 @@ namespace pkpy{ if(throw_err) ImportError(_S("module ", path.escape(), " not found")); else return nullptr; } - PK_ASSERT(out_size >= 0) + assert(out_size >= 0); source = Str(std::string_view((char*)out, out_size)); free(out); }else{ @@ -787,7 +790,7 @@ Str VM::disassemble(CodeObject_ co){ } std::string pointer; - if(std::find(jumpTargets.begin(), jumpTargets.end(), i) != jumpTargets.end()){ + if(jumpTargets.contains(i)){ pointer = "-> "; }else{ pointer = " "; @@ -817,7 +820,7 @@ void VM::__log_s_data(const char* title) { if(title) ss << title << " | "; std::map sp_bases; callstack.apply([&](Frame& f){ - if(f._sp_base == nullptr) PK_FATAL_ERROR(); + assert(f._sp_base != nullptr); sp_bases[f._sp_base] += 1; }); Frame* frame = &callstack.top(); @@ -1046,7 +1049,7 @@ PyVar VM::vectorcall(int ARGC, int KWARGC, bool op_call){ // handle boundmethod, do a patch if(callable_t == tp_bound_method){ - PK_DEBUG_ASSERT(p0[1] == PY_NULL) + assert(p0[1] == PY_NULL); BoundMethod& bm = PK_OBJ_GET(BoundMethod, callable); callable = bm.func; // get unbound method callable_t = _tp(callable); @@ -1097,11 +1100,7 @@ PyVar VM::vectorcall(int ARGC, int KWARGC, bool op_call){ callstack.popx(), ArgsView(__vectorcall_buffer, __vectorcall_buffer + co->nlocals) ); -#if PK_DEBUG_EXTRA_CHECK - default: PK_FATAL_ERROR(); break; -#else - default: PK_UNREACHABLE() -#endif + default: PK_UNREACHABLE(); }; // simple or normal @@ -1138,7 +1137,7 @@ PyVar VM::vectorcall(int ARGC, int KWARGC, bool op_call){ // [type, NULL, args..., kwargs...] PyVar new_f = *find_name_in_mro(PK_OBJ_GET(Type, callable), __new__); PyVar obj; - PK_DEBUG_ASSERT(new_f != nullptr && p0[1]==PY_NULL); + assert(new_f != nullptr && p0[1]==PY_NULL); if(new_f == __cached_object_new) { // fast path for object.__new__ obj = vm->new_object(PK_OBJ_GET(Type, callable)); @@ -1407,7 +1406,7 @@ PyObject* VM::bind(PyObject* obj, const char* sig, const char* docstring, Native } PyObject* VM::bind_property(PyObject* obj, const char* name, NativeFuncC fget, NativeFuncC fset){ - PK_ASSERT(is_type(obj, tp_type)); + assert(is_type(obj, tp_type)); std::string_view name_sv(name); int pos = name_sv.find(':'); if(pos > 0) name_sv = name_sv.substr(0, pos); PyVar _0 = new_object(tp_native_func, fget, 1); @@ -1437,7 +1436,7 @@ void VM::AttributeError(PyVar obj, StrName name){ } void VM::_error(PyVar e_obj){ - PK_ASSERT(isinstance(e_obj, tp_exception)) + assert(isinstance(e_obj, tp_exception)); Exception& e = PK_OBJ_GET(Exception, e_obj); if(callstack.empty()){ e.is_re = false; @@ -1752,8 +1751,8 @@ void VM::__breakpoint(){ if(is_list){ int max_line = frame_0->co->src->line_starts.size() + 1; - start = std::max(1, lineno-5); - end = std::min(max_line, lineno+5); + start = (std::max)(1, lineno-5); + end = (std::min)(max_line, lineno+5); }else{ start = frame_0->co->start_line; end = frame_0->co->end_line; diff --git a/src/array2d.cpp b/src/modules/array2d.cpp similarity index 98% rename from src/array2d.cpp rename to src/modules/array2d.cpp index bdf30cc6..a3bf66d8 100644 --- a/src/array2d.cpp +++ b/src/modules/array2d.cpp @@ -1,4 +1,5 @@ -#include "pocketpy/array2d.h" +#include "pocketpy/modules/array2d.hpp" +#include "pocketpy/interpreter/bindings.hpp" namespace pkpy{ @@ -340,10 +341,10 @@ struct Array2d{ for(int j = 0; j < self.n_rows; j++){ for(int i = 0; i < self.n_cols; i++){ if(vm->py_eq(self._get(i, j), value)){ - left = std::min(left, i); - top = std::min(top, j); - right = std::max(right, i); - bottom = std::max(bottom, j); + left = (std::min)(left, i); + top = (std::min)(top, j); + right = (std::max)(right, i); + bottom = (std::max)(bottom, j); } } } diff --git a/src/base64.cpp b/src/modules/base64.cpp similarity index 98% rename from src/base64.cpp rename to src/modules/base64.cpp index 2261a6b6..b1106359 100644 --- a/src/base64.cpp +++ b/src/modules/base64.cpp @@ -1,4 +1,5 @@ -#include "pocketpy/base64.h" +#include "pocketpy/modules/base64.hpp" +#include "pocketpy/interpreter/bindings.hpp" namespace pkpy{ diff --git a/src/csv.cpp b/src/modules/csv.cpp similarity index 97% rename from src/csv.cpp rename to src/modules/csv.cpp index 4aa68f62..97f1becf 100644 --- a/src/csv.cpp +++ b/src/modules/csv.cpp @@ -1,4 +1,5 @@ -#include "pocketpy/csv.h" +#include "pocketpy/modules/csv.hpp" +#include "pocketpy/interpreter/bindings.hpp" namespace pkpy{ diff --git a/src/dataclasses.cpp b/src/modules/dataclasses.cpp similarity index 97% rename from src/dataclasses.cpp rename to src/modules/dataclasses.cpp index 10a2e7f3..2426aeba 100644 --- a/src/dataclasses.cpp +++ b/src/modules/dataclasses.cpp @@ -1,4 +1,5 @@ -#include "pocketpy/dataclasses.h" +#include "pocketpy/modules/dataclasses.hpp" +#include "pocketpy/interpreter/bindings.hpp" namespace pkpy{ diff --git a/src/easing.cpp b/src/modules/easing.cpp similarity index 98% rename from src/easing.cpp rename to src/modules/easing.cpp index 615d434d..f06202d5 100644 --- a/src/easing.cpp +++ b/src/modules/easing.cpp @@ -1,4 +1,7 @@ -#include "pocketpy/easing.h" +#include "pocketpy/modules/easing.hpp" +#include "pocketpy/interpreter/bindings.hpp" + +#include namespace pkpy{ // https://easings.net/ diff --git a/src/io.cpp b/src/modules/io.cpp similarity index 98% rename from src/io.cpp rename to src/modules/io.cpp index 441ec0dc..fd948f12 100644 --- a/src/io.cpp +++ b/src/modules/io.cpp @@ -1,4 +1,5 @@ -#include "pocketpy/io.h" +#include "pocketpy/modules/io.hpp" +#include "pocketpy/interpreter/bindings.hpp" #if PK_ENABLE_OS #include @@ -75,7 +76,7 @@ void FileIO::_register(VM* vm, PyObject* mod, PyObject* type){ } unsigned char* buffer = (unsigned char*)malloc(buffer_size); i64 actual_size = io_fread(buffer, 1, buffer_size, io.fp); - PK_ASSERT(actual_size <= buffer_size); + assert(actual_size <= buffer_size); // in text mode, CR may be dropped, which may cause `actual_size < buffer_size` Bytes b(buffer, actual_size); if(io.is_text){ diff --git a/src/linalg.cpp b/src/modules/linalg.cpp similarity index 99% rename from src/linalg.cpp rename to src/modules/linalg.cpp index c856f980..997b1e58 100644 --- a/src/linalg.cpp +++ b/src/modules/linalg.cpp @@ -1,4 +1,5 @@ -#include "pocketpy/linalg.h" +#include "pocketpy/modules/linalg.hpp" +#include "pocketpy/interpreter/bindings.hpp" namespace pkpy{ @@ -76,7 +77,7 @@ namespace pkpy{ static Vec2 SmoothDamp(Vec2 current, Vec2 target, Vec2& currentVelocity, float smoothTime, float maxSpeed, float deltaTime) { // Based on Game Programming Gems 4 Chapter 1.10 - smoothTime = std::max(0.0001F, smoothTime); + smoothTime = (std::max)(0.0001F, smoothTime); float omega = 2.0F / smoothTime; float x = omega * deltaTime; diff --git a/src/modules.cpp b/src/modules/modules.cpp similarity index 98% rename from src/modules.cpp rename to src/modules/modules.cpp index 47b52edb..6499b802 100644 --- a/src/modules.cpp +++ b/src/modules/modules.cpp @@ -1,4 +1,12 @@ -#include "pocketpy/modules.h" +#include "pocketpy/modules/modules.hpp" +#include "pocketpy/interpreter/bindings.hpp" +#include "pocketpy/common/version.hpp" +#include "pocketpy/export.h" + +#include "pocketpy/common/_generated.hpp" + +#include +#include namespace pkpy{ diff --git a/src/random.cpp b/src/modules/random.cpp similarity index 98% rename from src/random.cpp rename to src/modules/random.cpp index 71a28701..1545bbca 100644 --- a/src/random.cpp +++ b/src/modules/random.cpp @@ -1,4 +1,7 @@ -#include "pocketpy/random.h" +#include "pocketpy/modules/random.hpp" +#include "pocketpy/interpreter/bindings.hpp" + +#include /* https://github.com/clibs/mt19937ar diff --git a/src/namedict.cpp b/src/namedict.cpp deleted file mode 100644 index f5198793..00000000 --- a/src/namedict.cpp +++ /dev/null @@ -1,4 +0,0 @@ -#include "pocketpy/namedict.h" - -namespace pkpy{ -} // namespace pkpy \ No newline at end of file diff --git a/src/objects/builtins.cpp b/src/objects/builtins.cpp new file mode 100644 index 00000000..60461a5b --- /dev/null +++ b/src/objects/builtins.cpp @@ -0,0 +1,6 @@ +#include "pocketpy/objects/builtins.hpp" + +namespace pkpy{ + PyVar const PY_OP_CALL(Type(), new PyObject(Type())); + PyVar const PY_OP_YIELD(Type(), new PyObject(Type())); +} // namespace pkpy \ No newline at end of file diff --git a/src/codeobject.cpp b/src/objects/codeobject.cpp similarity index 64% rename from src/codeobject.cpp rename to src/objects/codeobject.cpp index 091aca8c..6560287f 100644 --- a/src/codeobject.cpp +++ b/src/objects/codeobject.cpp @@ -1,4 +1,4 @@ -#include "pocketpy/codeobject.h" +#include "pocketpy/objects/codeobject.hpp" namespace pkpy{ @@ -6,7 +6,4 @@ namespace pkpy{ src(src), name(name), nlocals(0), start_line(-1), end_line(-1) { blocks.push_back(CodeBlock(CodeBlockType::NO_BLOCK, -1, 0)); } - - PyVar const PY_OP_CALL(Type(), new PyObject(Type())); - PyVar const PY_OP_YIELD(Type(), new PyObject(Type())); } // namespace pkpy \ No newline at end of file diff --git a/src/dict.cpp b/src/objects/dict.cpp similarity index 97% rename from src/dict.cpp rename to src/objects/dict.cpp index 20c81996..52711469 100644 --- a/src/dict.cpp +++ b/src/objects/dict.cpp @@ -1,4 +1,4 @@ -#include "pocketpy/dict.h" +#include "pocketpy/objects/dict.hpp" namespace pkpy{ @@ -140,7 +140,7 @@ namespace pkpy{ t[j++] = _items[i].first; i = _items[i].next; } - PK_ASSERT(j == _size); + assert(j == _size); return t; } @@ -152,7 +152,7 @@ namespace pkpy{ t[j++] = _items[i].second; i = _items[i].next; } - PK_ASSERT(j == _size); + assert(j == _size); return t; } diff --git a/src/objects/error.cpp b/src/objects/error.cpp new file mode 100644 index 00000000..41f772b5 --- /dev/null +++ b/src/objects/error.cpp @@ -0,0 +1,20 @@ +#include "pocketpy/objects/error.hpp" + +namespace pkpy{ + Str Exception::summary() const { + SStream ss; + if(is_re) ss << "Traceback (most recent call last):\n"; + // while(!st.empty()) { + // ss << st.top().snapshot() << '\n'; + // st.pop(); + // } + const auto& container = stacktrace.container(); + for(int i=container.size()-1; i>=0; i--){ + ss << container[i].snapshot() << '\n'; + } + if (!msg.empty()) ss << type.sv() << ": " << msg; + else ss << type.sv(); + return ss.str(); + } + +} // namespace pkpy \ No newline at end of file diff --git a/src/obj.cpp b/src/objects/object.cpp similarity index 69% rename from src/obj.cpp rename to src/objects/object.cpp index bbb7fb5d..15fc536f 100644 --- a/src/obj.cpp +++ b/src/objects/object.cpp @@ -1,4 +1,4 @@ -#include "pocketpy/obj.h" +#include "pocketpy/objects/object.hpp" namespace pkpy{ PyVar::PyVar(PyObject* p): PyVar(p->type, p) {} diff --git a/src/error.cpp b/src/objects/sourcedata.cpp similarity index 81% rename from src/error.cpp rename to src/objects/sourcedata.cpp index 837b5ec2..0e63ab84 100644 --- a/src/error.cpp +++ b/src/objects/sourcedata.cpp @@ -1,7 +1,6 @@ -#include "pocketpy/error.h" +#include "pocketpy/objects/sourcedata.hpp" namespace pkpy{ - SourceData::SourceData(std::string_view source, const Str& filename, CompileMode mode): filename(filename), mode(mode) { int index = 0; // Skip utf8 BOM if there is any. @@ -64,21 +63,4 @@ namespace pkpy{ } return ss.str(); } - - Str Exception::summary() const { - SStream ss; - if(is_re) ss << "Traceback (most recent call last):\n"; - // while(!st.empty()) { - // ss << st.top().snapshot() << '\n'; - // st.pop(); - // } - const auto& container = stacktrace.container(); - for(int i=container.size()-1; i>=0; i--){ - ss << container[i].snapshot() << '\n'; - } - if (!msg.empty()) ss << type.sv() << ": " << msg; - else ss << type.sv(); - return ss.str(); - } - } // namespace pkpy \ No newline at end of file diff --git a/src/tuplelist.cpp b/src/objects/tuplelist.cpp similarity index 96% rename from src/tuplelist.cpp rename to src/objects/tuplelist.cpp index b3334489..222d1d57 100644 --- a/src/tuplelist.cpp +++ b/src/objects/tuplelist.cpp @@ -1,4 +1,4 @@ -#include "pocketpy/tuplelist.h" +#include "pocketpy/objects/tuplelist.hpp" namespace pkpy { diff --git a/src/pocketpy.cpp b/src/pocketpy.cpp index 3f15387d..5fdf70f6 100644 --- a/src/pocketpy.cpp +++ b/src/pocketpy.cpp @@ -1,4 +1,19 @@ -#include "pocketpy/pocketpy.h" +#include "pocketpy/pocketpy.hpp" + +#include "pocketpy/common/_generated.hpp" + +#include "pocketpy/modules/array2d.hpp" +#include "pocketpy/modules/base64.hpp" +#include "pocketpy/modules/csv.hpp" +#include "pocketpy/modules/dataclasses.hpp" +#include "pocketpy/modules/easing.hpp" +#include "pocketpy/modules/io.hpp" +#include "pocketpy/modules/linalg.hpp" +#include "pocketpy/modules/random.hpp" +#include "pocketpy/modules/modules.hpp" + +#include +#include namespace pkpy{ @@ -332,7 +347,7 @@ void __init_builtins(VM* _vm) { // tp_object _vm->bind__repr__(VM::tp_object, [](VM* vm, PyVar obj) -> Str{ - if(is_tagged(obj)) PK_FATAL_ERROR(); + assert(!is_tagged(obj)); SStream ss; ss << "<" << _type_name(vm, vm->_tp(obj)) << " object at "; ss.write_hex(obj.get()); diff --git a/src/pocketpy_c.cpp b/src/pocketpy_c.cpp index 53a95e71..1eb05162 100644 --- a/src/pocketpy_c.cpp +++ b/src/pocketpy_c.cpp @@ -3,6 +3,8 @@ #include "pocketpy.h" #include "pocketpy_c.h" +#include + using namespace pkpy; #define PK_ASSERT_N_EXTRA_ELEMENTS(n) \ @@ -21,7 +23,7 @@ static int count_extra_elements(VM* vm, int n){ if(vm->callstack.empty()){ return vm->s_data.size(); } - PK_ASSERT(!vm->__c.s_view.empty()); + assert(!vm->__c.s_view.empty()); return vm->s_data._sp - vm->__c.s_view.top().end(); } @@ -31,7 +33,7 @@ static PyVar stack_item(VM* vm, int index){ if(vm->callstack.empty()){ begin = vm->s_data.begin(); }else{ - PK_ASSERT(!vm->__c.s_view.empty()); + assert(!vm->__c.s_view.empty()); begin = vm->__c.s_view.top().begin(); } int size = end - begin; @@ -347,7 +349,7 @@ static PyVar c_function_wrapper(VM* vm, ArgsView args) { vm->_error(e_obj); return nullptr; } - PK_ASSERT(retc == vm->s_data._sp-curr_sp); + assert(retc == vm->s_data._sp-curr_sp); if(retc == 0) return vm->None; if (retc == 1) return vm->s_data.popx(); ArgsView ret_view(curr_sp, vm->s_data._sp); diff --git a/src/repl.cpp b/src/tools/repl.cpp similarity index 92% rename from src/repl.cpp rename to src/tools/repl.cpp index 6d9b0941..a26c027b 100644 --- a/src/repl.cpp +++ b/src/tools/repl.cpp @@ -1,4 +1,7 @@ -#include "pocketpy/repl.h" +#include "pocketpy/tools/repl.hpp" + +#include "pocketpy/common/version.hpp" +#include "pocketpy/export.h" namespace pkpy { REPL::REPL(VM* vm) : vm(vm){