blueloveTH 2 лет назад
Родитель
Сommit
020904ca53
3 измененных файлов с 38 добавлено и 40 удалено
  1. 2 2
      src/cffi.h
  2. 19 21
      src/obj.h
  3. 17 17
      src/vm.h

+ 2 - 2
src/cffi.h

@@ -379,7 +379,7 @@ struct NativeProxyFuncC final: NativeProxyFuncCBase {
 };
 
 inline PyObject* _any_c_wrapper(VM* vm, ArgsView args){
-    NativeProxyFuncCBase* pf = static_cast<NativeProxyFuncCBase*>(lambda_get_userdata(args)._p);
+    NativeProxyFuncCBase* pf = lambda_get_userdata<NativeProxyFuncCBase*>(args);
     return (*pf)(vm, args);
 }
 
@@ -389,7 +389,7 @@ inline void bind_any_c_fp(VM* vm, PyObject* obj, Str name, T fp){
     static_assert(std::is_pointer_v<T>);
     auto proxy = new NativeProxyFuncC(fp);
     PyObject* func = VAR(NativeFunc(_any_c_wrapper, proxy->N, false));
-    _CAST(NativeFunc&, func).userdata._p = proxy;
+    _CAST(NativeFunc&, func).set_userdata(proxy);
     obj->attr().set(name, func);
 }
 

+ 19 - 21
src/obj.h

@@ -14,15 +14,6 @@ class VM;
 typedef PyObject* (*NativeFuncC)(VM*, ArgsView);
 typedef int (*LuaStyleFuncC)(VM*);
 
-union UserData{
-    void* _p;
-    void (*_fp)(void);
-    char _char;
-    int _int;
-    float _float;
-    bool _bool;
-};
-
 struct NativeFunc {
     NativeFuncC f;
     int argc;       // DONOT include self
@@ -33,7 +24,22 @@ struct NativeFunc {
     // (-2) or (-1) depends on the calling convention
     LuaStyleFuncC _lua_f;
 
-    UserData userdata;
+    using UserData = char[32];
+    UserData _userdata;
+
+    template <typename T>
+    void set_userdata(T data) {
+        static_assert(std::is_trivially_copyable_v<T>);
+        static_assert(sizeof(T) <= sizeof(UserData));
+        memcpy(_userdata, &data, sizeof(T));
+    }
+
+    template <typename T>
+    T get_userdata() const {
+        static_assert(std::is_trivially_copyable_v<T>);
+        static_assert(sizeof(T) <= sizeof(UserData));
+        return reinterpret_cast<const T&>(_userdata);
+    }
     
     NativeFunc(NativeFuncC f, int argc, bool method) : f(f), argc(argc), method(method), _lua_f(nullptr) {}
     PyObject* operator()(VM* vm, ArgsView args) const;
@@ -391,18 +397,10 @@ struct Py_<DummyModule> final: PyObject {
     void _obj_gc_mark() override {}
 };
 
-
 template<typename T>
-T lambda_get_fp(ArgsView args){
-    void (*f)();
-    if(args[-1] != PY_NULL) f = OBJ_GET(NativeFunc, args[-1]).userdata._fp;
-    else f = OBJ_GET(NativeFunc, args[-2]).userdata._fp;
-    return reinterpret_cast<T>(f);
-}
-
-inline UserData& lambda_get_userdata(ArgsView args){
-    if(args[-1] != PY_NULL) return OBJ_GET(NativeFunc, args[-1]).userdata;
-    else return OBJ_GET(NativeFunc, args[-2]).userdata;
+inline T lambda_get_userdata(ArgsView args){
+    if(args[-1] != PY_NULL) return OBJ_GET(NativeFunc, args[-1]).get_userdata<T>();
+    else return OBJ_GET(NativeFunc, args[-2]).get_userdata<T>();
 }
 
 

+ 17 - 17
src/vm.h

@@ -338,9 +338,9 @@ public:
     void bind##name(Type type, PyObject* (*f)(VM*, PyObject*)){                         \
         _all_types[type].m##name = f;                                                   \
         PyObject* nf = bind_method<0>(_t(type), #name, [](VM* vm, ArgsView args){       \
-            return lambda_get_fp<PyObject*(*)(VM*, PyObject*)>(args)(vm, args[0]);      \
+            return lambda_get_userdata<PyObject*(*)(VM*, PyObject*)>(args)(vm, args[0]);\
         });                                                                             \
-        OBJ_GET(NativeFunc, nf).userdata._fp = reinterpret_cast<void(*)()>(f);          \
+        OBJ_GET(NativeFunc, nf).set_userdata(f);                                        \
     }
 
     BIND_UNARY_SPECIAL(__repr__)
@@ -361,10 +361,10 @@ public:
         PyObject* obj = _t(type);                                                       \
         _all_types[type].m##name = f;                                                   \
         PyObject* nf = bind_method<1>(obj, #name, [](VM* vm, ArgsView args){            \
-            bool ok = lambda_get_fp<bool(*)(VM*, PyObject*, PyObject*)>(args)(vm, args[0], args[1]); \
+            bool ok = lambda_get_userdata<bool(*)(VM*, PyObject*, PyObject*)>(args)(vm, args[0], args[1]); \
             return ok ? vm->True : vm->False;                                           \
         });                                                                             \
