blueloveTH 2 tahun lalu
induk
melakukan
b637190ae7
4 mengubah file dengan 15 tambahan dan 340 penghapusan
  1. 12 334
      src/cffi.h
  2. 1 1
      src/common.h
  3. 1 4
      src/obj.h
  4. 1 1
      src/pocketpy.h

+ 12 - 334
src/cffi.h

@@ -72,345 +72,36 @@ auto native_proxy_callable(Ret(T::*func)(Params...)) {
     return NativeProxyMethod<Ret, T, Params...>(func);
 }
 
+struct VoidP{
+    PY_CLASS(VoidP, c, void_p)
 
-template<typename T>
-constexpr int type_index() { return 0; }
-template<> constexpr int type_index<void>() { return 1; }
-template<> constexpr int type_index<char>() { return 2; }
-template<> constexpr int type_index<short>() { return 3; }
-template<> constexpr int type_index<int>() { return 4; }
-template<> constexpr int type_index<long>() { return 5; }
-template<> constexpr int type_index<long long>() { return 6; }
-template<> constexpr int type_index<unsigned char>() { return 7; }
-template<> constexpr int type_index<unsigned short>() { return 8; }
-template<> constexpr int type_index<unsigned int>() { return 9; }
-template<> constexpr int type_index<unsigned long>() { return 10; }
-template<> constexpr int type_index<unsigned long long>() { return 11; }
-template<> constexpr int type_index<float>() { return 12; }
-template<> constexpr int type_index<double>() { return 13; }
-template<> constexpr int type_index<bool>() { return 14; }
-
-template<typename T>
-struct TypeId{ inline static int id; };
-
-struct TypeInfo;
-
-struct MemberInfo{
-    const TypeInfo* type;
-    int offset;
-};
-
-struct TypeInfo{
-    const char* name;
-    int size;
-    int index;
-    std::map<StrName, MemberInfo> members;
-};
-
-struct Vec2 {
-    float x, y;
-};
-
-struct TypeDB{
-    std::vector<TypeInfo> _by_index;
-    std::map<std::string_view, int> _by_name;
-
-    template<typename T>
-    void register_type(const char name[], std::map<StrName, MemberInfo>&& members){
-        TypeInfo ti;
-        ti.name = name;
-        if constexpr(std::is_same_v<T, void>) ti.size = 1;
-        else ti.size = sizeof(T);
-        ti.members = std::move(members);
-        TypeId<T>::id = ti.index = _by_index.size()+1;    // 0 is reserved for NULL
-        _by_name[name] = ti.index;
-        _by_index.push_back(ti);
-    }
-
-    const TypeInfo* get(int index) const {
-        return index == 0 ? nullptr : &_by_index[index-1];
-    }
-
-    const TypeInfo* get(std::string_view name) const {
-        auto it = _by_name.find(name);
-        if(it == _by_name.end()) return nullptr;
-        return get(it->second);
-    }
-
-    const TypeInfo* get(const Str& s) const {
-        return get(s.sv());
-    }
-
-    template<typename T>
-    const TypeInfo* get() const {
-        return get(TypeId<std::decay_t<T>>::id);
-    }
-};
-
-static TypeDB _type_db;
-
-
-inline static auto ___x = [](){
-    #define REGISTER_BASIC_TYPE(T) _type_db.register_type<T>(#T, {});
-    _type_db.register_type<void>("void", {});
-    REGISTER_BASIC_TYPE(char);
-    REGISTER_BASIC_TYPE(short);
-    REGISTER_BASIC_TYPE(int);
-    REGISTER_BASIC_TYPE(long);
-    REGISTER_BASIC_TYPE(long long);
-    REGISTER_BASIC_TYPE(unsigned char);
-    REGISTER_BASIC_TYPE(unsigned short);
-    REGISTER_BASIC_TYPE(unsigned int);
-    REGISTER_BASIC_TYPE(unsigned long);
-    REGISTER_BASIC_TYPE(unsigned long long);
-    REGISTER_BASIC_TYPE(float);
-    REGISTER_BASIC_TYPE(double);
-    REGISTER_BASIC_TYPE(bool);
-    #undef REGISTER_BASIC_TYPE
-
-    _type_db.register_type<Vec2>("Vec2", {
-        {"x", { _type_db.get<float>(), offsetof(Vec2, x) }},
-        {"y", { _type_db.get<float>(), offsetof(Vec2, y) }},
-    });
-    return 0;
-}();
-
-struct Pointer{
-    PY_CLASS(Pointer, c, _ptr)
-
-    const TypeInfo* ctype;      // this is immutable
-    int level;                  // level of pointer
-    char* ptr;
-
-    i64 unit_size() const {
-        return level == 1 ? ctype->size : sizeof(void*);
-    }
-
-    Pointer() : ctype(_type_db.get<void>()), level(1), ptr(nullptr) {}
-    Pointer(const TypeInfo* ctype, int level, char* ptr): ctype(ctype), level(level), ptr(ptr) {}
-    Pointer(const TypeInfo* ctype, char* ptr): ctype(ctype), level(1), ptr(ptr) {}
-
-    Pointer operator+(i64 offset) const { 
-        return Pointer(ctype, level, ptr+offset*unit_size());
-    }
-
-    Pointer operator-(i64 offset) const { 
-        return Pointer(ctype, level, ptr-offset*unit_size());
-    }
+    void* ptr;
+    VoidP(void* ptr): ptr(ptr){}
 
     static void _register(VM* vm, PyObject* mod, PyObject* type){
-        vm->bind_static_method<-1>(type, "__new__", CPP_NOT_IMPLEMENTED());
+        vm->bind_static_method<1>(type, "__new__", CPP_NOT_IMPLEMENTED());
 
-        vm->bind_method<0>(type, "__repr__", [](VM* vm, ArgsView args) {
-            Pointer& self = CAST(Pointer&, args[0]);
+        vm->bind_static_method<1>(type, "__repr__", [](VM* vm, const Args& args){
+            VoidP& self = CAST(VoidP&, args[0]);
             std::stringstream ss;
-            ss << "<" << self.ctype->name;
-            for(int i=0; i<self.level; i++) ss << "*";
-            ss << " at " << (i64)self.ptr << ">";
+            ss << "<void* at " << self.ptr << ">";
             return VAR(ss.str());
         });
-
-        vm->bind_method<1>(type, "__add__", [](VM* vm, ArgsView args) {
-            Pointer& self = CAST(Pointer&, args[0]);
-            return VAR_T(Pointer, self + CAST(i64, args[1]));
-        });
-
-        vm->bind_method<1>(type, "__sub__", [](VM* vm, ArgsView args) {
-            Pointer& self = CAST(Pointer&, args[0]);
-            return VAR_T(Pointer, self - CAST(i64, args[1]));
-        });
-
-        vm->bind_method<1>(type, "__eq__", [](VM* vm, ArgsView args) {
-            Pointer& self = CAST(Pointer&, args[0]);
-            Pointer& other = CAST(Pointer&, args[1]);
-            return VAR(self.ptr == other.ptr);
-        });
-
-        vm->bind_method<1>(type, "__ne__", [](VM* vm, ArgsView args) {
-            Pointer& self = CAST(Pointer&, args[0]);
-            Pointer& other = CAST(Pointer&, args[1]);
-            return VAR(self.ptr != other.ptr);
-        });
-
-        vm->bind_method<1>(type, "__getitem__", [](VM* vm, ArgsView args) {
-            Pointer& self = CAST(Pointer&, args[0]);
-            i64 index = CAST(i64, args[1]);
-            return (self+index).get(vm);
-        });
-
-        vm->bind_method<2>(type, "__setitem__", [](VM* vm, ArgsView args) {
-            Pointer& self = CAST(Pointer&, args[0]);
-            i64 index = CAST(i64, args[1]);
-            (self+index).set(vm, args[2]);
-            return vm->None;
-        });
-
-        vm->bind_method<1>(type, "__getattr__", [](VM* vm, ArgsView args) {
-            Pointer& self = CAST(Pointer&, args[0]);
-            const Str& name = CAST(Str&, args[1]);
-            return VAR_T(Pointer, self._to(vm, name));
-        });
-
-        vm->bind_method<0>(type, "get", [](VM* vm, ArgsView args) {
-            Pointer& self = CAST(Pointer&, args[0]);
-            return self.get(vm);
-        });
-
-        vm->bind_method<1>(type, "set", [](VM* vm, ArgsView args) {
-            Pointer& self = CAST(Pointer&, args[0]);
-            self.set(vm, args[1]);
-            return vm->None;
-        });
-    }
-
-    template<typename T>
-    T& ref() noexcept { return *reinterpret_cast<T*>(ptr); }
-
-    PyObject* get(VM* vm){
-        if(level > 1) return VAR_T(Pointer, ctype, level-1, ref<char*>());
-        switch(ctype->index){
-#define CASE(T) case type_index<T>(): return VAR(ref<T>())
-            case type_index<void>(): vm->ValueError("cannot get void*"); break;
-            CASE(char);
-            CASE(short);
-            CASE(int);
-            CASE(long);
-            CASE(long long);
-            CASE(unsigned char);
-            CASE(unsigned short);
-            CASE(unsigned int);
-            CASE(unsigned long);
-            CASE(unsigned long long);
-            CASE(float);
-            CASE(double);
-            CASE(bool);
-#undef CASE
-        }
-        return VAR_T(Pointer, *this);
-    }
-
-    void set(VM* vm, PyObject* val){
-        if(level > 1) {
-            Pointer& p = CAST(Pointer&, val);
-            ref<char*>() = p.ptr;   // We don't check the type, just copy the underlying address
-            return;
-        }
-        switch(ctype->index){
-#define CASE(T1, T2) case type_index<T1>(): ref<T1>() = CAST(T2, val); break
-            case type_index<void>(): vm->ValueError("cannot set void*"); break;
-            CASE(char, i64);
-            CASE(short, i64);
-            CASE(int, i64);
-            CASE(long, i64);
-            CASE(long long, i64);
-            CASE(unsigned char, i64);
-            CASE(unsigned short, i64);
-            CASE(unsigned int, i64);
-            CASE(unsigned long, i64);
-            CASE(unsigned long long, i64);
-            CASE(float, f64);
-            CASE(double, f64);
-            CASE(bool, bool);
-#undef CASE
-            default: FATAL_ERROR();
-        }
-    }
-
-    Pointer _to(VM* vm, StrName name){
-        auto it = ctype->members.find(name);
-        if(it == ctype->members.end()){
-            vm->AttributeError(fmt("struct '", ctype->name, "' has no member ", name.escape()));
-        }
-        const MemberInfo& info = it->second;
-        return {info.type, level, ptr+info.offset};
-    }
-};
-
-
-struct CType{
-    PY_CLASS(CType, c, ctype)
-
-    const TypeInfo* type;
-
-    CType() : type(_type_db.get<void>()) {}
-    CType(const TypeInfo* type) : type(type) {}
-
-    static void _register(VM* vm, PyObject* mod, PyObject* type){
-        vm->bind_static_method<1>(type, "__new__", [](VM* vm, ArgsView args) {
-            const Str& name = CAST(Str&, args[0]);
-            const TypeInfo* type = _type_db.get(name);
-            if(type == nullptr) vm->TypeError("unknown type: " + name.escape());
-            return VAR_T(CType, type);
-        });
     }
 };
 
 inline void add_module_c(VM* vm){
     PyObject* mod = vm->new_module("c");
-    Pointer::register_class(vm, mod);
-    CType::register_class(vm, mod);
-
-    vm->setattr(mod, "nullptr", VAR_T(Pointer));
-
-    vm->bind_func<1>(mod, "malloc", [](VM* vm, ArgsView args) {
-        i64 size = CAST(i64, args[0]);
-        return VAR_T(Pointer, _type_db.get<void>(), (char*)malloc(size));
-    });
-
-    vm->bind_func<1>(mod, "free", [](VM* vm, ArgsView args) {
-        Pointer& self = CAST(Pointer&, args[0]);
-        free(self.ptr);
-        return vm->None;
-    });
-
-    vm->bind_func<3>(mod, "memcpy", [](VM* vm, ArgsView args) {
-        Pointer& dst = CAST(Pointer&, args[0]);
-        Pointer& src = CAST(Pointer&, args[1]);
-        i64 size = CAST(i64, args[2]);
-        memcpy(dst.ptr, src.ptr, size);
-        return vm->None;
-    });
-
-    vm->bind_func<2>(mod, "cast", [](VM* vm, ArgsView args) {
-        Pointer& self = CAST(Pointer&, args[0]);
-        const Str& name = CAST(Str&, args[1]);
-        int level = 0;
-        for(int i=name.length()-1; i>=0; i--){
-            if(name[i] == '*') level++;
-            else break;
-        }
-        if(level == 0) vm->TypeError("expect a pointer type, such as 'int*'");
-        Str type_s = name.substr(0, name.length()-level);
-        const TypeInfo* type = _type_db.get(type_s);
-        if(type == nullptr) vm->TypeError("unknown type: " + type_s.escape());
-        return VAR_T(Pointer, type, level, self.ptr);
-    });
-
-    vm->bind_func<1>(mod, "sizeof", [](VM* vm, ArgsView args) {
-        const Str& name = CAST(Str&, args[0]);
-        if(name.index("*") != -1) return VAR(sizeof(void*));
-        const TypeInfo* type = _type_db.get(name);
-        if(type == nullptr) vm->TypeError("unknown type: " + name.escape());
-        return VAR(type->size);
-    });
-
-    vm->bind_func<3>(mod, "memset", [](VM* vm, ArgsView args) {
-        Pointer& dst = CAST(Pointer&, args[0]);
-        i64 val = CAST(i64, args[1]);
-        i64 size = CAST(i64, args[2]);
-        memset(dst.ptr, (int)val, size);
-        return vm->None;
-    });
+    VoidP::register_class(vm, mod);
 }
 
 inline PyObject* py_var(VM* vm, void* p){
-    return VAR_T(Pointer, _type_db.get<void>(), (char*)p);
+    return VAR_T(VoidP, p);
 }
 
 inline PyObject* py_var(VM* vm, char* p){
-    return VAR_T(Pointer, _type_db.get<char>(), (char*)p);
+    return VAR_T(VoidP, p);
 }
-
 /***********************************************/
 
 template<typename T>
@@ -434,20 +125,7 @@ struct pointer {
 template<typename T>
 T py_pointer_cast(VM* vm, PyObject* var){
     static_assert(std::is_pointer_v<T>);
-    Pointer& p = CAST(Pointer&, var);
-    const TypeInfo* type = _type_db.get<typename pointer<T>::baseT>();
-    const int level = pointer<T>::level;
-    if(p.ctype != type || p.level != level){
-        vm->TypeError("invalid pointer cast");
-    }
+    VoidP& p = CAST(VoidP&, var);
     return reinterpret_cast<T>(p.ptr);
 }
-
-template<typename T>
-std::enable_if_t<std::is_pointer_v<std::decay_t<T>>, PyObject*>
-py_var(VM* vm, T p){
-    const TypeInfo* type = _type_db.get<typename pointer<T>::baseT>();
-    if(type == nullptr) type = _type_db.get<void>();
-    return VAR_T(Pointer, type, pointer<T>::level, (char*)p);
-}
 }   // namespace pkpy

+ 1 - 1
src/common.h

@@ -35,7 +35,7 @@
 #define DEBUG_NO_BUILTIN_MODULES	0
 #define DEBUG_EXTRA_CHECK			1
 #define DEBUG_DIS_EXEC				1
-#define DEBUG_CEVAL_STEP			1
+#define DEBUG_CEVAL_STEP			0
 #define DEBUG_CEVAL_STEP_MIN		0
 #define DEBUG_FULL_EXCEPTION		0
 #define DEBUG_MEMORY_POOL			0

+ 1 - 4
src/obj.h

@@ -198,7 +198,6 @@ template <typename T> struct is_py_class<T, std::void_t<decltype(T::_type)>> : s
 
 template<typename T> void _check_py_class(VM*, PyObject*);
 template<typename T> T py_pointer_cast(VM*, PyObject*);
-template<typename T> T py_value_cast(VM*, PyObject*);
 
 template<typename __T>
 __T py_cast(VM* vm, PyObject* obj) {
@@ -208,9 +207,7 @@ __T py_cast(VM* vm, PyObject* obj) {
     }else if constexpr(is_py_class<T>::value){
         _check_py_class<T>(vm, obj);
         return OBJ_GET(T, obj);
-    }else if constexpr(std::is_pod_v<T>){
-        return py_value_cast<T>(vm, obj);
-    }else{
+    }else {
         return Discarded();
     }
 }

+ 1 - 1
src/pocketpy.h

@@ -772,7 +772,7 @@ inline void VM::post_init(){
     add_module_random(this);
     add_module_io(this);
     add_module_os(this);
-    // add_module_c(this);
+    add_module_c(this);
     add_module_gc(this);
 
     for(const char* name: {"this", "functools", "collections", "heapq", "bisect"}){