From 299370a225d5d448aae02b5b5e6f899307a35a34 Mon Sep 17 00:00:00 2001 From: blueloveTH Date: Wed, 9 Nov 2022 14:26:45 +0800 Subject: [PATCH] fix bugs of __new__ some renames --- src/codeobject.h | 6 +++--- src/obj.h | 6 +++--- src/pocketpy.h | 41 +++++++++++------------------------------ src/vm.h | 24 ++++++++++++++++-------- 4 files changed, 33 insertions(+), 44 deletions(-) diff --git a/src/codeobject.h b/src/codeobject.h index 576990d3..4f0765c7 100644 --- a/src/codeobject.h +++ b/src/codeobject.h @@ -106,12 +106,12 @@ private: std::vector s_data; int ip = 0; public: - StlDict* f_globals; - StlDict f_locals; + PyVarDict* f_globals; + PyVarDict f_locals; const CodeObject* code; - Frame(const CodeObject* code, StlDict locals, StlDict* globals) + Frame(const CodeObject* code, PyVarDict locals, PyVarDict* globals) : code(code), f_locals(locals), f_globals(globals) {} inline const ByteCode& readCode() { diff --git a/src/obj.h b/src/obj.h index f527624f..33b07d4e 100644 --- a/src/obj.h +++ b/src/obj.h @@ -18,7 +18,7 @@ class VM; typedef std::shared_ptr PyVar; typedef PyVar PyVarOrNull; typedef std::vector PyVarList; -typedef std::unordered_map<_Str, PyVar> StlDict; +typedef std::unordered_map<_Str, PyVar> PyVarDict; typedef std::shared_ptr _Pointer; typedef PyVar (*_CppFunc)(VM*, PyVarList); @@ -29,7 +29,7 @@ struct _Func { _Code code; std::vector<_Str> args; _Str starredArg; // empty if no *arg - StlDict kwArgs; // empty if no k=v + PyVarDict kwArgs; // empty if no k=v _Str doubleStarredArg; // empty if no **kwargs bool hasName(const _Str& val) const { @@ -81,7 +81,7 @@ typedef std::variantPyList(ret); }); - _vm->bindMethod("object", "__new__", [](VM* vm, PyVarList args) { - PyVar obj = vm->newObject(args.at(0), -1); - args.erase(args.begin()); - PyVarOrNull init_fn = vm->getAttr(obj, __init__, false); - if (init_fn != nullptr) vm->call(init_fn, args); - return obj; - }); - _vm->bindMethod("object", "__repr__", [](VM* vm, PyVarList args) { PyVar _self = args[0]; _Str s = "<" + _self->getTypeName() + " object at " + std::to_string((uintptr_t)_self.get()) + ">"; return vm->PyStr(s); }); - // a little buggy... e.g. dict() call this instead of obj.__new__ - // _vm->bindMethod("type", "__new__", [](VM* vm, PyVarList args) { - // return args.at(1)->attribs["__class__"]; - // }); + _vm->bindMethod("type", "__new__", [](VM* vm, PyVarList args) { + vm->_assert(args.size() == 1, "expected 1 argument"); + return args.at(0)->attribs[__class__]; + }); _vm->bindMethod("range", "__new__", [](VM* vm, PyVarList args) { _Range r; - if( args.size() == 0 ) vm->_error("TypeError", "range expected 1 arguments, got 0"); - else if (args.size() == 1+1) { - r.stop = vm->PyInt_AS_C(args[1]); - } - else if (args.size() == 2+1) { - r.start = vm->PyInt_AS_C(args[1]); - r.stop = vm->PyInt_AS_C(args[2]); - } - else if (args.size() == 3+1) { - r.start = vm->PyInt_AS_C(args[1]); - r.stop = vm->PyInt_AS_C(args[2]); - r.step = vm->PyInt_AS_C(args[3]); - } - else { - vm->_error("TypeError", "range expected 1 to 3 arguments, got " + std::to_string(args.size()-1)); + switch (args.size()) { + case 1: r.stop = vm->PyInt_AS_C(args[0]); break; + case 2: r.start = vm->PyInt_AS_C(args[0]); r.stop = vm->PyInt_AS_C(args[1]); break; + case 3: r.start = vm->PyInt_AS_C(args[0]); r.stop = vm->PyInt_AS_C(args[1]); r.step = vm->PyInt_AS_C(args[2]); break; + default: vm->_error("TypeError", "range expected 1-3 arguments, got " + std::to_string(args.size())); } return vm->PyRange(r); }); @@ -187,9 +169,8 @@ void __initializeBuiltinFunctions(VM* _vm) { /************ PyString ************/ _vm->bindMethod("str", "__new__", [](VM* vm, PyVarList args) { - vm->_assert(args[0] == vm->_tp_str, "str.__new__ must be called with str as first argument"); - vm->_assert(args.size() == 2, "str expected 1 argument"); - return vm->asStr(args[1]); + vm->_assert(args.size() == 1, "expected 1 argument"); + return vm->asStr(args[0]); }); _vm->bindMethod("str", "__add__", [](VM* vm, PyVarList args) { diff --git a/src/vm.h b/src/vm.h index bde4e995..02905ea5 100644 --- a/src/vm.h +++ b/src/vm.h @@ -28,14 +28,14 @@ private: std::stack< std::shared_ptr > callstack; std::vector numPool; public: - StlDict _types; // builtin types + PyVarDict _types; // builtin types PyVar None, True, False; PrintFn printFn = [](auto s){}; PyVar builtins; // builtins module PyVar _main; // __main__ module - StlDict _modules; // 3rd modules + PyVarDict _modules; // 3rd modules VM(){ initializeBuiltinClasses(); @@ -99,9 +99,18 @@ public: PyVar call(PyVar callable, PyVarList args){ if(callable->isType(_tp_type)){ - // add type itself as the first argument - args.insert(args.begin(), callable); - callable = getAttr(callable, __new__); + auto it = callable->attribs.find(__new__); + PyVar obj; + if(it != callable->attribs.end()){ + obj = call(it->second, args); + }else{ + obj = newObject(callable, -1); + } + if(obj->isType(callable)){ + PyVarOrNull init_fn = getAttr(obj, __init__, false); + if (init_fn != nullptr) call(init_fn, args); + } + return obj; } if(callable->isType(_tp_bounded_method)){ @@ -115,7 +124,7 @@ public: return f(this, args); } else if(callable->isType(_tp_function)){ _Func fn = PyFunction_AS_C(callable); - StlDict locals; + PyVarDict locals; int i = 0; for(const auto& name : fn.args){ if(i < args.size()) { @@ -412,7 +421,7 @@ public: return None; } - PyVar exec(const _Code& code, const StlDict& locals={}, PyVar _module=nullptr){ + PyVar exec(const _Code& code, const PyVarDict& locals={}, PyVar _module=nullptr){ if(_module == nullptr) _module = _main; auto frame = std::make_shared( code.get(), @@ -492,7 +501,6 @@ public: if(it != cls->attribs.end()){ PyVar valueFromCls = it->second; if(valueFromCls->isType(_tp_function) || valueFromCls->isType(_tp_native_function)){ - if(name == __new__) return valueFromCls; return PyBoundedMethod({obj, valueFromCls}); }else{ return valueFromCls;