-        OBJ_GET(NativeFunc, nf).userdata._fp = reinterpret_cast<void(*)()>(f);          \
+        OBJ_GET(NativeFunc, nf).set_userdata(f);                                        \
     }
 
     BIND_LOGICAL_SPECIAL(__eq__)
@@ -381,10 +381,10 @@ public:
     void bind##name(Type type, PyObject* (*f)(VM*, PyObject*, PyObject*)){              \
         PyObject* obj = _t(type);                                                       \
         _all_types[type].m##name = f;                                                   \
-        PyObject* nf = bind_method<1>(obj, #name, [](VM* vm, ArgsView args){                           \
-            return lambda_get_fp<PyObject*(*)(VM*, PyObject*, PyObject*)>(args)(vm, args[0], args[1]); \
+        PyObject* nf = bind_method<1>(obj, #name, [](VM* vm, ArgsView args){            \
+            return lambda_get_userdata<PyObject*(*)(VM*, PyObject*, PyObject*)>(args)(vm, args[0], args[1]); \
         });                                                                             \
-        OBJ_GET(NativeFunc, nf).userdata._fp = reinterpret_cast<void(*)()>(f);          \
+        OBJ_GET(NativeFunc, nf).set_userdata(f);                                        \
     }
 
     BIND_BINARY_SPECIAL(__add__)
@@ -408,29 +408,29 @@ public:
         PyObject* obj = _t(type);
         _all_types[type].m__getitem__ = f;
         PyObject* nf = bind_method<1>(obj, "__getitem__", [](VM* vm, ArgsView args){
-            return lambda_get_fp<PyObject*(*)(VM*, PyObject*, PyObject*)>(args)(vm, args[0], args[1]);
+            return lambda_get_userdata<PyObject*(*)(VM*, PyObject*, PyObject*)>(args)(vm, args[0], args[1]);
         });
-        OBJ_GET(NativeFunc, nf).userdata._fp = reinterpret_cast<void(*)()>(f);
+        OBJ_GET(NativeFunc, nf).set_userdata(f);
     }
 
     void bind__setitem__(Type type, void (*f)(VM*, PyObject*, PyObject*, PyObject*)){
         PyObject* obj = _t(type);
         _all_types[type].m__setitem__ = f;
         PyObject* nf = bind_method<2>(obj, "__setitem__", [](VM* vm, ArgsView args){
-            lambda_get_fp<void(*)(VM* vm, PyObject*, PyObject*, PyObject*)>(args)(vm, args[0], args[1], args[2]);
+            lambda_get_userdata<void(*)(VM* vm, PyObject*, PyObject*, PyObject*)>(args)(vm, args[0], args[1], args[2]);
             return vm->None;
         });
-        OBJ_GET(NativeFunc, nf).userdata._fp = reinterpret_cast<void(*)()>(f);
+        OBJ_GET(NativeFunc, nf).set_userdata(f);
     }
 
     void bind__delitem__(Type type, void (*f)(VM*, PyObject*, PyObject*)){
         PyObject* obj = _t(type);
         _all_types[type].m__delitem__ = f;
         PyObject* nf = bind_method<1>(obj, "__delitem__", [](VM* vm, ArgsView args){
-            lambda_get_fp<void(*)(VM*, PyObject*, PyObject*)>(args)(vm, args[0], args[1]);
+            lambda_get_userdata<void(*)(VM*, PyObject*, PyObject*)>(args)(vm, args[0], args[1]);
             return vm->None;
         });
-        OBJ_GET(NativeFunc, nf).userdata._fp = reinterpret_cast<void(*)()>(f);
+        OBJ_GET(NativeFunc, nf).set_userdata(f);
     }
 
     bool py_equals(PyObject* lhs, PyObject* rhs){
@@ -1406,20 +1406,20 @@ inline void VM::bind__hash__(Type type, i64 (*f)(VM*, PyObject*)){
     PyObject* obj = _t(type);
     _all_types[type].m__hash__ = f;
     PyObject* nf = bind_method<0>(obj, "__hash__", [](VM* vm, ArgsView args){
-        i64 ret = lambda_get_fp<i64(*)(VM*, PyObject*)>(args)(vm, args[0]);
+        i64 ret = lambda_get_userdata<i64(*)(VM*, PyObject*)>(args)(vm, args[0]);
         return VAR(ret);
     });
-    OBJ_GET(NativeFunc, nf).userdata._fp = reinterpret_cast<void(*)(void)>(f);
+    OBJ_GET(NativeFunc, nf).set_userdata(f);
 }
 
 inline void VM::bind__len__(Type type, i64 (*f)(VM*, PyObject*)){
     PyObject* obj = _t(type);
     _all_types[type].m__len__ = f;
     PyObject* nf = bind_method<0>(obj, "__len__", [](VM* vm, ArgsView args){
-        i64 ret = lambda_get_fp<i64(*)(VM*, PyObject*)>(args)(vm, args[0]);
+        i64 ret = lambda_get_userdata<i64(*)(VM*, PyObject*)>(args)(vm, args[0]);
         return VAR(ret);
     });
-    OBJ_GET(NativeFunc, nf).userdata._fp = reinterpret_cast<void(*)(void)>(f);
+    OBJ_GET(NativeFunc, nf).set_userdata(f);
 }