From d15747c2f0efc2f354bd15460d73a89a10160b7d Mon Sep 17 00:00:00 2001 From: blueloveTH Date: Wed, 22 Feb 2023 21:48:27 +0800 Subject: [PATCH] some optimize --- src/obj.h | 8 ++++++-- src/pocketpy.h | 38 ++++++++++++++++++++------------------ src/vm.h | 19 ++++++++++++++----- 3 files changed, 40 insertions(+), 25 deletions(-) diff --git a/src/obj.h b/src/obj.h index a6b6379d..72c28790 100644 --- a/src/obj.h +++ b/src/obj.h @@ -123,8 +123,12 @@ inline bool is_type(const PyVar& obj, Type type) noexcept { } } -inline bool is_int_or_float(const PyVar& obj) noexcept { - return obj.is_tag_01() || obj.is_tag_10(); +inline bool is_both_int_or_float(const PyVar& a, const PyVar& b) noexcept { + return ((a.cast() | b.cast()) & 0b11) != 0b00; +} + +inline bool is_both_int(const PyVar& a, const PyVar& b) noexcept { + return (a.cast() & b.cast() & 0b11) == 0b01; } inline bool is_int(const PyVar& obj) noexcept { diff --git a/src/pocketpy.h b/src/pocketpy.h index 7a11341d..543de4a3 100644 --- a/src/pocketpy.h +++ b/src/pocketpy.h @@ -20,8 +20,8 @@ CodeObject_ VM::compile(Str source, Str filename, CompileMode mode) { #define BIND_NUM_ARITH_OPT(name, op) \ _vm->_bind_methods<1>({"int","float"}, #name, [](VM* vm, pkpy::Args& args){ \ - 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])); \ + if(is_both_int(args[0], args[1])){ \ + return vm->PyInt(vm->_PyInt_AS_C(args[0]) op vm->_PyInt_AS_C(args[1])); \ }else{ \ return vm->PyFloat(vm->num_to_float(args[0]) op vm->num_to_float(args[1])); \ } \ @@ -29,10 +29,12 @@ CodeObject_ VM::compile(Str source, Str filename, CompileMode mode) { #define BIND_NUM_LOGICAL_OPT(name, op, is_eq) \ _vm->_bind_methods<1>({"int","float"}, #name, [](VM* vm, pkpy::Args& args){ \ - if(!is_int_or_float(args[0]) || !is_int_or_float(args[1])){ \ + if(!is_both_int_or_float(args[0], args[1])){ \ if constexpr(is_eq) return vm->PyBool(args[0] op args[1]); \ vm->TypeError("unsupported operand type(s) for " #op ); \ } \ + if(is_both_int(args[0], args[1])) \ + return vm->PyBool(vm->_PyInt_AS_C(args[0]) op vm->_PyInt_AS_C(args[1])); \ return vm->PyBool(vm->num_to_float(args[0]) op vm->num_to_float(args[1])); \ }); @@ -177,9 +179,9 @@ void init_builtins(VM* _vm) { }); _vm->_bind_methods<1>({"int", "float"}, "__pow__", [](VM* vm, pkpy::Args& args) { - if(is_int(args[0]) && is_int(args[1])){ - i64 lhs = vm->PyInt_AS_C(args[0]); - i64 rhs = vm->PyInt_AS_C(args[1]); + if(is_both_int(args[0], args[1])){ + i64 lhs = vm->_PyInt_AS_C(args[0]); + i64 rhs = vm->_PyInt_AS_C(args[1]); bool flag = false; if(rhs < 0) {flag = true; rhs = -rhs;} i64 ret = 1; @@ -326,29 +328,29 @@ void init_builtins(VM* _vm) { }); _vm->bind_method<1>("str", "__getitem__", [](VM* vm, pkpy::Args& args) { - const Str& _self (vm->PyStr_AS_C(args[0])); + const Str& self (vm->PyStr_AS_C(args[0])); if(is_type(args[1], vm->tp_slice)){ pkpy::Slice s = vm->PySlice_AS_C(args[1]); - s.normalize(_self.u8_length()); - return vm->PyStr(_self.u8_substr(s.start, s.stop)); + s.normalize(self.u8_length()); + return vm->PyStr(self.u8_substr(s.start, s.stop)); } - int _index = (int)vm->PyInt_AS_C(args[1]); - _index = vm->normalized_index(_index, _self.u8_length()); - return vm->PyStr(_self.u8_getitem(_index)); + int index = (int)vm->PyInt_AS_C(args[1]); + index = vm->normalized_index(index, self.u8_length()); + return vm->PyStr(self.u8_getitem(index)); }); _vm->bind_method<1>("str", "__gt__", [](VM* vm, pkpy::Args& args) { - const Str& _self (vm->PyStr_AS_C(args[0])); - const Str& _obj (vm->PyStr_AS_C(args[1])); - return vm->PyBool(_self > _obj); + const Str& self (vm->PyStr_AS_C(args[0])); + const Str& obj (vm->PyStr_AS_C(args[1])); + return vm->PyBool(self > obj); }); _vm->bind_method<1>("str", "__lt__", [](VM* vm, pkpy::Args& args) { - const Str& _self (vm->PyStr_AS_C(args[0])); - const Str& _obj (vm->PyStr_AS_C(args[1])); - return vm->PyBool(_self < _obj); + const Str& self (vm->PyStr_AS_C(args[0])); + const Str& obj (vm->PyStr_AS_C(args[1])); + return vm->PyBool(self < obj); }); _vm->bind_method<2>("str", "replace", [](VM* vm, pkpy::Args& args) { diff --git a/src/vm.h b/src/vm.h index 3565923e..9c5aba6d 100644 --- a/src/vm.h +++ b/src/vm.h @@ -416,10 +416,10 @@ public: } inline f64 num_to_float(const PyVar& obj){ - if (is_int(obj)){ - return (f64)PyInt_AS_C(obj); - }else if(is_float(obj)){ + if(is_float(obj)){ return PyFloat_AS_C(obj); + } else if (is_int(obj)){ + return (f64)PyInt_AS_C(obj); } TypeError("expected 'int' or 'float', got " + OBJ_NAME(_t(obj)).escape(true)); return 0; @@ -554,8 +554,11 @@ public: inline i64 PyInt_AS_C(const PyVar& obj){ check_type(obj, tp_int); - i64 value = obj.cast(); - return value >> 2; + return obj.cast() >> 2; + } + + inline i64 _PyInt_AS_C(const PyVar& obj){ + return obj.cast() >> 2; } inline PyVar PyFloat(f64 value) { @@ -572,6 +575,12 @@ public: return __8B(bits)._float; } + inline f64 _PyFloat_AS_C(const PyVar& obj){ + i64 bits = obj.cast(); + bits = (bits >> 2) << 2; + return __8B(bits)._float; + } + DEF_NATIVE(List, pkpy::List, tp_list) DEF_NATIVE(Tuple, pkpy::Tuple, tp_tuple) DEF_NATIVE(Function, pkpy::Function, tp_function)