blueloveTH пре 3 година
родитељ
комит
e61db0297b
3 измењених фајлова са 63 додато и 18 уклоњено
  1. 21 1
      src/cffi.h
  2. 5 0
      src/obj.h
  3. 37 17
      src/vm.h

+ 21 - 1
src/cffi.h

@@ -105,7 +105,7 @@ struct TypeDB{
 
     template<typename T>
     const TypeInfo* get() const {
-        return get(TypeId<T>::id);
+        return get(TypeId<std::decay_t<T>>::id);
     }
 };
 
@@ -303,6 +303,12 @@ struct Value {
         this->head = Pointer(type, data);
     }
 
+    Value(const TypeInfo* type, void* src) {
+        data = new char[type->size];
+        memcpy(data, src, type->size);
+        this->head = Pointer(type, data);
+    }
+
     static void _register(VM* vm, PyVar mod, PyVar type){
         vm->bind_static_method<-1>(type, "__new__", CPP_NOT_IMPLEMENTED());
 
@@ -442,6 +448,13 @@ T py_pointer_cast(VM* vm, const PyVar& var){
     return reinterpret_cast<T>(p.ptr);
 }
 
+template<typename T>
+T py_value_cast(VM* vm, const PyVar& var){
+    static_assert(std::is_pod_v<T>);
+    Value& v = CAST(Value&, var);
+    return *reinterpret_cast<T*>(v.data);
+}
+
 template<typename T>
 std::enable_if_t<std::is_pointer_v<std::decay_t<T>>, PyVar>
 py_var(VM* vm, T p){
@@ -449,4 +462,11 @@ py_var(VM* vm, T p){
     return VAR_T(Pointer, type, pointer<T>::level, (char*)p);
 }
 
+template<typename T>
+std::enable_if_t<!std::is_pointer_v<std::decay_t<T>>, PyVar>
+py_var(VM* vm, T p){
+    const TypeInfo* type = _type_db.get<T>();
+    return VAR_T(Value, type, &p);
+}
+
 }   // namespace pkpy

+ 5 - 0
src/obj.h

@@ -181,6 +181,9 @@ void _check_py_class(VM* vm, const PyVar& var);
 template<typename T>
 T py_pointer_cast(VM* vm, const PyVar& var);
 
+template<typename T>
+T py_value_cast(VM* vm, const PyVar& var);
+
 struct Discarded {};
 
 template<typename __T>
@@ -191,6 +194,8 @@ __T py_cast(VM* vm, const PyVar& 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{
         return Discarded();
     }

+ 37 - 17
src/vm.h

@@ -380,15 +380,6 @@ DEF_NATIVE_2(Slice, tp_slice)
 DEF_NATIVE_2(Exception, tp_exception)
 DEF_NATIVE_2(StarWrapper, tp_star_wrapper)
 
-template<typename T>
-std::enable_if_t<std::is_integral_v<T> && !std::is_same_v<std::decay_t<T>, bool>, PyVar> py_var(VM* vm, T _val){
-    i64 val = static_cast<i64>(_val);
-    if(((val << 2) >> 2) != val){
-        vm->_error("OverflowError", std::to_string(val) + " is out of range");
-    }
-    val = (val << 2) | 0b01;
-    return PyVar(reinterpret_cast<int*>(val));
-}
 template<> i64 py_cast<i64>(VM* vm, const PyVar& obj){
     vm->check_type(obj, vm->tp_int);
     return obj.bits >> 2;
@@ -429,14 +420,39 @@ template<> float _py_cast<float>(VM* vm, const PyVar& obj){
 }
 #endif
 
-template<typename T>
-std::enable_if_t<std::is_floating_point_v<T>, PyVar> py_var(VM* vm, T _val){
-    f64 val = static_cast<f64>(_val);
-    i64 bits = __8B(val)._int;
-    bits = (bits >> 2) << 2;
-    bits |= 0b10;
-    return PyVar(reinterpret_cast<int*>(bits));
-}
+
+#define PY_VAR_INT(T) \
+    PyVar py_var(VM* vm, T _val){           \
+        i64 val = static_cast<i64>(_val);   \
+        if(((val << 2) >> 2) != val){       \
+            vm->_error("OverflowError", std::to_string(val) + " is out of range");  \
+        }                                                                           \
+        val = (val << 2) | 0b01;                                                    \
+        return PyVar(reinterpret_cast<int*>(val));                                  \
+    }
+
+PY_VAR_INT(char)
+PY_VAR_INT(short)
+PY_VAR_INT(int)
+PY_VAR_INT(long)
+PY_VAR_INT(long long)
+PY_VAR_INT(unsigned char)
+PY_VAR_INT(unsigned short)
+PY_VAR_INT(unsigned int)
+PY_VAR_INT(unsigned long)
+PY_VAR_INT(unsigned long long)
+
+#define PY_VAR_FLOAT(T) \
+    PyVar py_var(VM* vm, T _val){           \
+        f64 val = static_cast<f64>(_val);   \
+        i64 bits = __8B(val)._int;          \
+        bits = (bits >> 2) << 2;            \
+        bits |= 0b10;                       \
+        return PyVar(reinterpret_cast<int*>(bits)); \
+    }
+
+PY_VAR_FLOAT(float)
+PY_VAR_FLOAT(double)
 
 const PyVar& py_var(VM* vm, bool val){
     return val ? vm->True : vm->False;
@@ -454,6 +470,10 @@ PyVar py_var(VM* vm, const char val[]){
     return VAR(Str(val));
 }
 
+PyVar py_var(VM* vm, std::string val){
+    return VAR(Str(std::move(val)));
+}
+
 template<typename T>
 void _check_py_class(VM* vm, const PyVar& obj){
     vm->check_type(obj, T::_type(vm));