mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 11:30:18 +00:00
some optimize
This commit is contained in:
parent
e13ca1a924
commit
d15747c2f0
@ -123,8 +123,12 @@ inline bool is_type(const PyVar& obj, Type type) noexcept {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool is_int_or_float(const PyVar& obj) noexcept {
|
inline bool is_both_int_or_float(const PyVar& a, const PyVar& b) noexcept {
|
||||||
return obj.is_tag_01() || obj.is_tag_10();
|
return ((a.cast<i64>() | b.cast<i64>()) & 0b11) != 0b00;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool is_both_int(const PyVar& a, const PyVar& b) noexcept {
|
||||||
|
return (a.cast<i64>() & b.cast<i64>() & 0b11) == 0b01;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool is_int(const PyVar& obj) noexcept {
|
inline bool is_int(const PyVar& obj) noexcept {
|
||||||
|
@ -20,8 +20,8 @@ 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_int(args[0]) && is_int(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])); \
|
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])); \
|
||||||
} \
|
} \
|
||||||
@ -29,10 +29,12 @@ CodeObject_ VM::compile(Str source, Str filename, CompileMode mode) {
|
|||||||
|
|
||||||
#define BIND_NUM_LOGICAL_OPT(name, op, is_eq) \
|
#define BIND_NUM_LOGICAL_OPT(name, op, is_eq) \
|
||||||
_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_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]); \
|
if constexpr(is_eq) return vm->PyBool(args[0] op args[1]); \
|
||||||
vm->TypeError("unsupported operand type(s) for " #op ); \
|
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])); \
|
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) {
|
_vm->_bind_methods<1>({"int", "float"}, "__pow__", [](VM* vm, pkpy::Args& args) {
|
||||||
if(is_int(args[0]) && is_int(args[1])){
|
if(is_both_int(args[0], args[1])){
|
||||||
i64 lhs = vm->PyInt_AS_C(args[0]);
|
i64 lhs = vm->_PyInt_AS_C(args[0]);
|
||||||
i64 rhs = vm->PyInt_AS_C(args[1]);
|
i64 rhs = vm->_PyInt_AS_C(args[1]);
|
||||||
bool flag = false;
|
bool flag = false;
|
||||||
if(rhs < 0) {flag = true; rhs = -rhs;}
|
if(rhs < 0) {flag = true; rhs = -rhs;}
|
||||||
i64 ret = 1;
|
i64 ret = 1;
|
||||||
@ -326,29 +328,29 @@ void init_builtins(VM* _vm) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
_vm->bind_method<1>("str", "__getitem__", [](VM* vm, pkpy::Args& args) {
|
_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)){
|
if(is_type(args[1], vm->tp_slice)){
|
||||||
pkpy::Slice s = vm->PySlice_AS_C(args[1]);
|
pkpy::Slice s = vm->PySlice_AS_C(args[1]);
|
||||||
s.normalize(_self.u8_length());
|
s.normalize(self.u8_length());
|
||||||
return vm->PyStr(_self.u8_substr(s.start, s.stop));
|
return vm->PyStr(self.u8_substr(s.start, s.stop));
|
||||||
}
|
}
|
||||||
|
|
||||||
int _index = (int)vm->PyInt_AS_C(args[1]);
|
int index = (int)vm->PyInt_AS_C(args[1]);
|
||||||
_index = vm->normalized_index(_index, _self.u8_length());
|
index = vm->normalized_index(index, self.u8_length());
|
||||||
return vm->PyStr(_self.u8_getitem(_index));
|
return vm->PyStr(self.u8_getitem(index));
|
||||||
});
|
});
|
||||||
|
|
||||||
_vm->bind_method<1>("str", "__gt__", [](VM* vm, pkpy::Args& args) {
|
_vm->bind_method<1>("str", "__gt__", [](VM* vm, pkpy::Args& args) {
|
||||||
const Str& _self (vm->PyStr_AS_C(args[0]));
|
const Str& self (vm->PyStr_AS_C(args[0]));
|
||||||
const Str& _obj (vm->PyStr_AS_C(args[1]));
|
const Str& obj (vm->PyStr_AS_C(args[1]));
|
||||||
return vm->PyBool(_self > _obj);
|
return vm->PyBool(self > obj);
|
||||||
});
|
});
|
||||||
|
|
||||||
_vm->bind_method<1>("str", "__lt__", [](VM* vm, pkpy::Args& args) {
|
_vm->bind_method<1>("str", "__lt__", [](VM* vm, pkpy::Args& args) {
|
||||||
const Str& _self (vm->PyStr_AS_C(args[0]));
|
const Str& self (vm->PyStr_AS_C(args[0]));
|
||||||
const Str& _obj (vm->PyStr_AS_C(args[1]));
|
const Str& obj (vm->PyStr_AS_C(args[1]));
|
||||||
return vm->PyBool(_self < _obj);
|
return vm->PyBool(self < obj);
|
||||||
});
|
});
|
||||||
|
|
||||||
_vm->bind_method<2>("str", "replace", [](VM* vm, pkpy::Args& args) {
|
_vm->bind_method<2>("str", "replace", [](VM* vm, pkpy::Args& args) {
|
||||||
|
19
src/vm.h
19
src/vm.h
@ -416,10 +416,10 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline f64 num_to_float(const PyVar& obj){
|
inline f64 num_to_float(const PyVar& obj){
|
||||||
if (is_int(obj)){
|
if(is_float(obj)){
|
||||||
return (f64)PyInt_AS_C(obj);
|
|
||||||
}else if(is_float(obj)){
|
|
||||||
return PyFloat_AS_C(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));
|
TypeError("expected 'int' or 'float', got " + OBJ_NAME(_t(obj)).escape(true));
|
||||||
return 0;
|
return 0;
|
||||||
@ -554,8 +554,11 @@ public:
|
|||||||
|
|
||||||
inline i64 PyInt_AS_C(const PyVar& obj){
|
inline i64 PyInt_AS_C(const PyVar& obj){
|
||||||
check_type(obj, tp_int);
|
check_type(obj, tp_int);
|
||||||
i64 value = obj.cast<i64>();
|
return obj.cast<i64>() >> 2;
|
||||||
return value >> 2;
|
}
|
||||||
|
|
||||||
|
inline i64 _PyInt_AS_C(const PyVar& obj){
|
||||||
|
return obj.cast<i64>() >> 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline PyVar PyFloat(f64 value) {
|
inline PyVar PyFloat(f64 value) {
|
||||||
@ -572,6 +575,12 @@ public:
|
|||||||
return __8B(bits)._float;
|
return __8B(bits)._float;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline f64 _PyFloat_AS_C(const PyVar& obj){
|
||||||
|
i64 bits = obj.cast<i64>();
|
||||||
|
bits = (bits >> 2) << 2;
|
||||||
|
return __8B(bits)._float;
|
||||||
|
}
|
||||||
|
|
||||||
DEF_NATIVE(List, pkpy::List, tp_list)
|
DEF_NATIVE(List, pkpy::List, tp_list)
|
||||||
DEF_NATIVE(Tuple, pkpy::Tuple, tp_tuple)
|
DEF_NATIVE(Tuple, pkpy::Tuple, tp_tuple)
|
||||||
DEF_NATIVE(Function, pkpy::Function, tp_function)
|
DEF_NATIVE(Function, pkpy::Function, tp_function)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user