mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 11:30:18 +00:00
Merge branch 'v2.0-c11' into pr/271
This commit is contained in:
commit
00a5b4d5d3
14
build_g.sh
14
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
|
||||
|
33
include/pocketpy/common/any.h
Normal file
33
include/pocketpy/common/any.h
Normal file
@ -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<typename T>
|
||||
any(T value){
|
||||
c11_userdata__ctor(this, &value, sizeof(T));
|
||||
}
|
||||
|
||||
any(){ }
|
||||
|
||||
template<typename T>
|
||||
T as(){
|
||||
return c11_userdata__as(T, this);
|
||||
}
|
||||
};
|
||||
} // namespace pkpy
|
||||
#endif
|
@ -1,113 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "pocketpy/common/traits.hpp"
|
||||
|
||||
#include <typeindex>
|
||||
#include <cassert>
|
||||
#include <utility>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
namespace pkpy {
|
||||
|
||||
template <typename T>
|
||||
constexpr inline bool is_any_sso_v = is_pod_v<T> && sizeof(T) <= sizeof(void*);
|
||||
|
||||
struct any {
|
||||
struct vtable {
|
||||
const std::type_index type;
|
||||
void (*deleter)(void*);
|
||||
|
||||
template <typename T>
|
||||
inline static vtable* get() {
|
||||
static_assert(std::is_same_v<T, std::decay_t<T>>);
|
||||
if constexpr(is_any_sso_v<T>) {
|
||||
static vtable vt{typeid(T), nullptr};
|
||||
return &vt;
|
||||
} else {
|
||||
static vtable vt{typeid(T), [](void* ptr) {
|
||||
delete static_cast<T*>(ptr);
|
||||
}};
|
||||
return &vt;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void* data;
|
||||
vtable* _vt;
|
||||
|
||||
any() : data(nullptr), _vt(nullptr) {}
|
||||
|
||||
explicit operator bool () const { return _vt != nullptr; }
|
||||
|
||||
template <typename T>
|
||||
any(T&& value) {
|
||||
using U = std::decay_t<T>;
|
||||
static_assert(!std::is_same_v<U, any>, "any(const any&) is deleted");
|
||||
static_assert(sizeof(U) == sizeof(T));
|
||||
if constexpr(is_any_sso_v<U>) {
|
||||
std::memcpy(&data, &value, sizeof(U));
|
||||
} else {
|
||||
data = new U(std::forward<T>(value));
|
||||
}
|
||||
_vt = vtable::get<U>();
|
||||
}
|
||||
|
||||
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 <typename T>
|
||||
T& _cast() const noexcept {
|
||||
static_assert(std::is_same_v<T, std::decay_t<T>>);
|
||||
if constexpr(is_any_sso_v<T>) {
|
||||
return *((T*)(&data));
|
||||
} else {
|
||||
return *(static_cast<T*>(data));
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T& cast() const {
|
||||
static_assert(std::is_same_v<T, std::decay_t<T>>);
|
||||
if(type_id() != typeid(T)) __bad_any_cast(typeid(T), type_id());
|
||||
return _cast<T>();
|
||||
}
|
||||
|
||||
static void __bad_any_cast(const std::type_index expected, const std::type_index actual);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct function;
|
||||
|
||||
template <typename Ret, typename... Params>
|
||||
struct function<Ret(Params...)> {
|
||||
any _impl;
|
||||
Ret (*_wrapper)(const any&, Params...);
|
||||
|
||||
function() : _impl(), _wrapper(nullptr) {}
|
||||
|
||||
explicit operator bool () const { return _wrapper != nullptr; }
|
||||
|
||||
template <typename F>
|
||||
function(F&& f) : _impl(std::forward<F>(f)) {
|
||||
_wrapper = [](const any& impl, Params... params) -> Ret {
|
||||
return impl._cast<std::decay_t<F>>()(std::forward<Params>(params)...);
|
||||
};
|
||||
}
|
||||
|
||||
Ret operator() (Params... params) const {
|
||||
assert(_wrapper);
|
||||
return _wrapper(_impl, std::forward<Params>(params)...);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace pkpy
|
@ -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);
|
||||
|
@ -5,7 +5,9 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -9,6 +9,8 @@
|
||||
#include "pocketpy/interpreter/frame.hpp"
|
||||
#include "pocketpy/interpreter/profiler.hpp"
|
||||
|
||||
#include <typeindex>
|
||||
|
||||
namespace pkpy {
|
||||
|
||||
/* Stack manipulation macros */
|
||||
|
@ -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 <typename T>
|
||||
T& lambda_get_userdata(PyVar* p) {
|
||||
T lambda_get_userdata(PyVar* p) {
|
||||
static_assert(std::is_same_v<T, std::decay_t<T>>);
|
||||
static_assert(is_pod_v<T>);
|
||||
int offset = p[-1] != nullptr ? -1 : -2;
|
||||
return p[offset].obj_get<NativeFunc>()._userdata.cast<T>();
|
||||
NativeFunc& nf = p[offset].obj_get<NativeFunc>();
|
||||
return nf._userdata.as<T>();
|
||||
}
|
||||
|
||||
} // namespace pkpy
|
||||
|
7
src/common/any.c
Normal file
7
src/common/any.c
Normal file
@ -0,0 +1,7 @@
|
||||
#include "pocketpy/common/any.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
void c11_userdata__ctor(c11_userdata* self, void* ptr, int size){
|
||||
memcpy(self, ptr, size);
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
#include "pocketpy/common/any.hpp"
|
||||
#include "pocketpy/common/utils.h"
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
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
|
Loading…
x
Reference in New Issue
Block a user