From e61db0297bec7917477db31b1c8a668510cb8661 Mon Sep 17 00:00:00 2001 From: blueloveTH Date: Tue, 14 Mar 2023 21:33:27 +0800 Subject: [PATCH] up --- src/cffi.h | 22 +++++++++++++++++++++- src/obj.h | 5 +++++ src/vm.h | 54 +++++++++++++++++++++++++++++++++++++----------------- 3 files changed, 63 insertions(+), 18 deletions(-) diff --git a/src/cffi.h b/src/cffi.h index 5dfb5616..ea5ab381 100644 --- a/src/cffi.h +++ b/src/cffi.h @@ -105,7 +105,7 @@ struct TypeDB{ template const TypeInfo* get() const { - return get(TypeId::id); + return get(TypeId>::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(p.ptr); } +template +T py_value_cast(VM* vm, const PyVar& var){ + static_assert(std::is_pod_v); + Value& v = CAST(Value&, var); + return *reinterpret_cast(v.data); +} + template std::enable_if_t>, PyVar> py_var(VM* vm, T p){ @@ -449,4 +462,11 @@ py_var(VM* vm, T p){ return VAR_T(Pointer, type, pointer::level, (char*)p); } +template +std::enable_if_t>, PyVar> +py_var(VM* vm, T p){ + const TypeInfo* type = _type_db.get(); + return VAR_T(Value, type, &p); +} + } // namespace pkpy \ No newline at end of file diff --git a/src/obj.h b/src/obj.h index 7cc5d4c4..61d3abaf 100644 --- a/src/obj.h +++ b/src/obj.h @@ -181,6 +181,9 @@ void _check_py_class(VM* vm, const PyVar& var); template T py_pointer_cast(VM* vm, const PyVar& var); +template +T py_value_cast(VM* vm, const PyVar& var); + struct Discarded {}; template @@ -191,6 +194,8 @@ __T py_cast(VM* vm, const PyVar& obj) { }else if constexpr(is_py_class::value){ _check_py_class(vm, obj); return OBJ_GET(T, obj); + }else if constexpr(std::is_pod_v){ + return py_value_cast(vm, obj); }else{ return Discarded(); } diff --git a/src/vm.h b/src/vm.h index f0e3f6e9..a97d8135 100644 --- a/src/vm.h +++ b/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 -std::enable_if_t && !std::is_same_v, bool>, PyVar> py_var(VM* vm, T _val){ - i64 val = static_cast(_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(val)); -} template<> i64 py_cast(VM* vm, const PyVar& obj){ vm->check_type(obj, vm->tp_int); return obj.bits >> 2; @@ -429,14 +420,39 @@ template<> float _py_cast(VM* vm, const PyVar& obj){ } #endif -template -std::enable_if_t, PyVar> py_var(VM* vm, T _val){ - f64 val = static_cast(_val); - i64 bits = __8B(val)._int; - bits = (bits >> 2) << 2; - bits |= 0b10; - return PyVar(reinterpret_cast(bits)); -} + +#define PY_VAR_INT(T) \ + PyVar py_var(VM* vm, T _val){ \ + i64 val = static_cast(_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(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(_val); \ + i64 bits = __8B(val)._int; \ + bits = (bits >> 2) << 2; \ + bits |= 0b10; \ + return PyVar(reinterpret_cast(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 void _check_py_class(VM* vm, const PyVar& obj){ vm->check_type(obj, T::_type(vm));