This commit is contained in:
blueloveTH 2023-02-20 04:21:35 +08:00
parent 404f7f8c6f
commit af945293cd
3 changed files with 20 additions and 13 deletions

View File

@ -142,4 +142,7 @@ union __8B {
f64 _float; f64 _float;
__8B(i64 val) : _int(val) {} __8B(i64 val) : _int(val) {}
__8B(f64 val) : _float(val) {} __8B(f64 val) : _float(val) {}
}; };
const i64 kMinSafeInt = -((i64)1 << 62);
const i64 kMaxSafeInt = ((i64)1 << 62) - 1;

View File

@ -20,7 +20,7 @@ CodeObject_ VM::compile(Str source, Str filename, CompileMode mode) {
#define BIND_NUM_ARITH_OPT(name, op) \ #define BIND_NUM_ARITH_OPT(name, op) \
_vm->_bind_methods<1>({"int","float"}, #name, [](VM* vm, pkpy::Args& args){ \ _vm->_bind_methods<1>({"int","float"}, #name, [](VM* vm, pkpy::Args& args){ \
if(is_type(args[0], vm->tp_int) && is_type(args[1], vm->tp_int)){ \ if(is_int(args[0]) && is_int(args[1])){ \
return vm->PyInt(vm->PyInt_AS_C(args[0]) op vm->PyInt_AS_C(args[1])); \ return vm->PyInt(vm->PyInt_AS_C(args[0]) op vm->PyInt_AS_C(args[1])); \
}else{ \ }else{ \
return vm->PyFloat(vm->num_to_float(args[0]) op vm->num_to_float(args[1])); \ return vm->PyFloat(vm->num_to_float(args[0]) op vm->num_to_float(args[1])); \
@ -82,9 +82,14 @@ void init_builtins(VM* _vm) {
}); });
_vm->bind_builtin_func<1>("repr", CPP_LAMBDA(vm->asRepr(args[0]))); _vm->bind_builtin_func<1>("repr", CPP_LAMBDA(vm->asRepr(args[0])));
_vm->bind_builtin_func<1>("hash", CPP_LAMBDA(vm->PyInt(vm->hash(args[0]))));
_vm->bind_builtin_func<1>("len", CPP_LAMBDA(vm->call(args[0], __len__, pkpy::no_arg()))); _vm->bind_builtin_func<1>("len", CPP_LAMBDA(vm->call(args[0], __len__, pkpy::no_arg())));
_vm->bind_builtin_func<1>("hash", [](VM* vm, pkpy::Args& args){
i64 value = vm->hash(args[0]);
if(value < kMinSafeInt || value > kMaxSafeInt) value >>= 2;
return vm->PyInt(value);
});
_vm->bind_builtin_func<1>("chr", [](VM* vm, pkpy::Args& args) { _vm->bind_builtin_func<1>("chr", [](VM* vm, pkpy::Args& args) {
i64 i = vm->PyInt_AS_C(args[0]); i64 i = vm->PyInt_AS_C(args[0]);
if (i < 0 || i > 128) vm->ValueError("chr() arg not in range(128)"); if (i < 0 || i > 128) vm->ValueError("chr() arg not in range(128)");

View File

@ -551,9 +551,7 @@ public:
} }
inline PyVar PyInt(i64 value) { inline PyVar PyInt(i64 value) {
const i64 MIN_SAFE_INT = -((i64)1 << 62); if(value < kMinSafeInt || value > kMaxSafeInt){
const i64 MAX_SAFE_INT = ((i64)1 << 62) - 1;
if(value < MIN_SAFE_INT || value > MAX_SAFE_INT){
_error("OverflowError", std::to_string(value) + " is out of range"); _error("OverflowError", std::to_string(value) + " is out of range");
} }
value = (value << 2) | 0b01; value = (value << 2) | 0b01;
@ -567,16 +565,17 @@ public:
} }
inline PyVar PyFloat(f64 value) { inline PyVar PyFloat(f64 value) {
auto bits = __8B(value); i64 bits = __8B(value)._int;
i64 _int = bits._int; bits = (bits >> 2) << 2;
bits._int = (_int & 0b00) | 0b10; bits |= 0b10;
return PyVar(reinterpret_cast<int*>(bits._int)); return PyVar(reinterpret_cast<int*>(bits));
} }
inline f64 PyFloat_AS_C(const PyVar& obj){ inline f64 PyFloat_AS_C(const PyVar& obj){
check_type(obj, tp_float); check_type(obj, tp_float);
i64 _int = obj.cast<i64>(); i64 bits = obj.cast<i64>();
return __8B(_int & 0b00)._float; bits = (bits >> 2) << 2;
return __8B(bits)._float;
} }
DEF_NATIVE(List, pkpy::List, tp_list) DEF_NATIVE(List, pkpy::List, tp_list)
@ -647,7 +646,7 @@ public:
i64 hash(const PyVar& obj){ i64 hash(const PyVar& obj){
if (is_type(obj, tp_str)) return PyStr_AS_C(obj).hash(); if (is_type(obj, tp_str)) return PyStr_AS_C(obj).hash();
if (is_int(obj)) return PyInt_AS_C(obj); if (is_int(obj)) return PyInt_AS_C(obj);
if (is_type(obj, tp_tuple)) { if (is_type(obj, tp_tuple)) {
i64 x = 1000003; i64 x = 1000003;
const pkpy::Tuple& items = PyTuple_AS_C(obj); const pkpy::Tuple& items = PyTuple_AS_C(obj);