diff --git a/src/ceval.h b/src/ceval.h index 64922653..db1d1472 100644 --- a/src/ceval.h +++ b/src/ceval.h @@ -482,40 +482,10 @@ __NEXT_STEP:; } DISPATCH(); /*****************************************/ - TARGET(IMPORT_NAME) { - StrName name(byte.arg); - PyObject* ext_mod = _modules.try_get(name); - if(ext_mod == nullptr){ - Str source; - auto it = _lazy_modules.find(name); - if(it == _lazy_modules.end()){ - Bytes b = _read_file_cwd(fmt(name, ".py")); - if(!b) { - for(Str path: _path){ -#ifdef _WIN32 - const char* sep = "\\"; -#else - const char* sep = "/"; -#endif - b = _read_file_cwd(fmt(path, sep, name, ".py")); - if(b) break; - } - if(!b) _error("ImportError", fmt("module ", name.escape(), " not found")); - } - source = Str(b.str()); - }else{ - source = it->second; - _lazy_modules.erase(it); - } - CodeObject_ code = compile(source, Str(name.sv())+".py", EXEC_MODE); - PyObject* new_mod = new_module(name); - _exec(code, new_mod); - new_mod->attr()._try_perfect_rehash(); - PUSH(new_mod); - }else{ - PUSH(ext_mod); - } - } DISPATCH(); + TARGET(IMPORT_NAME) + _name = StrName(byte.arg); + PUSH(py_import(_name)); + DISPATCH(); TARGET(IMPORT_STAR) _0 = POPX(); for(auto& [name, value]: _0->attr().items()){ diff --git a/src/pocketpy.h b/src/pocketpy.h index 4191e77f..67108cba 100644 --- a/src/pocketpy.h +++ b/src/pocketpy.h @@ -104,6 +104,10 @@ inline void init_builtins(VM* _vm) { return VAR_T(VoidP, obj); }); + _vm->bind_builtin_func<1>("__import__", [](VM* vm, ArgsView args) { + return vm->py_import(CAST(Str&, args[0])); + }); + _vm->bind_builtin_func<2>("divmod", [](VM* vm, ArgsView args) { i64 lhs = CAST(i64, args[0]); i64 rhs = CAST(i64, args[1]); diff --git a/src/vm.h b/src/vm.h index ca58b19c..79e4bfb2 100644 --- a/src/vm.h +++ b/src/vm.h @@ -548,6 +548,40 @@ public: return _all_types[obj->type].obj; } + PyObject* py_import(StrName name){ + PyObject* ext_mod = _modules.try_get(name); + if(ext_mod == nullptr){ + Str source; + auto it = _lazy_modules.find(name); + if(it == _lazy_modules.end()){ + Bytes b = _read_file_cwd(fmt(name, ".py")); + if(!b) { + for(Str path: _path){ +#ifdef _WIN32 + const char* sep = "\\"; +#else + const char* sep = "/"; +#endif + b = _read_file_cwd(fmt(path, sep, name, ".py")); + if(b) break; + } + if(!b) _error("ImportError", fmt("module ", name.escape(), " not found")); + } + source = Str(b.str()); + }else{ + source = it->second; + _lazy_modules.erase(it); + } + CodeObject_ code = compile(source, Str(name.sv())+".py", EXEC_MODE); + PyObject* new_mod = new_module(name); + _exec(code, new_mod); + new_mod->attr()._try_perfect_rehash(); + return new_mod; + }else{ + return ext_mod; + } + } + ~VM() { callstack.clear(); s_data.clear();