This commit is contained in:
blueloveTH 2023-03-14 21:33:27 +08:00
parent fb06b563a4
commit e61db0297b
3 changed files with 63 additions and 18 deletions

View File

@ -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

View File

@ -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();
}

View File

@ -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));