diff --git a/build_g.sh b/build_g.sh index 340e471c..bffbb51f 100644 --- a/build_g.sh +++ b/build_g.sh @@ -2,9 +2,17 @@ python prebuild.py SRC_C=$(find src/ -name "*.c") SRC_CPP=$(find src/ -name "*.cpp") -SRC="$SRC_C $SRC_CPP" -FLAGS="-std=c++17 -O0 -stdlib=libc++ -Iinclude -frtti -Wfatal-errors -g -DDEBUG -DPK_ENABLE_OS=1" +COMMON_FLAGS="-Iinclude -O0 -Wfatal-errors -g -DDEBUG -DPK_ENABLE_OS=1" -clang++ $FLAGS -o main src2/main.cpp $SRC +FLAGS_C="-std=c11 $COMMON_FLAGS" +FLAGS_CPP="-std=c++17 -stdlib=libc++ -frtti $COMMON_FLAGS" +echo "Compiling C files..." +clang $FLAGS_C -c $SRC_C +ar rcs libpocketpy_c.a *.o +rm *.o + +echo "Compiling C++ files..." +clang++ $FLAGS_CPP -o main src2/main.cpp $SRC_CPP libpocketpy_c.a +rm libpocketpy_c.a diff --git a/include/pocketpy/common/any.h b/include/pocketpy/common/any.h new file mode 100644 index 00000000..3e7e904b --- /dev/null +++ b/include/pocketpy/common/any.h @@ -0,0 +1,33 @@ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct c11_userdata{ + void* _0; + void* _1; +} c11_userdata; + +void c11_userdata__ctor(c11_userdata* self, void* ptr, int size); +#define c11_userdata__as(T, self) (*( (T*)(self) )) + +#ifdef __cplusplus +} + +namespace pkpy{ + struct any: c11_userdata{ + template + any(T value){ + c11_userdata__ctor(this, &value, sizeof(T)); + } + + any(){ } + + template + T as(){ + return c11_userdata__as(T, this); + } + }; +} // namespace pkpy +#endif \ No newline at end of file diff --git a/include/pocketpy/common/any.hpp b/include/pocketpy/common/any.hpp deleted file mode 100644 index 6fa09ee1..00000000 --- a/include/pocketpy/common/any.hpp +++ /dev/null @@ -1,113 +0,0 @@ -#pragma once - -#include "pocketpy/common/traits.hpp" - -#include -#include -#include -#include -#include - -namespace pkpy { - -template -constexpr inline bool is_any_sso_v = is_pod_v && sizeof(T) <= sizeof(void*); - -struct any { - struct vtable { - const std::type_index type; - void (*deleter)(void*); - - template - inline static vtable* get() { - static_assert(std::is_same_v>); - if constexpr(is_any_sso_v) { - static vtable vt{typeid(T), nullptr}; - return &vt; - } else { - static vtable vt{typeid(T), [](void* ptr) { - delete static_cast(ptr); - }}; - return &vt; - } - } - }; - - void* data; - vtable* _vt; - - any() : data(nullptr), _vt(nullptr) {} - - explicit operator bool () const { return _vt != nullptr; } - - template - any(T&& value) { - using U = std::decay_t; - static_assert(!std::is_same_v, "any(const any&) is deleted"); - static_assert(sizeof(U) == sizeof(T)); - if constexpr(is_any_sso_v) { - std::memcpy(&data, &value, sizeof(U)); - } else { - data = new U(std::forward(value)); - } - _vt = vtable::get(); - } - - any(any&& other) noexcept; - any& operator= (any&& other) noexcept; - - const std::type_index type_id() const { return _vt ? _vt->type : typeid(void); } - - any(const any& other) = delete; - any& operator= (const any& other) = delete; - - ~any() { - if(_vt && _vt->deleter) _vt->deleter(data); - } - - template - T& _cast() const noexcept { - static_assert(std::is_same_v>); - if constexpr(is_any_sso_v) { - return *((T*)(&data)); - } else { - return *(static_cast(data)); - } - } - - template - T& cast() const { - static_assert(std::is_same_v>); - if(type_id() != typeid(T)) __bad_any_cast(typeid(T), type_id()); - return _cast(); - } - - static void __bad_any_cast(const std::type_index expected, const std::type_index actual); -}; - -template -struct function; - -template -struct function { - any _impl; - Ret (*_wrapper)(const any&, Params...); - - function() : _impl(), _wrapper(nullptr) {} - - explicit operator bool () const { return _wrapper != nullptr; } - - template - function(F&& f) : _impl(std::forward(f)) { - _wrapper = [](const any& impl, Params... params) -> Ret { - return impl._cast>()(std::forward(params)...); - }; - } - - Ret operator() (Params... params) const { - assert(_wrapper); - return _wrapper(_impl, std::forward(params)...); - } -}; - -} // namespace pkpy diff --git a/include/pocketpy/common/sstream.h b/include/pocketpy/common/sstream.h index 282724de..6189e8ef 100644 --- a/include/pocketpy/common/sstream.h +++ b/include/pocketpy/common/sstream.h @@ -29,15 +29,15 @@ typedef struct pkpy_AnyStr { }; } pkpy_AnyStr; -inline pkpy_AnyStr pkpy_AnyStr__int(int x) { pkpy_AnyStr s; s.type = 1; s._int = x; return s; } -inline pkpy_AnyStr pkpy_AnyStr__i64(int64_t x) { pkpy_AnyStr s; s.type = 2; s._i64 = x; return s; } -inline pkpy_AnyStr pkpy_AnyStr__float(float x) { pkpy_AnyStr s; s.type = 3; s._float = x; return s; } -inline pkpy_AnyStr pkpy_AnyStr__double(double x) { pkpy_AnyStr s; s.type = 4; s._double = x; return s; } -inline pkpy_AnyStr pkpy_AnyStr__char(char x) { pkpy_AnyStr s; s.type = 5; s._char = x; return s; } -inline pkpy_AnyStr pkpy_AnyStr__str(const pkpy_Str* x) { pkpy_AnyStr s; s.type = 6; s._str = x; return s; } -inline pkpy_AnyStr pkpy_AnyStr__sv(c11_string x) { pkpy_AnyStr s; s.type = 7; s._sv = x; return s; } -inline pkpy_AnyStr pkpy_AnyStr__cstr(const char* x) { pkpy_AnyStr s; s.type = 8; s._cstr = x; return s; } -inline pkpy_AnyStr pkpy_AnyStr__ptr(void* x) { pkpy_AnyStr s; s.type = 9; s._ptr = x; return s; } +PK_INLINE pkpy_AnyStr pkpy_AnyStr__int(int x) { pkpy_AnyStr s; s.type = 1; s._int = x; return s; } +PK_INLINE pkpy_AnyStr pkpy_AnyStr__i64(int64_t x) { pkpy_AnyStr s; s.type = 2; s._i64 = x; return s; } +PK_INLINE pkpy_AnyStr pkpy_AnyStr__float(float x) { pkpy_AnyStr s; s.type = 3; s._float = x; return s; } +PK_INLINE pkpy_AnyStr pkpy_AnyStr__double(double x) { pkpy_AnyStr s; s.type = 4; s._double = x; return s; } +PK_INLINE pkpy_AnyStr pkpy_AnyStr__char(char x) { pkpy_AnyStr s; s.type = 5; s._char = x; return s; } +PK_INLINE pkpy_AnyStr pkpy_AnyStr__str(const pkpy_Str* x) { pkpy_AnyStr s; s.type = 6; s._str = x; return s; } +PK_INLINE pkpy_AnyStr pkpy_AnyStr__sv(c11_string x) { pkpy_AnyStr s; s.type = 7; s._sv = x; return s; } +PK_INLINE pkpy_AnyStr pkpy_AnyStr__cstr(const char* x) { pkpy_AnyStr s; s.type = 8; s._cstr = x; return s; } +PK_INLINE pkpy_AnyStr pkpy_AnyStr__ptr(void* x) { pkpy_AnyStr s; s.type = 9; s._ptr = x; return s; } void pkpy_SStream__ctor(pkpy_SStream* self); void pkpy_SStream__dtor(pkpy_SStream* self); diff --git a/include/pocketpy/common/str.h b/include/pocketpy/common/str.h index 9469fafc..c09be739 100644 --- a/include/pocketpy/common/str.h +++ b/include/pocketpy/common/str.h @@ -5,7 +5,9 @@ extern "C" { #endif #include + #include "pocketpy/common/vector.h" +#include "pocketpy/common/utils.h" /* string_view */ typedef struct c11_string{ @@ -23,7 +25,7 @@ typedef struct pkpy_Str{ }; } pkpy_Str; -inline const char* pkpy_Str__data(const pkpy_Str* self){ +PK_INLINE const char* pkpy_Str__data(const pkpy_Str* self){ return self->is_sso ? self->_inlined : self->_ptr; } diff --git a/include/pocketpy/common/utils.h b/include/pocketpy/common/utils.h index d395c654..f11604da 100644 --- a/include/pocketpy/common/utils.h +++ b/include/pocketpy/common/utils.h @@ -4,6 +4,12 @@ extern "C" { #endif +#ifdef __cplusplus +#define PK_INLINE inline +#else +#define PK_INLINE static inline +#endif + #define PK_REGION(name) 1 #define PK_SLICE_LOOP(i, start, stop, step) for(int i = start; step > 0 ? i < stop : i > stop; i += step) diff --git a/include/pocketpy/interpreter/vm.hpp b/include/pocketpy/interpreter/vm.hpp index 1c2ec125..cb5276f6 100644 --- a/include/pocketpy/interpreter/vm.hpp +++ b/include/pocketpy/interpreter/vm.hpp @@ -9,6 +9,8 @@ #include "pocketpy/interpreter/frame.hpp" #include "pocketpy/interpreter/profiler.hpp" +#include + namespace pkpy { /* Stack manipulation macros */ diff --git a/include/pocketpy/objects/codeobject.hpp b/include/pocketpy/objects/codeobject.hpp index baefd679..d9afc2c9 100644 --- a/include/pocketpy/objects/codeobject.hpp +++ b/include/pocketpy/objects/codeobject.hpp @@ -1,6 +1,6 @@ #pragma once -#include "pocketpy/common/any.hpp" +#include "pocketpy/common/any.h" #include "pocketpy/objects/tuplelist.hpp" #include "pocketpy/objects/namedict.hpp" #include "pocketpy/objects/sourcedata.hpp" @@ -171,10 +171,12 @@ struct Function { }; template -T& lambda_get_userdata(PyVar* p) { +T lambda_get_userdata(PyVar* p) { static_assert(std::is_same_v>); + static_assert(is_pod_v); int offset = p[-1] != nullptr ? -1 : -2; - return p[offset].obj_get()._userdata.cast(); + NativeFunc& nf = p[offset].obj_get(); + return nf._userdata.as(); } } // namespace pkpy diff --git a/src/common/any.c b/src/common/any.c new file mode 100644 index 00000000..af22bd94 --- /dev/null +++ b/src/common/any.c @@ -0,0 +1,7 @@ +#include "pocketpy/common/any.h" + +#include + +void c11_userdata__ctor(c11_userdata* self, void* ptr, int size){ + memcpy(self, ptr, size); +} diff --git a/src/common/any.cpp b/src/common/any.cpp deleted file mode 100644 index 6ec3636d..00000000 --- a/src/common/any.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#include "pocketpy/common/any.hpp" -#include "pocketpy/common/utils.h" - -#include - -namespace pkpy { - -void any::__bad_any_cast(const std::type_index expected, const std::type_index actual) { - PK_FATAL_ERROR("bad_any_cast: expected %s, got %s\n", expected.name(), actual.name()) -} - -any::any(any&& other) noexcept : data(other.data), _vt(other._vt) { - other.data = nullptr; - other._vt = nullptr; -} - -any& any::operator= (any&& other) noexcept { - if(data) _vt->deleter(data); - data = other.data; - _vt = other._vt; - other.data = nullptr; - other._vt = nullptr; - return *this; -} - -} // namespace pkpy