mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 11:30:18 +00:00
up
This commit is contained in:
parent
fb06b563a4
commit
e61db0297b
22
src/cffi.h
22
src/cffi.h
@ -105,7 +105,7 @@ struct TypeDB{
|
|||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
const TypeInfo* get() const {
|
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);
|
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){
|
static void _register(VM* vm, PyVar mod, PyVar type){
|
||||||
vm->bind_static_method<-1>(type, "__new__", CPP_NOT_IMPLEMENTED());
|
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);
|
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>
|
template<typename T>
|
||||||
std::enable_if_t<std::is_pointer_v<std::decay_t<T>>, PyVar>
|
std::enable_if_t<std::is_pointer_v<std::decay_t<T>>, PyVar>
|
||||||
py_var(VM* vm, T p){
|
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);
|
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
|
} // namespace pkpy
|
@ -181,6 +181,9 @@ void _check_py_class(VM* vm, const PyVar& var);
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
T py_pointer_cast(VM* vm, const PyVar& var);
|
T py_pointer_cast(VM* vm, const PyVar& var);
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T py_value_cast(VM* vm, const PyVar& var);
|
||||||
|
|
||||||
struct Discarded {};
|
struct Discarded {};
|
||||||
|
|
||||||
template<typename __T>
|
template<typename __T>
|
||||||
@ -191,6 +194,8 @@ __T py_cast(VM* vm, const PyVar& obj) {
|
|||||||
}else if constexpr(is_py_class<T>::value){
|
}else if constexpr(is_py_class<T>::value){
|
||||||
_check_py_class<T>(vm, obj);
|
_check_py_class<T>(vm, obj);
|
||||||
return OBJ_GET(T, 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();
|
return Discarded();
|
||||||
}
|
}
|
||||||
|
52
src/vm.h
52
src/vm.h
@ -380,15 +380,6 @@ DEF_NATIVE_2(Slice, tp_slice)
|
|||||||
DEF_NATIVE_2(Exception, tp_exception)
|
DEF_NATIVE_2(Exception, tp_exception)
|
||||||
DEF_NATIVE_2(StarWrapper, tp_star_wrapper)
|
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){
|
template<> i64 py_cast<i64>(VM* vm, const PyVar& obj){
|
||||||
vm->check_type(obj, vm->tp_int);
|
vm->check_type(obj, vm->tp_int);
|
||||||
return obj.bits >> 2;
|
return obj.bits >> 2;
|
||||||
@ -429,15 +420,40 @@ template<> float _py_cast<float>(VM* vm, const PyVar& obj){
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
std::enable_if_t<std::is_floating_point_v<T>, PyVar> py_var(VM* vm, T _val){
|
#define PY_VAR_INT(T) \
|
||||||
f64 val = static_cast<f64>(_val);
|
PyVar py_var(VM* vm, T _val){ \
|
||||||
i64 bits = __8B(val)._int;
|
i64 val = static_cast<i64>(_val); \
|
||||||
bits = (bits >> 2) << 2;
|
if(((val << 2) >> 2) != val){ \
|
||||||
bits |= 0b10;
|
vm->_error("OverflowError", std::to_string(val) + " is out of range"); \
|
||||||
return PyVar(reinterpret_cast<int*>(bits));
|
} \
|
||||||
|
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){
|
const PyVar& py_var(VM* vm, bool val){
|
||||||
return val ? vm->True : vm->False;
|
return val ? vm->True : vm->False;
|
||||||
}
|
}
|
||||||
@ -454,6 +470,10 @@ PyVar py_var(VM* vm, const char val[]){
|
|||||||
return VAR(Str(val));
|
return VAR(Str(val));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PyVar py_var(VM* vm, std::string val){
|
||||||
|
return VAR(Str(std::move(val)));
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void _check_py_class(VM* vm, const PyVar& obj){
|
void _check_py_class(VM* vm, const PyVar& obj){
|
||||||
vm->check_type(obj, T::_type(vm));
|
vm->check_type(obj, T::_type(vm));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user