diff --git a/plugins/flutter/src/pocketpy.h b/plugins/flutter/src/pocketpy.h index bcad5d69..c821b4f4 100644 --- a/plugins/flutter/src/pocketpy.h +++ b/plugins/flutter/src/pocketpy.h @@ -4507,9 +4507,9 @@ public: } template - inline PyVar newObject(PyVar type, T _value) { + inline PyVar newObject(PyVar type, T&& _value) { __checkType(type, _tp_type); - return pkpy::make_shared>(_value, type); + return pkpy::make_shared>(std::forward(_value), type); } PyVar newModule(_Str name) { diff --git a/src/pocketpy.h b/src/pocketpy.h index ded93e16..fc6699c6 100644 --- a/src/pocketpy.h +++ b/src/pocketpy.h @@ -5,13 +5,13 @@ #include "repl.h" #define BIND_NUM_ARITH_OPT(name, op) \ - _vm->bindMethodMulti({"int","float"}, #name, [](VM* vm, const pkpy::ArgList& args){ \ + _vm->bindMethodMulti({"int","float"}, #name, [](VM* vm, const pkpy::ArgList& args){ \ if(!vm->isIntOrFloat(args[0], args[1])) \ - vm->typeError("unsupported operand type(s) for " #op ); \ - if(args[0]->isType(vm->_tp_int) && args[1]->isType(vm->_tp_int)){ \ - return vm->PyInt(vm->PyInt_AS_C(args[0]) op vm->PyInt_AS_C(args[1])); \ + vm->typeError("unsupported operand type(s) for " #op ); \ + if(args._index(0)->isType(vm->_tp_int) && args._index(1)->isType(vm->_tp_int)){ \ + return vm->PyInt(vm->PyInt_AS_C(args._index(0)) op vm->PyInt_AS_C(args._index(1))); \ }else{ \ - return vm->PyFloat(vm->numToFloat(args[0]) op vm->numToFloat(args[1])); \ + return vm->PyFloat(vm->numToFloat(args._index(0)) op vm->numToFloat(args._index(1))); \ } \ }); @@ -21,7 +21,7 @@ if constexpr(is_eq) return vm->PyBool(args[0] == args[1]); \ vm->typeError("unsupported operand type(s) for " #op ); \ } \ - return vm->PyBool(vm->numToFloat(args[0]) op vm->numToFloat(args[1])); \ + return vm->PyBool(vm->numToFloat(args._index(0)) op vm->numToFloat(args._index(1))); \ }); @@ -205,17 +205,17 @@ void __initializeBuiltinFunctions(VM* _vm) { _vm->bindMethod("int", "__floordiv__", [](VM* vm, const pkpy::ArgList& args) { if(!args[0]->isType(vm->_tp_int) || !args[1]->isType(vm->_tp_int)) vm->typeError("unsupported operand type(s) for " "//" ); - _Int rhs = vm->PyInt_AS_C(args[1]); + _Int rhs = vm->PyInt_AS_C(args._index(1)); if(rhs == 0) vm->zeroDivisionError(); - return vm->PyInt(vm->PyInt_AS_C(args[0]) / rhs); + return vm->PyInt(vm->PyInt_AS_C(args._index(0)) / rhs); }); _vm->bindMethod("int", "__mod__", [](VM* vm, const pkpy::ArgList& args) { if(!args[0]->isType(vm->_tp_int) || !args[1]->isType(vm->_tp_int)) vm->typeError("unsupported operand type(s) for " "%" ); - _Int rhs = vm->PyInt_AS_C(args[1]); + _Int rhs = vm->PyInt_AS_C(args._index(1)); if(rhs == 0) vm->zeroDivisionError(); - return vm->PyInt(vm->PyInt_AS_C(args[0]) % rhs); + return vm->PyInt(vm->PyInt_AS_C(args._index(0)) % rhs); }); _vm->bindMethod("int", "__repr__", [](VM* vm, const pkpy::ArgList& args) { @@ -227,10 +227,10 @@ void __initializeBuiltinFunctions(VM* _vm) { }); #define __INT_BITWISE_OP(name,op) \ - _vm->bindMethod("int", #name, [](VM* vm, const pkpy::ArgList& args) { \ - if(!args[0]->isType(vm->_tp_int) || !args[1]->isType(vm->_tp_int)) \ - vm->typeError("unsupported operand type(s) for " #op ); \ - return vm->PyInt(vm->PyInt_AS_C(args[0]) op vm->PyInt_AS_C(args[1])); \ + _vm->bindMethod("int", #name, [](VM* vm, const pkpy::ArgList& args) { \ + if(!args[0]->isType(vm->_tp_int) || !args[1]->isType(vm->_tp_int)) \ + vm->typeError("unsupported operand type(s) for " #op ); \ + return vm->PyInt(vm->PyInt_AS_C(args._index(0)) op vm->PyInt_AS_C(args._index(1))); \ }); __INT_BITWISE_OP(__lshift__, <<) @@ -241,12 +241,6 @@ void __initializeBuiltinFunctions(VM* _vm) { #undef __INT_BITWISE_OP - _vm->bindMethod("int", "__xor__", [](VM* vm, const pkpy::ArgList& args) { - if(!args[0]->isType(vm->_tp_int) || !args[1]->isType(vm->_tp_int)) - vm->typeError("unsupported operand type(s) for " "^" ); - return vm->PyInt(vm->PyInt_AS_C(args[0]) ^ vm->PyInt_AS_C(args[1])); - }); - /************ PyFloat ************/ _vm->bindMethod("float", "__new__", [](VM* vm, const pkpy::ArgList& args) { if(args.size() == 0) return vm->PyFloat(0.0); diff --git a/src/safestl.h b/src/safestl.h index 9388e42a..62c91cdc 100644 --- a/src/safestl.h +++ b/src/safestl.h @@ -142,6 +142,10 @@ namespace pkpy { return _args[i]; } + inline const PyVar& _index(uint8_t i) const { + return _args[i]; + } + // overload = for && ArgList& operator=(ArgList&& other){ if(this != &other){ diff --git a/src/vm.h b/src/vm.h index 964f056e..6a8c6125 100644 --- a/src/vm.h +++ b/src/vm.h @@ -156,20 +156,23 @@ protected: case OP_POP_TOP: frame->popValue(this); break; case OP_BINARY_OP: { - pkpy::ArgList args = frame->popNValuesReversed(this, 2); - frame->push(fastCall(BINARY_SPECIAL_METHODS[byte.arg], std::move(args))); + frame->push( + fastCall(BINARY_SPECIAL_METHODS[byte.arg], + frame->popNValuesReversed(this, 2)) + ); } break; case OP_BITWISE_OP: { - pkpy::ArgList args = frame->popNValuesReversed(this, 2); - frame->push(fastCall(BITWISE_SPECIAL_METHODS[byte.arg], std::move(args))); + frame->push( + fastCall(BITWISE_SPECIAL_METHODS[byte.arg], + frame->popNValuesReversed(this, 2)) + ); } break; case OP_COMPARE_OP: { - pkpy::ArgList args = frame->popNValuesReversed(this, 2); // for __ne__ we use the negation of __eq__ int op = byte.arg == 3 ? 2 : byte.arg; - PyVar res = fastCall(CMP_SPECIAL_METHODS[op], std::move(args)); + PyVar res = fastCall(CMP_SPECIAL_METHODS[op], frame->popNValuesReversed(this, 2)); if(op != byte.arg) res = PyBool(!PyBool_AS_C(res)); frame->push(std::move(res)); } break; @@ -264,11 +267,11 @@ protected: case OP_GOTO: { PyVar obj = frame->popValue(this); const _Str& label = PyStr_AS_C(obj); - auto it = frame->code->co_labels.find(label); - if(it == frame->code->co_labels.end()){ + int* target = frame->code->co_labels.try_get(label); + if(target == nullptr){ _error("KeyError", "label '" + label + "' not found"); } - frame->safeJump(it->second); + frame->safeJump(*target); } break; case OP_GET_ITER: { @@ -440,8 +443,8 @@ public: PyVar fastCall(const _Str& name, pkpy::ArgList&& args){ PyObject* cls = args[0]->_type.get(); while(cls != None.get()) { - auto it = cls->attribs.find(name); - if(it != cls->attribs.end()) return call(it->second, std::move(args)); + PyVar* val = cls->attribs.try_get(name); + if(val != nullptr) return call(*val, std::move(args)); cls = cls->attribs[__base__].get(); } attributeError(args[0], name); @@ -531,7 +534,7 @@ public: for(int i=0; ikwArgs.find(key) == fn->kwArgs.end()){ + if(!fn->kwArgs.contains(key)){ typeError(key.__escape(true) + " is an invalid keyword argument for " + fn->name + "()"); } const PyVar& val = kwargs[i+1]; @@ -544,8 +547,8 @@ public: locals[key] = val; } - auto it_m = (*callable)->attribs.find(__module__); - PyVar _module = it_m != (*callable)->attribs.end() ? it_m->second : topFrame()->_module; + PyVar* it_m = (*callable)->attribs.try_get(__module__); + PyVar _module = it_m != nullptr ? *it_m : topFrame()->_module; if(opCall){ __pushNewFrame(fn->code, _module, std::move(locals)); return __py2py_call_signal; @@ -968,12 +971,12 @@ public: /***** Pointers' Impl *****/ PyVar NameRef::get(VM* vm, Frame* frame) const{ - auto it = frame->f_locals.find(pair->first); - if(it != frame->f_locals.end()) return it->second; - it = frame->f_globals().find(pair->first); - if(it != frame->f_globals().end()) return it->second; - it = vm->builtins->attribs.find(pair->first); - if(it != vm->builtins->attribs.end()) return it->second; + PyVar* val = frame->f_locals.try_get(pair->first); + if(val) return *val; + val = frame->f_globals().try_get(pair->first); + if(val) return *val; + val = vm->builtins->attribs.try_get(pair->first); + if(val) return *val; vm->nameError(pair->first); return nullptr; }