This commit is contained in:
blueloveTH 2024-03-02 03:46:28 +08:00
parent 6755c73a58
commit 2055f9cd46
3 changed files with 12 additions and 14 deletions

View File

@ -83,15 +83,13 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Setup Alpine Linux v3.15 for aarch64 - name: Setup Alpine Linux for aarch64
uses: jirutka/setup-alpine@v1 uses: jirutka/setup-alpine@v1
with: with:
arch: x86 arch: x86
packages: gcc g++ make cmake libc-dev linux-headers python3 packages: gcc g++ make cmake libc-dev linux-headers python3
branch: v3.15
- name: Build and Test - name: Build and Test
run: | run: |
ln -s /usr/bin/python3 /usr/bin/python
uname -m uname -m
python cmake_build.py python cmake_build.py
python scripts/run_tests.py python scripts/run_tests.py

View File

@ -8,17 +8,9 @@ namespace pkpy {
#define PY_CLASS(T, mod, name) \ #define PY_CLASS(T, mod, name) \
static Type _type(VM* vm) { return vm->_cxx_typeid_map[&typeid(T)]; } \ static Type _type(VM* vm) { return vm->_cxx_typeid_map[&typeid(T)]; } \
static void _check_type(VM* vm, PyObject* val){ \
if(!vm->isinstance(val, T::_type(vm))){ \
vm->TypeError("expected '" #mod "." #name "', got " + _type_name(vm, vm->_tp(val)).escape()); \
} \
} \
static PyObject* register_class(VM* vm, PyObject* mod, Type base=0) { \ static PyObject* register_class(VM* vm, PyObject* mod, Type base=0) { \
std::string_view mod_name = PK_OBJ_GET(Str, mod->attr("__name__")).sv(); \ std::string_view mod_name = PK_OBJ_GET(Str, mod->attr("__name__")).sv(); \
if(mod_name != #mod) { \ if(mod_name != #mod) throw std::runtime_error(_S("register_class() failed: ", mod_name, " != ", #mod).str()); \
Str msg = _S("register_class() failed: ", mod_name, " != ", #mod); \
throw std::runtime_error(msg.str()); \
} \
PyObject* type = vm->new_type_object(mod, #name, base); \ PyObject* type = vm->new_type_object(mod, #name, base); \
mod->attr().set(#name, type); \ mod->attr().set(#name, type); \
vm->_cxx_typeid_map[&typeid(T)] = PK_OBJ_GET(Type, type); \ vm->_cxx_typeid_map[&typeid(T)] = PK_OBJ_GET(Type, type); \

View File

@ -354,6 +354,11 @@ public:
TypeError("expected " + _type_name(vm, type).escape() + ", got " + _type_name(vm, _tp(obj)).escape()); TypeError("expected " + _type_name(vm, type).escape() + ", got " + _type_name(vm, _tp(obj)).escape());
} }
void check_compatible_type(PyObject* obj, Type type){
if(isinstance(obj, type)) return;
TypeError(_S(_type_name(vm, _tp(obj)).escape(), " is not compatible with ", _type_name(vm, type).escape()));
}
PyObject* _t(Type t){ PyObject* _t(Type t){
return _all_types[t.index].obj; return _all_types[t.index].obj;
} }
@ -371,7 +376,10 @@ public:
struct ImportContext{ struct ImportContext{
std::vector<Str> pending; std::vector<Str> pending;
pod_vector<bool> pending_is_init; // a.k.a __init__.py pod_vector<bool> pending_is_init; // a.k.a __init__.py
struct Temp{ struct Temp{
PK_ALWAYS_PASS_BY_POINTER(Temp)
ImportContext* ctx; ImportContext* ctx;
Temp(ImportContext* ctx, Str name, bool is_init) : ctx(ctx){ Temp(ImportContext* ctx, Str name, bool is_init) : ctx(ctx){
ctx->pending.push_back(name); ctx->pending.push_back(name);
@ -436,7 +444,7 @@ public:
#elif _MSC_VER #elif _MSC_VER
throw std::runtime_error(__FUNCSIG__ + std::string(" failed: T not found")); throw std::runtime_error(__FUNCSIG__ + std::string(" failed: T not found"));
#else #else
throw std::runtime_error("py_var() failed: T not found"); throw std::runtime_error("_find_type_in_cxx_typeid_map() failed: T not found");
#endif #endif
} }
return it->second; return it->second;
@ -556,7 +564,7 @@ __T _py_cast__internal(VM* vm, PyObject* obj) {
} }
} }
Type type = vm->_find_type_in_cxx_typeid_map<T>(); Type type = vm->_find_type_in_cxx_typeid_map<T>();
if constexpr(with_check) vm->check_non_tagged_type(obj, type); if constexpr(with_check) vm->check_compatible_type(obj, type);
return PK_OBJ_GET(T, obj); return PK_OBJ_GET(T, obj);
} }